This commit is contained in:
2026-01-02 07:04:03 +01:00
parent b8cdeb343a
commit 999e5fb752
16 changed files with 1284 additions and 148 deletions

View File

@@ -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
}
}
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

View File

@@ -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" }
}
}
]
}

BIN
ccc.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
dss.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -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);
}
}

View File

@@ -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<BlockModelPart> parts = model.getParts(Random.create(42L));
List<BlockModelPart> posts = new ArrayList<>();
List<BlockModelPart> left = new ArrayList<>();
List<BlockModelPart> 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<BakedQuad> 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<Direction, List<BakedQuad>> faceQuads = new EnumMap<>(Direction.class);
private final List<BakedQuad> 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<Direction, List<BakedQuad>> faceQuads;
private final List<BakedQuad> unculled;
private final boolean useAo;
private final Sprite particleSprite;
StaticBlockModelPart(EnumMap<Direction, List<BakedQuad>> faceQuads, List<BakedQuad> unculled,
boolean useAo, Sprite particleSprite) {
this.faceQuads = faceQuads;
this.unculled = unculled;
this.useAo = useAo;
this.particleSprite = particleSprite;
}
@Override
public List<BakedQuad> getQuads(Direction face) {
if (face == null) return unculled;
List<BakedQuad> 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<BlockModelPart> parts;
private final Sprite particleSprite;
StaticBlockStateModel(List<BlockModelPart> parts, Sprite particleSprite) {
this.parts = parts;
this.particleSprite = particleSprite;
}
@Override
public void addParts(Random random, List<BlockModelPart> out) {
out.addAll(parts);
}
@Override
public Sprite particleSprite() {
return particleSprite;
}
}
}

View File

@@ -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<Anim> 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 {
}
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}));