More model/rendering fixes:

- Breaking change: Change ClientRegistry.bindTileEntityRenderer to a factory, so mods don't have to manually specify the dispatcher.
- Breaking change: Delete obsolete SimpleModelState (the class was duplicated by mistake, see SimpleModelTransform) and ICustomModelState (part of the old loader API).
- Breaking change: Rename getTextureDependencies to getTextures, for consistency.
- Reinstate the getRenderLayer method, fixed appropriately to return the new RenderType value.
- Fix OBJ loader applying the model transform in the wrong reference frame.
- Fix vanilla bug in TransformationMatrix#func_227986_a_
- Fix QuadTransformer logic.
- Added new method to IModelConfiguration to retrieve the owner IUnbakedModel, needed in order to construct ItemOverrideLists when baking custom models.
- Reintroduce multi-layer model through the new model loader system.
This commit is contained in:
David Quintana 2019-12-27 22:30:16 +01:00
parent e8ce61d4cd
commit fc189c9aaf
29 changed files with 325 additions and 344 deletions

View file

@ -25,7 +25,7 @@
}
- p_229111_8_.func_177552_f().func_181688_b(p_229111_2_).func_228830_a_(p_229111_3_, p_229111_4_);
+ net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(p_229111_4_, p_229111_8_, p_229111_2_, p_229111_3_);
+ p_229111_8_ = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(p_229111_4_, p_229111_8_, p_229111_2_, p_229111_3_);
p_229111_4_.func_227861_a_(-0.5D, -0.5D, -0.5D);
if (!p_229111_8_.func_188618_c() && (p_229111_1_.func_77973_b() != Items.field_203184_eO || flag1)) {
RenderType rendertype = RenderTypeLookup.func_228389_a_(p_229111_1_);

View file

@ -9,6 +9,15 @@
private final Matrix4f field_227976_a_;
private boolean field_227977_b_;
@Nullable
@@ -97,7 +97,7 @@
if (p_227986_0_ != null) {
matrix4f.field_226578_d_ = p_227986_0_.func_195899_a();
matrix4f.field_226582_h_ = p_227986_0_.func_195900_b();
- matrix4f.field_226589_o_ = p_227986_0_.func_195902_c();
+ matrix4f.field_226586_l_ = p_227986_0_.func_195902_c();
}
return matrix4f;
@@ -133,4 +133,32 @@
public int hashCode() {
return Objects.hash(this.field_227976_a_);

View file

@ -34,6 +34,7 @@ import java.util.function.Supplier;
import javax.annotation.Nonnull;
import net.minecraft.client.renderer.RenderType;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.cache.Cache;
@ -52,11 +53,10 @@ import net.minecraft.world.World;
public class MinecraftForgeClient
{
/* TODO: reimplement
public static BlockRenderLayer getRenderLayer()
public static RenderType getRenderLayer()
{
return ForgeHooksClient.renderLayer.get();
}*/
}
/**
* returns the Locale set by the player in Minecraft.

View file

@ -44,6 +44,13 @@ public class BlockModelConfiguration implements IModelConfiguration
this.owner = owner;
}
@Nullable
@Override
public IUnbakedModel getOwnerModel()
{
return owner;
}
@Override
public String getModelName()
{
@ -138,12 +145,12 @@ public class BlockModelConfiguration implements IModelConfiguration
geometry.getTextures(this, modelGetter, missingTextureErrors);
}
public IBakedModel bake(ModelBakery bakery, Function<Material, TextureAtlasSprite> bakedTextureGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation)
public IBakedModel bake(ModelBakery bakery, Function<Material, TextureAtlasSprite> bakedTextureGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
IModelGeometry<?> geometry = getCustomGeometry();
if (geometry == null)
throw new IllegalStateException("Can not use custom baking without custom geometry");
return geometry.bake(this, bakery, bakedTextureGetter, sprite, overrides, modelLocation);
return geometry.bake(this, bakery, bakedTextureGetter, modelTransform, overrides, modelLocation);
}
public static class VisibilityData

View file

@ -109,10 +109,10 @@ final class FancyMissingModel implements IUnbakedModel
@Nullable
@Override
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
IBakedModel bigMissing = missingModel.func_225613_a_(bakery, spriteGetter, sprite, modelLocation);
ModelTransformComposition smallState = new ModelTransformComposition(sprite, new SimpleModelTransform(smallTransformation));
IBakedModel bigMissing = missingModel.func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation);
ModelTransformComposition smallState = new ModelTransformComposition(modelTransform, new SimpleModelTransform(smallTransformation));
IBakedModel smallMissing = missingModel.func_225613_a_(bakery, spriteGetter, smallState, modelLocation);
return new BakedModel(bigMissing, smallMissing, fontCache.getUnchecked(DefaultVertexFormats.BLOCK), message, spriteGetter.apply(font2));
}

View file

@ -1,64 +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 java.util.function.Predicate;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.resource.VanillaResourceType;
public interface ICustomModelLoader extends ISelectiveResourceReloadListener
{
@Override
void onResourceManagerReload(IResourceManager resourceManager);
@Override
default void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate)
{
if (resourcePredicate.test(VanillaResourceType.MODELS))
{
onResourceManagerReload(resourceManager);
}
}
/**
* Checks if given model should be loaded by this loader.
* Reading file contents is inadvisable, if possible decision should be made based on the location alone.
* @param modelLocation The path, either to an actual file or a {@link net.minecraft.client.renderer.model.ModelResourceLocation}.
*/
boolean accepts(ResourceLocation modelLocation);
/**
* @param modelLocation The model to (re)load, either path to an
* actual file or a {@link net.minecraft.client.renderer.model.ModelResourceLocation}.
*/
IUnbakedModel loadModel(ResourceLocation modelLocation) throws Exception;
@Override
default IResourceType getResourceType()
{
return VanillaResourceType.MODELS;
}
}

View file

@ -20,15 +20,25 @@
package net.minecraftforge.client.model;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.Material;
import net.minecraftforge.client.model.geometry.IModelGeometryPart;
import javax.annotation.Nullable;
/*
* Interface that provides generic access to the data within BlockModel,
* while allowing non-blockmodel usage of models
*/
public interface IModelConfiguration {
/**
* If available, gets the owning model (usually BlockModel) of this configuration
*/
@Nullable
IUnbakedModel getOwnerModel();
/**
* @return The name of the model being baked, for logging and cache purposes.
*/

View file

@ -82,15 +82,15 @@ public final class ItemLayerModel implements IModelGeometry<ItemLayerModel>
}
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation)
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
//TODO: Verify
TransformationMatrix transform = sprite.func_225615_b_();
TransformationMatrix transform = modelTransform.func_225615_b_();
ImmutableList<BakedQuad> quads = getQuadsForSprites(textures, DefaultVertexFormats.BLOCK, transform, spriteGetter);
TextureAtlasSprite particle = spriteGetter.apply(
owner.isTexturePresent("particle") ? owner.resolveTexture("particle") : textures.get(0)
);
ImmutableMap<TransformType, TransformationMatrix> map = PerspectiveMapWrapper.getTransforms(sprite);
ImmutableMap<TransformType, TransformationMatrix> map = PerspectiveMapWrapper.getTransforms(modelTransform);
return new BakedItemModel(quads, particle, map, overrides, transform.isIdentity());
}

View file

@ -80,12 +80,12 @@ public final class ModelFluid implements IModelGeometry<ModelFluid>
}
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation)
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
FluidAttributes attrs = fluid.getAttributes();
return new CachingBakedFluid(
sprite.func_225615_b_(),
PerspectiveMapWrapper.getTransforms(sprite),
modelTransform.func_225615_b_(),
PerspectiveMapWrapper.getTransforms(modelTransform),
modelLocation,
attrs.getColor(),
spriteGetter.apply(ForgeHooksClient.getBlockMaterial(attrs.getStillTexture())),

View file

@ -63,11 +63,11 @@ public class ModelLoaderRegistry
registerLoader(new ResourceLocation("forge:bucket"), ModelDynBucket.LoaderDynBucket2.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);
// 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));
//registerLoader(new ResourceLocation("forge:multi-layer"), new ModelLoaderAdapter(MultiLayerModel.Loader.INSTANCE));
}
/**
@ -212,22 +212,22 @@ public class ModelLoaderRegistry
}
}
public static IBakedModel bakeHelper(BlockModel blockModel, ModelBakery modelBakery, BlockModel otherModel, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public static IBakedModel bakeHelper(BlockModel blockModel, ModelBakery modelBakery, BlockModel otherModel, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
IBakedModel model;
IModelGeometry<?> customModel = blockModel.customData.getCustomGeometry();
IModelTransform customModelState = blockModel.customData.getCustomModelState();
if (customModelState != null)
{
sprite = new ModelTransformComposition(customModelState, sprite, sprite.isUvLock());
modelTransform = new ModelTransformComposition(customModelState, modelTransform, modelTransform.isUvLock());
}
if (customModel != null)
{
model = customModel.bake(blockModel.customData, modelBakery, spriteGetter, sprite, blockModel.getOverrides(modelBakery, otherModel, spriteGetter), modelLocation);
model = customModel.bake(blockModel.customData, modelBakery, spriteGetter, modelTransform, blockModel.getOverrides(modelBakery, otherModel, spriteGetter), modelLocation);
}
else
{
model = blockModel.bakeVanilla(modelBakery, otherModel, spriteGetter, sprite, modelLocation);
model = blockModel.bakeVanilla(modelBakery, otherModel, spriteGetter, modelTransform, modelLocation);
}
if (customModelState != null && !model.doesHandlePerspectives())
@ -248,18 +248,18 @@ public class ModelLoaderRegistry
}
@Override
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
for(BlockPart blockpart : elements) {
for(Direction direction : blockpart.mapFaces.keySet()) {
BlockPartFace blockpartface = blockpart.mapFaces.get(direction);
TextureAtlasSprite textureatlassprite1 = spriteGetter.apply(owner.resolveTexture(blockpartface.texture));
if (blockpartface.cullFace == null) {
modelBuilder.addGeneralQuad(BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction, sprite, modelLocation));
modelBuilder.addGeneralQuad(BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction, modelTransform, modelLocation));
} else {
modelBuilder.addFaceQuad(
sprite.func_225615_b_().rotateTransform(blockpartface.cullFace),
BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction, sprite, modelLocation));
modelTransform.func_225615_b_().rotateTransform(blockpartface.cullFace),
BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction, modelTransform, modelLocation));
}
}
}

View file

@ -19,138 +19,115 @@
package net.minecraftforge.client.model;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.collect.Sets;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.datafixers.util.Pair;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.RenderType;
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.resources.IResourceManager;
import net.minecraft.util.Direction;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.function.Function;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
/**
* A model that can be rendered in multiple {@link BlockRenderLayer}.
* A model that can be rendered in multiple {@link RenderType}.
*/
/* TODO: reimplement
public final class MultiLayerModel implements IUnbakedModel
public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
{
private static final Logger LOGGER = LogManager.getLogger();
public static final MultiLayerModel INSTANCE = new MultiLayerModel(ImmutableMap.of());
private final ImmutableMap<Optional<BlockRenderLayer>, ResourceLocation> models;
private final ImmutableMap<RenderType, IUnbakedModel> models;
@Nullable
private final IUnbakedModel base;
public MultiLayerModel(ImmutableMap<Optional<BlockRenderLayer>, ResourceLocation> models)
public MultiLayerModel(@Nullable IUnbakedModel base, ImmutableMap<RenderType, IUnbakedModel> models)
{
this.base = base;
this.models = models;
}
@Override
public Collection<ResourceLocation> getDependencies()
{
return ImmutableList.copyOf(models.values());
}
@Override
public Collection<Material> func_225614_a_(Function<ResourceLocation, IUnbakedModel> p_225614_1_, Set<com.mojang.datafixers.util.Pair<String, String>> p_225614_2_)
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors)
{
Set<Material> materials = Sets.newHashSet();
if (base != null)
materials.addAll(base.func_225614_a_(modelGetter, missingTextureErrors));
for (IUnbakedModel m : models.values())
materials.addAll(m.func_225614_a_(modelGetter, missingTextureErrors));
return Collections.emptyList();
}
private static ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> buildModels(ImmutableMap<Optional<BlockRenderLayer>, ResourceLocation> models, IModelTransform sprite, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, ResourceLocation p_225613_4_)
private static ImmutableMap<RenderType, IBakedModel> buildModels(ImmutableMap<RenderType, IUnbakedModel> models, IModelTransform modelTransform, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, ResourceLocation modelLocation)
{
ImmutableMap.Builder<Optional<BlockRenderLayer>, IBakedModel> builder = ImmutableMap.builder();
for(Optional<BlockRenderLayer> key : models.keySet())
ImmutableMap.Builder<RenderType, IBakedModel> builder = ImmutableMap.builder();
for(Map.Entry<RenderType, IUnbakedModel> entry : models.entrySet())
{
IUnbakedModel model = ModelLoader.defaultModelGetter().apply(models.get(key));
builder.put(key, model.func_225613_a_(bakery, spriteGetter, sprite, p_225613_4_));
builder.put(entry.getKey(), entry.getValue().func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation));
}
return builder.build();
}
@Nullable
@Override
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation p_225613_4_)
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
IUnbakedModel missing = ModelLoader.instance().getMissingModel();
return new MultiLayerBakedModel(
buildModels(models, sprite, bakery, spriteGetter, p_225613_4_),
missing.func_225613_a_(bakery, spriteGetter, sprite, p_225613_4_),
PerspectiveMapWrapper.getTransforms(sprite)
base != null ? base.func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation) : null,
buildModels(models, modelTransform, bakery, spriteGetter, modelLocation),
missing.func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation),
PerspectiveMapWrapper.getTransforms(modelTransform)
);
}
public MultiLayerModel process(ImmutableMap<String, String> customData)
{
ImmutableMap.Builder<Optional<BlockRenderLayer>, ResourceLocation> builder = ImmutableMap.builder();
for(String key : customData.keySet())
{
if("base".equals(key))
{
builder.put(Optional.empty(), getLocation(customData.get(key)));
}
for(BlockRenderLayer layer : BlockRenderLayer.values())
{
if(layer.toString().equals(key))
{
builder.put(Optional.of(layer), getLocation(customData.get(key)));
}
}
}
ImmutableMap<Optional<BlockRenderLayer>, ResourceLocation> models = builder.build();
if(models.isEmpty()) return INSTANCE;
return new MultiLayerModel(models);
}
private ResourceLocation getLocation(String json)
{
JsonElement e = new JsonParser().parse(json);
if(e.isJsonPrimitive() && e.getAsJsonPrimitive().isString())
{
return new ModelResourceLocation(e.getAsString());
}
LOGGER.fatal("Expect ModelResourceLocation, got: {}", json);
return new ModelResourceLocation("builtin/missing", "missing");
}
private static final class MultiLayerBakedModel implements IBakedModel
{
private final ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> models;
private final ImmutableMap<RenderType, IBakedModel> models;
private final ImmutableMap<TransformType, TransformationMatrix> cameraTransforms;
private final IBakedModel base;
private final IBakedModel missing;
public MultiLayerBakedModel(ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> models, IBakedModel missing, ImmutableMap<TransformType, TransformationMatrix> cameraTransforms)
public MultiLayerBakedModel(@Nullable IBakedModel base, ImmutableMap<RenderType, IBakedModel> models, IBakedModel missing, ImmutableMap<TransformType, TransformationMatrix> cameraTransforms)
{
this.models = models;
this.cameraTransforms = cameraTransforms;
this.missing = missing;
this.base = models.getOrDefault(Optional.empty(), missing);
this.base = base != null ? base : missing;
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand)
{
BlockRenderLayer layer = MinecraftForgeClient.getRenderLayer();
return getQuads(state, side, rand, EmptyModelData.INSTANCE);
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData)
{
RenderType layer = MinecraftForgeClient.getRenderLayer();
if (layer == null)
{
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
@ -161,7 +138,8 @@ public final class MultiLayerModel implements IUnbakedModel
return builder.build();
}
// assumes that child model will handle this state properly. FIXME?
return models.getOrDefault(Optional.of(layer), missing).getQuads(state, side, rand);
List<BakedQuad> quads = models.getOrDefault(layer, missing).getQuads(state, side, rand, extraData);
return quads;
}
@Override
@ -201,9 +179,9 @@ public final class MultiLayerModel implements IUnbakedModel
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType cameraTransformType)
public IBakedModel handlePerspective(TransformType cameraTransformType, MatrixStack mat)
{
return PerspectiveMapWrapper.handlePerspective(this, cameraTransforms, cameraTransformType);
return PerspectiveMapWrapper.handlePerspective(this, cameraTransforms, cameraTransformType, mat);
}
@Override
@ -212,5 +190,39 @@ public final class MultiLayerModel implements IUnbakedModel
return ItemOverrideList.EMPTY;
}
}
}
*/
public static final class Loader implements IModelLoader<MultiLayerModel>
{
public static final Loader INSTANCE = new Loader();
private Loader() {}
@Override
public void onResourceManagerReload(IResourceManager resourceManager)
{
}
@Override
public MultiLayerModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
{
ImmutableMap.Builder<RenderType, IUnbakedModel> builder = ImmutableMap.builder();
JsonObject layersObject = JSONUtils.getJsonObject(modelContents, "layers");
BlockModel base = null;
if(layersObject.has("base"))
{
base = deserializationContext.deserialize(JSONUtils.getJsonObject(layersObject, "base"), BlockModel.class);
}
for(RenderType layer : RenderType.func_228661_n_()) // block layers
{
String layerName = layer.toString(); // mc overrides toString to return the ID for the layer
if(layersObject.has(layerName))
{
builder.put(layer, deserializationContext.deserialize(JSONUtils.getJsonObject(layersObject, layerName), BlockModel.class));
}
}
ImmutableMap<RenderType, IUnbakedModel> models = builder.build();
return new MultiLayerModel(base, models);
}
}
}

View file

@ -48,22 +48,22 @@ public class QuadTransformer
private void processVertices(int[] inData, int[] outData)
{
int stride = format.getIntegerSize();
int count = inData.length / stride;
int stride = format.getSize();
int count = (inData.length * 4) / stride;
for (int i=0;i<count;i++)
{
int offset = positionOffset + i * stride;
float x = Float.intBitsToFloat(inData[offset ]);
float y = Float.intBitsToFloat(inData[offset + 1]);
float z = Float.intBitsToFloat(inData[offset + 2]);
float x = Float.intBitsToFloat(getAtByteOffset(inData, offset ));
float y = Float.intBitsToFloat(getAtByteOffset(inData, offset + 4));
float z = Float.intBitsToFloat(getAtByteOffset(inData, offset + 8));
Vector4f pos = new Vector4f(x, y, z, 1);
transform.transformPosition(pos);
pos.func_229374_e_();
pos.func_229375_f_();
outData[offset] = Float.floatToRawIntBits(pos.getX());
outData[offset + 1] = Float.floatToRawIntBits(pos.getY());
outData[offset + 2] = Float.floatToRawIntBits(pos.getZ());
putAtByteOffset(outData, offset, Float.floatToRawIntBits(pos.getX()));
putAtByteOffset(outData,offset + 4, Float.floatToRawIntBits(pos.getY()));
putAtByteOffset(outData,offset + 8, Float.floatToRawIntBits(pos.getZ()));
}
if (normalOffset >= 0)
@ -71,25 +71,57 @@ public class QuadTransformer
for (int i=0;i<count;i++)
{
int offset = normalOffset + i * stride;
int normalIn = inData[offset];
float x = (((normalIn)>>24)&0xFF)/255.0f;
float y = (((normalIn<<8)>>24)&0xFF)/255.0f;
float z = (((normalIn<<16)>>24)&0xFF)/255.0f;
int normalIn = getAtByteOffset(inData,offset);
if (normalIn != 0)
{
float x = (((normalIn) >> 24) & 0xFF) / 255.0f;
float y = (((normalIn << 8) >> 24) & 0xFF) / 255.0f;
float z = (((normalIn << 16) >> 24) & 0xFF) / 255.0f;
Vector3f pos = new Vector3f(x, y, z);
transform.transformNormal(pos);
Vector3f pos = new Vector3f(x, y, z);
transform.transformNormal(pos);
pos.func_229194_d_();
int normalOut =
(((int)(x/255.0)&0xFF)<<24) |
(((int)(y/255.0)&0xFF)<<16) |
(((int)(z/255.0)&0xFF)<<8) |
(normalIn&0xFF);
int normalOut = (((int) (x / 255.0) & 0xFF) << 24) |
(((int) (y / 255.0) & 0xFF) << 16) |
(((int) (z / 255.0) & 0xFF) << 8) |
(normalIn & 0xFF);
outData[offset] = normalOut;
putAtByteOffset(outData, offset, normalOut);
}
}
}
}
private static int getAtByteOffset(int[] inData, int offset)
{
int index = offset / 4;
int lsb = inData[index];
int shift = (offset % 4) * 8;
if (shift == 0)
return inData[index];
int msb = inData[index+1];
return (lsb >>> shift) | (msb << (32-shift));
}
private static void putAtByteOffset(int[] outData, int offset, int value)
{
int index = offset / 4;
int shift = (offset % 4) * 8;
if (shift == 0)
outData[index] = value;
int lsbMask = 0xFFFFFFFF >>> (32-shift);
int msbMask = 0xFFFFFFFF << shift;
outData[index] = (outData[index] & lsbMask) | (value << shift);
outData[index+1] = (outData[index+1] & msbMask) | (value >>> (32-shift));
}
private static int findPositionOffset(VertexFormat fmt)
{
int index;

View file

@ -1,57 +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.TransformationMatrix;
import net.minecraft.client.renderer.model.IModelTransform;
import com.google.common.collect.ImmutableMap;
/**
* Simple implementation of IModelState via a map and a default value.
*/
public final class SimpleModelState implements IModelTransform
{
private final ImmutableMap<? extends Object, TransformationMatrix> map;
private final TransformationMatrix def;
public SimpleModelState(ImmutableMap<? extends Object, TransformationMatrix> map)
{
this(map, TransformationMatrix.func_227983_a_());
}
public SimpleModelState(ImmutableMap<? extends Object, TransformationMatrix> map, TransformationMatrix def)
{
this.map = map;
this.def = def;
}
@Override
public TransformationMatrix func_225615_b_()
{
return def;
}
@Override
public TransformationMatrix getPartTransformation(Object part)
{
return map.getOrDefault(part, TransformationMatrix.func_227983_a_());
}
}

View file

@ -460,7 +460,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
@Nullable
@Override
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
ImmutableMap.Builder<String, TextureAtlasSprite> builder = ImmutableMap.builder();
TextureAtlasSprite missing = spriteGetter.apply(new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, MissingTextureSprite.getLocation()));
@ -477,7 +477,7 @@ public enum B3DLoader implements ISelectiveResourceReloadListener
}
}
builder.put("missingno", missing);
return new BakedWrapper(model.getRoot(), sprite, smooth, gui3d, DefaultVertexFormats.BLOCK, meshes, builder.build());
return new BakedWrapper(model.getRoot(), modelTransform, smooth, gui3d, DefaultVertexFormats.BLOCK, meshes, builder.build());
}
public ModelWrapper retexture(ImmutableMap<String, String> textures)

