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:
parent
e8ce61d4cd
commit
fc189c9aaf
29 changed files with 325 additions and 344 deletions
|
@ -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_);
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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())),
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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_());
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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_();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -51,3 +51,5 @@ loaderVersion="[28,)"
|
|||
## modId="custom_tnt_test"
|
||||
[[mods]]
|
||||
modId="new_model_loader_test"
|
||||
[[mods]]
|
||||
modId="forgedebugmultilayermodel"
|
|
@ -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"}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "forgedebugmultilayermodel:block/test_layer_block"
|
||||
}
|
|
@ -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 }
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue