Keep authored JSON separate from generated output. Export rotated model bounds for SDK-free navigation and check grazing voxel corners. Include unretouched in-game before/after captures and explicit art/performance limits; pilots are an intermediate pass, not completion of the full asset set. Co-Authored-By: Codex <noreply@openai.com>
@@ -5,9 +5,8 @@
|
||||
"flecktarn": "airdef:block/flecktarn",
|
||||
"radar_face": "airdef:block/radar_face",
|
||||
"metal": "airdef:block/metal",
|
||||
"mk_de": "airdef:block/mk_de",
|
||||
"bare_antenna": "airdef:block/bare_antenna",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"mk_de": "airdef:block/mk_de",
|
||||
"particle": "airdef:block/flecktarn_s21"
|
||||
},
|
||||
"elements": [
|
||||
@@ -15,11 +14,11 @@
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-6.0
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
12.0,
|
||||
5.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
@@ -28,7 +27,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
},
|
||||
@@ -37,7 +36,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
},
|
||||
@@ -46,7 +45,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -55,7 +54,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -81,14 +80,14 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
-2.5,
|
||||
5.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
14.0,
|
||||
14.0
|
||||
18.5,
|
||||
12.0,
|
||||
15.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
@@ -96,7 +95,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -105,7 +104,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -114,7 +113,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -123,7 +122,75 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
13.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
@@ -218,7 +285,7 @@
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
14.0,
|
||||
13.0,
|
||||
10.0
|
||||
],
|
||||
"to": [
|
||||
@@ -232,7 +299,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
@@ -241,7 +308,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
@@ -250,7 +317,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
@@ -259,7 +326,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
@@ -285,150 +352,168 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
20.0,
|
||||
3.0,
|
||||
-5.5
|
||||
-4.7,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.119999999999997,
|
||||
6.5,
|
||||
1.5
|
||||
-2.5,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": 22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
-3.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.119999999999997,
|
||||
3.0,
|
||||
-5.5
|
||||
18.5,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
6.5,
|
||||
1.5
|
||||
20.7,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": -22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
19.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
5.5,
|
||||
14.0,
|
||||
0.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
10.5,
|
||||
14.8,
|
||||
7.0
|
||||
5.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
@@ -436,143 +521,75 @@
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.8000000000000007
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.8000000000000007
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.8000000000000007
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.8000000000000007
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
6.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
6.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
14.0,
|
||||
5.0
|
||||
],
|
||||
"to": [
|
||||
3.0,
|
||||
16.0,
|
||||
6.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#bare_antenna"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.800000000000001,
|
||||
7.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
10.0,
|
||||
-2.0
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
@@ -580,8 +597,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
@@ -589,8 +606,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
@@ -598,8 +615,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
@@ -607,8 +624,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
@@ -616,8 +633,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
@@ -625,207 +642,139 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
20.0,
|
||||
7.0,
|
||||
-5.0
|
||||
18.5,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.8,
|
||||
10.0,
|
||||
-2.0
|
||||
18.619999999999997,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.800000000000001,
|
||||
7.0,
|
||||
-1.5
|
||||
-2.6199999999999974,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
10.0,
|
||||
0.5
|
||||
-2.5,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
20.0,
|
||||
7.0,
|
||||
-1.5
|
||||
],
|
||||
"to": [
|
||||
20.8,
|
||||
10.0,
|
||||
0.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
"texture": "#mk_de"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
"flecktarn_b": "airdef:block/flecktarn_b",
|
||||
"radar_face_b": "airdef:block/radar_face_b",
|
||||
"metal_b": "airdef:block/metal_b",
|
||||
"mk_de_b": "airdef:block/mk_de_b",
|
||||
"bare_antenna_b": "airdef:block/bare_antenna_b",
|
||||
"dark_metal_b": "airdef:block/dark_metal_b",
|
||||
"mk_de_b": "airdef:block/mk_de_b",
|
||||
"particle": "airdef:block/flecktarn_s21_b"
|
||||
},
|
||||
"elements": [
|
||||
@@ -15,11 +14,11 @@
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-6.0
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
12.0,
|
||||
5.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
@@ -28,7 +27,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
},
|
||||
@@ -37,7 +36,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
},
|
||||
@@ -46,7 +45,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -55,7 +54,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -81,14 +80,14 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
-2.5,
|
||||
5.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
14.0,
|
||||
14.0
|
||||
18.5,
|
||||
12.0,
|
||||
15.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
@@ -96,7 +95,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -105,7 +104,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -114,7 +113,7 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -123,7 +122,75 @@
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
13.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
@@ -218,7 +285,7 @@
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
14.0,
|
||||
13.0,
|
||||
10.0
|
||||
],
|
||||
"to": [
|
||||
@@ -232,7 +299,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
@@ -241,7 +308,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
@@ -250,7 +317,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
@@ -259,7 +326,7 @@
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
@@ -285,226 +352,244 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
20.0,
|
||||
3.0,
|
||||
-5.5
|
||||
-4.7,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.119999999999997,
|
||||
6.5,
|
||||
1.5
|
||||
-2.5,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": 22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
-3.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.119999999999997,
|
||||
3.0,
|
||||
-5.5
|
||||
18.5,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
6.5,
|
||||
1.5
|
||||
20.7,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.5
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
3.5
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
7.0
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": -22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
19.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
14.0,
|
||||
5.0
|
||||
0.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
3.0,
|
||||
16.0,
|
||||
6.0
|
||||
5.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
1.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
1.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#bare_antenna_b"
|
||||
"texture": "#dark_metal_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.800000000000001,
|
||||
7.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
10.0,
|
||||
-2.0
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
@@ -512,8 +597,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
@@ -521,8 +606,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
@@ -530,8 +615,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
@@ -539,8 +624,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
@@ -548,8 +633,8 @@
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
}
|
||||
@@ -557,139 +642,71 @@
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
20.0,
|
||||
7.0,
|
||||
-5.0
|
||||
-2.6199999999999974,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.8,
|
||||
10.0,
|
||||
-2.0
|
||||
-2.5,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.800000000000001,
|
||||
7.0,
|
||||
-1.5
|
||||
],
|
||||
"to": [
|
||||
-4.0,
|
||||
10.0,
|
||||
0.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
"texture": "#mk_de_b"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,10 +154,10 @@ fd5ca8c85d054580e6f95cb88bfed6216c9b41ddab9efec2eb4a642ad408c17c assets/airdef/
|
||||
9fa54aaabfc0dd1b6af4fdd1fd4ac9a4248c4837801a7d74e441627f565a18fa assets/airdef/models/block/gepard_dish.json
|
||||
993b426346250e248abea70a461a7e9343d264585997adee252d8f803d635acd assets/airdef/models/block/gepard_guns.json
|
||||
9f5b572110c02fbae42a1aff8db716094d198b209d19dfc2e6a72430378fc179 assets/airdef/models/block/gepard_guns_burnt.json
|
||||
288029fc93a84ee5d68605d061bde9fdb31b759a4a17766bb8df008beb9c2064 assets/airdef/models/block/gepard_hull.json
|
||||
743dba3635ae9683e744c1691315a104e48e10011cfbe6e74565eecd6ce7dfcb assets/airdef/models/block/gepard_hull_burnt.json
|
||||
38ae7a16ba13e5ac0cff7f8f1856e24b512f4e68bff7b71297b3d2838333fc2a assets/airdef/models/block/gepard_turret.json
|
||||
cf464948fd36c74cf6f49b10f4f2e0e4b9e52b9d8324c27302e8e1c2ae8ae73f assets/airdef/models/block/gepard_turret_burnt.json
|
||||
b1ee075e7ec6c4d044ae45ae488995371e6128fa5d38bdc6babdbae9f746a752 assets/airdef/models/block/gepard_hull.json
|
||||
37179a4c80b8e440c9be9e94e28f3d4852af77831aca0e1d17f6db22dec43905 assets/airdef/models/block/gepard_hull_burnt.json
|
||||
d2da35d3023db04251a73030f7baca7f448b2a341315c1a3d9a7d9ec8dfb5c6d assets/airdef/models/block/gepard_turret.json
|
||||
0d2f0217c9e9e9d0305c990576f86ac5665738db5eead729750836e9e371aa85 assets/airdef/models/block/gepard_turret_burnt.json
|
||||
d43f9cda780b1821a6e778555a1be5bd112a1d9655ff96d35acebec61cf11e0b assets/airdef/models/block/geran3.json
|
||||
83cf0a42e59f6aee1039925f849398960334f2545558409e7ccd7173ac841d73 assets/airdef/models/block/geran3_flame.json
|
||||
ac93e872743844465f0688162dddd7433352e8710612dd391a1e92b7f36e6b0d assets/airdef/models/block/gerbera.json
|
||||
@@ -203,10 +203,10 @@ b0ae344fbad3b982e7821cd1b26f9922e2a5713b38107521ddc5a5b2abd9e39c assets/airdef/
|
||||
088f42bb17f4d6099c16adf6cc0426b6d04ff9a43abdf125476a3571e924fcbd assets/airdef/models/block/radar_truck.json
|
||||
4cd60dfb1e598efbd127894b0ad1b1737569dfc0fc5c9b193034f9125daa9c15 assets/airdef/models/block/radar_truck_burnt.json
|
||||
f102765390762d45954b26405b6acdde845df7f0a319bac53d25508e768957b5 assets/airdef/models/block/reentry.json
|
||||
0a27047ed66a18b513c5113e4b4ba1d8667ac75d36f661e58415a9d6870c0bc9 assets/airdef/models/block/s400_chassis.json
|
||||
b86ccc0a31dc63239b598542070173ebbc6d354b3d8dec880c62ea192d6ea9f7 assets/airdef/models/block/s400_chassis_burnt.json
|
||||
0107a6689048c7267ea1c68713593026fa495cb33443a6b1aab815a17602fe81 assets/airdef/models/block/s400_tubes.json
|
||||
6e4a35843d29bba30b9969af7ed9a60ad05ea4e4b9fde0507ea6ba6dcb9d7dd7 assets/airdef/models/block/s400_tubes_burnt.json
|
||||
87085a7ac475dec2abcd5b1ff6443e2847614726219ca522b199bc70a5c10f2e assets/airdef/models/block/s400_chassis.json
|
||||
f10710d0387edc746380287edbb987341cb88c95d974f89a48b19543cef737dc assets/airdef/models/block/s400_chassis_burnt.json
|
||||
7b2cac0485b4242534e99bbfc0406ee393d508ca971d4d88caf3f13892b473c1 assets/airdef/models/block/s400_tubes.json
|
||||
973e02b2058c0b3d59c156f2ac94fbba4ac90a97736e8a4cc9be177b5e0f19a9 assets/airdef/models/block/s400_tubes_burnt.json
|
||||
088f42bb17f4d6099c16adf6cc0426b6d04ff9a43abdf125476a3571e924fcbd assets/airdef/models/block/s500_chassis.json
|
||||
3e35ed19ea22c8309ac7c0ccc9c12e31b2387de97c6b72ba519bae34f681c58c assets/airdef/models/block/s500_chassis_burnt.json
|
||||
6ce00881e2a5107874e82e94a243fcd95c3eb6e9a24e8839c11227c8e330485f assets/airdef/models/block/s500_tubes.json
|
||||
@@ -215,7 +215,7 @@ b86ccc0a31dc63239b598542070173ebbc6d354b3d8dec880c62ea192d6ea9f7 assets/airdef/
|
||||
0e3cbae5029377886325aedc43705d9975cb1dc889a37613b92a97bdf36b4db7 assets/airdef/models/block/searchlight_burnt.json
|
||||
2d790e8845598e8cf7ae577492632ef52e075d590011e66fa8ab686096cda313 assets/airdef/models/block/searchlight_head.json
|
||||
f0f9ec6cefc0750e4d6cb330c21df8c2bcf02b1b7408f90f40ebb35a572a13cb assets/airdef/models/block/searchlight_head_burnt.json
|
||||
b2e28d73f50b238f6bc7d6dae560695e70ae8b843f6853f9e468bf8d2b371e6c assets/airdef/models/block/shahed.json
|
||||
0d9aa1bc000619e0151c2263e847c81967ab1b7662464525cd42118f5d1d82f4 assets/airdef/models/block/shahed.json
|
||||
d5b9ed76b1744d0c93a809b6a4c16bc3dfa7ff4784e3cb9968aa36b12fc30484 assets/airdef/models/block/shahed_prop.json
|
||||
465e6aa2a8ac3c563b1e546fc844a0520fc89f3ce528d49f193aa6c21e19308f assets/airdef/models/block/target.json
|
||||
69c5c103c228abe6162f2e1252139689b768ff8dd3f835f8f79ce7d324c3f124 assets/airdef/models/block/tor_chassis.json
|
||||
@@ -570,3 +570,4 @@ cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/ho
|
||||
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_zircon.json
|
||||
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/mover.json
|
||||
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/remover.json
|
||||
8182bfca0dc64498eb620ffafe33c0e773d633f126f2194459a97f495ffe2ba1 src/sim/generated_bounds.rs
|
||||
|
||||
@@ -7,5 +7,9 @@ copies this tree into its temporary staging tree, validates the merged runtime a
|
||||
the generated manifest. Do not edit generated files under `airdef-mod/assets/` directly; an untracked or
|
||||
hand-edited output is treated as a conflict and left untouched.
|
||||
|
||||
This directory is intentionally kept separate from runtime and generated output. It currently contains no
|
||||
asset payloads.
|
||||
This directory is intentionally kept separate from runtime and generated output. The initial art pilots are
|
||||
S-400 chassis/canisters, Gepard hull/turret and Shahed, including burnt variants for the ground vehicles.
|
||||
The JSON is editable directly. `python tools/pilot_models.py` is an optional authoring helper that overwrites
|
||||
only those named pilot JSONs; the normal regeneration never invokes it. After editing, run
|
||||
`python tools/gen_models.py` to validate and install the authored models. `generated_bounds.rs` is derived
|
||||
from the final staged geometry, including overrides and element rotation, for chassis navigation.
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"flecktarn_s21": "airdef:block/flecktarn_s21",
|
||||
"flecktarn": "airdef:block/flecktarn",
|
||||
"radar_face": "airdef:block/radar_face",
|
||||
"metal": "airdef:block/metal",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"mk_de": "airdef:block/mk_de",
|
||||
"particle": "airdef:block/flecktarn_s21"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
5.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_s21"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.5,
|
||||
5.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
18.5,
|
||||
12.0,
|
||||
15.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
13.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.0,
|
||||
4.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
12.0,
|
||||
-6.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
13.0,
|
||||
10.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
18.0,
|
||||
12.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.7,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-2.5,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": 22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
-3.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
18.5,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.7,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": -22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
19.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
5.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
10.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
18.5,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
18.619999999999997,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.6199999999999974,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-2.5,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,712 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"flecktarn_s21_b": "airdef:block/flecktarn_s21_b",
|
||||
"flecktarn_b": "airdef:block/flecktarn_b",
|
||||
"radar_face_b": "airdef:block/radar_face_b",
|
||||
"metal_b": "airdef:block/metal_b",
|
||||
"dark_metal_b": "airdef:block/dark_metal_b",
|
||||
"mk_de_b": "airdef:block/mk_de_b",
|
||||
"particle": "airdef:block/flecktarn_s21_b"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
5.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_s21_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.5,
|
||||
5.0,
|
||||
-5.0
|
||||
],
|
||||
"to": [
|
||||
18.5,
|
||||
12.0,
|
||||
15.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
12.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
13.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.0,
|
||||
4.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
12.0,
|
||||
-6.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#radar_face_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
13.0,
|
||||
10.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
18.0,
|
||||
12.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#metal_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.7,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-2.5,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.2,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": 22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
-3.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
18.5,
|
||||
4.8,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.7,
|
||||
10.7,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.8999999999999995
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.1999999999999993,
|
||||
16
|
||||
],
|
||||
"texture": "#flecktarn_b"
|
||||
}
|
||||
},
|
||||
"rotation": {
|
||||
"angle": -22.5,
|
||||
"axis": "z",
|
||||
"origin": [
|
||||
19.6,
|
||||
7.75,
|
||||
5.0
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
5.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
10.0,
|
||||
13.05,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
13.7,
|
||||
8.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.6499999999999986
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal_b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.6199999999999974,
|
||||
6.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
-2.5,
|
||||
9.0,
|
||||
2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.25,
|
||||
6.0
|
||||
],
|
||||
"texture": "#mk_de_b"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// Generated by tools/gen_models.py from the final staged models; do not edit.
|
||||
pub fn bounds(id: &str) -> Option<([f64; 3], [f64; 3])> {
|
||||
Some(match id {
|
||||
"airdef:amraam_missile" => ([0.97, 0.97, -16.0], [15.03, 15.03, 25.9]),
|
||||
"airdef:barge" => ([-16.0, 0.0, -16.0], [32.0, 6.5, 32.0]),
|
||||
"airdef:beam" => ([6.5, 6.5, -16.0], [9.5, 9.5, 32.0]),
|
||||
"airdef:buk_chassis" => ([-14.5, 0.0, -16.0], [30.5, 17.4, 32.0]),
|
||||
"airdef:buk_chassis_burnt" => ([-14.5, 0.0, -16.0], [30.5, 17.4, 32.0]),
|
||||
"airdef:buk_rails" => ([-12.0, 0.0, -16.0], [28.0, 7.5, 27.0]),
|
||||
"airdef:buk_rails_burnt" => ([-12.0, 0.0, -16.0], [28.0, 7.5, 27.0]),
|
||||
"airdef:buk_turret" => ([-4.0, 0.0, -10.0], [20.0, 14.0, 20.0]),
|
||||
"airdef:buk_turret_burnt" => ([-4.0, 0.0, -10.0], [20.0, 14.0, 20.0]),
|
||||
"airdef:debris" => ([2.0, 6.0, 3.0], [14.0, 9.0, 13.0]),
|
||||
"airdef:depot" => ([-14.0, 0.0, -14.0], [30.0, 17.0, 30.0]),
|
||||
"airdef:depot_burnt" => ([-14.0, 0.0, -14.0], [30.0, 17.0, 30.0]),
|
||||
"airdef:ew_truck" => ([-9.0, -1.379664, -16.0], [25.0, 32.0, 33.379664]),
|
||||
"airdef:ew_truck_burnt" => ([-9.0, -1.379664, -16.0], [25.0, 22.0, 33.379664]),
|
||||
"airdef:fireball" => ([0.0, 0.0, 0.0], [16.0, 16.0, 16.0]),
|
||||
"airdef:flame" => ([5.625, 5.625, -8.0], [10.375, 10.375, 26.0]),
|
||||
"airdef:flare" => ([6.5, 6.5, 6.5], [9.5, 16.0, 9.5]),
|
||||
"airdef:flash" => ([-4.0, -4.0, -4.0], [20.0, 20.0, 20.0]),
|
||||
"airdef:gepard_dish" => ([-4.0, 0.0, 6.0], [20.0, 14.0, 8.0]),
|
||||
"airdef:gepard_guns" => ([-9.0, 3.5, -16.0], [25.0, 9.0, 14.0]),
|
||||
"airdef:gepard_guns_burnt" => ([-9.0, 3.5, -16.0], [25.0, 9.0, 14.0]),
|
||||
"airdef:gepard_hull" => ([-14.5, 0.0, -15.0], [30.5, 17.2, 31.0]),
|
||||
"airdef:gepard_hull_burnt" => ([-14.5, 0.0, -15.0], [30.5, 17.2, 31.0]),
|
||||
"airdef:gepard_turret" => ([-5.745184, 0.0, -10.0], [21.745184, 18.0, 16.0]),
|
||||
"airdef:gepard_turret_burnt" => ([-5.745184, 0.0, -10.0], [21.745184, 18.0, 16.0]),
|
||||
"airdef:geran3" => ([-10.0, 4.341543, -16.0], [26.0, 17.005161, 29.9]),
|
||||
"airdef:geran3_flame" => ([6.15, 6.15, 6.0], [9.85, 9.85, 24.0]),
|
||||
"airdef:gerbera" => ([-9.0, 3.0, -15.0], [25.0, 13.0, 24.5]),
|
||||
"airdef:irist_chassis" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:irist_chassis_burnt" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:irist_missile" => ([1.47, 1.47, -16.0], [14.53, 14.53, 23.9]),
|
||||
"airdef:irist_tubes" => ([-2.5, 0.0, -16.0], [18.5, 9.0, 32.0]),
|
||||
"airdef:irist_tubes_burnt" => ([-2.5, 0.0, -16.0], [18.5, 9.0, 32.0]),
|
||||
"airdef:iskander" => ([-1.74, -1.74, -16.0], [17.74, 17.74, 29.9]),
|
||||
"airdef:kalibr" => ([-6.0, 1.52, -16.0], [22.0, 14.48, 29.9]),
|
||||
"airdef:kh101" => ([-12.5, 3.2, -16.0], [28.5, 16.0, 28.4]),
|
||||
"airdef:kh22" => ([-10.0, -1.2, -16.0], [26.0, 17.2, 29.9]),
|
||||
"airdef:kinzhal" => ([-3.06, -3.06, -16.0], [19.06, 19.06, 29.9]),
|
||||
"airdef:lancet" => ([-1.40452, -1.40452, -16.0], [17.40452, 17.40452, 24.5]),
|
||||
"airdef:launch_ramp" => ([1.0, 0.0, -12.708033], [15.0, 19.342915, 32.0]),
|
||||
"airdef:launcher_truck" => ([-10.5, -1.379664, -16.379664], [26.5, 31.288582, 32.0]),
|
||||
"airdef:m48n6" => ([0.09, 0.09, -16.0], [15.91, 15.91, 27.9]),
|
||||
"airdef:m57e6" => ([1.47, 1.47, -16.0], [14.53, 14.53, 26.9]),
|
||||
"airdef:m77n6" => ([0.82, 0.82, -16.0], [15.18, 15.18, 29.9]),
|
||||
"airdef:nasams_launcher" => ([0.0, 0.0, -16.0], [16.0, 9.0, 32.0]),
|
||||
"airdef:nasams_launcher_burnt" => ([0.0, 0.0, -16.0], [16.0, 9.0, 32.0]),
|
||||
"airdef:nasams_trailer" => ([-9.0, -1.379664, -16.0], [25.0, 13.0, 26.0]),
|
||||
"airdef:nasams_trailer_burnt" => ([-9.0, -1.379664, -16.0], [25.0, 13.0, 26.0]),
|
||||
"airdef:p1sun" => ([-0.5, -0.5, -14.0], [16.5, 16.5, 10.0]),
|
||||
"airdef:p1sun_launcher" => ([-0.5, 0.0, -16.0], [16.5, 7.0, 32.0]),
|
||||
"airdef:p1sun_launcher_burnt" => ([-0.5, 0.0, -16.0], [16.5, 7.0, 32.0]),
|
||||
"airdef:pac3" => ([1.47, 1.47, -16.0], [14.53, 14.53, 25.9]),
|
||||
"airdef:pantsir_dish" => ([-6.5, -8.0, 7.0], [22.5, 16.5, 10.0]),
|
||||
"airdef:pantsir_pack" => ([-11.0, 2.0, -16.0], [27.0, 15.0, 12.0]),
|
||||
"airdef:pantsir_pack_burnt" => ([-11.0, 2.0, -16.0], [27.0, 15.0, 12.0]),
|
||||
"airdef:pantsir_truck" => ([-10.5, -1.379664, -16.0], [26.5, 21.0, 33.379664]),
|
||||
"airdef:pantsir_truck_burnt" => ([-10.5, -1.379664, -16.0], [26.5, 21.0, 33.379664]),
|
||||
"airdef:pantsir_turret" => ([-2.12, 0.0, -11.0], [18.12, 17.0, 16.0]),
|
||||
"airdef:pantsir_turret_burnt" => ([-2.12, 0.0, -11.0], [18.0, 17.0, 16.0]),
|
||||
"airdef:patriot_launcher" => ([-8.0, 0.0, -14.0], [24.0, 19.0, 30.0]),
|
||||
"airdef:patriot_launcher_burnt" => ([-8.0, 0.0, -14.0], [24.0, 19.0, 30.0]),
|
||||
"airdef:patriot_radar" => ([-9.0, -1.410323, -10.0], [25.0, 30.0, 26.0]),
|
||||
"airdef:patriot_trailer" => ([-10.0, -1.410323, -16.0], [26.0, 16.0, 33.010323]),
|
||||
"airdef:patriot_trailer_burnt" => ([-10.0, -1.410323, -16.0], [26.0, 16.0, 33.010323]),
|
||||
"airdef:patriot_truck" => ([-9.0, -1.410323, -16.0], [25.0, 25.0, 33.010323]),
|
||||
"airdef:radar_panel" => ([-10.5, -6.0, 7.0], [26.5, 26.5, 12.0]),
|
||||
"airdef:radar_trailer" => ([-9.0, -1.379664, -12.0], [25.0, 18.0, 26.379664]),
|
||||
"airdef:radar_truck" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:radar_truck_burnt" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:reentry" => ([6.5, 6.5, -16.0], [9.5, 9.5, 32.0]),
|
||||
"airdef:s400_chassis" => ([-10.5, 0.0, -16.460181], [26.5, 22.0, 32.0]),
|
||||
"airdef:s400_chassis_burnt" => ([-10.5, 0.0, -16.460181], [26.5, 19.5, 32.0]),
|
||||
"airdef:s400_tubes" => ([-0.5, 0.0, -16.0], [16.5, 15.0, 32.0]),
|
||||
"airdef:s400_tubes_burnt" => ([-0.5, 0.0, -16.0], [16.5, 15.0, 32.0]),
|
||||
"airdef:s500_chassis" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:s500_chassis_burnt" => ([-10.5, -1.379664, -16.379664], [26.5, 22.0, 32.0]),
|
||||
"airdef:s500_tubes" => ([-3.0, 0.0, -16.0], [19.0, 9.5, 32.0]),
|
||||
"airdef:s500_tubes_burnt" => ([-3.0, 0.0, -16.0], [19.0, 9.5, 32.0]),
|
||||
"airdef:searchlight" => ([2.0, 0.0, 2.0], [14.0, 12.0, 14.0]),
|
||||
"airdef:searchlight_burnt" => ([2.0, 0.0, 2.0], [14.0, 12.0, 14.0]),
|
||||
"airdef:searchlight_head" => ([3.0, 3.0, -2.5], [13.0, 13.0, 14.0]),
|
||||
"airdef:searchlight_head_burnt" => ([3.0, 3.0, -2.5], [13.0, 13.0, 14.0]),
|
||||
"airdef:shahed" => ([-13.0, 4.73352, -16.0], [29.0, 13.2, 28.0]),
|
||||
"airdef:shahed_prop" => ([-4.0, -4.0, 7.0], [20.0, 20.0, 9.5]),
|
||||
"airdef:target" => ([2.0, -8.0, 2.0], [14.0, 24.0, 14.0]),
|
||||
"airdef:tor_chassis" => ([-14.5, 0.0, -16.0], [30.5, 17.4, 32.0]),
|
||||
"airdef:tor_chassis_burnt" => ([-14.5, 0.0, -16.0], [30.5, 17.4, 32.0]),
|
||||
"airdef:tor_turret" => ([-4.0, 0.0, -11.0], [20.0, 17.5, 22.0]),
|
||||
"airdef:tor_turret_burnt" => ([-4.0, 0.0, -11.0], [20.0, 17.5, 22.0]),
|
||||
"airdef:tracer" => ([7.3, 7.3, -16.0], [8.7, 8.7, 32.0]),
|
||||
"airdef:tzm_truck" => ([-9.0, -1.379664, -16.0], [25.0, 26.0, 33.379664]),
|
||||
"airdef:tzm_truck_burnt" => ([-9.0, -1.379664, -16.0], [25.0, 26.0, 33.379664]),
|
||||
"airdef:zircon" => ([0.16, 0.16, -16.0], [15.84, 15.84, 29.9]),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use glam::{DQuat, DVec3};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod catalog;
|
||||
mod generated_bounds;
|
||||
mod damage;
|
||||
pub mod doctrine;
|
||||
pub mod fires;
|
||||
|
||||
@@ -81,7 +81,7 @@ struct Chassis {
|
||||
|
||||
impl Chassis {
|
||||
fn for_kind(kind: SamKind) -> Self {
|
||||
let (radius, height) = match kind.spec().family {
|
||||
let (radius, height): (f64, f64) = match kind.spec().family {
|
||||
Family::Trainable => (2.25, 3.0),
|
||||
Family::Gun => (1.75, 3.0),
|
||||
Family::Turret => (2.0, 3.25),
|
||||
@@ -90,14 +90,27 @@ impl Chassis {
|
||||
Family::Truck => (1.75, 2.75),
|
||||
Family::Light => (1.25, 2.5),
|
||||
};
|
||||
// Rendered geometry may extend past the nominal family envelope (rotated wheels too).
|
||||
// Read the generated bounds of the exact body rather than letting art silently shrink clearance.
|
||||
let (radius, height) = match super::generated_bounds::bounds(kind.spec().parts.body) {
|
||||
Some((lo, hi)) => {
|
||||
let scale = kind.spec().scale / 16.0;
|
||||
let half_x = (lo[0] - 8.0).abs().max((hi[0] - 8.0).abs()) * scale;
|
||||
let half_z = (lo[2] - 8.0).abs().max((hi[2] - 8.0).abs()) * scale;
|
||||
(radius.max(half_x.hypot(half_z) + 0.125), height.max(hi[1] * scale))
|
||||
}
|
||||
None => (radius, height), // Content validation rejects missing models before packaging.
|
||||
};
|
||||
Self { radius, height }
|
||||
}
|
||||
|
||||
/// Integer voxel sample points inside the conservative footprint.
|
||||
/// Every voxel whose square intersects the conservative footprint, including grazing corners.
|
||||
fn samples(self) -> Vec<(i32, i32)> {
|
||||
let r = self.radius.ceil() as i32;
|
||||
(-r..=r).flat_map(|x| (-r..=r).filter_map(move |z| {
|
||||
((x * x + z * z) as f64 <= self.radius * self.radius + 0.5).then_some((x, z))
|
||||
let dx = (f64::from(x.abs()) - 0.5).max(0.0);
|
||||
let dz = (f64::from(z.abs()) - 0.5).max(0.0);
|
||||
(dx * dx + dz * dz <= self.radius * self.radius).then_some((x, z))
|
||||
})).collect()
|
||||
}
|
||||
}
|
||||
@@ -569,6 +582,23 @@ impl SamKind {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn gun_chassis_cannot_use_the_old_one_point_seven_five_block_radius() {
|
||||
// The rendered Gepard hull alone is wider/longer than that nominal family circle.
|
||||
assert!(Chassis::for_kind(SamKind::Gepard).radius > 2.5);
|
||||
for kind in SamKind::ALL {
|
||||
assert!(super::super::generated_bounds::bounds(kind.spec().parts.body).is_some(), "{kind:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn footprint_checks_voxels_grazed_between_their_centres() {
|
||||
let cells = Chassis { radius: 2.75, height: 3.0 }.samples();
|
||||
assert!(cells.contains(&(3, 1)), "the body reaches the near corner of this voxel");
|
||||
assert!(cells.contains(&(-3, -1)));
|
||||
assert!(!cells.contains(&(3, 3)));
|
||||
}
|
||||
|
||||
/// The land as the game would tell it: the height map, and under it the blocks that are solid.
|
||||
struct Src<H: Fn(i32, i32) -> i32, B: Fn(i32, i32) -> i32> {
|
||||
height: H,
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Пилотный художественный проход (#115)
|
||||
|
||||
Это промежуточные модели для оценки направления, а не завершённая переработка всего набора.
|
||||
Изменены С-400 (шасси и ТПК), Гепард (корпус и башня), Шахед. Исходный шумный камуфляж
|
||||
в основном сохранён: следующий художественный этап — спокойнее материалы, яснее крупные формы
|
||||
и плотность пикселей. Число элементов само по себе не является доказательством качества.
|
||||
|
||||
| Пилот | До | После |
|
||||
|---|---|---|
|
||||
| С-400 |  |  |
|
||||
| Гепард |  |  |
|
||||
| Шахед |  |  |
|
||||
|
||||
## Что изменено
|
||||
|
||||
- С-400: округлые ступенчатые колёса без звёздчатого пересечения двух квадратов, ступицы,
|
||||
разделённые кабины со стеклом/крышей, читаемая рама; четыре ТПК с округлым сечением и обвязкой.
|
||||
- Гепард: наклонная лобовая часть, отдельная верхняя плита, катки на непрерывной гусенице,
|
||||
скошенные стороны башни и люки. Подвижные пушки и обзорная антенна используют прежние крепления.
|
||||
- Шахед: более плавный контур носа/крыла, тоньше крыло, переработаны законцовки и задняя часть;
|
||||
пропеллер остаётся отдельной анимируемой частью. Это стилизация существующего игрового прототипа.
|
||||
- Наземные пилоты имеют соответствующие обгоревшие варианты.
|
||||
|
||||
Геометрия сделана внутри проекта; исходные игровые текстуры не заимствованы из внешних фотографий.
|
||||
Визуальные референсы: [Гепард, Bundeswehr](https://www.bundeswehr.de/de/meldungen/flugabwehrkanonenpanzer-gepard-5400072),
|
||||
[51П6, фотография автора Mike1979 Russia](https://commons.wikimedia.org/wiki/File:51P6_launcher_S-400_Triumf_Army-2022_2022-08-20_2416.jpg).
|
||||
Это ориентиры внешнего вида, не утверждение о точном воспроизведении конкретной модификации.
|
||||
|
||||
## Метод сравнения и ограничения
|
||||
|
||||
Настоящий Horizon/AirDef, macOS arm64, Apple M5/Metal, offscreen 2560×1440. Временный игровой home,
|
||||
ровный полигон, ясная погода, day_time 6000, spectator. Для пары используются одинаковые WASM,
|
||||
движок и сцена: в пакете «до» заменены только девять JSON пилотов на их версии из `4a3500f`.
|
||||
Скриншоты не ретушировались. Камера проверена по status после переноса:
|
||||
|
||||
| Пилот | Позиция камеры | yaw / pitch |
|
||||
|---|---|---|
|
||||
| С-400 | -4, 114, 25 | -30 / 12 |
|
||||
| Гепард | 20, 114, 25 | 30 / 18 |
|
||||
| Шахед | 28, 115, 27 | 35 / 30 |
|
||||
|
||||
РЛС продолжает вращаться; её угол и фаза облаков в паре могут различаться. Пилот Шахеда показан как
|
||||
статичная модель для сравнения геометрии. Здесь не проверены все ракурсы, полёт/пуск, повреждение
|
||||
в кино и массовая нагрузка. Native HDR не включался; HD — отдельный режим рендера мода.
|
||||
|
||||
[Общий вид до, HD](media/model-pilots/before-overview-hd.png) ·
|
||||
[Общий вид после, HD](media/model-pilots/after-overview-hd.png) ·
|
||||
[После ночью, HD](media/model-pilots/after-overview-night-hd.png).
|
||||
|
||||
## Бюджет и редактирование
|
||||
|
||||
| Часть | Элементов до | После |
|
||||
|---|---:|---:|
|
||||
| s400_chassis | 35 | 78 |
|
||||
| s400_tubes | 6 | 29 |
|
||||
| gepard_hull | 8 | 55 |
|
||||
| gepard_turret | 12 | 11 |
|
||||
| shahed | 26 | 29 |
|
||||
|
||||
Новые runtime IDs или отдельные части сцены не добавлены. Рост числа граней требует замера на массовом
|
||||
сценарии; отсутствие роста draw calls или сохранение FPS этим отчётом не обещается.
|
||||
|
||||
Редактируемые JSON: `airdef-mod/source-assets/assets/airdef/models/block/`.
|
||||
Необязательный экспортёр: `python tools/pilot_models.py` (перезаписывает только эти пилоты).
|
||||
Установка/валидация: `python tools/gen_models.py`. Габариты для навигации вычисляются из итоговой
|
||||
геометрии после authored overrides, включая поворот элементов. Стандартная regeneration сохраняет
|
||||
авторские исходники. Полный набор и художественная приёмка остаются в #115.
|
||||
@@ -44,7 +44,9 @@
|
||||
|
||||
## Авторские и сгенерированные ресурсы
|
||||
|
||||
- `tools/gen_models.py` генерирует геометрию моделей, блоковые состояния, item registry, локализацию и data JSON.
|
||||
- `tools/gen_models.py` генерирует геометрию моделей и управляет сборкой набора.
|
||||
- `tools/airdef_assets/registry.py` создаёт blockstate/item registry, локализацию и data JSON.
|
||||
- `tools/airdef_assets/bounds.py` экспортирует габариты итоговых моделей для headless-навигации; authored overrides входят в расчёт.
|
||||
- `tools/gen_tex.py` отвечает за вывод процедурных текстур и иконок; переиспользуемые примитивы палитры также находятся здесь.
|
||||
- `tools/airdef_assets/texture_catalog.py` связывает стабильную палитру и процедурные функции с текстурами моделей, не смешивая каталог с геометрией.
|
||||
- `tools/airdef_assets/icons.py` содержит каталог предметов и чистую функцию рендера иконки с явными параметрами `(name, color, seed)`.
|
||||
@@ -53,3 +55,5 @@
|
||||
- `airdef-mod/assets/` и `airdef-mod/data/` — упакованные generated output. Не редактируйте их вручную; добавляйте авторские исходники в `source-assets`.
|
||||
- `airdef-mod/generated-manifest.txt` хранит SHA-256 только для управляемого результата. Неизменённые старые outputs можно заменить или удалить; посторонние и вручную правленные файлы блокируют конфликтующий запуск.
|
||||
- `python3 tools/test_gen_assets.py` проверяет manifest, защиту ручных файлов, откат при ошибке записи, детерминизм и полный цикл authored icon override/validation.
|
||||
|
||||
`airdef-mod/src/sim/generated_bounds.rs` также управляется manifest: это данные геометрии, а не файл для ручного редактирования. Пилотный арт и сравнения — в `docs/MODEL-PILOTS.md`.
|
||||
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
@@ -0,0 +1,42 @@
|
||||
"""Export conservative model bounds for SDK-free chassis navigation."""
|
||||
import itertools
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def model_bounds(model):
|
||||
points = []
|
||||
for element in model.get("elements", []):
|
||||
rotation = element.get("rotation")
|
||||
for point in itertools.product(*zip(element["from"], element["to"])):
|
||||
point = list(point)
|
||||
if rotation:
|
||||
axis = "xyz".index(rotation["axis"])
|
||||
a, b = (axis + 1) % 3, (axis + 2) % 3
|
||||
origin = rotation["origin"]
|
||||
x, y = point[a] - origin[a], point[b] - origin[b]
|
||||
angle = math.radians(rotation["angle"])
|
||||
# Rescaled rotations expand in the plane perpendicular to the rotation axis.
|
||||
scale = 1 / math.cos(angle) if rotation.get("rescale") else 1
|
||||
point[a] = origin[a] + (x * math.cos(angle) - y * math.sin(angle)) * scale
|
||||
point[b] = origin[b] + (x * math.sin(angle) + y * math.cos(angle)) * scale
|
||||
points.append(point)
|
||||
if not points:
|
||||
return None
|
||||
return tuple([min(p[a] for p in points) for a in range(3)]), tuple([max(p[a] for p in points) for a in range(3)])
|
||||
|
||||
|
||||
def write_rust_bounds(stage):
|
||||
stage = Path(stage)
|
||||
rows = ["// Generated by tools/gen_models.py from the final staged models; do not edit.\n",
|
||||
"pub fn bounds(id: &str) -> Option<([f64; 3], [f64; 3])> {\n Some(match id {\n"]
|
||||
for path in sorted((stage / "assets/airdef/models/block").glob("*.json")):
|
||||
bounds = model_bounds(json.loads(path.read_text(encoding="utf-8")))
|
||||
if bounds:
|
||||
lo, hi = ([round(float(x), 6) for x in corner] for corner in bounds)
|
||||
rows.append(f' "airdef:{path.stem}" => ({lo}, {hi}),\n')
|
||||
rows.append(" _ => return None,\n })\n}\n")
|
||||
target = stage / "src/sim/generated_bounds.rs"
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_text("".join(rows), encoding="utf-8")
|
||||
@@ -0,0 +1,40 @@
|
||||
"""Resource registrations and localization, independent of geometry and raster generation."""
|
||||
import json
|
||||
import os
|
||||
|
||||
def write_json(path, obj):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(obj, f, ensure_ascii=False, indent=1)
|
||||
|
||||
|
||||
|
||||
def write_registry(out, namespace, models, items, camera_models):
|
||||
a = os.path.join(out, "assets", namespace)
|
||||
d = os.path.join(out, "data", namespace, "horizon")
|
||||
lang = {}
|
||||
NS = namespace
|
||||
for name, title in models:
|
||||
write_json(os.path.join(a, "blockstates", name + ".json"), {"variants": {"": {"model": f"{NS}:block/{name}"}}})
|
||||
write_json(os.path.join(d, "block", name + ".json"),
|
||||
{"template": "minecraft:stone", "item": False})
|
||||
lang[f"block.{NS}.{name}"] = title
|
||||
for name, title, _ in items:
|
||||
write_json(os.path.join(a, "models", "item", name + ".json"),
|
||||
{"parent": "minecraft:item/generated", "textures": {"layer0": f"{NS}:item/{name}"}})
|
||||
write_json(os.path.join(a, "items", name + ".json"),
|
||||
{"model": {"type": "minecraft:model", "model": f"{NS}:item/{name}"}})
|
||||
write_json(os.path.join(d, "item", name + ".json"), {"template": "minecraft:stick", "max_stack_size": 1})
|
||||
lang[f"item.{NS}.{name}"] = title
|
||||
# Предметы-иконки для камеры монитора: 3D-модель цели в интерфейсе.
|
||||
for name in camera_models:
|
||||
title = dict(models)[name]
|
||||
write_json(os.path.join(a, "models", "item", "cam_" + name + ".json"),
|
||||
{"parent": f"{NS}:block/{name}",
|
||||
"display": {"gui": {"rotation": [20, 145, 0], "translation": [0, 0, 0], "scale": [0.36, 0.36, 0.36]}}})
|
||||
write_json(os.path.join(a, "items", "cam_" + name + ".json"),
|
||||
{"model": {"type": "minecraft:model", "model": f"{NS}:item/cam_{name}"}})
|
||||
write_json(os.path.join(d, "item", "cam_" + name + ".json"), {"template": "minecraft:stick", "max_stack_size": 1})
|
||||
lang[f"item.{NS}.cam_{name}"] = title
|
||||
write_json(os.path.join(a, "lang", "en_us.json"), lang)
|
||||
write_json(os.path.join(a, "lang", "ru_ru.json"), lang)
|
||||
@@ -24,6 +24,8 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from PIL import Image
|
||||
import gen_tex as GT
|
||||
from airdef_assets import pipeline
|
||||
from airdef_assets.bounds import write_rust_bounds
|
||||
from airdef_assets.registry import write_json, write_registry
|
||||
from airdef_assets.texture_catalog import RINGED, STRETCH_FN, TEXTURES
|
||||
from airdef_assets.icons import ITEMS, render_icon
|
||||
ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "airdef-mod"))
|
||||
@@ -1042,11 +1044,6 @@ WRECKS = ["patriot_trailer", "patriot_launcher", "gepard_hull", "gepard_turret",
|
||||
|
||||
CAM_MODELS = ["shahed", "geran3", "lancet", "gerbera", "kh101", "kalibr", "kh22", "zircon", "iskander", "kinzhal", "reentry"]
|
||||
|
||||
def write_json(path, obj):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(obj, f, ensure_ascii=False, indent=1)
|
||||
|
||||
|
||||
def generate(out):
|
||||
# Пишет весь набор в каталог out (зеркало airdef-mod/). Звуки (tools/gen_sounds.py) и sounds.json не трогаем.
|
||||
@@ -1054,37 +1051,15 @@ def generate(out):
|
||||
d = os.path.join(out, "data", NS, "horizon")
|
||||
os.makedirs(os.path.join(a, "textures", "block"))
|
||||
os.makedirs(os.path.join(a, "textures", "item"))
|
||||
lang = {}
|
||||
for wid in WRECKS:
|
||||
fn, title = MODELS[wid]
|
||||
MODELS[wid + "_burnt"] = ((lambda fn=fn, wid=wid: burnt_parts(fn(), zlib.crc32(wid.encode()))), title + " (остов)")
|
||||
for name, (fn, title) in MODELS.items():
|
||||
for name, (fn, _) in MODELS.items():
|
||||
write_json(os.path.join(a, "models", "block", name + ".json"), model(fn(), name.endswith("_burnt")))
|
||||
write_json(os.path.join(a, "blockstates", name + ".json"), {"variants": {"": {"model": f"{NS}:block/{name}"}}})
|
||||
write_json(os.path.join(d, "block", name + ".json"),
|
||||
{"template": "minecraft:stone", "item": False})
|
||||
lang[f"block.{NS}.{name}"] = title
|
||||
GT.write_block_textures(a, TEXTURES, VARIANTS, STRETCH_FN)
|
||||
for i, (name, title, color) in enumerate(ITEMS):
|
||||
for name, _, color in ITEMS:
|
||||
GT.write_item_icon(a, name, render_icon(name, color, zlib.crc32(name.encode())))
|
||||
write_json(os.path.join(a, "models", "item", name + ".json"),
|
||||
{"parent": "minecraft:item/generated", "textures": {"layer0": f"{NS}:item/{name}"}})
|
||||
write_json(os.path.join(a, "items", name + ".json"),
|
||||
{"model": {"type": "minecraft:model", "model": f"{NS}:item/{name}"}})
|
||||
write_json(os.path.join(d, "item", name + ".json"), {"template": "minecraft:stick", "max_stack_size": 1})
|
||||
lang[f"item.{NS}.{name}"] = title
|
||||
# Предметы-иконки для камеры монитора: 3D-модель цели в интерфейсе.
|
||||
for name in CAM_MODELS:
|
||||
title = MODELS[name][1]
|
||||
write_json(os.path.join(a, "models", "item", "cam_" + name + ".json"),
|
||||
{"parent": f"{NS}:block/{name}",
|
||||
"display": {"gui": {"rotation": [20, 145, 0], "translation": [0, 0, 0], "scale": [0.36, 0.36, 0.36]}}})
|
||||
write_json(os.path.join(a, "items", "cam_" + name + ".json"),
|
||||
{"model": {"type": "minecraft:model", "model": f"{NS}:item/cam_{name}"}})
|
||||
write_json(os.path.join(d, "item", "cam_" + name + ".json"), {"template": "minecraft:stick", "max_stack_size": 1})
|
||||
lang[f"item.{NS}.cam_{name}"] = title
|
||||
write_json(os.path.join(a, "lang", "en_us.json"), lang)
|
||||
write_json(os.path.join(a, "lang", "ru_ru.json"), lang)
|
||||
write_registry(out, NS, [(name, title) for name, (_, title) in MODELS.items()], ITEMS, CAM_MODELS)
|
||||
return len(MODELS), len(ITEMS), len(TEXTURES)
|
||||
|
||||
|
||||
@@ -1210,6 +1185,7 @@ def regenerate(root=ROOT, source_root=None, manifest=None, *, check=False, repor
|
||||
if errors:
|
||||
details = "\n".join(f" - {err}" for err in errors)
|
||||
raise ValueError(f"ПРОВЕРКА НАБОРА НЕ ПРОЙДЕНА, ошибок: {len(errors)}. Ничего не записано в {root}.\n{details}")
|
||||
write_rust_bounds(stage)
|
||||
new = {}
|
||||
for dirpath, dirs, names in os.walk(stage):
|
||||
dirs.sort()
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export the three art pilots to authored JSON. Run gen_models.py afterwards.
|
||||
|
||||
The JSON under source-assets is the editable deliverable. This optional authoring helper
|
||||
only rewrites its explicitly named pilots; the normal generator never calls it.
|
||||
Existing origins, launcher grid and animation parts are retained.
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
import zlib
|
||||
import gen_models as g
|
||||
|
||||
ROOT = Path(g.ROOT)
|
||||
SOURCE = ROOT / "source-assets/assets/airdef/models/block"
|
||||
|
||||
|
||||
def tire(x0, x1, z, radius=4.5):
|
||||
"""Five voxel strips: rounded silhouette, without overlapping rotated squares' star tips."""
|
||||
parts = []
|
||||
for lo, hi, width in [(-1, -.6, .6), (-.6, -.2, .92), (-.2, .2, 1), (.2, .6, .92), (.6, 1, .6)]:
|
||||
parts += g.both(g.el((x0, radius + lo * radius, z - width * radius),
|
||||
(x1, radius + hi * radius, z + width * radius), "tire"))
|
||||
parts += g.both(g.el((x0 - .05, radius - 2.2, z - 2.2),
|
||||
(x0, radius + 2.2, z + 2.2), "hub"))
|
||||
return parts
|
||||
|
||||
|
||||
def s400_chassis():
|
||||
parts = [p for p in g.maz_chassis("ru_green") if p["tex"] != "tire"]
|
||||
for z in [-10.5, -1.5, 16.5, 25.5]:
|
||||
parts += tire(-9, -5.5, z)
|
||||
# Cab roof and inset windscreen separate the cabin from the flat cargo deck.
|
||||
for x0, x1 in [(-5.7, 2.7), (13.3, 21.7)]:
|
||||
parts += [g.el((x0, 19, -15), (x1, 19.5, -7), "ru_green"),
|
||||
g.el((x0 + .5, 15, -15.8), (x1 - .5, 18.5, -15.55), "glass_cab", rot=("x", 22.5))]
|
||||
parts += g.both(g.B(-14.5, 8.3, -12.5, -14, 8.8, -7, "dark_metal"))
|
||||
parts += g.both(g.B(-14.4, 13, -10.2, -14.1, 13.4, -8.4, "bare_antenna"))
|
||||
# Underbody rails and an engine-deck grille read at normal gameplay distance.
|
||||
parts += [g.el((1, 4.2, -8), (3, 5, 29), "dark_metal"),
|
||||
g.el((13, 4.2, -8), (15, 5, 29), "dark_metal"),
|
||||
g.el((-3, 13.1, -3), (19, 13.5, 3), "bare_nozzle")]
|
||||
return parts
|
||||
|
||||
|
||||
def s400_tubes():
|
||||
parts = []
|
||||
# Same four centres and 7-unit diameter as Muzzle::Grid; pivots are unchanged.
|
||||
for x in [.5, 8.5]:
|
||||
for y in [0, 8]:
|
||||
for lo, hi, width in [(-1, -.6, .6), (-.6, -.2, .92), (-.2, .2, 1), (.2, .6, .92), (.6, 1, .6)]:
|
||||
parts.append(g.el((x + 3.5 - 3.5 * width, y + 3.5 + lo * 3.5, -16),
|
||||
(x + 3.5 + 3.5 * width, y + 3.5 + hi * 3.5, 32),
|
||||
"tube", {"north": "tube_cap", "south": "tube_cap"}))
|
||||
for z in [-1, 26]:
|
||||
parts.append(g.el((x - .15, y + 2.6, z), (x + 7.15, y + 4.4, z + 1), "dark_metal"))
|
||||
parts += [g.el((-.5, 0, 26), (16.5, 1, 29), "dark_metal")]
|
||||
return parts
|
||||
|
||||
|
||||
def gepard_hull():
|
||||
parts = [g.el((-10, 4, -8), (26, 15, 30), "flecktarn"),
|
||||
g.el((-10, 4, -15), (26, 9, -8), "flecktarn"),
|
||||
g.el((-9.5, 9, -14), (25.5, 13, -7), "flecktarn", rot=("x", -22.5)),
|
||||
g.el((-9, 15, -4), (25, 16.5, 18), "flecktarn"),
|
||||
g.el((-8, 15, 18), (24, 16, 30), "dark_metal"),
|
||||
g.el((-6, 16.6, -6), (3, 17.2, -1), "metal")]
|
||||
# Side tracks remain a continuous loop; visible road wheels replace a featureless slab.
|
||||
parts += g.both(g.el((-14, 0, -14), (-10, 8.8, 31), "track"))
|
||||
for z in [-10, -4, 2, 8, 14, 20, 26]:
|
||||
for lo, hi, width in [(-1, -.5, .65), (-.5, .5, 1), (.5, 1, .65)]:
|
||||
parts += g.both(g.el((-14.08, 4.3 + lo * 3.5, z - width * 2.8),
|
||||
(-14.02, 4.3 + hi * 3.5, z + width * 2.8), "hub"))
|
||||
parts += g.both(g.el((-14.5, 8.6, -14), (-10, 10, 31), "flecktarn"))
|
||||
for z in [20, 24, 28]:
|
||||
parts += [g.el((-6, 16.1, z), (22, 16.3, z + 1), "bare_nozzle")]
|
||||
return parts
|
||||
|
||||
|
||||
def gepard_turret():
|
||||
# Preserve the aiming origin, gun pack, tracking radar and search-dish attachment.
|
||||
parts = [g.el((-4, 0, -5), (20, 5, 16), "flecktarn"),
|
||||
g.el((-2.5, 5, -5), (18.5, 12, 15), "flecktarn"),
|
||||
g.el((-2, 12, -2), (18, 13, 14), "flecktarn"),
|
||||
g.el((3, 4, -10), (13, 12, -6), "radar_face"),
|
||||
g.el((7, 13, 10), (9, 18, 12), "metal")]
|
||||
parts += g.both(g.el((-4.7, 4.8, -4), (-2.5, 10.7, 14), "flecktarn", rot=("z", 22.5)))
|
||||
parts += [g.el((0, 13.05, 2), (5, 13.7, 8), "dark_metal"),
|
||||
g.el((10, 13.05, 2), (15, 13.7, 8), "dark_metal")]
|
||||
parts += g.decal("mk_de", 6, 9, -4, 2, 10.5)
|
||||
return parts
|
||||
|
||||
|
||||
def shahed():
|
||||
parts = g.ogive(-16, -9, 2.5, "shahed_nose", 4) + g.oct_z(-9, 22, 2.5, "shahed")
|
||||
parts += g.delta2("shahed", "kh101_belly", -2, 21, 26, 21, 12, 7.5, 8.3)
|
||||
parts += g.both(g.B(-20.8, 7.6, 18, -20.1, 13.2, 26, "shahed"))
|
||||
parts += g.oct_z(22, 28, 1.8, "dark_metal")
|
||||
parts += g.both(g.B(.8, 5.5, 24, 1.5, 6.6, 28, "bare_nozzle"))
|
||||
parts += [g.B(-1.3, 10.5, -3, 1.3, 10.8, 7, "shahed")]
|
||||
return parts
|
||||
|
||||
|
||||
def export(name, parts, burnt=False):
|
||||
model = g.model(parts, burnt=burnt)
|
||||
# The authoring tool reuses existing textures; it never creates untracked palette variants.
|
||||
for key, value in model["textures"].items():
|
||||
if not (ROOT / "assets/airdef/textures" / (value.split(":", 1)[1] + ".png")).exists():
|
||||
base = g.VARIANTS[key][0]
|
||||
candidate = base + "_b" if burnt else base
|
||||
if not (ROOT / "assets/airdef/textures/block" / (candidate + ".png")).exists():
|
||||
candidate = base
|
||||
model["textures"][key] = "airdef:block/" + candidate
|
||||
SOURCE.mkdir(parents=True, exist_ok=True)
|
||||
(SOURCE / (name + ".json")).write_text(json.dumps(model, indent=1) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
for name, make in [("s400_chassis", s400_chassis), ("s400_tubes", s400_tubes),
|
||||
("gepard_hull", gepard_hull), ("gepard_turret", gepard_turret), ("shahed", shahed)]:
|
||||
parts = make()
|
||||
export(name, parts)
|
||||
if name != "shahed":
|
||||
export(name + "_burnt", g.burnt_parts(parts, zlib.crc32(name.encode())), burnt=True)
|
||||
print(name, len(parts), "elements")
|
||||
@@ -0,0 +1,36 @@
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from airdef_assets.bounds import model_bounds, write_rust_bounds
|
||||
from airdef_assets.pipeline import overlay_sources
|
||||
|
||||
|
||||
class BoundsTests(unittest.TestCase):
|
||||
def test_rotated_wheel_bounds_include_the_corners_outside_its_original_box(self):
|
||||
lo, hi = model_bounds({"elements": [{"from": [-1, -1, -1], "to": [1, 1, 1],
|
||||
"rotation": {"axis": "x", "angle": 45, "origin": [0, 0, 0]}}]})
|
||||
self.assertAlmostEqual(hi[1], math.sqrt(2))
|
||||
self.assertAlmostEqual(lo[2], -math.sqrt(2))
|
||||
self.assertEqual((lo[0], hi[0]), (-1, 1))
|
||||
|
||||
def test_final_authored_override_controls_exported_bounds(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
rel = Path("assets/airdef/models/block/test.json")
|
||||
stage, source = root / "stage", root / "source"
|
||||
for folder, extent in [(stage, 1), (source, 30)]:
|
||||
(folder / rel).parent.mkdir(parents=True)
|
||||
(folder / rel).write_text(json.dumps({"elements": [{"from": [0, 0, 0], "to": [extent, 2, 3]}]}))
|
||||
overlay_sources(stage, source)
|
||||
write_rust_bounds(stage)
|
||||
text = (stage / "src/sim/generated_bounds.rs").read_text()
|
||||
self.assertIn('"airdef:test"', text)
|
||||
self.assertIn("[30.0, 2.0, 3.0]", text)
|
||||
self.assertEqual(json.loads((source / rel).read_text())["elements"][0]["to"][0], 30)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||