View file

@ -149,13 +149,13 @@ public class CompositeModel implements IBakedModel
{
private final String name;
private final BlockModel model;
private final IModelTransform sprite;
private final IModelTransform modelTransform;
private Submodel(String name, BlockModel model, IModelTransform sprite)
private Submodel(String name, BlockModel model, IModelTransform modelTransform)
{
this.name = name;
this.model = model;
this.sprite = sprite;
this.modelTransform = modelTransform;
}
@Override
@ -165,19 +165,19 @@ public class CompositeModel implements IBakedModel
}
@Override
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
throw new UnsupportedOperationException("Attempted to call adQuads on a Submodel instance. Please don't.");
}
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public IBakedModel func_225613_a_(ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
return model.func_225613_a_(bakery, spriteGetter, new ModelTransformComposition(this.sprite, sprite,
this.sprite.isUvLock() || sprite.isUvLock()), modelLocation);
return model.func_225613_a_(bakery, spriteGetter, new ModelTransformComposition(this.modelTransform, modelTransform,
this.modelTransform.isUvLock() || modelTransform.isUvLock()), modelLocation);
}
@Override
public Collection<Material> getTextureDependencies(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors)
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors)
{
return model.func_225614_a_(modelGetter, missingTextureErrors);
}
@ -205,7 +205,7 @@ public class CompositeModel implements IBakedModel
}
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation)
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
Material particleLocation = owner.resolveTexture("particle");
TextureAtlasSprite particle = spriteGetter.apply(particleLocation);
@ -216,7 +216,7 @@ public class CompositeModel implements IBakedModel
Submodel submodel = part.getValue();
if (!owner.getPartVisibility(submodel))
continue;
bakedParts.put(part.getKey(), submodel.func_225613_a_(bakery, spriteGetter, sprite, modelLocation));
bakedParts.put(part.getKey(), submodel.func_225613_a_(bakery, spriteGetter, modelTransform, modelLocation));
}
return new CompositeModel(owner.isShadedInGui(), owner.useSmoothLighting(), particle, bakedParts.build(), overrides);
}
@ -227,7 +227,7 @@ public class CompositeModel implements IBakedModel
Set<Material> textures = new HashSet<>();
for(Submodel part : parts.values())
{
textures.addAll(part.getTextureDependencies(owner, modelGetter, missingTextureErrors));
textures.addAll(part.getTextures(owner, modelGetter, missingTextureErrors));
}
return textures;
}
@ -254,11 +254,11 @@ public class CompositeModel implements IBakedModel
for(Map.Entry<String, JsonElement> part : modelContents.get("parts").getAsJsonObject().entrySet())
{
// TODO: Allow customizing state? If so, how?
IModelTransform sprite = SimpleModelTransform.IDENTITY;
IModelTransform modelTransform = SimpleModelTransform.IDENTITY;
parts.put(part.getKey(), new Submodel(
part.getKey(),
ModelLoaderRegistry.ExpandedBlockModelDeserializer.INSTANCE.fromJson(part.getValue(), BlockModel.class),
sprite));
deserializationContext.deserialize(part.getValue(), BlockModel.class),
modelTransform));
}
return new Geometry(parts.build());
}

