diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java index ca6ab3018..46f1c464c 100644 --- a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java +++ b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java @@ -30,8 +30,10 @@ import net.minecraftforge.client.model.IColoredBakedQuad.ColoredBakedQuad; import net.minecraftforge.client.model.ICustomModelLoader; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.IModel; +import net.minecraftforge.client.model.IModelCustomData; import net.minecraftforge.client.model.IModelPart; import net.minecraftforge.client.model.IModelState; +import net.minecraftforge.client.model.IRetexturableModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.client.model.ISmartItemModel; import net.minecraftforge.client.model.ModelLoader; @@ -56,11 +58,14 @@ import org.apache.logging.log4j.Level; import org.lwjgl.BufferUtils; import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.common.collect.Multimap; /* @@ -238,24 +243,28 @@ public class B3DLoader implements ICustomModelLoader public static TRSRTransformation getNodeMatrix(Animation animation, Node node, int frame) { TRSRTransformation ret = TRSRTransformation.identity(); - if(node.getParent() != null) - { - TRSRTransformation pm = cache.getUnchecked(Triple., Integer>of(animation, node.getParent(), frame)); - ret = ret.compose(pm); - } Key key = null; if(animation != null) key = animation.getKeys().get(frame, node); else if(key == null && node.getAnimation() != null && node.getAnimation() != animation) key = node.getAnimation().getKeys().get(frame, node); - if(key == null) - { - FMLLog.severe("invalid key index: " + frame); - } - else + if(key != null) { + Node parent = node.getParent(); + if(parent != null) + { + TRSRTransformation pm = cache.getUnchecked(Triple., Integer>of(animation, node.getParent(), frame)); + ret = ret.compose(pm); + ret = ret.compose(new TRSRTransformation(parent.getPos(), parent.getRot(), parent.getScale(), null)); + } ret = ret.compose(new TRSRTransformation(key.getPos(), key.getRot(), key.getScale(), null)); Matrix4f rm = new TRSRTransformation(node.getPos(), node.getRot(), node.getScale(), null).getMatrix(); rm.invert(); ret = ret.compose(new TRSRTransformation(rm)); + if(parent != null) + { + rm = new TRSRTransformation(parent.getPos(), parent.getRot(), parent.getScale(), null).getMatrix(); + rm.invert(); + ret = ret.compose(new TRSRTransformation(rm)); + } } return ret; } @@ -305,14 +314,14 @@ public class B3DLoader implements ICustomModelLoader } } - public static class Wrapper extends PartWrapper implements IModel + public static class Wrapper extends PartWrapper implements IRetexturableModel, IModelCustomData { private final ResourceLocation location; private final ImmutableMap textures; public Wrapper(ResourceLocation location, List textures, B3DModel.Node mesh) { - this(location, buildTextures(location, textures), mesh); + this(location, buildTextures(textures), mesh); } public Wrapper(ResourceLocation location, ImmutableMap textures, B3DModel.Node mesh) @@ -322,19 +331,24 @@ public class B3DLoader implements ICustomModelLoader this.textures = textures; } - private static ImmutableMap buildTextures(ResourceLocation location, List textures) + private static ImmutableMap buildTextures(List textures) { ImmutableMap.Builder builder = ImmutableMap.builder(); for(Texture t : textures) { String path = t.getPath(); - if(path.endsWith(".png")) path = path.substring(0, path.length() - ".png".length()); - builder.put(t.getPath(), new ResourceLocation(location.getResourceDomain(), path)); + builder.put(path, new ResourceLocation(getLocation(path))); } return builder.build(); } + private static String getLocation(String path) + { + if(path.endsWith(".png")) path = path.substring(0, path.length() - ".png".length()); + return path; + } + public Collection getDependencies() { // no dependencies for in-file models @@ -344,17 +358,32 @@ public class B3DLoader implements ICustomModelLoader public Collection getTextures() { - return textures.values(); + return Collections2.filter(textures.values(), new Predicate() + { + public boolean apply(ResourceLocation loc) + { + return !loc.getResourcePath().startsWith("#"); + } + }); } public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function bakedTextureGetter) { ImmutableMap.Builder builder = ImmutableMap.builder(); - for(String path : textures.keySet()) + TextureAtlasSprite missing = bakedTextureGetter.apply(new ResourceLocation("missingno")); + for(Map.Entry e : textures.entrySet()) { - builder.put(path, bakedTextureGetter.apply(textures.get(path))); + if(e.getValue().getResourcePath().startsWith("#")) + { + FMLLog.severe("unresolved texture '%s' for b3d model '%s'", e.getValue().getResourcePath(), location); + builder.put(e.getKey(), missing); + } + else + { + builder.put(e.getKey(), bakedTextureGetter.apply(e.getValue())); + } } - builder.put("missingno", bakedTextureGetter.apply(new ResourceLocation("missingno"))); + builder.put("missingno", missing); return new BakedWrapper(this, state, format, builder.build()); } @@ -396,6 +425,35 @@ public class B3DLoader implements ICustomModelLoader else if (!location.equals(other.location)) return false; return true; } + + @Override + public IModel retexture(ImmutableMap textures) + { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for(Map.Entry e : this.textures.entrySet()) + { + String path = e.getKey(); + String loc = getLocation(path); + if(textures.containsKey(loc)) + { + String newLoc = textures.get(loc); + if(newLoc == null) newLoc = getLocation(path); + builder.put(e.getKey(), new ResourceLocation(newLoc)); + } + else + { + builder.put(e); + } + } + return new Wrapper(location, builder.build(), getNode()); + } + + @Override + public IModel process(ImmutableMap customData) + { + // TODO keyframe + return null; + } } private static class BakedWrapper implements IFlexibleBakedModel, ISmartBlockModel, ISmartItemModel @@ -454,9 +512,10 @@ public class B3DLoader implements ICustomModelLoader for(Face f : faces) { buf.clear(); - List textures = f.getBrush().getTextures(); + List textures = null; + if(f.getBrush() != null) textures = f.getBrush().getTextures(); TextureAtlasSprite sprite; - if(textures.isEmpty()) sprite = this.textures.get("missingno"); + if(textures == null || textures.isEmpty()) sprite = this.textures.get("missingno"); else if(textures.get(0) == B3DModel.Texture.White) sprite = ModelLoader.White.instance; else sprite = this.textures.get(textures.get(0).getPath()); putVertexData(f.getV1(), sprite); diff --git a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java index 3fe304b15..2358b93f5 100644 --- a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java @@ -64,14 +64,9 @@ public class ModelLoaderRegistryDebug private void clientPreInit() { - //ModelLoaderRegistry.registerLoader(DummyModelLoader.instance); B3DLoader.instance.addDomain(MODID.toLowerCase()); - //ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), "forgedebug:dummymodel"); - String modelLocation = MODID.toLowerCase() + ":untitled2.b3d"; - ModelBakery.addVariantName(Item.getItemFromBlock(CustomModelBlock.instance), modelLocation); Item item = Item.getItemFromBlock(CustomModelBlock.instance); - ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(modelLocation, "inventory")); - //ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation("forgedebug:dummymodel", "inventory")); + ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + CustomModelBlock.name, "inventory")); } public static class CustomModelBlock extends Block @@ -100,9 +95,7 @@ public class ModelLoaderRegistryDebug @Override public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) { - IModel model = ModelLoaderRegistry.getModel(new ResourceLocation(MODID.toLowerCase(),"block/untitled2.b3d")); - B3DLoader.B3DState defaultState = ((B3DLoader.Wrapper)model).getDefaultState(); - B3DLoader.B3DState newState = new B3DLoader.B3DState(defaultState.getAnimation(), counter); + B3DLoader.B3DState newState = new B3DLoader.B3DState(null, counter); return ((IExtendedBlockState)this.state.getBaseState()).withProperty(B3DLoader.B3DFrameProperty.instance, newState); } @@ -120,106 +113,4 @@ public class ModelLoaderRegistryDebug return false; } } - - public static class DummyModelLoader implements ICustomModelLoader - { - public static final DummyModelLoader instance = new DummyModelLoader(); - public static final ResourceLocation dummyTexture = new ResourceLocation("minecraft:blocks/dirt"); - - public boolean accepts(ResourceLocation modelLocation) - { - return modelLocation.getResourceDomain().equals("forgedebug") && modelLocation.getResourcePath().contains("dummymodel"); - } - - public IModel loadModel(ResourceLocation model) - { - return DummyModel.instance; - } - - public static enum DummyModel implements IModel - { - instance; - - public Collection getDependencies() - { - return Collections.emptyList(); - } - - public Collection getTextures() - { - return Collections.singletonList(dummyTexture); - } - - public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function textures) - { - return new DummyBakedModel(textures.apply(dummyTexture)); - } - - public IModelState getDefaultState() - { - return ModelRotation.X0_Y0; - } - } - - public static class DummyBakedModel implements IFlexibleBakedModel - { - private final TextureAtlasSprite texture; - - public DummyBakedModel(TextureAtlasSprite texture) - { - this.texture = texture; - } - - public List getFaceQuads(EnumFacing side) - { - return Collections.emptyList(); - } - - private int[] vertexToInts(float x, float y, float z, int color, float u, float v) - { - return new int[] { - Float.floatToRawIntBits(x), - Float.floatToRawIntBits(y), - Float.floatToRawIntBits(z), - color, - Float.floatToRawIntBits(texture.getInterpolatedU(u)), - Float.floatToRawIntBits(texture.getInterpolatedV(v)), - 0 - }; - } - - public List getGeneralQuads() - { - List ret = new ArrayList(); - // 1 half-way rotated quad looking UP - ret.add(new BakedQuad(Ints.concat( - vertexToInts(0, .5f, .5f, -1, 0, 0), - vertexToInts(.5f, .5f, 1, -1, 0, 16), - vertexToInts(1, .5f, .5f, -1, 16, 16), - vertexToInts(.5f, .5f, 0, -1, 16, 0) - ), -1, EnumFacing.UP)); - return ret; - } - - public boolean isGui3d() { return true; } - - public boolean isAmbientOcclusion() { return true; } - - public boolean isBuiltInRenderer() { return false; } - - public TextureAtlasSprite getTexture() { return this.texture; } - - public ItemCameraTransforms getItemCameraTransforms() - { - return ItemCameraTransforms.DEFAULT; - } - - public VertexFormat getFormat() - { - return Attributes.DEFAULT_BAKED_FORMAT; - } - } - - public void onResourceManagerReload(IResourceManager resourceManager) {} - } } diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/CustomModelBlock.json b/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/CustomModelBlock.json index 1ebdfc8c8..c6db8d825 100644 --- a/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/CustomModelBlock.json +++ b/src/test/resources/assets/forgedebugmodelloaderregistry/blockstates/CustomModelBlock.json @@ -1,5 +1,18 @@ { + "forge_marker": 1, + "defaults": { + "textures": { + "#texture": "forgedebugmodelloaderregistry:texture", + "#chest": "entity/chest/normal" + }, + "model": "forgedebugmodelloaderregistry:chest.b3d" + }, "variants": { - "normal" : { "model" : "forgedebugmodelloaderregistry:untitled2.b3d" } + "normal": { + "dummy": "" + }, + "inventory": { + "dummy": "" + } } } diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d b/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d new file mode 100644 index 000000000..b070d7a6f Binary files /dev/null and b/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d differ diff --git a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d b/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d index 14e9c4d4a..8f4bd091b 100644 Binary files a/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d and b/src/test/resources/assets/forgedebugmodelloaderregistry/models/block/untitled2.b3d differ