diff --git a/.tmp-mc/assets/minecraft/blockstates/oak_fence_gate.json b/.tmp-mc/assets/minecraft/blockstates/oak_fence_gate.json new file mode 100644 index 0000000..872298c --- /dev/null +++ b/.tmp-mc/assets/minecraft/blockstates/oak_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "model": "minecraft:block/oak_fence_gate", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=false,open=true": { + "model": "minecraft:block/oak_fence_gate_open", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=false": { + "model": "minecraft:block/oak_fence_gate_wall", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=true": { + "model": "minecraft:block/oak_fence_gate_wall_open", + "uvlock": true, + "y": 270 + }, + "facing=north,in_wall=false,open=false": { + "model": "minecraft:block/oak_fence_gate", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=false,open=true": { + "model": "minecraft:block/oak_fence_gate_open", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=false": { + "model": "minecraft:block/oak_fence_gate_wall", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=true": { + "model": "minecraft:block/oak_fence_gate_wall_open", + "uvlock": true, + "y": 180 + }, + "facing=south,in_wall=false,open=false": { + "model": "minecraft:block/oak_fence_gate", + "uvlock": true + }, + "facing=south,in_wall=false,open=true": { + "model": "minecraft:block/oak_fence_gate_open", + "uvlock": true + }, + "facing=south,in_wall=true,open=false": { + "model": "minecraft:block/oak_fence_gate_wall", + "uvlock": true + }, + "facing=south,in_wall=true,open=true": { + "model": "minecraft:block/oak_fence_gate_wall_open", + "uvlock": true + }, + "facing=west,in_wall=false,open=false": { + "model": "minecraft:block/oak_fence_gate", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=false,open=true": { + "model": "minecraft:block/oak_fence_gate_open", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=false": { + "model": "minecraft:block/oak_fence_gate_wall", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=true": { + "model": "minecraft:block/oak_fence_gate_wall_open", + "uvlock": true, + "y": 90 + } + } +} \ No newline at end of file diff --git a/.tmp-mc/assets/minecraft/models/block/template_fence_gate.json b/.tmp-mc/assets/minecraft/models/block/template_fence_gate.json new file mode 100644 index 0000000..b1a090f --- /dev/null +++ b/.tmp-mc/assets/minecraft/models/block/template_fence_gate.json @@ -0,0 +1,107 @@ +{ "parent": "block/block", + "display": { + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0, -1, 0], + "scale":[ 0.8, 0.8, 0.8 ] + }, + "head": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, -3, -6], + "scale":[ 1, 1, 1] + } + }, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 5, 7 ], + "to": [ 2, 16, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 5, 7 ], + "to": [ 16, 16, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 6, 6, 7 ], + "to": [ 8, 15, 9 ], + "faces": { + "down": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "up": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "north": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "south": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 8, 6, 7 ], + "to": [ 10, 15, 9 ], + "faces": { + "down": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "up": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "north": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "south": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 2, 6, 7 ], + "to": [ 6, 9, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" }, + "south": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 2, 12, 7 ], + "to": [ 6, 15, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" }, + "south": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of right-hand gate door", + "from": [ 10, 6, 7 ], + "to": [ 14, 9, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" }, + "south": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of right-hand gate door", + "from": [ 10, 12, 7 ], + "to": [ 14, 15, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" }, + "south": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/.tmp-mc/assets/minecraft/models/block/template_fence_gate_open.json b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_open.json new file mode 100644 index 0000000..af2062a --- /dev/null +++ b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_open.json @@ -0,0 +1,95 @@ +{ + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 5, 7 ], + "to": [ 2, 16, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 5, 7 ], + "to": [ 16, 16, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 0, 6, 13 ], + "to": [ 2, 15, 15 ], + "faces": { + "down": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "up": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "north": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "south": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 14, 6, 13 ], + "to": [ 16, 15, 15 ], + "faces": { + "down": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "up": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "north": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "south": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 0, 6, 9 ], + "to": [ 2, 9, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 0, 12, 9 ], + "to": [ 2, 15, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 14, 6, 9 ], + "to": [ 16, 9, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 14, 12, 9 ], + "to": [ 16, 15, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall.json b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall.json new file mode 100644 index 0000000..7b30133 --- /dev/null +++ b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall.json @@ -0,0 +1,96 @@ +{ + "ambientocclusion": true, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 2, 7 ], + "to": [ 2, 13, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 2, 7 ], + "to": [ 16, 13, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 6, 3, 7 ], + "to": [ 8, 12, 9 ], + "faces": { + "down": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "up": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "north": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "south": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 8, 3, 7 ], + "to": [ 10, 12, 9 ], + "faces": { + "down": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "up": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "north": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "south": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 2, 3, 7 ], + "to": [ 6, 6, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" }, + "south": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 2, 9, 7 ], + "to": [ 6, 12, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" }, + "south": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of right-hand gate door", + "from": [ 10, 3, 7 ], + "to": [ 14, 6, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" }, + "south": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of right-hand gate door", + "from": [ 10, 9, 7 ], + "to": [ 14, 12, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" }, + "south": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall_open.json b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall_open.json new file mode 100644 index 0000000..6fddae6 --- /dev/null +++ b/.tmp-mc/assets/minecraft/models/block/template_fence_gate_wall_open.json @@ -0,0 +1,96 @@ +{ + "ambientocclusion": true, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 2, 7 ], + "to": [ 2, 13, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 2, 7 ], + "to": [ 16, 13, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 0, 3, 13 ], + "to": [ 2, 12, 15 ], + "faces": { + "down": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "up": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "north": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "south": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 14, 3, 13 ], + "to": [ 16, 12, 15 ], + "faces": { + "down": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "up": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "north": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "south": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 0, 3, 9 ], + "to": [ 2, 6, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 0, 9, 9 ], + "to": [ 2, 12, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 14, 3, 9 ], + "to": [ 16, 6, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 14, 9, 9 ], + "to": [ 16, 12, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/assets/minecraft/models/block/template_fence_gate.json b/assets/minecraft/models/block/template_fence_gate.json new file mode 100644 index 0000000..b1a090f --- /dev/null +++ b/assets/minecraft/models/block/template_fence_gate.json @@ -0,0 +1,107 @@ +{ "parent": "block/block", + "display": { + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0, -1, 0], + "scale":[ 0.8, 0.8, 0.8 ] + }, + "head": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, -3, -6], + "scale":[ 1, 1, 1] + } + }, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 5, 7 ], + "to": [ 2, 16, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 5, 7 ], + "to": [ 16, 16, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 6, 6, 7 ], + "to": [ 8, 15, 9 ], + "faces": { + "down": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "up": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "north": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "south": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 8, 6, 7 ], + "to": [ 10, 15, 9 ], + "faces": { + "down": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "up": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "north": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "south": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 2, 6, 7 ], + "to": [ 6, 9, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" }, + "south": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 2, 12, 7 ], + "to": [ 6, 15, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" }, + "south": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of right-hand gate door", + "from": [ 10, 6, 7 ], + "to": [ 14, 9, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" }, + "south": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of right-hand gate door", + "from": [ 10, 12, 7 ], + "to": [ 14, 15, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" }, + "south": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/assets/minecraft/models/block/template_fence_gate_open.json b/assets/minecraft/models/block/template_fence_gate_open.json new file mode 100644 index 0000000..af2062a --- /dev/null +++ b/assets/minecraft/models/block/template_fence_gate_open.json @@ -0,0 +1,95 @@ +{ + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 5, 7 ], + "to": [ 2, 16, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 5, 7 ], + "to": [ 16, 16, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 0, 6, 13 ], + "to": [ 2, 15, 15 ], + "faces": { + "down": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "up": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "north": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "south": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 14, 6, 13 ], + "to": [ 16, 15, 15 ], + "faces": { + "down": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "up": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "north": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "south": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 0, 6, 9 ], + "to": [ 2, 9, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 0, 12, 9 ], + "to": [ 2, 15, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 14, 6, 9 ], + "to": [ 16, 9, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 14, 12, 9 ], + "to": [ 16, 15, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/assets/minecraft/models/block/template_fence_gate_wall.json b/assets/minecraft/models/block/template_fence_gate_wall.json new file mode 100644 index 0000000..7b30133 --- /dev/null +++ b/assets/minecraft/models/block/template_fence_gate_wall.json @@ -0,0 +1,96 @@ +{ + "ambientocclusion": true, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 2, 7 ], + "to": [ 2, 13, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 2, 7 ], + "to": [ 16, 13, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 6, 3, 7 ], + "to": [ 8, 12, 9 ], + "faces": { + "down": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "up": { "uv": [ 6, 7, 8, 9 ], "texture": "#texture" }, + "north": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "south": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 8, 3, 7 ], + "to": [ 10, 12, 9 ], + "faces": { + "down": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "up": { "uv": [ 8, 7, 10, 9 ], "texture": "#texture" }, + "north": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "south": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" }, + "west": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }, + "east": { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 2, 3, 7 ], + "to": [ 6, 6, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" }, + "south": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 2, 9, 7 ], + "to": [ 6, 12, 9 ], + "faces": { + "down": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "up": { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" }, + "north": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" }, + "south": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of right-hand gate door", + "from": [ 10, 3, 7 ], + "to": [ 14, 6, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" }, + "south": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of right-hand gate door", + "from": [ 10, 9, 7 ], + "to": [ 14, 12, 9 ], + "faces": { + "down": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "up": { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" }, + "north": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" }, + "south": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/assets/minecraft/models/block/template_fence_gate_wall_open.json b/assets/minecraft/models/block/template_fence_gate_wall_open.json new file mode 100644 index 0000000..6fddae6 --- /dev/null +++ b/assets/minecraft/models/block/template_fence_gate_wall_open.json @@ -0,0 +1,96 @@ +{ + "ambientocclusion": true, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "__comment": "Left-hand post", + "from": [ 0, 2, 7 ], + "to": [ 2, 13, 9 ], + "faces": { + "down": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "up": { "uv": [ 0, 7, 2, 9 ], "texture": "#texture" }, + "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" } + } + }, + { "__comment": "Right-hand post", + "from": [ 14, 2, 7 ], + "to": [ 16, 13, 9 ], + "faces": { + "down": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "up": { "uv": [ 14, 7, 16, 9 ], "texture": "#texture" }, + "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" }, + "west": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }, + "east": { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "east" } + } + }, + { "__comment": "Inner vertical post of left-hand gate door", + "from": [ 0, 3, 13 ], + "to": [ 2, 12, 15 ], + "faces": { + "down": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "up": { "uv": [ 0, 13, 2, 15 ], "texture": "#texture" }, + "north": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "south": { "uv": [ 0, 1, 2, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Inner vertical post of right-hand gate door", + "from": [ 14, 3, 13 ], + "to": [ 16, 12, 15 ], + "faces": { + "down": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "up": { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" }, + "north": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "south": { "uv": [ 14, 1, 16, 10 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 0, 3, 9 ], + "to": [ 2, 6, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 0, 9, 9 ], + "to": [ 2, 12, 13 ], + "faces": { + "down": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "up": { "uv": [ 0, 9, 2, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + }, + { "__comment": "Lower horizontal bar of left-hand gate door", + "from": [ 14, 3, 9 ], + "to": [ 16, 6, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }, + "east": { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" } + } + }, + { "__comment": "Upper horizontal bar of left-hand gate door", + "from": [ 14, 9, 9 ], + "to": [ 16, 12, 13 ], + "faces": { + "down": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "up": { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" }, + "west": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" }, + "east": { "uv": [ 13, 1, 15, 4 ], "texture": "#texture" } + } + } + ] +} diff --git a/ccc.png b/ccc.png deleted file mode 100644 index 1e76290..0000000 Binary files a/ccc.png and /dev/null differ diff --git a/dss.png b/dss.png deleted file mode 100644 index ebff7c5..0000000 Binary files a/dss.png and /dev/null differ diff --git a/src/client/java/com/straice/smoothdoors/client/anim/DoorAnimation.java b/src/client/java/com/straice/smoothdoors/client/anim/DoorAnimation.java new file mode 100644 index 0000000..b573938 --- /dev/null +++ b/src/client/java/com/straice/smoothdoors/client/anim/DoorAnimation.java @@ -0,0 +1,78 @@ +package com.straice.smoothdoors.client.anim; + +import net.minecraft.block.BlockState; +import net.minecraft.block.DoorBlock; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.enums.DoorHinge; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.world.BlockRenderView; + +final class DoorAnimation { + + private DoorAnimation() {} + + static void apply(BlockState state, float angleDeg, MatrixStack matrices, BlockRenderView world) { + if (world == null) return; + + Direction facing = state.get(DoorBlock.FACING); + DoorHinge hinge = state.get(DoorBlock.HINGE); + + Direction hingeSide = (hinge == DoorHinge.RIGHT) + ? facing.rotateYClockwise() + : facing.rotateYCounterclockwise(); + + Box bb = state.getOutlineShape(world, BlockPos.ORIGIN, ShapeContext.absent()).getBoundingBox(); + + float cx = (float) ((bb.minX + bb.maxX) * 0.5); + float cz = (float) ((bb.minZ + bb.maxZ) * 0.5); + + float pivotX = cx; + float pivotZ = cz; + + switch (hingeSide) { + case EAST -> pivotX = (float) bb.maxX; + case WEST -> pivotX = (float) bb.minX; + case SOUTH -> pivotZ = (float) bb.maxZ; + case NORTH -> pivotZ = (float) bb.minZ; + default -> { + pivotX = cx; + pivotZ = cz; + } + } + + float thickness = (facing == Direction.NORTH || facing == Direction.SOUTH) + ? (float) (bb.maxZ - bb.minZ) + : (float) (bb.maxX - bb.minX); + float halfT = thickness * 0.5f; + + float dX = 0.0f; + float dZ = 0.0f; + switch (facing) { + case NORTH -> dZ = halfT; + case SOUTH -> dZ = -halfT; + case WEST -> dX = halfT; + case EAST -> dX = -halfT; + default -> { + dX = 0.0f; + dZ = 0.0f; + } + } + + double rad = Math.toRadians(angleDeg); + float cos = (float) Math.cos(rad); + float sin = (float) Math.sin(rad); + float rotDX = dX * cos - dZ * sin; + float rotDZ = dX * sin + dZ * cos; + float shiftX = dX - rotDX; + float shiftZ = dZ - rotDZ; + + matrices.translate(shiftX, 0.0f, shiftZ); + matrices.translate(pivotX, 0.0f, pivotZ); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angleDeg)); + matrices.translate(-pivotX, 0.0f, -pivotZ); + } +} diff --git a/src/client/java/com/straice/smoothdoors/client/anim/FenceGateAnimation.java b/src/client/java/com/straice/smoothdoors/client/anim/FenceGateAnimation.java new file mode 100644 index 0000000..8cb1b6d --- /dev/null +++ b/src/client/java/com/straice/smoothdoors/client/anim/FenceGateAnimation.java @@ -0,0 +1,234 @@ +package com.straice.smoothdoors.client.anim; + +import net.minecraft.block.BlockState; +import net.minecraft.block.FenceGateBlock; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.RenderLayers; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.block.BlockModelRenderer; +import net.minecraft.client.render.model.BakedQuad; +import net.minecraft.client.render.model.BlockModelPart; +import net.minecraft.client.render.model.BlockStateModel; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.random.Random; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; + +final class FenceGateAnimation { + + private static final float POST_EDGE = 2.0f / 16.0f; + private static final float EDGE_EPS = 1.0e-4f; + + private FenceGateAnimation() {} + + static void render(BlockState state, float angleDeg, MatrixStack matrices, + VertexConsumerProvider consumers, int light, int overlay) { + MinecraftClient mc = MinecraftClient.getInstance(); + if (mc.world == null) return; + + Direction facing = state.get(FenceGateBlock.FACING); + boolean leftRightIsX = facing.getAxis() == Direction.Axis.Z; + + BlockStateModel baseModel = mc.getBlockRenderManager().getModel(state); + FenceGateModels models = splitFenceGateModels(baseModel, leftRightIsX); + if (models.isEmpty()) return; + + int tint = mc.getBlockColors().getColor(state, null, null, 0); + float r = ((tint >> 16) & 0xFF) / 255.0f; + float g = ((tint >> 8) & 0xFF) / 255.0f; + float b = (tint & 0xFF) / 255.0f; + + VertexConsumer consumer = consumers.getBuffer(RenderLayers.getEntityBlockLayer(state)); + + if (models.posts != null) { + BlockModelRenderer.render(matrices.peek(), consumer, models.posts, r, g, b, light, overlay); + } + + float leftPivotX = leftRightIsX ? (1.0f / 16.0f) : 0.5f; + float leftPivotZ = leftRightIsX ? 0.5f : (1.0f / 16.0f); + float rightPivotX = leftRightIsX ? (15.0f / 16.0f) : 0.5f; + float rightPivotZ = leftRightIsX ? 0.5f : (15.0f / 16.0f); + + if (models.left != null) { + matrices.push(); + matrices.translate(leftPivotX, 0.0f, leftPivotZ); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-angleDeg)); + matrices.translate(-leftPivotX, 0.0f, -leftPivotZ); + BlockModelRenderer.render(matrices.peek(), consumer, models.left, r, g, b, light, overlay); + matrices.pop(); + } + + if (models.right != null) { + matrices.push(); + matrices.translate(rightPivotX, 0.0f, rightPivotZ); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angleDeg)); + matrices.translate(-rightPivotX, 0.0f, -rightPivotZ); + BlockModelRenderer.render(matrices.peek(), consumer, models.right, r, g, b, light, overlay); + matrices.pop(); + } + } + + private static FenceGateModels splitFenceGateModels(BlockStateModel model, boolean leftRightIsX) { + List parts = model.getParts(Random.create(42L)); + List posts = new ArrayList<>(); + List left = new ArrayList<>(); + List right = new ArrayList<>(); + + for (BlockModelPart part : parts) { + FenceGateCollector postsCollector = new FenceGateCollector(); + FenceGateCollector leftCollector = new FenceGateCollector(); + FenceGateCollector rightCollector = new FenceGateCollector(); + + for (Direction dir : Direction.values()) { + addFenceGateQuads(part, dir, leftRightIsX, postsCollector, leftCollector, rightCollector); + } + addFenceGateQuads(part, null, leftRightIsX, postsCollector, leftCollector, rightCollector); + + if (!postsCollector.isEmpty()) posts.add(postsCollector.toPart(part)); + if (!leftCollector.isEmpty()) left.add(leftCollector.toPart(part)); + if (!rightCollector.isEmpty()) right.add(rightCollector.toPart(part)); + } + + return new FenceGateModels( + posts.isEmpty() ? null : new StaticBlockStateModel(posts, model.particleSprite()), + left.isEmpty() ? null : new StaticBlockStateModel(left, model.particleSprite()), + right.isEmpty() ? null : new StaticBlockStateModel(right, model.particleSprite()) + ); + } + + private static void addFenceGateQuads(BlockModelPart part, Direction dir, boolean leftRightIsX, + FenceGateCollector posts, FenceGateCollector left, FenceGateCollector right) { + List quads = part.getQuads(dir); + if (quads.isEmpty()) return; + + for (BakedQuad quad : quads) { + FenceGateSection section = classifyFenceGateQuad(quad, leftRightIsX); + switch (section) { + case POSTS -> posts.add(dir, quad); + case LEFT -> left.add(dir, quad); + case RIGHT -> right.add(dir, quad); + } + } + } + + private static FenceGateSection classifyFenceGateQuad(BakedQuad quad, boolean leftRightIsX) { + int[] data = quad.vertexData(); + if (data.length < 8) return FenceGateSection.LEFT; + + int stride = data.length / 4; + float min = Float.POSITIVE_INFINITY; + float max = Float.NEGATIVE_INFINITY; + int coordOffset = leftRightIsX ? 0 : 2; + + for (int i = 0; i < 4; i++) { + int base = i * stride + coordOffset; + float coord = Float.intBitsToFloat(data[base]); + min = Math.min(min, coord); + max = Math.max(max, coord); + } + + if (max <= POST_EDGE + EDGE_EPS || min >= (1.0f - POST_EDGE) - EDGE_EPS) { + return FenceGateSection.POSTS; + } + + float center = (min + max) * 0.5f; + return center <= 0.5f ? FenceGateSection.LEFT : FenceGateSection.RIGHT; + } + + private enum FenceGateSection { POSTS, LEFT, RIGHT } + + private static final class FenceGateModels { + final BlockStateModel posts; + final BlockStateModel left; + final BlockStateModel right; + + FenceGateModels(BlockStateModel posts, BlockStateModel left, BlockStateModel right) { + this.posts = posts; + this.left = left; + this.right = right; + } + + boolean isEmpty() { + return posts == null && left == null && right == null; + } + } + + private static final class FenceGateCollector { + private final EnumMap> faceQuads = new EnumMap<>(Direction.class); + private final List unculled = new ArrayList<>(); + + void add(Direction face, BakedQuad quad) { + if (face == null) { + unculled.add(quad); + return; + } + faceQuads.computeIfAbsent(face, k -> new ArrayList<>()).add(quad); + } + + boolean isEmpty() { + return unculled.isEmpty() && faceQuads.isEmpty(); + } + + BlockModelPart toPart(BlockModelPart template) { + return new StaticBlockModelPart(faceQuads, unculled, template.useAmbientOcclusion(), template.particleSprite()); + } + } + + private static final class StaticBlockModelPart implements BlockModelPart { + private final EnumMap> faceQuads; + private final List unculled; + private final boolean useAo; + private final Sprite particleSprite; + + StaticBlockModelPart(EnumMap> faceQuads, List unculled, + boolean useAo, Sprite particleSprite) { + this.faceQuads = faceQuads; + this.unculled = unculled; + this.useAo = useAo; + this.particleSprite = particleSprite; + } + + @Override + public List getQuads(Direction face) { + if (face == null) return unculled; + List quads = faceQuads.get(face); + return (quads == null) ? List.of() : quads; + } + + @Override + public boolean useAmbientOcclusion() { + return useAo; + } + + @Override + public Sprite particleSprite() { + return particleSprite; + } + } + + private static final class StaticBlockStateModel implements BlockStateModel { + private final List parts; + private final Sprite particleSprite; + + StaticBlockStateModel(List parts, Sprite particleSprite) { + this.parts = parts; + this.particleSprite = particleSprite; + } + + @Override + public void addParts(Random random, List out) { + out.addAll(parts); + } + + @Override + public Sprite particleSprite() { + return particleSprite; + } + } +} diff --git a/src/client/java/com/straice/smoothdoors/client/anim/SddAnimator.java b/src/client/java/com/straice/smoothdoors/client/anim/SddAnimator.java index bfe4112..e3b7481 100644 --- a/src/client/java/com/straice/smoothdoors/client/anim/SddAnimator.java +++ b/src/client/java/com/straice/smoothdoors/client/anim/SddAnimator.java @@ -5,7 +5,6 @@ import com.straice.smoothdoors.config.SddConfigManager; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.minecraft.block.*; -import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.DoorHinge; import net.minecraft.block.enums.DoubleBlockHalf; import net.minecraft.client.MinecraftClient; @@ -14,7 +13,6 @@ import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.*; -import net.minecraft.util.shape.VoxelShape; import java.lang.reflect.Field; @@ -22,7 +20,7 @@ public final class SddAnimator { private static final MinecraftClient MC = MinecraftClient.getInstance(); - // Duración base (segundos) a speed = 1.0x + // Base duration (seconds) at speed = 1.0x private static final float BASE_DURATION_S = 0.35f; private static final Long2ObjectOpenHashMap ANIMS = new Long2ObjectOpenHashMap<>(); @@ -44,7 +42,7 @@ public final class SddAnimator { // === API usada por mixins === - /** Oculta el bloque vanilla mientras animamos (evita “doble puerta”). */ + /** Oculta el bloque vanilla mientras animamos (evita doble puerta). */ public static boolean shouldHideInChunk(BlockPos pos, BlockState state) { synchronized (ANIMS) { if (ANIMS.containsKey(pos.asLong())) return true; @@ -160,7 +158,7 @@ public final class SddAnimator { matrices.push(); - // Fijo en mundo: bloque - cámara + // Fijo en mundo: bloque - camara matrices.translate( pos.getX() - camPos.x, pos.getY() - camPos.y, @@ -170,10 +168,13 @@ public final class SddAnimator { float eased = easeInOut(t); float angleDeg = lerpAngleDeg(anim.fromOpen, anim.toOpen, eased, anim.kind, state); - applyTransform(anim.kind, state, angleDeg, matrices); - int light = WorldRenderer.getLightmapCoordinates((net.minecraft.world.BlockRenderView) MC.world, pos); - MC.getBlockRenderManager().renderBlockAsEntity(state, matrices, consumers, light, OverlayTexture.DEFAULT_UV); + if (anim.kind == Kind.FENCE_GATE) { + FenceGateAnimation.render(state, angleDeg, matrices, consumers, light, OverlayTexture.DEFAULT_UV); + } else { + applyTransform(anim.kind, state, angleDeg, matrices); + MC.getBlockRenderManager().renderBlockAsEntity(state, matrices, consumers, light, OverlayTexture.DEFAULT_UV); + } matrices.pop(); } @@ -207,7 +208,7 @@ public final class SddAnimator { } } - // === Ángulos y transforms === + // === Angulos y transforms === private static float lerpAngleDeg(boolean fromOpen, boolean toOpen, float t, Kind kind, BlockState state) { float a = angleFor(kind, state, fromOpen); @@ -230,142 +231,11 @@ public final class SddAnimator { private static void applyTransform(Kind kind, BlockState state, float angleDeg, MatrixStack matrices) { switch (kind) { - case DOOR -> transformDoor(state, angleDeg, matrices); - case TRAPDOOR -> transformTrapdoor(state, angleDeg, matrices); - case FENCE_GATE -> transformFenceGate(state, angleDeg, matrices); - } - } - - /** - * FIX del pivote: - * Estabas rotando alrededor de una “punta” (esquina). Una puerta real rota alrededor de la línea de bisagra: - * - Coordenada del eje de bisagra (hingeSide): en el BORDE del modelo (min/max del bounding box) - * - Coordenada perpendicular: en el CENTRO del modelo (centro del bounding box) - * - * Esto quita el efecto de que la animación “empiece por encima/encima” y que parezca que se desplaza. - */ - private static void transformDoor(BlockState state, float angleDeg, MatrixStack matrices) { - if (MC.world == null) return; - - Direction facing = state.get(DoorBlock.FACING); - DoorHinge hinge = state.get(DoorBlock.HINGE); - - Direction hingeSide = (hinge == DoorHinge.RIGHT) - ? facing.rotateYClockwise() - : facing.rotateYCounterclockwise(); - - Box bb = state.getOutlineShape(MC.world, BlockPos.ORIGIN, ShapeContext.absent()).getBoundingBox(); - - float cx = (float) ((bb.minX + bb.maxX) * 0.5); - float cz = (float) ((bb.minZ + bb.maxZ) * 0.5); - - float pivotX = cx; - float pivotZ = cz; - - switch (hingeSide) { - case EAST -> pivotX = (float) bb.maxX; - case WEST -> pivotX = (float) bb.minX; - case SOUTH -> pivotZ = (float) bb.maxZ; - case NORTH -> pivotZ = (float) bb.minZ; - default -> { - pivotX = cx; - pivotZ = cz; + case DOOR -> DoorAnimation.apply(state, angleDeg, matrices, MC.world); + case TRAPDOOR -> TrapdoorAnimation.apply(state, angleDeg, matrices, MC.world); + case FENCE_GATE -> { } } - - float thickness = (facing == Direction.NORTH || facing == Direction.SOUTH) - ? (float) (bb.maxZ - bb.minZ) - : (float) (bb.maxX - bb.minX); - float halfT = thickness * 0.5f; - - float dX = 0.0f; - float dZ = 0.0f; - switch (facing) { - case NORTH -> dZ = halfT; - case SOUTH -> dZ = -halfT; - case WEST -> dX = halfT; - case EAST -> dX = -halfT; - default -> { - dX = 0.0f; - dZ = 0.0f; - } - } - - double rad = Math.toRadians(angleDeg); - float cos = (float) Math.cos(rad); - float sin = (float) Math.sin(rad); - float rotDX = dX * cos - dZ * sin; - float rotDZ = dX * sin + dZ * cos; - float shiftX = dX - rotDX; - float shiftZ = dZ - rotDZ; - - matrices.translate(shiftX, 0.0f, shiftZ); - matrices.translate(pivotX, 0.0f, pivotZ); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angleDeg)); - matrices.translate(-pivotX, 0.0f, -pivotZ); - } - - // (trapdoors/gates luego los ajustamos) - private static void transformTrapdoor(BlockState state, float baseAngleDeg, MatrixStack matrices) { - if (MC.world == null) return; - - Direction facing = state.get(TrapdoorBlock.FACING); - BlockHalf half = state.get(TrapdoorBlock.HALF); - - VoxelShape collShape = state.getCollisionShape(MC.world, BlockPos.ORIGIN, ShapeContext.absent()); - Box bb = collShape.isEmpty() - ? state.getOutlineShape(MC.world, BlockPos.ORIGIN, ShapeContext.absent()).getBoundingBox() - : collShape.getBoundingBox(); - - float angle; - switch (facing) { - case NORTH -> angle = baseAngleDeg; - case SOUTH -> angle = -baseAngleDeg; - case EAST -> angle = baseAngleDeg; - case WEST -> angle = -baseAngleDeg; - default -> angle = baseAngleDeg; - } - if (half == BlockHalf.TOP) angle = -angle; - - float pivotX = (float) ((bb.minX + bb.maxX) * 0.5); - float pivotZ = (float) ((bb.minZ + bb.maxZ) * 0.5); - Direction hingeSide = facing.getOpposite(); - switch (hingeSide) { - case NORTH -> pivotZ = (float) bb.minZ; - case SOUTH -> pivotZ = (float) bb.maxZ; - case WEST -> pivotX = (float) bb.minX; - case EAST -> pivotX = (float) bb.maxX; - default -> { - pivotX = (float) ((bb.minX + bb.maxX) * 0.5); - pivotZ = (float) ((bb.minZ + bb.maxZ) * 0.5); - } - } - float thickness = (float) (bb.maxY - bb.minY); - float halfT = thickness > 0.0f ? thickness * 0.5f : (3.0f / 32.0f); - - float pivotYClosed = (half == BlockHalf.TOP) ? (float) bb.maxY - halfT : (float) bb.minY + halfT; - float pivotYOpen = (half == BlockHalf.TOP) ? (float) bb.maxY : (float) bb.minY; - - float progress = MathHelper.clamp(Math.abs(angle) / 90.0f, 0.0f, 1.0f); - float pivotY = MathHelper.lerp(progress, pivotYClosed, pivotYOpen); - float pivotXInterp = pivotX; - float pivotZInterp = pivotZ; - - matrices.translate(pivotXInterp, pivotY, pivotZInterp); - - if (facing == Direction.NORTH || facing == Direction.SOUTH) { - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(angle)); - } else { - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(angle)); - } - - matrices.translate(-pivotXInterp, -pivotY, -pivotZInterp); - } - - private static void transformFenceGate(BlockState state, float angleDeg, MatrixStack matrices) { - matrices.translate(0.5f, 0.0f, 0.5f); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angleDeg)); - matrices.translate(-0.5f, 0.0f, -0.5f); } // === Utilidades === @@ -511,4 +381,3 @@ public final class SddAnimator { } } } - diff --git a/src/client/java/com/straice/smoothdoors/client/anim/TrapdoorAnimation.java b/src/client/java/com/straice/smoothdoors/client/anim/TrapdoorAnimation.java new file mode 100644 index 0000000..497a533 --- /dev/null +++ b/src/client/java/com/straice/smoothdoors/client/anim/TrapdoorAnimation.java @@ -0,0 +1,87 @@ +package com.straice.smoothdoors.client.anim; + +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.TrapdoorBlock; +import net.minecraft.block.enums.BlockHalf; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockRenderView; + +final class TrapdoorAnimation { + + private TrapdoorAnimation() {} + + static void apply(BlockState state, float baseAngleDeg, MatrixStack matrices, BlockRenderView world) { + if (world == null) return; + + Direction facing = state.get(TrapdoorBlock.FACING); + BlockHalf half = state.get(TrapdoorBlock.HALF); + + VoxelShape collShape = state.getCollisionShape(world, BlockPos.ORIGIN, ShapeContext.absent()); + Box bb = collShape.isEmpty() + ? state.getOutlineShape(world, BlockPos.ORIGIN, ShapeContext.absent()).getBoundingBox() + : collShape.getBoundingBox(); + + Direction hingeSide = facing.getOpposite(); + + float pivotX = (float) ((bb.minX + bb.maxX) * 0.5); + float pivotZ = (float) ((bb.minZ + bb.maxZ) * 0.5); + switch (hingeSide) { + case NORTH -> pivotZ = (float) bb.minZ; + case SOUTH -> pivotZ = (float) bb.maxZ; + case WEST -> pivotX = (float) bb.minX; + case EAST -> pivotX = (float) bb.maxX; + default -> { + pivotX = (float) ((bb.minX + bb.maxX) * 0.5); + pivotZ = (float) ((bb.minZ + bb.maxZ) * 0.5); + } + } + float pivotY = (half == BlockHalf.TOP) ? (float) bb.maxY : (float) bb.minY; + + float angle; + switch (hingeSide) { + case NORTH, EAST -> angle = -baseAngleDeg; + case SOUTH, WEST -> angle = baseAngleDeg; + default -> angle = baseAngleDeg; + } + if (half == BlockHalf.TOP) angle = -angle; + + float thickness = (float) (bb.maxY - bb.minY); + float halfT = thickness > 0.0f ? thickness * 0.5f : (3.0f / 32.0f); + float dY = (half == BlockHalf.TOP) ? -halfT : halfT; + + double rad = Math.toRadians(angle); + float cos = (float) Math.cos(rad); + float sin = (float) Math.sin(rad); + + float shiftX = 0.0f; + float shiftY = 0.0f; + float shiftZ = 0.0f; + if (hingeSide == Direction.NORTH || hingeSide == Direction.SOUTH) { + float rotY = dY * cos; + float rotZ = dY * sin; + shiftY = dY - rotY; + shiftZ = -rotZ; + } else { + float rotX = -dY * sin; + float rotY = dY * cos; + shiftX = -rotX; + shiftY = dY - rotY; + } + + matrices.translate(shiftX, shiftY, shiftZ); + matrices.translate(pivotX, pivotY, pivotZ); + if (hingeSide == Direction.NORTH || hingeSide == Direction.SOUTH) { + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(angle)); + } else { + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(angle)); + } + matrices.translate(-pivotX, -pivotY, -pivotZ); + matrices.translate(-shiftX, -shiftY, -shiftZ); + } +} diff --git a/src/client/java/com/straice/smoothdoors/client/ui/SddConfigScreen.java b/src/client/java/com/straice/smoothdoors/client/ui/SddConfigScreen.java index 820e05f..31304c6 100644 --- a/src/client/java/com/straice/smoothdoors/client/ui/SddConfigScreen.java +++ b/src/client/java/com/straice/smoothdoors/client/ui/SddConfigScreen.java @@ -57,11 +57,11 @@ public class SddConfigScreen extends Screen { // Fence gates row addDrawableChild(toggle(leftX, y, colW, h, - () -> "Fences | Use: " + (cfg.connectFenceGates ? "ON" : "OFF"), + () -> "Gates | Use: " + (cfg.connectFenceGates ? "ON" : "OFF"), () -> cfg.connectFenceGates = !cfg.connectFenceGates)); addDrawableChild(toggle(rightX, y, colW, h, - () -> "Fences | Redstone: " + (cfg.redstoneDoubleFenceGates ? "ON" : "OFF"), + () -> "Gates | Redstone: " + (cfg.redstoneDoubleFenceGates ? "ON" : "OFF"), () -> cfg.redstoneDoubleFenceGates = !cfg.redstoneDoubleFenceGates)); y += 34; @@ -78,7 +78,7 @@ public class SddConfigScreen extends Screen { y += 24; addDrawableChild(toggle(centerX - 120, y, 240, h, - () -> "Animation Fences: " + (cfg.animateFenceGates ? "ON" : "OFF"), + () -> "Animation Gates: " + (cfg.animateFenceGates ? "ON" : "OFF"), () -> cfg.animateFenceGates = !cfg.animateFenceGates)); y += 34; @@ -98,7 +98,7 @@ public class SddConfigScreen extends Screen { y += 24; addDrawableChild(new SpeedSlider(centerX - 120, y, 240, h, - "Speed Fences", cfg.fenceGateSpeed, v -> { + "Speed Gates", cfg.fenceGateSpeed, v -> { cfg.fenceGateSpeed = v; SddConfigManager.save(); }));