View file

@ -45,7 +45,7 @@ public interface IModelGeometry<T extends IModelGeometry<T>>
return Optional.empty();
}
IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation);
IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation);
Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors);
}

View file

@ -39,9 +39,9 @@ public interface IModelGeometryPart
{
String name();
void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation);
void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation);
default Collection<Material> getTextureDependencies(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
default Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
// No texture dependencies
return Collections.emptyList();
}

View file

@ -43,10 +43,10 @@ public interface IMultipartModelGeometry<T extends IMultipartModelGeometry<T>> e
Optional<? extends IModelGeometryPart> getPart(String name);
@Override
default void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
default void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
getParts().stream().filter(part -> owner.getPartVisibility(part))
.forEach(part -> part.addQuads(owner, modelBuilder, bakery, spriteGetter, sprite, modelLocation));
.forEach(part -> part.addQuads(owner, modelBuilder, bakery, spriteGetter, modelTransform, modelLocation));
}
@Override
@ -54,7 +54,7 @@ public interface IMultipartModelGeometry<T extends IMultipartModelGeometry<T>> e
{
Set<Material> combined = Sets.newHashSet();
for (IModelGeometryPart part : getParts())
combined.addAll(part.getTextureDependencies(owner, modelGetter, missingTextureErrors));
combined.addAll(part.getTextures(owner, modelGetter, missingTextureErrors));
return combined;
}
}

