From d6bc936ffa0438cdd5506a67d6ddbf11e1a3ea57 Mon Sep 17 00:00:00 2001 From: RainWarrior Date: Thu, 4 Jun 2015 18:49:57 +0300 Subject: [PATCH] B3D Improvements - fixed keyframe transformation application - textures are now resolved the same way as in vanilla models - added the ability to use forge blockstate texture information - removed unused code from the B3D example --- .../client/model/b3d/B3DLoader.java | 101 ++++++++++++---- .../debug/ModelLoaderRegistryDebug.java | 113 +----------------- .../blockstates/CustomModelBlock.json | 15 ++- .../models/block/chest.b3d | Bin 0 -> 6104 bytes .../models/block/untitled2.b3d | Bin 2173 -> 2174 bytes 5 files changed, 96 insertions(+), 133 deletions(-) create mode 100644 src/test/resources/assets/forgedebugmodelloaderregistry/models/block/chest.b3d 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 ca6ab3018a..46f1c464ce 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 3fe304b152..2358b93f5c 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 1ebdfc8c8a..c6db8d8257 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 0000000000000000000000000000000000000000..b070d7a6fabd24734f4b11657566e347c321499e GIT binary patch literal 6104 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 delta 29 jcmew-@K->@$;sHIl!JkRk%56B#5E#V14wTa&Ex<8ZzTpy