Hook "gui_light" value from the model into the IBakedModel implementations.

Apply some of the suggestions from the 1.14 models PR.
This commit is contained in:
David Quintana 2020-01-23 22:41:32 +01:00
parent c4e000dbe7
commit 509a28efd3
18 changed files with 239 additions and 103 deletions

View File

@ -5,7 +5,7 @@
private final ItemCameraTransforms field_177651_f;
+ public Builder(net.minecraftforge.client.model.IModelConfiguration model, ItemOverrideList overrides) {
+ this(model.useSmoothLighting(), model.isShadedInGui(), true/*TODO: Forge*/, model.getCameraTransforms(), overrides);
+ this(model.useSmoothLighting(), model.isShadedInGui(), model.isSideLit(), model.getCameraTransforms(), overrides);
+ }
+
public Builder(BlockModel p_i230060_1_, ItemOverrideList p_i230060_2_, boolean p_i230060_3_) {

View File

@ -17,14 +17,13 @@
p_195667_3_[i].func_227788_a_(i, this.field_110975_c >> i, this.field_110974_d >> i, p_195667_1_ >> i, p_195667_2_ >> i, this.field_229226_c_.field_229245_b_ >> i, this.field_229226_c_.field_229246_c_ >> i, this.field_195670_c.length > 1, false);
}
@@ -341,4 +342,10 @@
@@ -341,4 +342,9 @@
}
}
+
+
+ // Forge Start
+
+ public int getPixelRGBA(int frameIndex, int x, int y) {
+ return this.field_195670_c[frameIndex].func_195709_a(x + this.field_195671_d[frameIndex] * func_94211_a(), y + this.field_195672_e[frameIndex] * func_94216_b());
+ return this.field_195670_c[0].func_195709_a(x + this.field_195671_d[frameIndex] * func_94211_a(), y + this.field_195672_e[frameIndex] * func_94216_b());
+ }
}

View File

@ -1,3 +1,22 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.event;
import com.mojang.blaze3d.matrix.MatrixStack;

View File

@ -43,13 +43,15 @@ public class BakedItemModel implements IBakedModel
protected final ImmutableMap<TransformType, TransformationMatrix> transforms;
protected final ItemOverrideList overrides;
protected final IBakedModel guiModel;
protected final boolean isSideLit;
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TransformationMatrix> transforms, ItemOverrideList overrides, boolean untransformed)
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TransformationMatrix> transforms, ItemOverrideList overrides, boolean untransformed, boolean isSideLit)
{
this.quads = quads;
this.particle = particle;
this.transforms = transforms;
this.overrides = overrides;
this.isSideLit = isSideLit;
this.guiModel = untransformed && hasGuiIdentity(transforms) ? new BakedGuiItemModel<>(this) : null;
}
@ -61,7 +63,7 @@ public class BakedItemModel implements IBakedModel
@Override public boolean isAmbientOcclusion() { return true; }
@Override public boolean isGui3d() { return false; }
@Override public boolean func_230044_c_() { return false; }
@Override public boolean func_230044_c_() { return isSideLit; }
@Override public boolean isBuiltInRenderer() { return false; }
@Override public TextureAtlasSprite getParticleTexture() { return particle; }
@Override public ItemOverrideList getOverrides() { return overrides; }

View File

@ -106,7 +106,13 @@ public class BlockModelConfiguration implements IModelConfiguration
@Override
public boolean isShadedInGui() {
return owner.func_230176_c_() == BlockModel.GuiLight.SIDE;
return true;
}
@Override
public boolean isSideLit()
{
return owner.func_230176_c_().func_230178_a_();
}
@Override

View File

@ -1,43 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.model;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation;
import java.util.function.Function;
/**
* For use when loading a custom model for use in entity/tileentity renderers, or other situations in which the main atlas is not wanted.
*/
/*
public class DummyAtlasSprite extends TextureAtlasSprite
{
public static final TextureAtlasSprite INSTANCE = new DummyAtlasSprite();
public static final Function<ResourceLocation, TextureAtlasSprite> GETTER = t -> INSTANCE;
private DummyAtlasSprite()
{
super(new ResourceLocation("forge", "dummy"), 1, 1);
// Set the min/max coords to 0..1 range, to use the full texture.
func_217789_a(0, 0, 1, 1);
}
}
*/