View file

@ -33,18 +33,18 @@ import java.util.function.Function;
public interface ISimpleModelGeometry<T extends ISimpleModelGeometry<T>> extends IModelGeometry<T>
{
@Override
default IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ItemOverrideList overrides, ResourceLocation modelLocation)
default IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
TextureAtlasSprite particle = spriteGetter.apply(owner.resolveTexture("particle"));
IModelBuilder<?> builder = IModelBuilder.of(owner, overrides, particle);
addQuads(owner, builder, bakery, spriteGetter, sprite, modelLocation);
addQuads(owner, builder, bakery, spriteGetter, modelTransform, modelLocation);
return builder.build();
}
void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation);
void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation);
@Override
Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors);

View file

@ -395,7 +395,8 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
Vec2f uv2 = new Vec2f(((float) fakeLight * 0x20) / 0xFFFF, ((float) fakeLight * 0x20) / 0xFFFF);
boolean hasTransform = !transform.isIdentity();
TransformationMatrix transformation = hasTransform ? transform : null;
// The incoming transform is referenced on the center of the block, but our coords are referenced on the corner
TransformationMatrix transformation = hasTransform ? transform.blockCenterToCorner() : transform;
for(int i=0;i<4;i++)
{
@ -556,7 +557,7 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
}
@Override
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
for(ModelMesh mesh : meshes)
{
@ -570,7 +571,7 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
for (int[][] face : mesh.faces)
{
Pair<BakedQuad, Direction> quad = makeQuad(face, tintIndex, colorTint, mat.ambientColor, isFullbright, texture, DefaultVertexFormats.BLOCK, sprite.func_225615_b_());
Pair<BakedQuad, Direction> quad = makeQuad(face, tintIndex, colorTint, mat.ambientColor, isFullbright, texture, DefaultVertexFormats.BLOCK, modelTransform.func_225615_b_());
if (quad.getRight() == null)
modelBuilder.addGeneralQuad(quad.getLeft());
else
@ -580,7 +581,7 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
}
@Override
public Collection<Material> getTextureDependencies(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors)
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors)
{
return meshes.stream().map(mesh -> ModelLoaderRegistry.resolveTexture(mesh.mat.diffuseColorMap, owner)).collect(Collectors.toSet());
}
@ -606,21 +607,21 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
}
@Override
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform sprite, ResourceLocation modelLocation)
public void addQuads(IModelConfiguration owner, IModelBuilder<?> modelBuilder, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ResourceLocation modelLocation)
{
super.addQuads(owner, modelBuilder, bakery, spriteGetter, sprite, modelLocation);
super.addQuads(owner, modelBuilder, bakery, spriteGetter, modelTransform, modelLocation);
getParts().stream().filter(part -> owner.getPartVisibility(part))
.forEach(part -> part.addQuads(owner, modelBuilder, bakery, spriteGetter, sprite, modelLocation));
.forEach(part -> part.addQuads(owner, modelBuilder, bakery, spriteGetter, modelTransform, modelLocation));
}
@Override
public Collection<Material> getTextureDependencies(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors)
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors)
{
Set<Material> combined = Sets.newHashSet();
combined.addAll(super.getTextureDependencies(owner, modelGetter, missingTextureErrors));
combined.addAll(super.getTextures(owner, modelGetter, missingTextureErrors));
for (IModelGeometryPart part : getParts())
combined.addAll(part.getTextureDependencies(owner, modelGetter, missingTextureErrors));
combined.addAll(part.getTextures(owner, modelGetter, missingTextureErrors));
return combined;
}

