From e283d51e28d9a4ff1f86a5fad6ec3e78dc5fddb3 Mon Sep 17 00:00:00 2001 From: Matthew Mirvish Date: Sat, 21 Oct 2017 01:27:35 -0400 Subject: [PATCH] [1.12.x] [Animation API] Add rotation origin variable (#4466) --- .../model/animation/ModelBlockAnimation.java | 24 +++- .../debug/ModelAnimationDebug.java | 109 +++++++++++++++++- .../armatures/block/rotatest.json | 56 +++++++++ .../asms/block/rotatest.json | 13 +++ .../blockstates/rotatest.json | 13 +++ .../models/block/rotatest.json | 60 ++++++++++ 6 files changed, 270 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json create mode 100644 src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json create mode 100644 src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json create mode 100644 src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json diff --git a/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java b/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java index f9f5eadb87..29bf147457 100644 --- a/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java +++ b/src/main/java/net/minecraftforge/client/model/animation/ModelBlockAnimation.java @@ -329,6 +329,7 @@ public class ModelBlockAnimation time -= Math.floor(time); Vector3f translation = new Vector3f(0, 0, 0); Vector3f scale = new Vector3f(1, 1, 1); + Vector3f origin = new Vector3f(0, 0, 0); AxisAngle4f rotation = new AxisAngle4f(0, 0, 0, 0); for(MBVariableClip var : variables) { @@ -393,11 +394,24 @@ public class ModelBlockAnimation case ZS: scale.z = value; break; + case XORIGIN: + origin.x = value - 0.5F; + break; + case YORIGIN: + origin.y = value - 0.5F; + break; + case ZORIGIN: + origin.z = value - 0.5F; + break; } } Quat4f rot = new Quat4f(); rot.set(rotation); - return TRSRTransformation.blockCenterToCorner(new TRSRTransformation(translation, rot, scale, null)); + TRSRTransformation base = new TRSRTransformation(translation, rot, scale, null); + Vector3f negOrigin = new Vector3f(origin); + negOrigin.negate(); + base = new TRSRTransformation(origin, null, null, null).compose(base).compose(new TRSRTransformation(negOrigin, null, null, null)); + return TRSRTransformation.blockCenterToCorner(base); } } } @@ -503,7 +517,13 @@ public class ModelBlockAnimation @SerializedName("scale_y") YS, @SerializedName("scale_z") - ZS; + ZS, + @SerializedName("origin_x") + XORIGIN, + @SerializedName("origin_y") + YORIGIN, + @SerializedName("origin_z") + ZORIGIN; } public static enum Type diff --git a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java index 9c2c9acd29..bc1265a2c9 100644 --- a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java @@ -22,9 +22,7 @@ import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; +import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -79,6 +77,10 @@ public class ModelAnimationDebug @ObjectHolder(blockName) public static final Item TEST_ITEM = null; + public static final String rotateBlockName = "rotatest"; + @ObjectHolder(rotateBlockName) + public static final Block TEST_ROTATE_BLOCK = null; + @Instance(MODID) public static ModelAnimationDebug instance; @@ -94,6 +96,7 @@ public class ModelAnimationDebug public static void registerBlocks(RegistryEvent.Register event) { GameRegistry.registerTileEntity(Chest.class, MODID + ":" + "tile_" + blockName); + GameRegistry.registerTileEntity(Spin.class, MODID + ":" + "tile_" + rotateBlockName); event.getRegistry().register( new Block(Material.WOOD) { @@ -181,6 +184,56 @@ public class ModelAnimationDebug return true; } }); + + event.getRegistry().register(new Block(Material.WOOD){ + { + setCreativeTab(CreativeTabs.BUILDING_BLOCKS); + setUnlocalizedName(MODID + "." + rotateBlockName); + setRegistryName(new ResourceLocation(MODID, rotateBlockName)); + } + + @Override + public ExtendedBlockState createBlockState() + { + return new ExtendedBlockState(this, new IProperty[]{ Properties.StaticProperty }, new IUnlistedProperty[]{ Properties.AnimationProperty }); + } + + @Override + public boolean isOpaqueCube(IBlockState state) { return false; } + + @Override + public boolean isFullCube(IBlockState state) { return false; } + + @Override + public boolean hasTileEntity(IBlockState state) { + return true; + } + + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.withProperty(Properties.StaticProperty, false); + } + + @Override + public int getMetaFromState(IBlockState state) { + return 0; + } + + @Override + public EnumBlockRenderType getRenderType(IBlockState state) { + return EnumBlockRenderType.ENTITYBLOCK_ANIMATED; + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return getDefaultState(); + } + + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return new Spin(); + } + }); } @SubscribeEvent @@ -196,6 +249,11 @@ public class ModelAnimationDebug } }.setRegistryName(TEST_BLOCK.getRegistryName()) ); + event.getRegistry().register( + new ItemBlock(TEST_ROTATE_BLOCK) { + + }.setRegistryName(TEST_ROTATE_BLOCK.getRegistryName()) + ); } } @@ -229,6 +287,7 @@ public class ModelAnimationDebug chest.handleEvents(time, pastEvents); } }); + ClientRegistry.bindTileEntitySpecialRenderer(Spin.class, new AnimationTESR()); String entityName = MODID + ":entity_chest"; //EntityRegistry.registerGlobalEntityID(EntityChest.class, entityName, EntityRegistry.findGlobalUniqueEntityId()); EntityRegistry.registerModEntity(new ResourceLocation(entityName), EntityChest.class, entityName, 0, ModelAnimationDebug.instance, 64, 20, true, 0xFFAAAA00, 0xFFDDDD00); @@ -298,6 +357,50 @@ public class ModelAnimationDebug logger = event.getModLog(); } + public static class Spin extends TileEntity implements ITickable, ICapabilityProvider { + + @Nullable + private final IAnimationStateMachine asm; + private final VariableValue cycle = new VariableValue(0); + + public Spin() { + asm = proxy.load(new ResourceLocation(MODID, "asms/block/rotatest.json"), ImmutableMap.of("cycle", cycle)); + + } + + int tickcounter; + + @Override + public void update() { + tickcounter++; + if (world.isRemote) { + cycle.setValue(tickcounter/40.0F); + } + } + + @Override + public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing side) { + return capability == CapabilityAnimation.ANIMATION_CAPABILITY || super.hasCapability(capability, side); + } + + @Override + @Nullable + public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing side) + { + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm); + } + return super.getCapability(capability, side); + } + + @Override + public boolean hasFastRenderer() + { + return true; + } + } + public static class Chest extends TileEntity { @Nullable diff --git a/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json b/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json new file mode 100644 index 0000000000..45d922d806 --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/armatures/block/rotatest.json @@ -0,0 +1,56 @@ +{ + "joints": { + "wall": { "0": [1.0]}, + "wall2" : { "1": [1.0]}, + "stick": {"2": [1.0]}, + "cube": {"3": [1.0]} + }, + "clips": { + "default": { + "loop": true, + "joint_clips": { + "stick": [ + { + "variable": "offset_x", + "type": "uniform", + "interpolation": "linear", + "samples": [0, 0.6875, 0] + } + ], + "cube": [ + { + "variable": "offset_x", + "type": "uniform", + "interpolation": "linear", + "samples": [0, 0.6875, 0] + }, + { + "variable": "axis_z", + "type": "uniform", + "interpolation": "nearest", + "samples": [ 1 ] + }, + { + "variable": "origin_x", + "type": "uniform", + "interpolation": "nearest", + "samples": [ 0.15625 ] + }, + { + "variable": "origin_y", + "type": "uniform", + "interpolation": "nearest", + "samples": [ 0.40625 ] + }, + { + "variable": "angle", + "type": "uniform", + "interpolation": "linear", + "samples": [0, 120, 240, 0, 120, 240] + } + ] + }, + "events": {} + } + } +} diff --git a/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json b/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json new file mode 100644 index 0000000000..de347b33b2 --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/asms/block/rotatest.json @@ -0,0 +1,13 @@ +{ + "parameters": { + + }, + "clips": { + "default": ["apply", "forgedebugmodelanimation:block/rotatest@default", "#cycle" ] + }, + "states": [ + "default" + ], + "transitions": {}, + "start_state": "default" +} diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json b/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json new file mode 100644 index 0000000000..124651670c --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/blockstates/rotatest.json @@ -0,0 +1,13 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "forgedebugmodelanimation:rotatest" + }, + "variants": { + "normal": [{}], + "static": { + "true": {}, + "false": {} + } + } +} diff --git a/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json b/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json new file mode 100644 index 0000000000..33b89d1924 --- /dev/null +++ b/src/test/resources/assets/forgedebugmodelanimation/models/block/rotatest.json @@ -0,0 +1,60 @@ +{ + "textures": { + "0": "blocks/log_oak", + "1": "blocks/iron_block", + "2": "blocks/stone_slab_top", + "3": "blocks/sponge" + }, + "elements": [ + { + "name": "WallA", + "from": [ 0.0, 0.0, 0.0 ], + "to": [ 16.0, 8.0, 2.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 8.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 0.0, 2.0, 8.0 ] }, + "south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 8.0 ] }, + "west": { "texture": "#0", "uv": [ 0.0, 0.0, 2.0, 8.0 ] }, + "up": { "texture": "#1", "uv": [ 0.0, 1.0, 16.0, 3.0 ] }, + "down": { "texture": "#1", "uv": [ 0.0, 1.0, 16.0, 3.0 ] } + } + }, + { + "name": "WallB", + "from": [ 0.0, 0.0, 14.0 ], + "to": [ 16.0, 8.0, 16.0 ], + "faces": { + "north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 8.0 ] }, + "east": { "texture": "#0", "uv": [ 0.0, 0.0, 2.0, 8.0 ] }, + "south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 8.0 ] }, + "west": { "texture": "#0", "uv": [ 0.0, 0.0, 2.0, 8.0 ] }, + "up": { "texture": "#1", "uv": [ 0.0, 1.0, 16.0, 3.0 ] }, + "down": { "texture": "#1", "uv": [ 0.0, 1.0, 16.0, 3.0 ] } + } + }, + { + "name": "Stick", + "from": [ 2.0, 6.0, 2.0 ], + "to": [ 3.0, 7.0, 14.0 ], + "faces": { + "east": { "texture": "#2", "uv": [ 1.0, 1.0, 13.0, 2.0 ] }, + "west": { "texture": "#2", "uv": [ 1.0, 2.0, 13.0, 3.0 ] }, + "up": { "texture": "#2", "uv": [ 0.0, 0.0, 1.0, 12.0 ] }, + "down": { "texture": "#2", "uv": [ 0.0, 0.0, 1.0, 12.0 ] } + } + }, + { + "name": "Rotate", + "from": [ 1.0, 5.0, 6.5 ], + "to": [ 4.0, 8.0, 9.5 ], + "faces": { + "north": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] }, + "east": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] }, + "south": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] }, + "west": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] }, + "up": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] }, + "down": { "texture": "#3", "uv": [ 0.0, 0.0, 3.0, 3.0 ] } + } + } + ] +}