View File

@ -32,7 +32,6 @@ import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.texture.MissingTextureSprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.LivingEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.Fluids;
@ -185,7 +184,7 @@ public final class DynamicBucketModel implements IModelGeometry<DynamicBucketMod
}
}
return new BakedModel(bakery, owner, this, builder.build(), particleSprite, Maps.immutableEnumMap(transformMap), Maps.newHashMap(), transform.isIdentity(), modelTransform);
return new BakedModel(bakery, owner, this, builder.build(), particleSprite, Maps.immutableEnumMap(transformMap), Maps.newHashMap(), transform.isIdentity(), modelTransform, owner.isSideLit());
}
@Override
@ -297,6 +296,7 @@ public final class DynamicBucketModel implements IModelGeometry<DynamicBucketMod
private final DynamicBucketModel parent;
private final Map<String, IBakedModel> cache; // contains all the baked models since they'll never change
private final IModelTransform originalTransform;
private final boolean isSideLit;
BakedModel(ModelBakery bakery,
IModelConfiguration owner, DynamicBucketModel parent,
@ -305,13 +305,14 @@ public final class DynamicBucketModel implements IModelGeometry<DynamicBucketMod
ImmutableMap<TransformType, TransformationMatrix> transforms,
Map<String, IBakedModel> cache,
boolean untransformed,
IModelTransform originalTransform)
IModelTransform originalTransform, boolean isSideLit)
{
super(quads, particle, transforms, new ContainedFluidOverrideHandler(bakery), untransformed);
super(quads, particle, transforms, new ContainedFluidOverrideHandler(bakery), untransformed, isSideLit);
this.owner = owner;
this.parent = parent;
this.cache = cache;
this.originalTransform = originalTransform;
this.isSideLit = isSideLit;
}
}

View File

@ -178,7 +178,7 @@ final class FancyMissingModel implements IUnbakedModel
public boolean isGui3d() { return false; }
@Override
public boolean func_230044_c_() { return false; } // TODO: Forge: Auto-generated method stub
public boolean func_230044_c_() { return false; }
@Override
public boolean isBuiltInRenderer() { return false; }

View File

@ -442,7 +442,6 @@ public final class FluidModel implements IModelGeometry<FluidModel>
@Override
public boolean func_230044_c_()
{
// TODO: Forge: Auto-generated method stub
return false;
}

View File

@ -62,6 +62,11 @@ public interface IModelConfiguration {
*/
boolean isShadedInGui();
/**
* @return True if the item is lit from the side
*/
boolean isSideLit();
/**
* @return True if the item requires per-vertex lighting.
*/

View File

@ -26,7 +26,6 @@ import net.minecraft.client.renderer.TransformationMatrix;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
@ -91,7 +90,7 @@ public final class ItemLayerModel implements IModelGeometry<ItemLayerModel>
owner.isTexturePresent("particle") ? owner.resolveTexture("particle") : textures.get(0)
);
ImmutableMap<TransformType, TransformationMatrix> map = PerspectiveMapWrapper.getTransforms(modelTransform);
return new BakedItemModel(quads, particle, map, overrides, transform.isIdentity());
return new BakedItemModel(quads, particle, map, overrides, transform.isIdentity(), owner.isSideLit());
}
public static ImmutableList<BakedQuad> getQuadsForSprites(List<Material> textures, TransformationMatrix transform, Function<Material, TextureAtlasSprite> spriteGetter)

View File