View file

@ -32,6 +32,7 @@ import net.minecraft.tileentity.TileEntity;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
public class ClientRegistry
{
@ -42,9 +43,9 @@ public class ClientRegistry
* Call this during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}.
* This method is safe to call during parallel mod loading.
*/
public static synchronized <T extends TileEntity> void bindTileEntityRenderer(TileEntityType<T> tileEntityType, TileEntityRenderer<? super T> specialRenderer)
public static synchronized <T extends TileEntity> void bindTileEntityRenderer(TileEntityType<T> tileEntityType, Function<TileEntityRendererDispatcher, TileEntityRenderer<? super T>> rendererFactory)
{
TileEntityRendererDispatcher.instance.setSpecialRendererInternal(tileEntityType, specialRenderer);
TileEntityRendererDispatcher.instance.setSpecialRendererInternal(tileEntityType, rendererFactory.apply(TileEntityRendererDispatcher.instance));
}
/**

View file

@ -17,28 +17,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
package net.minecraftforge.debug.client.model;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.registries.ObjectHolder;
//@Mod(modid = MultiLayerModelTest.MODID, name = "ForgeDebugMultiLayerModel", version = MultiLayerModelTest.VERSION, acceptableRemoteVersions = "*")
@Mod(MultiLayerModelTest.MODID)
public class MultiLayerModelTest
{
private static final boolean ENABLED = true;
@ -50,7 +44,7 @@ public class MultiLayerModelTest
@ObjectHolder(blockName)
public static final Block TEST_BLOCK = null;
//@Mod.EventBusSubscriber(modid = MODID)
@Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
public static class Registration
{
@net.minecraftforge.eventbus.api.SubscribeEvent
@ -59,48 +53,28 @@ public class MultiLayerModelTest
if (!ENABLED)
return;
event.getRegistry().register(
new Block(Material.WOOD)
new Block(Block.Properties.create(Material.WOOD))
{
{
setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
setUnlocalizedName(MODID + "." + blockName);
setRegistryName(blockId);
}
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override
public boolean isFullCube(IBlockState state)
{
return false;
}
@Override
public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer)
{
return layer == BlockRenderLayer.SOLID || layer == BlockRenderLayer.TRANSLUCENT;
}
}
}.setRegistryName(blockId)
);
}
@net.minecraftforge.eventbus.api.SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event)
{
event.getRegistry().register(new ItemBlock(TEST_BLOCK).setRegistryName(TEST_BLOCK.getRegistryName()));
if (!ENABLED)
return;
event.getRegistry().register(new BlockItem(TEST_BLOCK, new Item.Properties().group(ItemGroup.MISC)).setRegistryName(TEST_BLOCK.getRegistryName()));
}
@SubscribeEvent
public static void registerModels(ModelRegistryEvent event)
@net.minecraftforge.eventbus.api.SubscribeEvent
public static void clientSetup(FMLClientSetupEvent event)
{
if (!ENABLED)
return;
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(TEST_BLOCK), 0, new ModelResourceLocation(blockId, "inventory"));
RenderTypeLookup.setRenderLayer(TEST_BLOCK, (layer) -> {
return layer == RenderType.func_228639_c_() || layer == RenderType.func_228645_f_();
});
}
}
}
*/

