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 committed 2020-01-23 22:54:54 +01:00
1 parent c4e000dbe7
commit 509a28efd3
18 files changed
+239 -103

No files matched your search

@@ -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;
@@ -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; }
@@ -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
@@ -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);
}
}
*/
@@ -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;
}
}
@@ -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; }
@@ -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;
}
@@ -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.
*/
@@ -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)
@@ -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);
@@ -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
@@ -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
@@ -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) {