@ -47,35 +47,50 @@ import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Central hub for custom model loaders.
*/
public class ModelLoaderRegistry
{
public static final String WHITE_TEXTURE = "forge:white";
private static final Map<ResourceLocation, IModelLoader<?>> loaders = Maps.newHashMap();
private static volatile boolean registryFrozen = false;
// Forge built-in loaders
public static void init()
{
registerLoader(new ResourceLocation("forge:obj"), OBJLoader.INSTANCE);
registerLoader(new ResourceLocation("forge:bucket"), DynamicBucketModel.Loader.INSTANCE);
registerLoader(new ResourceLocation("forge:composite"), CompositeModel.Loader.INSTANCE);
registerLoader(new ResourceLocation("minecraft:elements"), VanillaProxy.Loader.INSTANCE);
registerLoader(new ResourceLocation("forge:multi-layer"), MultiLayerModel.Loader.INSTANCE);
registerLoader(new ResourceLocation("minecraft","elements"), VanillaProxy.Loader.INSTANCE);
registerLoader(new ResourceLocation("forge","obj"), OBJLoader.INSTANCE);
registerLoader(new ResourceLocation("forge","bucket"), DynamicBucketModel.Loader.INSTANCE);
registerLoader(new ResourceLocation("forge","composite"), CompositeModel.Loader.INSTANCE);
registerLoader(new ResourceLocation("forge","multi-layer"), MultiLayerModel.Loader.INSTANCE);
// TODO: Implement as new model loaders
//registerLoader(new ResourceLocation("forge:b3d"), new ModelLoaderAdapter(B3DLoader.INSTANCE));
//registerLoader(new ResourceLocation("forge:fluid"), new ModelLoaderAdapter(ModelFluid.FluidLoader.INSTANCE));
}
public static void initComplete()
{
registryFrozen = true;
}
/**
* Makes system aware of your loader.
*/
public static void registerLoader(ResourceLocation id, IModelLoader<?> loader)
{
loaders.put(id, loader);
((IReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addReloadListener(loader);
if (registryFrozen)
throw new IllegalStateException("Can not register model loaders after models have started loading. Please use FMLClientSetupEvent or ModelRegistryEvent to register your loaders.");
synchronized(loaders)
{
loaders.put(id, loader);
((IReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addReloadListener(loader);
}
}
public static IModelGeometry<?> getModel(ResourceLocation loaderId, JsonDeserializationContext deserializationContext, JsonObject data)
@ -83,7 +98,10 @@ public class ModelLoaderRegistry
try
{
if (!loaders.containsKey(loaderId))
throw new IllegalStateException(String.format("Model loader '%s' not found.", loaderId));
{
throw new IllegalStateException(String.format("Model loader '%s' not found. Registered loaders: %s", loaderId,
loaders.keySet().stream().map(ResourceLocation::toString).collect(Collectors.joining(", "))));
}
IModelLoader<?> loader = loaders.get(loaderId);
@ -106,12 +124,26 @@ public class ModelLoaderRegistry
return getModel(loader, deserializationContext, object);
}
private static final Pattern FILESYSTEM_PATH_TO_RESLOC = Pattern.compile("(?:.*[\\\\/]assets[\\\\/](?<namespace>[a-z_-]+)[\\\\/]textures[\\\\/])?(?<path>[a-z_\\\\/-]+)\\.png");
/* Explanation:
* This takes anything that looks like a valid resourcepack texture location, and tries to extract a resourcelocation out of it.
* 1. it will ignore anything up to and including an /assets/ folder,
* 2. it will take the next path component as a namespace,
* 3. it will match but skip the /textures/ part of the path,
* 4. it will take the rest of the path up to but excluding the .png extension as the resource path
* It's a best-effort situation, to allow model files exported by modelling software to be used without post-processing.
* Example:
* C:\Something\Or Other\src\main\resources\assets\mymodid\textures\item\my_thing.png
* ........................................--------_______----------_____________----
* <namespace> <path>
* Result after replacing '\' to '/': mymodid:item/my_thing
*/
private static final Pattern FILESYSTEM_PATH_TO_RESLOC =
Pattern.compile("(?:.*[\\\\/]assets[\\\\/](?<namespace>[a-z_-]+)[\\\\/]textures[\\\\/])?(?<path>[a-z_\\\\/-]+)\\.png");
public static Material resolveTexture(@Nullable String tex, IModelConfiguration owner)
{
if (tex == null)
return blockMaterial("forge:white");
return blockMaterial(WHITE_TEXTURE);
if (tex.startsWith("#"))
return owner.resolveTexture(tex);

View File

@ -93,7 +93,7 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
return new MultiLayerBakedModel(
owner.useSmoothLighting(), owner.isShadedInGui(),
spriteGetter.apply(owner.resolveTexture("particle")), overrides,
owner.isSideLit(), spriteGetter.apply(owner.resolveTexture("particle")), overrides,
buildModels(models, modelTransform, bakery, spriteGetter, modelLocation),
missing.func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation),
PerspectiveMapWrapper.getTransforms(new ModelTransformComposition(owner.getCombinedTransform(), modelTransform)));
@ -105,14 +105,16 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
private final ImmutableMap<TransformType, TransformationMatrix> cameraTransforms;
protected final boolean ambientOcclusion;
protected final boolean gui3d;
protected final boolean isSideLit;
protected final TextureAtlasSprite particle;
protected final ItemOverrideList overrides;
private final IBakedModel missing;
public MultiLayerBakedModel(
boolean ambientOcclusion, boolean isGui3d, TextureAtlasSprite particle, ItemOverrideList overrides,
boolean ambientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrideList overrides,
ImmutableMap<RenderType, IBakedModel> models, IBakedModel missing, ImmutableMap<TransformType, TransformationMatrix> cameraTransforms)
{
this.isSideLit = isSideLit;
this.models = models;
this.cameraTransforms = cameraTransforms;
this.missing = missing;
@ -167,8 +169,7 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
@Override
public boolean func_230044_c_()
{
// TODO: Forge: Auto-generated method stub
return false;
return isSideLit;
}
@Override

View File

@ -44,7 +44,6 @@ import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.MissingTextureSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraftforge.client.model.*;
import net.minecraftforge.common.model.*;
@ -151,9 +150,9 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
if(model == null) throw new ModelLoadingException("Error loading model previously: " + file);
if(!(model.getRoot().getKind() instanceof Mesh))
{
return new ModelWrapper(modelLocation, model, ImmutableSet.of(), true, true, 1);
return new ModelWrapper(modelLocation, model, ImmutableSet.of(), true, true, true, 1);
}
return new ModelWrapper(modelLocation, model, ImmutableSet.of(model.getRoot().getName()), true, true, 1);
return new ModelWrapper(modelLocation, model, ImmutableSet.of(model.getRoot().getName()), true, true, true, 1);
}
public static final class B3DState implements IModelTransform
@ -406,18 +405,20 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
private final ImmutableMap<String, String> textures;
private final boolean smooth;
private final boolean gui3d;
private final boolean isSideLit;
private final int defaultKey;
public ModelWrapper(ResourceLocation modelLocation, B3DModel model, ImmutableSet<String> meshes, boolean smooth, boolean gui3d, int defaultKey)
public ModelWrapper(ResourceLocation modelLocation, B3DModel model, ImmutableSet<String> meshes, boolean smooth, boolean gui3d, boolean isSideLit, int defaultKey)
{
this(modelLocation, model, meshes, smooth, gui3d, defaultKey, buildTextures(model.getTextures()));
this(modelLocation, model, meshes, smooth, gui3d, isSideLit, defaultKey, buildTextures(model.getTextures()));
}
public ModelWrapper(ResourceLocation modelLocation, B3DModel model, ImmutableSet<String> meshes, boolean smooth, boolean gui3d, int defaultKey, ImmutableMap<String, String> textures)
public ModelWrapper(ResourceLocation modelLocation, B3DModel model, ImmutableSet<String> meshes, boolean smooth, boolean gui3d, boolean isSideLit, int defaultKey, ImmutableMap<String, String> textures)
{
this.modelLocation = modelLocation;
this.model = model;
this.meshes = meshes;
this.isSideLit = isSideLit;
this.textures = textures;
this.smooth = smooth;
this.gui3d = gui3d;
@ -477,7 +478,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
}
}
builder.put("missingno", missing);
return new BakedWrapper(model.getRoot(), modelTransform, smooth, gui3d, meshes, builder.build());
return new BakedWrapper(model.getRoot(), modelTransform, smooth, gui3d, isSideLit, meshes, builder.build());
}
public ModelWrapper retexture(ImmutableMap<String, String> textures)
@ -501,7 +502,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
builder.put(e);
}
}
return new ModelWrapper(modelLocation, model, meshes, smooth, gui3d, defaultKey, builder.build());
return new ModelWrapper(modelLocation, model, meshes, smooth, gui3d, isSideLit, defaultKey, builder.build());
}
public ModelWrapper process(ImmutableMap<String, String> data)
@ -514,7 +515,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
JsonElement e = new JsonParser().parse(data.get("mesh"));
if(e.isJsonPrimitive() && e.getAsJsonPrimitive().isString())
{
return new ModelWrapper(modelLocation, model, ImmutableSet.of(e.getAsString()), smooth, gui3d, defaultKey, textures);
return new ModelWrapper(modelLocation, model, ImmutableSet.of(e.getAsString()), smooth, gui3d, isSideLit, defaultKey, textures);
}
else if (e.isJsonArray())
{
@ -554,7 +555,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
return this;
}
}
return hasChanged ? new ModelWrapper(modelLocation, model, newMeshes, smooth, gui3d, newDefaultKey, textures) : this;
return hasChanged ? new ModelWrapper(modelLocation, model, newMeshes, smooth, gui3d, isSideLit, newDefaultKey, textures) : this;
}
@Override
@ -578,7 +579,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
{
return this;
}
return new ModelWrapper(modelLocation, model, meshes, value, gui3d, defaultKey, textures);
return new ModelWrapper(modelLocation, model, meshes, value, gui3d, isSideLit, defaultKey, textures);
}
public ModelWrapper gui3d(boolean value)
@ -587,7 +588,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
{
return this;
}
return new ModelWrapper(modelLocation, model, meshes, smooth, value, defaultKey, textures);
return new ModelWrapper(modelLocation, model, meshes, smooth, value, isSideLit, defaultKey, textures);
}
}
@ -597,15 +598,16 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
private final IModelTransform state;
private final boolean smooth;
private final boolean gui3d;
private final boolean isSideLit;
private final ImmutableSet<String> meshes;
private final ImmutableMap<String, TextureAtlasSprite> textures;
private final LoadingCache<Integer, B3DState> cache;
private ImmutableList<BakedQuad> quads;
public BakedWrapper(final Node<?> node, final IModelTransform state, final boolean smooth, final boolean gui3d, final ImmutableSet<String> meshes, final ImmutableMap<String, TextureAtlasSprite> textures)
public BakedWrapper(final Node<?> node, final IModelTransform state, final boolean smooth, final boolean gui3d, boolean isSideLit, final ImmutableSet<String> meshes, final ImmutableMap<String, TextureAtlasSprite> textures)
{
this(node, state, smooth, gui3d, meshes, textures, CacheBuilder.newBuilder()
this(node, state, smooth, gui3d, isSideLit, meshes, textures, CacheBuilder.newBuilder()
.maximumSize(128)
.expireAfterAccess(2, TimeUnit.MINUTES)
.build(new CacheLoader<Integer, B3DState>()
@ -625,12 +627,13 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
}));
}
public BakedWrapper(Node<?> node, IModelTransform state, boolean smooth, boolean gui3d, ImmutableSet<String> meshes, ImmutableMap<String, TextureAtlasSprite> textures, LoadingCache<Integer, B3DState> cache)
public BakedWrapper(Node<?> node, IModelTransform state, boolean smooth, boolean gui3d, boolean isSideLit, ImmutableSet<String> meshes, ImmutableMap<String, TextureAtlasSprite> textures, LoadingCache<Integer, B3DState> cache)
{
this.node = node;
this.state = state;
this.smooth = smooth;
this.gui3d = gui3d;
this.isSideLit = isSideLit;
this.meshes = meshes;
this.textures = textures;
this.cache = cache;
@ -797,8 +800,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
@Override
public boolean func_230044_c_()
{
// TODO: Forge: Auto-generated method stub
return false;
return isSideLit;
}
@Override

View File

@ -125,6 +125,7 @@ public class ClientModLoader
private static void postSidedRunnable(Consumer<Supplier<Event>> perModContainerEventProcessor) {
RenderingRegistry.loadEntityRenderers(mc.getRenderManager());
ModelLoaderRegistry.initComplete();
}
private static void preSidedRunnable(Consumer<Supplier<Event>> perModContainerEventProcessor) {

View File

@ -19,32 +19,37 @@
package net.minecraftforge.debug.client.model;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.mojang.datafixers.util.Pair;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FourWayBlock;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.*;
import net.minecraft.resources.IResourceManager;
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.obj.OBJLoader;
import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.NonNullLazy;
import net.minecraftforge.client.model.IModelBuilder;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.ISimpleModelGeometry;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.common.Mod;
@ -54,6 +59,10 @@ import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Function;
@Mod(NewModelLoaderTest.MODID)
public class NewModelLoaderTest
@ -105,11 +114,89 @@ public class NewModelLoaderTest
new Item(new Item.Properties().group(ItemGroup.MISC))
);
public static RegistryObject<Item> custom_loader = ITEMS.register("custom_loader", () ->
new Item(new Item.Properties().group(ItemGroup.MISC))
);
public NewModelLoaderTest()
{
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
BLOCKS.register(modEventBus);
ITEMS.register(modEventBus);
modEventBus.addListener(this::clientSetup);
}
public void clientSetup(FMLClientSetupEvent event)
{
ModelLoaderRegistry.registerLoader(new ResourceLocation(MODID, "custom_loader"), new TestLoader());
}
static class TestLoader implements IModelLoader<TestModel>
{
@Override
public void onResourceManagerReload(IResourceManager resourceManager)
{
}
@Override
public TestModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
{
return new TestModel();
}
}
static class TestModel implements ISimpleModelGeometry<TestModel>
{
@Override
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<net.minecraft.client.renderer.model.Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
TextureAtlasSprite texture = spriteGetter.apply(owner.resolveTexture("particle"));
BakedQuadBuilder builder = new BakedQuadBuilder();
builder.setTexture(texture);
builder.setQuadOrientation(Direction.UP);
putVertex(builder, 0,1,0.5f, texture.getInterpolatedU(0), texture.getInterpolatedV(0), 1, 1, 1);
putVertex(builder, 0,0,0.5f, texture.getInterpolatedU(0), texture.getInterpolatedV(16), 1, 1, 1);
putVertex(builder, 1,0,0.5f, texture.getInterpolatedU(16), texture.getInterpolatedV(16), 1, 1, 1);
putVertex(builder, 1,1,0.5f, texture.getInterpolatedU(16), texture.getInterpolatedV(0), 1, 1, 1);
modelBuilder.addGeneralQuad(builder.build());
}
private void putVertex(BakedQuadBuilder builder, int x, float y, float z, float u, float v, float red, float green, float blue)
{
ImmutableList<VertexFormatElement> elements = DefaultVertexFormats.BLOCK.func_227894_c_();
for(int i=0;i<elements.size();i++)
{
switch(elements.get(i).getUsage())
{
case POSITION:
builder.put(i, x, y, z);
break;
case UV:
if (elements.get(i).getIndex() == 0)
builder.put(i, u, v);
else
builder.put(i);
break;
case COLOR:
builder.put(i, red, green, blue, 1.0f);
break;
default:
builder.put(i);
break;
}
}
}
@Override
public Collection<net.minecraft.client.renderer.model.Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors)
{
return Collections.singleton(owner.resolveTexture("particle"));
}
}
}

View File

@ -1,3 +1,22 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.debug.client.rendering;
import net.minecraft.entity.passive.CowEntity;

View File

@ -0,0 +1,7 @@
{
"parent": "forge:item/default",
"loader": "new_model_loader_test:custom_loader",
"textures": {
"particle": "item/quartz"
}
}