View file

@ -23,12 +23,17 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
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.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.*;
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
@ -45,6 +50,8 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
@Mod(NewModelLoaderTest.MODID)
public class NewModelLoaderTest
{
@ -52,8 +59,27 @@ public class NewModelLoaderTest
public static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, MODID);
public static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, MODID);
public static RegistryObject<Block> obj_block = BLOCKS.register("obj_block", () ->
new Block(Block.Properties.create(Material.WOOD)) {
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{
builder.add(BlockStateProperties.HORIZONTAL_FACING);
}
@Nullable
@Override
public BlockState getStateForPlacement(BlockItemUseContext context)
{
return getDefaultState().with(
BlockStateProperties.HORIZONTAL_FACING, context.getPlacementHorizontalFacing()
);
}
}
);
public static RegistryObject<Item> obj_item = ITEMS.register("obj_item", () ->
new Item(new Item.Properties().group(ItemGroup.MISC)) {
new BlockItem(obj_block.get(), new Item.Properties().group(ItemGroup.MISC)) {
@Override
public boolean canEquip(ItemStack stack, EquipmentSlotType armorType, Entity entity)
{

View file

@ -51,3 +51,5 @@ loaderVersion="[28,)"
## modId="custom_tnt_test"
[[mods]]
modId="new_model_loader_test"
[[mods]]
modId="forgedebugmultilayermodel"

View file

@ -1,26 +1,5 @@
{
"forge_marker": 1,
"defaults": {
"model": "forge:multi-layer",
"custom": {
// base is used for model properties - camera transforms, isGui3d, e.t.c.
"base": "forgedebugmultilayermodel:test_layer_block#aux",
// per-layer models
"Solid": "forgedebugmultilayermodel:test_layer_block#aux",
"Translucent": "forgedebugmultilayermodel:test_layer_block#pane"
},
"transform": "forge:default-block"
},
"variants": {
"normal": [{}],
"inventory": [{}],
"pane": [{
"model": "minecraft:pink_stained_glass_pane_noside"
}],
"aux": [{
"model": "cube_all",
"textures": { "all": "blocks/slime" },
"transform": { "scale": 0.5 }
}]
"": { "model": "forgedebugmultilayermodel:block/test_layer_block"}
}
}

View file

@ -0,0 +1,21 @@
{
"parent": "block/block",
"loader": "forge:multi-layer",
"layers": {
"__comment": "base is used for model properties - camera transforms, isGui3d, e.t.c.",
"base": {
"parent": "block/cube_all",
"textures": { "all": "block/slime_block" }
},
"__comment": "per-layer models",
"solid": {
"parent": "block/cube_all",
"textures": { "all": "block/slime_block" },
"transform": { "scale": 0.5 }
},
"translucent": {
"parent": "minecraft:block/pink_stained_glass_pane_noside"
}
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "forgedebugmultilayermodel:block/test_layer_block"
}

View file

@ -0,0 +1,8 @@
{
"variants": {
"facing=east": { "model": "new_model_loader_test:block/obj_block", "y": 90 },
"facing=west": { "model": "new_model_loader_test:block/obj_block", "y": 270 },
"facing=north": { "model": "new_model_loader_test:block/obj_block", "y": 0 },
"facing=south": { "model": "new_model_loader_test:block/obj_block", "y": 180 }
}
}

View file

@ -0,0 +1,17 @@
{
"parent": "forge:item/default",
"loader": "forge:composite",
"parts": {
"part1": {
"loader": "forge:obj",
"model": "new_model_loader_test:models/item/sugar_glider.obj",
"ambientToFullbright": true,
"textures": {
"qr": "minecraft:block/oak_planks"
}
}
},
"textures": {
"particle": "block/oak_planks"
}
}