diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch index 2226f0b87..7d8ba1837 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemCameraTransforms.java.patch @@ -12,3 +12,12 @@ public class ItemCameraTransforms { public static final ItemCameraTransforms field_178357_a = new ItemCameraTransforms(); +@@ -117,7 +121,7 @@ + } + + @SideOnly(Side.CLIENT) +- public static enum TransformType ++ public static enum TransformType implements net.minecraftforge.client.model.IModelPart + { + NONE, + THIRD_PERSON, diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch index e0fa743a5..22f137782 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemTransformVec3f.java.patch @@ -12,7 +12,7 @@ +@Deprecated +public class ItemTransformVec3f implements net.minecraftforge.client.model.IModelState { -+ public net.minecraftforge.client.model.TRSRTransformation apply(net.minecraftforge.client.model.IModelPart part) { return new net.minecraftforge.client.model.TRSRTransformation(this); } ++ public com.google.common.base.Optional apply(com.google.common.base.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(this, part); } public static final ItemTransformVec3f field_178366_a = new ItemTransformVec3f(new Vector3f(), new Vector3f(), new Vector3f(1.0F, 1.0F, 1.0F)); public final Vector3f field_178364_b; public final Vector3f field_178365_c; diff --git a/patches/minecraft/net/minecraft/client/resources/model/ModelRotation.java.patch b/patches/minecraft/net/minecraft/client/resources/model/ModelRotation.java.patch index f7b079566..893292696 100644 --- a/patches/minecraft/net/minecraft/client/resources/model/ModelRotation.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/model/ModelRotation.java.patch @@ -14,7 +14,7 @@ } } + -+ public net.minecraftforge.client.model.TRSRTransformation apply(net.minecraftforge.client.model.IModelPart part) { return new net.minecraftforge.client.model.TRSRTransformation(getMatrix()); } ++ public com.google.common.base.Optional apply(com.google.common.base.Optional part) { return net.minecraftforge.client.ForgeHooksClient.applyTransform(getMatrix(), part); } + public javax.vecmath.Matrix4f getMatrix() { return net.minecraftforge.client.ForgeHooksClient.getMatrix(this); } + public EnumFacing rotate(EnumFacing facing) { return func_177523_a(facing); } + public int rotate(EnumFacing facing, int vertexIndex) { return func_177520_a(facing, vertexIndex); } diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index 5ca7c02b7..7d105f2ca 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -70,6 +70,8 @@ import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.event.sound.PlaySoundEvent; +import net.minecraftforge.client.model.IFlexibleBakedModel; +import net.minecraftforge.client.model.IModelPart; import net.minecraftforge.client.model.IPerspectiveAwareModel; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.TRSRTransformation; @@ -82,8 +84,8 @@ import net.minecraftforge.fml.common.FMLLog; import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.GL11; +import com.google.common.base.Optional; import com.google.common.collect.Maps; @SuppressWarnings("deprecation") @@ -111,7 +113,7 @@ public class ForgeHooksClient if (block != null && block.isBed(world, pos, entity)) { - GL11.glRotatef((float)(block.getBedDirection(world, pos).getHorizontalIndex() * 90), 0.0F, 1.0F, 0.0F); + glRotatef((float)(block.getBedDirection(world, pos).getHorizontalIndex() * 90), 0.0F, 1.0F, 0.0F); } } @@ -378,7 +380,7 @@ public class ForgeHooksClient { if(model instanceof IPerspectiveAwareModel) { - Pair pair = ((IPerspectiveAwareModel)model).handlePerspective(cameraTransformType); + Pair pair = ((IPerspectiveAwareModel)model).handlePerspective(cameraTransformType); if(pair.getRight() != null) multiplyCurrentGlMatrix(pair.getRight()); return pair.getLeft(); @@ -402,7 +404,7 @@ public class ForgeHooksClient matrixBuf.put(t); } matrixBuf.flip(); - GL11.glMultMatrix(matrixBuf); + glMultMatrix(matrixBuf); } // moved and expanded from WorldVertexBufferUploader.draw @@ -523,7 +525,7 @@ public class ForgeHooksClient Class tileClass = tileItemMap.get(Pair.of(item, metadata)); if (tileClass != null) { - TileEntitySpecialRenderer r = TileEntityRendererDispatcher.instance.getSpecialRendererByClass(tileClass); + TileEntitySpecialRenderer r = TileEntityRendererDispatcher.instance.getSpecialRendererByClass(tileClass); if (r != null) { r.renderTileEntityAt(null, 0, 0, 0, 0, -1); @@ -562,4 +564,16 @@ public class ForgeHooksClient faceData[i * 7 + 6] = x | (y << 0x08) | (z << 0x10); } } + + public static Optional applyTransform(ItemTransformVec3f transform, Optional part) + { + if(part.isPresent()) return Optional.absent(); + return Optional.of(new TRSRTransformation(transform)); + } + + public static Optional applyTransform(Matrix4f matrix, Optional part) + { + if(part.isPresent()) return Optional.absent(); + return Optional.of(new TRSRTransformation(matrix)); + } } diff --git a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java b/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java index b07bb2668..255985659 100644 --- a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java +++ b/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java @@ -193,7 +193,7 @@ public class BlockStateLoader IModelState partState = new ModelStateComposition(baseTr, part.getState()); if (part.isUVLock()) partState = new ModelLoader.UVLock(partState); - models.put(entry.getKey(), Pair.of(runModelHooks(model, part.getTextures(), part.getCustomData()), partState)); + models.put(entry.getKey(), Pair.of(runModelHooks(model, part.getTextures(), part.getCustomData()), partState)); } return new MultiModel(getModelLocation(), hasBase ? base : null, baseTr, models.build()); diff --git a/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java b/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java index 2a644a3ad..d950d6dfc 100644 --- a/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java +++ b/src/main/java/net/minecraftforge/client/model/ForgeBlockStateV1.java @@ -467,40 +467,40 @@ public class ForgeBlockStateV1 extends Marker } else if (transform.equals("forge:default-block")) { - IModelState thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( + TRSRTransformation thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( new Vector3f(0, 1.5f / 16, -2.75f / 16), TRSRTransformation.quatFromYXZDegrees(new Vector3f(10, -45, 170)), new Vector3f(0.375f, 0.375f, 0.375f), null)); - ret.state = Optional.of(new IPerspectiveState.Impl(TRSRTransformation.identity(), ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson))); + ret.state = Optional.of(new SimpleModelState(ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson))); } else if (transform.equals("forge:default-item")) { - IModelState thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( + TRSRTransformation thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( new Vector3f(0, 1f / 16, -3f / 16), TRSRTransformation.quatFromYXZDegrees(new Vector3f(-90, 0, 0)), new Vector3f(0.55f, 0.55f, 0.55f), null)); - IModelState firstperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( + TRSRTransformation firstperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( new Vector3f(0, 4f / 16, 2f / 16), TRSRTransformation.quatFromYXZDegrees(new Vector3f(0, -135, 25)), new Vector3f(1.7f, 1.7f, 1.7f), null)); - ret.state = Optional.of(new IPerspectiveState.Impl(TRSRTransformation.identity(), ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson, TransformType.FIRST_PERSON, firstperson))); + ret.state = Optional.of(new SimpleModelState(ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson, TransformType.FIRST_PERSON, firstperson))); } else if (transform.equals("forge:default-tool")) { - IModelState thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( + TRSRTransformation thirdperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( new Vector3f(0, 1.25f / 16, -3.5f / 16), TRSRTransformation.quatFromYXZDegrees(new Vector3f(0, 90, -35)), new Vector3f(0.85f, 0.85f, 0.85f), null)); - IModelState firstperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( + TRSRTransformation firstperson = TRSRTransformation.blockCenterToCorner(new TRSRTransformation( new Vector3f(0, 4f / 16, 2f / 16), TRSRTransformation.quatFromYXZDegrees(new Vector3f(0, -135, 25)), new Vector3f(1.7f, 1.7f, 1.7f), null)); - ret.state = Optional.of(new IPerspectiveState.Impl(TRSRTransformation.identity(), ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson, TransformType.FIRST_PERSON, firstperson))); + ret.state = Optional.of(new SimpleModelState(ImmutableMap.of(TransformType.THIRD_PERSON, thirdperson, TransformType.FIRST_PERSON, firstperson))); } else { @@ -522,7 +522,7 @@ public class ForgeBlockStateV1 extends Marker else { JsonObject transform = json.get("transform").getAsJsonObject(); - EnumMap transforms = Maps.newEnumMap(TransformType.class); + EnumMap transforms = Maps.newEnumMap(TransformType.class); if(transform.has("thirdperson")) { TRSRTransformation t = context.deserialize(transform.get("thirdperson"), TRSRTransformation.class); @@ -582,7 +582,7 @@ public class ForgeBlockStateV1 extends Marker } else { - state = new IPerspectiveState.Impl(base, Maps.immutableEnumMap(transforms)); + state = new SimpleModelState(Maps.immutableEnumMap(transforms), Optional.of(base)); } ret.state = Optional.of(state); } diff --git a/src/main/java/net/minecraftforge/client/model/IModel.java b/src/main/java/net/minecraftforge/client/model/IModel.java index 457f8a581..3ac54704d 100644 --- a/src/main/java/net/minecraftforge/client/model/IModel.java +++ b/src/main/java/net/minecraftforge/client/model/IModel.java @@ -12,7 +12,7 @@ import com.google.common.base.Function; * Interface for models that can be baked * (possibly to different vertex formats and with different state). */ -public interface IModel extends IModelPart +public interface IModel { /* * Returns all model locations that this model depends on. diff --git a/src/main/java/net/minecraftforge/client/model/IModelState.java b/src/main/java/net/minecraftforge/client/model/IModelState.java index 34795854b..dff153de3 100644 --- a/src/main/java/net/minecraftforge/client/model/IModelState.java +++ b/src/main/java/net/minecraftforge/client/model/IModelState.java @@ -1,16 +1,17 @@ package net.minecraftforge.client.model; -import com.google.common.base.Function; +import com.google.common.base.Optional; /* * Represents the dynamic information associated with the model. * Common use case is (possibly interpolated) animation frame. */ -public interface IModelState extends Function +public interface IModelState { /* - * returns the transformation (in the local coordinates) that needs to be applied to the specific part of the model. + * Returns the transformation that needs to be applied to the specific part of the model. + * Coordinate system is determined by the part type. + * if no part is provided, global model transformation is returned. */ - @Override - TRSRTransformation apply(IModelPart part); -} + Optional apply(Optional part); +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/client/model/IPerspectiveAwareModel.java b/src/main/java/net/minecraftforge/client/model/IPerspectiveAwareModel.java index 1a32071f6..7856bb04c 100644 --- a/src/main/java/net/minecraftforge/client/model/IPerspectiveAwareModel.java +++ b/src/main/java/net/minecraftforge/client/model/IPerspectiveAwareModel.java @@ -9,27 +9,26 @@ import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.util.EnumFacing; import org.apache.commons.lang3.tuple.Pair; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; /* * Model that changes based on the rendering perspective * (first-person, GUI, e.t.c - see TransformType) */ -@SuppressWarnings("deprecation") -public interface IPerspectiveAwareModel extends IBakedModel +public interface IPerspectiveAwareModel extends IFlexibleBakedModel { /* * Returns the pair of the model for the given perspective, and the matrix * that should be applied to the GL state before rendering it (matrix may be null). */ - Pair handlePerspective(TransformType cameraTransformType); + Pair handlePerspective(TransformType cameraTransformType); - public static class MapWrapper implements IFlexibleBakedModel, IPerspectiveAwareModel + public static class MapWrapper implements IPerspectiveAwareModel { private final IFlexibleBakedModel parent; private final ImmutableMap transforms; @@ -40,17 +39,31 @@ public interface IPerspectiveAwareModel extends IBakedModel this.transforms = transforms; } - public MapWrapper(IFlexibleBakedModel parent, IPerspectiveState state, IModelPart part) + public MapWrapper(IFlexibleBakedModel parent, IModelState state) { - this(parent, getTransforms(state, part)); + this(parent, getTransforms(state)); } - public static ImmutableMap getTransforms(IPerspectiveState state, IModelPart part) + public static ImmutableMap getTransforms(IModelState state) { ImmutableMap.Builder builder = ImmutableMap.builder(); for(TransformType type : TransformType.values()) { - builder.put(type, state.forPerspective(type).apply(part)); + Optional tr = state.apply(Optional.of(type)); + if(tr.isPresent()) + { + builder.put(type, tr.get()); + } + } + return builder.build(); + } + + public static ImmutableMap getTransforms(ItemCameraTransforms transforms) + { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for(TransformType type : TransformType.values()) + { + builder.put(type, new TRSRTransformation(transforms.func_181688_b(type))); } return builder.build(); } @@ -65,12 +78,12 @@ public interface IPerspectiveAwareModel extends IBakedModel public VertexFormat getFormat() { return parent.getFormat(); } @Override - public Pair handlePerspective(TransformType cameraTransformType) + public Pair handlePerspective(TransformType cameraTransformType) { TRSRTransformation tr = transforms.get(cameraTransformType); Matrix4f mat = null; if(tr != null && tr != TRSRTransformation.identity()) mat = TRSRTransformation.blockCornerToCenter(tr).getMatrix(); - return Pair.of((IBakedModel)this, mat); + return Pair.of(this, mat); } } } diff --git a/src/main/java/net/minecraftforge/client/model/IPerspectiveState.java b/src/main/java/net/minecraftforge/client/model/IPerspectiveState.java deleted file mode 100644 index a057a85e6..000000000 --- a/src/main/java/net/minecraftforge/client/model/IPerspectiveState.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.minecraftforge.client.model; - -import java.util.Map; - -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -/** - * IModelState that can change depending on the perspective. - */ -@SuppressWarnings("deprecation") -public interface IPerspectiveState extends IModelState -{ - /** - * @return the additional state that needs to be applied for each part when in given perspective type. - */ - public IModelState forPerspective(TransformType type); - - public static class Impl implements IPerspectiveState - { - private final IModelState parent; - private final ImmutableMap states; - - public Impl(IModelState parent, ImmutableMap states) - { - this.parent = parent; - this.states = states; - } - - public Impl(IModelState parent, ItemCameraTransforms transforms) - { - this(parent, getMap(transforms)); - } - - private static ImmutableMap getMap(ItemCameraTransforms transforms) - { - Map map = Maps.newHashMap(); - for(TransformType type : TransformType.values()) - { - map.put(type, transforms.func_181688_b(type)); - } - return Maps.immutableEnumMap(map); - } - - public TRSRTransformation apply(IModelPart part) - { - return parent.apply(part); - } - - public IModelState forPerspective(TransformType type) - { - IModelState state = states.get(type); - if(state == null) state = TRSRTransformation.identity(); - return state; - } - - @Override - public String toString() - { - return Objects.toStringHelper(this.getClass()).add("parent", parent).add("states", states).toString(); - } - } -} diff --git a/src/main/java/net/minecraftforge/client/model/ISmartBlockModel.java b/src/main/java/net/minecraftforge/client/model/ISmartBlockModel.java index 37dee843e..718f90de5 100644 --- a/src/main/java/net/minecraftforge/client/model/ISmartBlockModel.java +++ b/src/main/java/net/minecraftforge/client/model/ISmartBlockModel.java @@ -1,9 +1,94 @@ package net.minecraftforge.client.model; +import java.util.List; + +import javax.vecmath.Matrix4f; + import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.util.EnumFacing; + +import org.apache.commons.lang3.tuple.Pair; public interface ISmartBlockModel extends IBakedModel { IBakedModel handleBlockState(IBlockState state); + + public static abstract class Wrapper implements ISmartBlockModel, IFlexibleBakedModel + { + protected final IFlexibleBakedModel parent; + + public Wrapper(IFlexibleBakedModel parent) + { + this.parent = parent; + } + + public List getFaceQuads(EnumFacing side) + { + return parent.getFaceQuads(side); + } + + public List getGeneralQuads() + { + return parent.getGeneralQuads(); + } + + public boolean isAmbientOcclusion() + { + return parent.isAmbientOcclusion(); + } + + public boolean isGui3d() + { + return parent.isGui3d(); + } + + public boolean isBuiltInRenderer() + { + return parent.isBuiltInRenderer(); + } + + public TextureAtlasSprite getTexture() + { + return parent.getTexture(); + } + + public ItemCameraTransforms getItemCameraTransforms() + { + return parent.getItemCameraTransforms(); + } + + public VertexFormat getFormat() + { + return parent.getFormat(); + } + } + + public static abstract class PerspectiveWrapper extends Wrapper implements IPerspectiveAwareModel + { + protected final IPerspectiveAwareModel parent; + + public PerspectiveWrapper(IPerspectiveAwareModel parent) + { + super(parent); + this.parent = parent; + } + + public Pair handlePerspective(TransformType type) + { + Pair pair = parent.handlePerspective(type); + return Pair.of(new ISmartBlockModel.Wrapper(pair.getLeft()) + { + public IBakedModel handleBlockState(IBlockState state) + { + return PerspectiveWrapper.this.handleBlockState(state); + } + }, pair.getRight()); + } + } } diff --git a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java b/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java index a0d5a881c..326d300fb 100644 --- a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java +++ b/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java @@ -5,7 +5,6 @@ import java.util.BitSet; import java.util.Collection; import java.util.List; -import javax.vecmath.Matrix4f; import javax.vecmath.Vector4f; import net.minecraft.client.renderer.block.model.BakedQuad; @@ -15,20 +14,17 @@ import net.minecraft.client.renderer.block.model.ModelBlock; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; -import org.apache.commons.lang3.tuple.Pair; - import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -@SuppressWarnings("deprecation") -public class ItemLayerModel implements IRetexturableModel { +public class ItemLayerModel implements IRetexturableModel +{ public static final ItemLayerModel instance = new ItemLayerModel(ImmutableList.of()); @@ -85,40 +81,33 @@ public class ItemLayerModel implements IRetexturableModel { public IFlexibleBakedModel bake(IModelState state, final VertexFormat format, Function bakedTextureGetter) { ImmutableList.Builder builder = ImmutableList.builder(); - final TRSRTransformation transform = state.apply(this); + Optional transform = state.apply(Optional.absent()); for(int i = 0; i < textures.size(); i++) { TextureAtlasSprite sprite = bakedTextureGetter.apply(textures.get(i)); builder.addAll(getQuadsForSprite(i, sprite, format, transform)); } TextureAtlasSprite particle = bakedTextureGetter.apply(textures.isEmpty() ? new ResourceLocation("missingno") : textures.get(0)); - if(state instanceof IPerspectiveState) + ImmutableMap map = IPerspectiveAwareModel.MapWrapper.getTransforms(state); + IFlexibleBakedModel ret = new BakedModel(builder.build(), particle, format); + if(map.isEmpty()) { - IPerspectiveState ps = (IPerspectiveState)state; - ImmutableMap map = IPerspectiveAwareModel.MapWrapper.getTransforms(ps, this); - return new BakedModel(builder.build(), particle, format, Maps.immutableEnumMap(map)); + return ret; } - return new BakedModel(builder.build(), particle, format); + return new IPerspectiveAwareModel.MapWrapper(ret, map); } - public static class BakedModel implements IFlexibleBakedModel, IPerspectiveAwareModel + public static class BakedModel implements IFlexibleBakedModel { private final ImmutableList quads; private final TextureAtlasSprite particle; private final VertexFormat format; - private final ImmutableMap transforms; public BakedModel(ImmutableList quads, TextureAtlasSprite particle, VertexFormat format) - { - this(quads, particle, format, ImmutableMap.of()); - } - - public BakedModel(ImmutableList quads, TextureAtlasSprite particle, VertexFormat format, ImmutableMap transforms) { this.quads = quads; this.particle = particle; this.format = format; - this.transforms = transforms; } public boolean isAmbientOcclusion() { return true; } @@ -129,18 +118,9 @@ public class ItemLayerModel implements IRetexturableModel { public List getFaceQuads(EnumFacing side) { return ImmutableList.of(); } public List getGeneralQuads() { return quads; } public VertexFormat getFormat() { return format; } - - @Override - public Pair handlePerspective(TransformType cameraTransformType) - { - TRSRTransformation tr = transforms.get(cameraTransformType); - Matrix4f mat = null; - if(tr != null && tr != TRSRTransformation.identity()) mat = TRSRTransformation.blockCornerToCenter(tr).getMatrix(); - return Pair.of((IBakedModel)this, mat); - } } - public ImmutableList getQuadsForSprite(int tint, TextureAtlasSprite sprite, VertexFormat format, TRSRTransformation transform) + public ImmutableList getQuadsForSprite(int tint, TextureAtlasSprite sprite, VertexFormat format, Optional transform) { ImmutableList.Builder builder = ImmutableList.builder(); @@ -215,7 +195,7 @@ public class ItemLayerModel implements IRetexturableModel { return (pixels[u + (vMax - 1 - v) * uMax] >> 24 & 0xFF) == 0; } - private static void addSideQuad(ImmutableList.Builder builder, BitSet faces, VertexFormat format, TRSRTransformation transform, EnumFacing side, int tint, TextureAtlasSprite sprite, int uMax, int vMax, int u, int v) + private static void addSideQuad(ImmutableList.Builder builder, BitSet faces, VertexFormat format, Optional transform, EnumFacing side, int tint, TextureAtlasSprite sprite, int uMax, int vMax, int u, int v) { int si = side.ordinal(); if(si > 4) si -= 2; @@ -227,7 +207,7 @@ public class ItemLayerModel implements IRetexturableModel { } } - private static BakedQuad buildSideQuad(VertexFormat format, TRSRTransformation transform, EnumFacing side, int tint, TextureAtlasSprite sprite, int u, int v) + private static BakedQuad buildSideQuad(VertexFormat format, Optional transform, EnumFacing side, int tint, TextureAtlasSprite sprite, int u, int v) { final float eps0 = 30e-5f; final float eps1 = 45e-5f; @@ -308,7 +288,7 @@ public class ItemLayerModel implements IRetexturableModel { } private static final BakedQuad buildQuad( - VertexFormat format, TRSRTransformation transform, EnumFacing side, int tint, + VertexFormat format, Optional transform, EnumFacing side, int tint, float x0, float y0, float z0, float u0, float v0, float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, @@ -324,7 +304,7 @@ public class ItemLayerModel implements IRetexturableModel { return builder.build(); } - private static void putVertex(UnpackedBakedQuad.Builder builder, VertexFormat format, TRSRTransformation transform, EnumFacing side, float x, float y, float z, float u, float v) + private static void putVertex(UnpackedBakedQuad.Builder builder, VertexFormat format, Optional transform, EnumFacing side, float x, float y, float z, float u, float v) { Vector4f vec = new Vector4f(); for(int e = 0; e < format.getElementCount(); e++) @@ -332,12 +312,19 @@ public class ItemLayerModel implements IRetexturableModel { switch(format.getElement(e).getUsage()) { case POSITION: - vec.x = x; - vec.y = y; - vec.z = z; - vec.w = 1; - transform.getMatrix().transform(vec); - builder.put(e, vec.x, vec.y, vec.z, vec.w); + if(transform.isPresent()) + { + vec.x = x; + vec.y = y; + vec.z = z; + vec.w = 1; + transform.get().getMatrix().transform(vec); + builder.put(e, vec.x, vec.y, vec.z, vec.w); + } + else + { + builder.put(e, x, y, z, 1); + } break; case COLOR: builder.put(e, 1f, 1f, 1f, 1f); diff --git a/src/main/java/net/minecraftforge/client/model/MapModelState.java b/src/main/java/net/minecraftforge/client/model/MapModelState.java index 1861a745e..62d93912e 100644 --- a/src/main/java/net/minecraftforge/client/model/MapModelState.java +++ b/src/main/java/net/minecraftforge/client/model/MapModelState.java @@ -2,41 +2,78 @@ package net.minecraftforge.client.model; import java.util.Map; +import com.google.common.base.Objects; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; /* - * Simple implementation of IModelState via a map and a default value. + * Simple implementation of IModelState via a map and a default value. Provides a full state for each part. */ public class MapModelState implements IModelState { - private final ImmutableMap map; + private final ImmutableMap map; private final IModelState def; - public MapModelState(Map map) + public MapModelState(Map map) { this(map, TRSRTransformation.identity()); } - public MapModelState(Map map, TRSRTransformation def) + public MapModelState(Map map, TRSRTransformation def) { this(map, (IModelState)def); } - public MapModelState(Map map, IModelState def) + public MapModelState(Map map, IModelState def) { - this.map = ImmutableMap.copyOf(map); + this.map = ImmutableMap.copyOf(map); this.def = def; } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { - if(!map.containsKey(part)) return def.apply(part); - return map.get(part).apply(part); + if(!part.isPresent() || !map.containsKey(part.get())) return def.apply(part); + return map.get(part.get()).apply(Optional.absent()); } - public IModelState getState(IModelPart part) + public IModelState getState(Object obj) { - if(!map.containsKey(part)) return def; - return map.get(part); + Wrapper w = wrap(obj); + if(!map.containsKey(w)) return def; + return map.get(w); + } + + public static class Wrapper implements IModelPart + { + private final Object obj; + + public Wrapper(Object obj) + { + this.obj = obj; + } + + @Override + public int hashCode() + { + return obj.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Wrapper other = (Wrapper)obj; + return Objects.equal(this.obj, other.obj); + } + } + + public static Wrapper wrap(Object obj) + { + return new Wrapper(obj); } } diff --git a/src/main/java/net/minecraftforge/client/model/ModelFluid.java b/src/main/java/net/minecraftforge/client/model/ModelFluid.java index a283f0790..3a8740d6e 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelFluid.java +++ b/src/main/java/net/minecraftforge/client/model/ModelFluid.java @@ -5,9 +5,12 @@ import java.util.Collections; import java.util.EnumMap; import java.util.List; +import javax.vecmath.Vector4f; + import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.IResourceManager; @@ -57,7 +60,13 @@ public class ModelFluid implements IModelCustomData public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function bakedTextureGetter) { - return new BakedFluid(state.apply(this), format, fluid.getColor(), bakedTextureGetter.apply(fluid.getStill()), bakedTextureGetter.apply(fluid.getFlowing()), fluid.isGaseous()); + ImmutableMap map = IPerspectiveAwareModel.MapWrapper.getTransforms(state); + IFlexibleBakedModel ret = new BakedFluid(state.apply(Optional.absent()), format, fluid.getColor(), bakedTextureGetter.apply(fluid.getStill()), bakedTextureGetter.apply(fluid.getFlowing()), fluid.isGaseous()); + if(map.isEmpty()) + { + return ret; + } + return new IPerspectiveAwareModel.MapWrapper(ret, map); } public IModelState getDefaultState() @@ -91,7 +100,7 @@ public class ModelFluid implements IModelCustomData private static final int z[] = { 0, 1, 1, 0 }; private static final float eps = 1e-3f; - private final TRSRTransformation transformation; + private final Optional transformation; private final VertexFormat format; private final int color; private final TextureAtlasSprite still, flowing; @@ -99,12 +108,12 @@ public class ModelFluid implements IModelCustomData private final Optional state; private final EnumMap> faceQuads; - public BakedFluid(TRSRTransformation transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas) + public BakedFluid(Optional transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas) { this(transformation, format, color, still, flowing, gas, Optional.absent()); } - public BakedFluid(TRSRTransformation transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas, Optional stateOption) + public BakedFluid(Optional transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas, Optional stateOption) { this.transformation = transformation; this.format = format; @@ -237,7 +246,14 @@ public class ModelFluid implements IModelCustomData switch(format.getElement(e).getUsage()) { case POSITION: - builder.put(e, x - side.getDirectionVec().getX() * eps, y, z - side.getDirectionVec().getZ() * eps, 1f); + float[] data = new float[]{ x - side.getDirectionVec().getX() * eps, y, z - side.getDirectionVec().getZ() * eps, 1 }; + if(transformation.isPresent()) + { + Vector4f vec = new Vector4f(data); + transformation.get().getMatrix().transform(vec); + vec.get(data); + } + builder.put(e, data); break; case COLOR: float d = LightUtil.diffuseLight(side); diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index d286890a5..fd93a3f4b 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -24,6 +24,7 @@ import net.minecraft.client.renderer.ItemModelMesher; import net.minecraft.client.renderer.block.model.BlockPart; import net.minecraft.client.renderer.block.model.BlockPartFace; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.block.model.ItemModelGenerator; import net.minecraft.client.renderer.block.model.ModelBlock; import net.minecraft.client.renderer.block.model.ModelBlockDefinition; @@ -55,6 +56,7 @@ import net.minecraftforge.fml.common.registry.RegistryDelegate; import org.apache.commons.lang3.tuple.Pair; import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -332,7 +334,14 @@ public class ModelLoader extends ModelBakery throw new IllegalArgumentException("can't bake vanilla models to the format that doesn't fit into the default one: " + format); } ModelBlock model = this.model; - if(model == null) return getMissingModel().bake(state, format, bakedTextureGetter); + if(model == null) return getMissingModel().bake(getMissingModel().getDefaultState(), format, bakedTextureGetter); + + List newTransforms = Lists.newArrayList(); + for(int i = 0; i < model.getElements().size(); i++) + { + newTransforms.add(null); + } + ItemCameraTransforms transforms = model.func_181682_g(); boolean uvlock = false; if(state instanceof UVLock) @@ -340,43 +349,58 @@ public class ModelLoader extends ModelBakery uvlock = true; state = ((UVLock)state).getParent(); } - IPerspectiveState perState = state instanceof IPerspectiveState ? (IPerspectiveState)state : new IPerspectiveState.Impl(state, transforms); + Map tMap = Maps.newHashMap(); + tMap.putAll(IPerspectiveAwareModel.MapWrapper.getTransforms(transforms)); + tMap.putAll(IPerspectiveAwareModel.MapWrapper.getTransforms(state)); + IModelState perState = new SimpleModelState(ImmutableMap.copyOf(tMap)); + if(hasItemModel(model)) { return new ItemLayerModel(model).bake(perState, format, bakedTextureGetter); } if(isCustomRenderer(model)) return new IFlexibleBakedModel.Wrapper(new BuiltInModel(transforms), format); - // TODO perspective awareness for this - return bakeNormal(model, perState, state.apply(this), format, bakedTextureGetter, uvlock); + return bakeNormal(model, perState, state.apply(Optional.absent()).or(TRSRTransformation.identity()), newTransforms, format, bakedTextureGetter, uvlock); } - private IFlexibleBakedModel bakeNormal(ModelBlock model, IPerspectiveState perState, TRSRTransformation state, VertexFormat format, Function bakedTextureGetter, boolean uvLocked) + private IFlexibleBakedModel bakeNormal(ModelBlock model, IModelState perState, final TRSRTransformation modelState, List newTransforms, VertexFormat format, Function bakedTextureGetter, boolean uvLocked) { TextureAtlasSprite particle = bakedTextureGetter.apply(new ResourceLocation(model.resolveTextureName("particle"))); SimpleBakedModel.Builder builder = (new SimpleBakedModel.Builder(model)).setTexture(particle); - for(BlockPart part : (Iterable)model.getElements()) + for(int i = 0; i < model.getElements().size(); i++) { + BlockPart part = model.getElements().get(i); + TRSRTransformation transformation = modelState; + if(newTransforms.get(i) != null) + { + transformation = transformation.compose(newTransforms.get(i)); + } for(Map.Entry e : (Iterable>)part.mapFaces.entrySet()) { TextureAtlasSprite textureatlassprite1 = bakedTextureGetter.apply(new ResourceLocation(model.resolveTextureName(e.getValue().texture))); - if (e.getValue().cullFace == null || !TRSRTransformation.isInteger(state.getMatrix())) + if (e.getValue().cullFace == null || !TRSRTransformation.isInteger(transformation.getMatrix())) { - builder.addGeneralQuad(makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), state, uvLocked)); + builder.addGeneralQuad(makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), transformation, uvLocked)); } else { - builder.addFaceQuad(state.rotate(e.getValue().cullFace), makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), state, uvLocked)); + builder.addFaceQuad(modelState.rotate(e.getValue().cullFace), makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), transformation, uvLocked)); } } } - return new IPerspectiveAwareModel.MapWrapper(new IFlexibleBakedModel.Wrapper(builder.makeBakedModel(), format), perState, this); + return new ISmartBlockModel.PerspectiveWrapper(new IPerspectiveAwareModel.MapWrapper(new IFlexibleBakedModel.Wrapper(builder.makeBakedModel(), format), perState)) + { + public IBakedModel handleBlockState(IBlockState state) + { + return VanillaModelWrapper.this.handleBlockState(parent, modelState, state); + } + }; } - public IModelState getDefaultState() + private IBakedModel handleBlockState(IFlexibleBakedModel model, TRSRTransformation modelState, IBlockState state) { - return ModelRotation.X0_Y0; + return model; } @Override @@ -439,6 +463,11 @@ public class ModelLoader extends ModelBakery return new VanillaModelWrapper(location, neweModel); } + + public IModelState getDefaultState() + { + return ModelRotation.X0_Y0; + } } public static class UVLock implements IModelState @@ -455,7 +484,7 @@ public class ModelLoader extends ModelBakery return parent; } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { return parent.apply(part); } @@ -503,7 +532,7 @@ public class ModelLoader extends ModelBakery public WeightedRandomModel(ModelResourceLocation parent, Variants variants) { this.variants = variants.getVariants(); - ImmutableMap.Builder builder = ImmutableMap.builder(); + ImmutableMap.Builder builder = ImmutableMap.builder(); for (Variant v : (List)variants.getVariants()) { ResourceLocation loc = v.getModelLocation(); @@ -533,14 +562,14 @@ public class ModelLoader extends ModelBakery model = new WeightedPartWrapper(model); models.add(model); - builder.put(model, v.getState()); + builder.put(MapModelState.wrap(model), v.getState()); } if (models.size() == 0) //If all variants are missing, add one with the missing model and default rotation. { IModel missing = getMissingModel(); models.add(missing); - builder.put(missing, TRSRTransformation.identity()); + builder.put(MapModelState.wrap(missing), TRSRTransformation.identity()); } defaultState = new MapModelState(builder.build()); @@ -563,11 +592,11 @@ public class ModelLoader extends ModelBakery return state; } - private IModelState getState(IModelState state, IModelPart part) + private IModelState getState(IModelState state, IModel model) { if(state instanceof MapModelState) { - return ((MapModelState)state).getState(part); + return ((MapModelState)state).getState(model); } return state; } diff --git a/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java b/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java index fb4dbd223..231b47b0e 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java +++ b/src/main/java/net/minecraftforge/client/model/ModelStateComposition.java @@ -1,5 +1,7 @@ package net.minecraftforge.client.model; +import com.google.common.base.Optional; + public class ModelStateComposition implements IModelState { private final IModelState first; @@ -11,8 +13,13 @@ public class ModelStateComposition implements IModelState this.second = second; } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { - return first.apply(part).compose(second.apply(part)); + Optional f = first.apply(part), s = second.apply(part); + if(f.isPresent() && s.isPresent()) + { + return Optional.of(f.get().compose(s.get())); + } + return f.or(s); } } diff --git a/src/main/java/net/minecraftforge/client/model/MultiModel.java b/src/main/java/net/minecraftforge/client/model/MultiModel.java index 115d3b9d8..4f0178c54 100644 --- a/src/main/java/net/minecraftforge/client/model/MultiModel.java +++ b/src/main/java/net/minecraftforge/client/model/MultiModel.java @@ -15,7 +15,6 @@ import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; @@ -93,16 +92,8 @@ public class MultiModel implements IModel ImmutableMap.Builder> builder = ImmutableMap.builder(); for(TransformType type : TransformType.values()) { - Pair p = perBase.handlePerspective(type); - IFlexibleBakedModel newBase; - if(p.getLeft() instanceof IFlexibleBakedModel) - { - newBase = (IFlexibleBakedModel)p.getLeft(); - } - else - { - newBase = new IFlexibleBakedModel.Wrapper(p.getLeft(), base.getFormat()); - } + Pair p = perBase.handlePerspective(type); + IFlexibleBakedModel newBase = p.getLeft(); builder.put(type, Pair.of(new Baked(location, false, newBase, parts), new TRSRTransformation(p.getRight()))); } transforms = builder.build(); @@ -172,11 +163,11 @@ public class MultiModel implements IModel } @Override - public Pair handlePerspective(TransformType cameraTransformType) + public Pair handlePerspective(TransformType cameraTransformType) { - if(transforms.isEmpty()) return Pair.of(this, null); + if(transforms.isEmpty()) return Pair.of(this, null); Pair p = transforms.get(cameraTransformType); - return Pair.of((IBakedModel)p.getLeft(), p.getRight().getMatrix()); + return Pair.of(p.getLeft(), p.getRight().getMatrix()); } } @@ -261,12 +252,6 @@ public class MultiModel implements IModel return new Baked(location, true, bakedBase, mapBuilder.build()); } - @Override - public IModelState getDefaultState() - { - return baseState; - } - /** * @return The base model of this MultiModel. May be null. */ @@ -282,4 +267,10 @@ public class MultiModel implements IModel { return parts; } + + @Override + public IModelState getDefaultState() + { + return baseState; + } } diff --git a/src/main/java/net/minecraftforge/client/model/SimpleModelState.java b/src/main/java/net/minecraftforge/client/model/SimpleModelState.java new file mode 100644 index 000000000..a4da1cc28 --- /dev/null +++ b/src/main/java/net/minecraftforge/client/model/SimpleModelState.java @@ -0,0 +1,30 @@ +package net.minecraftforge.client.model; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; + +/* + * Simple implementation of IModelState via a map and a default value. + */ +public class SimpleModelState implements IModelState +{ + private final ImmutableMap map; + private final Optional def; + + public SimpleModelState(ImmutableMap map) + { + this(map, Optional.absent()); + } + + public SimpleModelState(ImmutableMap map, Optional def) + { + this.map = map; + this.def = def; + } + + public Optional apply(Optional part) + { + if(!part.isPresent() || !map.containsKey(part.get())) return def; + return Optional.fromNullable(map.get(part.get())); + } +} diff --git a/src/main/java/net/minecraftforge/client/model/TRSRTransformation.java b/src/main/java/net/minecraftforge/client/model/TRSRTransformation.java index b6a201e2a..5f1f0d222 100644 --- a/src/main/java/net/minecraftforge/client/model/TRSRTransformation.java +++ b/src/main/java/net/minecraftforge/client/model/TRSRTransformation.java @@ -17,6 +17,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import com.google.common.base.Objects; +import com.google.common.base.Optional; /* * Interpolation-friendly affine transformation. @@ -474,9 +475,13 @@ public class TRSRTransformation implements IModelState, ITransformation return (Quat4f)rightRot.clone(); } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { - return this; + if(part.isPresent()) + { + return Optional.absent(); + } + return Optional.of(this); } public EnumFacing rotate(EnumFacing facing) 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 68da43dec..c06eacba2 100644 --- a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java +++ b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java @@ -22,7 +22,6 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.MathHelper; @@ -34,7 +33,6 @@ import net.minecraftforge.client.model.IModelCustomData; import net.minecraftforge.client.model.IModelPart; import net.minecraftforge.client.model.IModelState; import net.minecraftforge.client.model.IPerspectiveAwareModel; -import net.minecraftforge.client.model.IPerspectiveState; import net.minecraftforge.client.model.IRetexturableModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.client.model.ISmartItemModel; @@ -59,6 +57,8 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import com.google.common.base.Function; +import com.google.common.base.Objects; +import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -260,13 +260,15 @@ public class B3DLoader implements ICustomModelLoader return parent; } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { - if(!(part instanceof PartWrapper)) + // TODO optionify better + if(!part.isPresent()) return parent.apply(part); + if(!(part.get() instanceof NodeJoint)) { - throw new IllegalArgumentException("B3DState can only be applied to b3d models"); + return Optional.absent(); } - Node node = ((PartWrapper)part).getNode(); + Node node = ((NodeJoint)part.get()).getNode(); TRSRTransformation nodeTransform; if(progress < 1e-5 || frame == nextFrame) { @@ -281,11 +283,11 @@ public class B3DLoader implements ICustomModelLoader nodeTransform = getNodeMatrix(node, frame); nodeTransform = nodeTransform.slerp(getNodeMatrix(node, nextFrame), progress); } - if(parent != null) + if(parent != null && node.getParent() == null) { - return parent.apply(part).compose(nodeTransform); + return Optional.of(parent.apply(part).or(TRSRTransformation.identity()).compose(nodeTransform)); } - return nodeTransform; + return Optional.of(nodeTransform); } private static LoadingCache, Integer>, TRSRTransformation> cache = CacheBuilder.newBuilder() @@ -301,7 +303,7 @@ public class B3DLoader implements ICustomModelLoader public TRSRTransformation getNodeMatrix(Node node) { - return cache.getUnchecked(Triple., Integer>of(animation, node, frame)); + return getNodeMatrix(node, frame); } public TRSRTransformation getNodeMatrix(Node node, int frame) @@ -320,25 +322,102 @@ public class B3DLoader implements ICustomModelLoader Node parent = node.getParent(); if(parent != null) { + // parent model-global current pose TRSRTransformation pm = cache.getUnchecked(Triple., Integer>of(animation, node.getParent(), frame)); ret = ret.compose(pm); + // joint offset in the parent coords ret = ret.compose(new TRSRTransformation(parent.getPos(), parent.getRot(), parent.getScale(), null)); } + // current node local pose ret = ret.compose(new TRSRTransformation(key.getPos(), key.getRot(), key.getScale(), null)); - Matrix4f rm = new TRSRTransformation(node.getPos(), node.getRot(), node.getScale(), null).getMatrix(); + // this part moved inside the model + // inverse bind of the curent node + /*Matrix4f rm = new TRSRTransformation(node.getPos(), node.getRot(), node.getScale(), null).getMatrix(); rm.invert(); ret = ret.compose(new TRSRTransformation(rm)); if(parent != null) { + // inverse bind of the parent rm = new TRSRTransformation(parent.getPos(), parent.getRot(), parent.getScale(), null).getMatrix(); rm.invert(); ret = ret.compose(new TRSRTransformation(rm)); + }*/ + // TODO cache + TRSRTransformation invBind = new NodeJoint(node).getInvBindPose(); + ret = ret.compose(invBind); + } + else + { + Node parent = node.getParent(); + if(parent != null) + { + // parent model-global current pose + TRSRTransformation pm = cache.getUnchecked(Triple., Integer>of(animation, node.getParent(), frame)); + ret = ret.compose(pm); + // joint offset in the parent coords + ret = ret.compose(new TRSRTransformation(parent.getPos(), parent.getRot(), parent.getScale(), null)); } + ret = ret.compose(new TRSRTransformation(node.getPos(), node.getRot(), node.getScale(), null)); + // TODO cache + TRSRTransformation invBind = new NodeJoint(node).getInvBindPose(); + ret = ret.compose(invBind); } return ret; } } + public static class NodeJoint implements IModelPart + { + private final Node node; + + public NodeJoint(Node node) + { + this.node = node; + } + + public TRSRTransformation getInvBindPose() + { + Matrix4f m = new TRSRTransformation(node.getPos(), node.getRot(), node.getScale(), null).getMatrix(); + m.invert(); + TRSRTransformation pose = new TRSRTransformation(m); + + if(node.getParent() != null) + { + TRSRTransformation parent = new NodeJoint(node.getParent()).getInvBindPose(); + pose = pose.compose(parent); + } + return pose; + } + + public Optional getParent() + { + // FIXME cache? + if(node.getParent() == null) return Optional.absent(); + return Optional.of(new NodeJoint(node.getParent())); + } + + public Node getNode() + { + return node; + } + + @Override + public int hashCode() + { + return node.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + NodeJoint other = (NodeJoint) obj; + return Objects.equal(node, other.node); + } + } + public static enum B3DFrameProperty implements IUnlistedProperty { instance; @@ -760,10 +839,10 @@ public class B3DLoader implements ICustomModelLoader Mesh mesh = (Mesh)node.getKind(); Collection faces = mesh.bake(new Function, Matrix4f>() { - // gets transformation in global space + private final TRSRTransformation global = state.apply(Optional.absent()).or(TRSRTransformation.identity()); public Matrix4f apply(Node node) { - return state.apply(PartWrapper.create(node)).getMatrix(); + return global.compose(state.apply(Optional.of(new NodeJoint(node))).or(TRSRTransformation.identity())).getMatrix(); } }); for(Face f : faces) @@ -914,13 +993,14 @@ public class B3DLoader implements ICustomModelLoader return this; } - public Pair handlePerspective(TransformType cameraTransformType) + public Pair handlePerspective(TransformType cameraTransformType) { - if(state instanceof IPerspectiveState) + TRSRTransformation tr = state.apply(Optional.of(cameraTransformType)).or(TRSRTransformation.identity()); + if(tr != TRSRTransformation.identity()) { - return Pair.of((IBakedModel)this, TRSRTransformation.blockCornerToCenter(((IPerspectiveState)state).forPerspective(cameraTransformType).apply(PartWrapper.create(node))).getMatrix()); + return Pair.of(this, TRSRTransformation.blockCornerToCenter(tr).getMatrix()); } - return Pair.of((IBakedModel)this, null); + return Pair.of(this, null); } } } diff --git a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java b/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java index 9afe97410..f882cb369 100644 --- a/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java +++ b/src/main/java/net/minecraftforge/client/model/obj/OBJModel.java @@ -38,7 +38,6 @@ import net.minecraftforge.client.model.IModelCustomData; import net.minecraftforge.client.model.IModelPart; import net.minecraftforge.client.model.IModelState; import net.minecraftforge.client.model.IPerspectiveAwareModel; -import net.minecraftforge.client.model.IPerspectiveState; import net.minecraftforge.client.model.IRetexturableModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.client.model.ISmartItemModel; @@ -54,6 +53,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.google.common.base.Charsets; import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; @@ -121,11 +121,6 @@ public class OBJModel implements IRetexturableModel, IModelCustomData return new OBJBakedModel(this, state, format, builder.build()); } - public TRSRTransformation getDefaultState() - { - return TRSRTransformation.identity(); - } - public MaterialLibrary getMatLib() { return this.matLib; @@ -1108,13 +1103,13 @@ public class OBJModel implements IRetexturableModel, IModelCustomData this.faces = faces == null ? new LinkedHashSet() : faces; } - public LinkedHashSet applyTransform(TRSRTransformation transform) + public LinkedHashSet applyTransform(Optional transform) { LinkedHashSet faceSet = new LinkedHashSet(); for (Face f : this.faces) { // if (minUVBounds != null && maxUVBounds != null) f.normalizeUVs(minUVBounds, maxUVBounds); - faceSet.add(f.bake(transform)); + faceSet.add(f.bake(transform.or(TRSRTransformation.identity()))); } return faceSet; } @@ -1169,10 +1164,10 @@ public class OBJModel implements IRetexturableModel, IModelCustomData return parent; } - public TRSRTransformation apply(IModelPart part) + public Optional apply(Optional part) { if (parent != null) return parent.apply(part); - return new TRSRTransformation(EnumFacing.NORTH); + return Optional.absent(); } public Map getVisibilityMap() @@ -1325,7 +1320,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData { quads = Collections.synchronizedSet(new LinkedHashSet()); Set faces = Collections.synchronizedSet(new LinkedHashSet()); - TRSRTransformation transform = TRSRTransformation.identity(); + Optional transform = Optional.absent(); for (Group g : this.model.getMatLib().getGroups().values()) { // g.minUVBounds = this.model.getMatLib().minUVBounds; @@ -1337,7 +1332,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData OBJState state = (OBJState) this.state; if (state.parent != null) { - transform = state.parent.apply(model); + transform = state.parent.apply(Optional.absent()); } //TODO: can this be replaced by updateStateVisibilityMap(OBJState)? if (state.getGroupNamesFromMap().contains(Group.ALL)) @@ -1374,7 +1369,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData } else { - transform = state.apply(model); + transform = state.apply(Optional.absent()); faces.addAll(g.applyTransform(transform)); } } @@ -1578,13 +1573,14 @@ public class OBJModel implements IRetexturableModel, IModelCustomData } @Override - public Pair handlePerspective(TransformType cameraTransformType) + public Pair handlePerspective(TransformType cameraTransformType) { - if (state instanceof IPerspectiveState) + TRSRTransformation tr = state.apply(Optional.of(cameraTransformType)).or(TRSRTransformation.identity()); + if(tr != TRSRTransformation.identity()) { - return Pair.of((IBakedModel) this, TRSRTransformation.blockCornerToCenter(((IPerspectiveState) state).forPerspective(cameraTransformType).apply(model)).getMatrix()); + return Pair.of(this, TRSRTransformation.blockCornerToCenter(tr).getMatrix()); } - return Pair.of((IBakedModel) this, null); + return Pair.of(this, null); } @Override @@ -1605,4 +1601,10 @@ public class OBJModel implements IRetexturableModel, IModelCustomData this.modelLocation = modelLocation; } } + + @Override + public IModelState getDefaultState() + { + return TRSRTransformation.identity(); + } } diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java b/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java index ff84baebe..00773d4fe 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/LightUtil.java @@ -17,9 +17,10 @@ import com.google.common.cache.LoadingCache; public class LightUtil { + private static final float s2 = (float)Math.pow(2, .5); + public static float diffuseLight(float x, float y, float z) { - float s2 = (float)Math.pow(2, .5); float y1 = y + 3 - 2 * s2; return (x * x * 0.6f + (y1 * y1 * (3 + 2 * s2)) / 8 + z * z * 0.8f); } diff --git a/src/test/java/net/minecraftforge/debug/LayerBreakingTest.java b/src/test/java/net/minecraftforge/debug/LayerBreakingTest.java index 573e1b012..52167ecac 100644 --- a/src/test/java/net/minecraftforge/debug/LayerBreakingTest.java +++ b/src/test/java/net/minecraftforge/debug/LayerBreakingTest.java @@ -147,16 +147,6 @@ public class LayerBreakingTest IFlexibleBakedModel solid; IFlexibleBakedModel translucent; - @SuppressWarnings("unused") - private class DefState implements IModelState - { - @Override - public TRSRTransformation apply(IModelPart part) - { - return TRSRTransformation.identity(); - } - }; - @Override public List getFaceQuads(EnumFacing p_177551_1_) { diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json b/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json new file mode 100644 index 000000000..d7ef2789f --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/models/block/engine.json @@ -0,0 +1,39 @@ +// vanilla json model, no modifications + +{ + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 4, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture":"#base" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture":"#base" }, + "north": { "uv": [ 0, 0, 16, 4 ], "texture":"#front" }, + "south": { "uv": [ 0, 0, 16, 4 ], "texture":"#front" }, + "west": { "uv": [ 0, 0, 16, 4 ], "texture":"#front" }, + "east": { "uv": [ 0, 0, 16, 4 ], "texture":"#front" } + } + }, + { + "from": [ 4, 4, 4 ], + "to": [ 12, 8, 12 ], + "faces": { + "north": { "uv": [ 4, 4, 12, 8 ], "texture":"#chamber" }, + "south": { "uv": [ 4, 4, 12, 8 ], "texture":"#chamber" }, + "west": { "uv": [ 4, 4, 12, 8 ], "texture":"#chamber" }, + "east": { "uv": [ 4, 4, 12, 8 ], "texture":"#chamber" } + } + }, + { + "from": [ 4, 12, 4 ], + "to": [ 12, 16, 12 ], + "faces": { + "up": { "uv": [ 0, 0, 8, 8 ], "texture":"#trunk" }, + "north": { "uv": [ 4, 12, 12, 16 ], "texture":"#trunk" }, + "south": { "uv": [ 4, 12, 12, 16 ], "texture":"#trunk" }, + "west": { "uv": [ 4, 12, 12, 16 ], "texture":"#trunk" }, + "east": { "uv": [ 4, 12, 12, 16 ], "texture":"#trunk" } + } + } + ] +} diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json b/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json new file mode 100644 index 000000000..b6de7a275 --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/models/block/engine_ring.json @@ -0,0 +1,36 @@ +{ + "elements": [ + { + "from": [ 0, 4, 0 ], + "to": [ 16, 8, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture":"#base" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture":"#base" }, + "north": { "uv": [ 0, 4, 16, 8 ], "texture":"#front" }, + "south": { "uv": [ 0, 4, 16, 8 ], "texture":"#front" }, + "west": { "uv": [ 0, 4, 16, 8 ], "texture":"#front" }, + "east": { "uv": [ 0, 4, 16, 8 ], "texture":"#front" } + } + }, + { + "from": [ 4, 0, 4 ], + "to": [ 12, 4, 12 ], + "faces": { + "north": { "uv": [ 4, 8, 12, 12 ], "texture":"#chamber" }, + "south": { "uv": [ 4, 8, 12, 12 ], "texture":"#chamber" }, + "west": { "uv": [ 4, 8, 12, 12 ], "texture":"#chamber" }, + "east": { "uv": [ 4, 8, 12, 12 ], "texture":"#chamber" } + } + }, + { + "from": [ 4, 8, 4 ], + "to": [ 12, 12, 12 ], + "faces": { + "north": { "uv": [ 4, 8, 12, 12 ], "texture":"#trunk" }, + "south": { "uv": [ 4, 8, 12, 12 ], "texture":"#trunk" }, + "west": { "uv": [ 4, 8, 12, 12 ], "texture":"#trunk" }, + "east": { "uv": [ 4, 8, 12, 12 ], "texture":"#trunk" } + } + } + ] +}