@adatechnology/game-vehicles-three 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.global.js +1860 -271
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
package/dist/index.global.js
CHANGED
|
@@ -5128,8 +5128,8 @@ var GameVehiclesThree = (() => {
|
|
|
5128
5128
|
});
|
|
5129
5129
|
return GRM[kind];
|
|
5130
5130
|
}
|
|
5131
|
-
function mkSurf(
|
|
5132
|
-
const geo =
|
|
5131
|
+
function mkSurf(mesh2, W) {
|
|
5132
|
+
const geo = mesh2.geometry, pos = geo.attributes.position, ix = geo.index, n = ix ? ix.count : pos.count;
|
|
5133
5133
|
geo.computeBoundingBox();
|
|
5134
5134
|
const bb = geo.boundingBox.clone();
|
|
5135
5135
|
const T = [], BY = {}, BX = {}, Q = 0.02;
|
|
@@ -5146,11 +5146,11 @@ var GameVehiclesThree = (() => {
|
|
|
5146
5146
|
S.hit = function(o, dd) {
|
|
5147
5147
|
const d = dd.clone().normalize();
|
|
5148
5148
|
ray.set(o, d);
|
|
5149
|
-
const
|
|
5150
|
-
if (!
|
|
5149
|
+
const list2 = Math.abs(d.y) < 0.5 ? BY[Math.floor(o.y / Q)] : BX[Math.floor(o.x / Q)];
|
|
5150
|
+
if (!list2) return null;
|
|
5151
5151
|
let best = 1e9, bt = null;
|
|
5152
|
-
for (let k = 0; k <
|
|
5153
|
-
const t = T[
|
|
5152
|
+
for (let k = 0; k < list2.length; k++) {
|
|
5153
|
+
const t = T[list2[k]];
|
|
5154
5154
|
if (!ray.intersectTriangle(t[0], t[1], t[2], false, tmp)) continue;
|
|
5155
5155
|
const dist = tmp.distanceTo(o);
|
|
5156
5156
|
if (dist < best) {
|
|
@@ -5325,8 +5325,8 @@ var GameVehiclesThree = (() => {
|
|
|
5325
5325
|
t.castShadow = false;
|
|
5326
5326
|
return t;
|
|
5327
5327
|
}
|
|
5328
|
-
function lineOn(c, Gd,
|
|
5329
|
-
const pts =
|
|
5328
|
+
function lineOn(c, Gd, list2, r, mat, off) {
|
|
5329
|
+
const pts = list2.map(function(q) {
|
|
5330
5330
|
const s = Gd.at(q[0], q[1]);
|
|
5331
5331
|
return s.p.addScaledVector(s.n, off || 3e-3);
|
|
5332
5332
|
});
|
|
@@ -5397,8 +5397,8 @@ var GameVehiclesThree = (() => {
|
|
|
5397
5397
|
const r = sh(q[0]), y = (r[0] + r[1]) / 2 + (q[1] || 0), s = Gd.at(q[0], y), rad = q[2] || Math.min(0.034, (r[1] - r[0]) * 0.4);
|
|
5398
5398
|
const cup = onSurf(c.cylinder(rad * 1.35, rad * 1.2, 0.012, LH, 0, 0, 0), s, 8e-3);
|
|
5399
5399
|
cup.castShadow = false;
|
|
5400
|
-
const
|
|
5401
|
-
|
|
5400
|
+
const ring2 = onSurf(c.add(new THREE.TorusGeometry(rad * 1.05, 4e-3, 6, 22), MT.chrome), s, 0.012, new V3(0, 0, 1));
|
|
5401
|
+
ring2.castShadow = false;
|
|
5402
5402
|
const b = onSurf(c.sphere(rad, MT.head, 0, 0, 0, 1, 0.55, 1), s, 0.01);
|
|
5403
5403
|
b.castShadow = false;
|
|
5404
5404
|
inner.push(b);
|
|
@@ -6015,9 +6015,9 @@ var GameVehiclesThree = (() => {
|
|
|
6015
6015
|
});
|
|
6016
6016
|
})();
|
|
6017
6017
|
const REFLB = CM("#d3d7da", { metalness: 0.35, roughness: 0.28 });
|
|
6018
|
-
function dlo(
|
|
6018
|
+
function dlo(list2) {
|
|
6019
6019
|
return function(def) {
|
|
6020
|
-
return
|
|
6020
|
+
return list2.concat([def[def.length - 1]]);
|
|
6021
6021
|
};
|
|
6022
6022
|
}
|
|
6023
6023
|
function cabTaper(belt, top, x0, L, a) {
|
|
@@ -8375,7 +8375,7 @@ var GameVehiclesThree = (() => {
|
|
|
8375
8375
|
guards: [-1.1, 2],
|
|
8376
8376
|
lightsY: 0.62
|
|
8377
8377
|
});
|
|
8378
|
-
const
|
|
8378
|
+
const box2 = boxBody(c, { x0: f - len - 0.1, x1: -3.72, y0: 0.98, y1: 3.38, W: 2.42, col: "#f1f1ec" });
|
|
8379
8379
|
[1, -1].forEach(function(s) {
|
|
8380
8380
|
c.roundBox(4.6, 0.32, 0.01, 0.01, CM("#1f4fa3", { roughness: 0.5 }), -1, 1.35, s * 1.217);
|
|
8381
8381
|
c.roundBox(4.6, 0.06, 0.01, 0.01, CM("#e0a21c", { roughness: 0.5 }), -1, 1.56, s * 1.217);
|
|
@@ -8406,7 +8406,7 @@ var GameVehiclesThree = (() => {
|
|
|
8406
8406
|
c2.rod(new V3(-3.86, 0.6, z), new V3(-3.86, 3.5, z), 0.022, kit.steelMaterial);
|
|
8407
8407
|
});
|
|
8408
8408
|
});
|
|
8409
|
-
void
|
|
8409
|
+
void box2;
|
|
8410
8410
|
}
|
|
8411
8411
|
);
|
|
8412
8412
|
fx.register(
|
|
@@ -9583,9 +9583,9 @@ var GameVehiclesThree = (() => {
|
|
|
9583
9583
|
return m;
|
|
9584
9584
|
}
|
|
9585
9585
|
function fenestron(c, x, y, R, w, n, mat, bladeMat) {
|
|
9586
|
-
const
|
|
9587
|
-
|
|
9588
|
-
c.deform.push(
|
|
9586
|
+
const ring2 = c.add(new THREE.TorusGeometry(R + 0.06, 0.07, 10, 36), mat, x, y, 0);
|
|
9587
|
+
ring2.scale.z = w / 0.14;
|
|
9588
|
+
c.deform.push(ring2);
|
|
9589
9589
|
const duct = c.cylinder(R + 0.01, R + 0.01, w, MT.dark, x, y, 0, "z", { seg: 36, open: true });
|
|
9590
9590
|
duct.material = CM("#141516", { roughness: 0.8, side: THREE.DoubleSide });
|
|
9591
9591
|
const g = new THREE.Group();
|
|
@@ -9613,7 +9613,7 @@ var GameVehiclesThree = (() => {
|
|
|
9613
9613
|
);
|
|
9614
9614
|
}
|
|
9615
9615
|
c.spin.push({ o: g, axis: "z", v: 22 });
|
|
9616
|
-
return { ring, fan: g, duct };
|
|
9616
|
+
return { ring: ring2, fan: g, duct };
|
|
9617
9617
|
}
|
|
9618
9618
|
function xRotor(c, x, y, z, R, ch, mat, tip) {
|
|
9619
9619
|
const g = new THREE.Group();
|
|
@@ -11330,16 +11330,16 @@ var GameVehiclesThree = (() => {
|
|
|
11330
11330
|
function settle(c, tilt, riseOnly) {
|
|
11331
11331
|
if (tilt) c.vehicle.rotation.z += tilt;
|
|
11332
11332
|
c.root.updateMatrixWorld(true);
|
|
11333
|
-
const inv = new THREE.Matrix4().copy(c.root.matrixWorld).invert(),
|
|
11333
|
+
const inv = new THREE.Matrix4().copy(c.root.matrixWorld).invert(), box2 = new THREE.Box3(), tmp = new THREE.Box3();
|
|
11334
11334
|
c.vehicle.traverse(function(ob) {
|
|
11335
11335
|
if (!ob.isMesh) return;
|
|
11336
11336
|
for (let q = ob; q && q !== c.vehicle; q = q.parent)
|
|
11337
11337
|
if (!q.visible || q.userData.decal || q.userData.ghost || q.userData.antena) return;
|
|
11338
11338
|
if (!ob.geometry.boundingBox) ob.geometry.computeBoundingBox();
|
|
11339
11339
|
tmp.copy(ob.geometry.boundingBox).applyMatrix4(ob.matrixWorld).applyMatrix4(inv);
|
|
11340
|
-
|
|
11340
|
+
box2.union(tmp);
|
|
11341
11341
|
});
|
|
11342
|
-
if (!
|
|
11342
|
+
if (!box2.isEmpty() && (!riseOnly || box2.min.y < -5e-3)) c.vehicle.position.y -= box2.min.y;
|
|
11343
11343
|
}
|
|
11344
11344
|
function rollover(c, o) {
|
|
11345
11345
|
o = o || {};
|
|
@@ -11616,10 +11616,10 @@ var GameVehiclesThree = (() => {
|
|
|
11616
11616
|
function periscope(c, x, y, z, w, label, o) {
|
|
11617
11617
|
o = o || {};
|
|
11618
11618
|
const rot = o.rot || 0;
|
|
11619
|
-
const
|
|
11619
|
+
const box2 = c.roundBox(0.14, 0.12, w + 0.06, 0.02, o.mat || OLIVE_STEEL, x, y, z, { rot: [0, rot, 0] });
|
|
11620
11620
|
const gl = c.roundBox(0.02, 0.07, w, 0.01, MT.armorGlass, x + Math.cos(rot) * 0.07, y, z - Math.sin(rot) * 0.07, { rot: [0, rot, 0] });
|
|
11621
11621
|
if (label) kit.asGlass(c, gl, label, "laminated");
|
|
11622
|
-
return
|
|
11622
|
+
return box2;
|
|
11623
11623
|
}
|
|
11624
11624
|
function sideSeat(c, x0, x1, fl, z, dir, o) {
|
|
11625
11625
|
o = o || {};
|
|
@@ -13947,7 +13947,7 @@ var GameVehiclesThree = (() => {
|
|
|
13947
13947
|
o = o || {};
|
|
13948
13948
|
if (kit.lod.on) o = Object.assign({}, o, { seg: Math.max(kit.lod.minLoftSegments, Math.round((o.seg || 24) * kit.lod.loftSegmentFraction)) });
|
|
13949
13949
|
if (o.smooth) st = resample(st, o.smooth);
|
|
13950
|
-
const seg = o.seg || 24, pos = [], idx = [],
|
|
13950
|
+
const seg = o.seg || 24, pos = [], idx = [], ring2 = seg + 1, axisY = o.axis === "y";
|
|
13951
13951
|
st.forEach(function(s) {
|
|
13952
13952
|
const a0 = s[1], b0 = s[2], cc = (a0 + b0) / 2, hh = Math.abs(a0 - b0) / 2, w = s[3] / 2, e = 2 / (s[4] || o.p || 2.4), zc = s[5] || 0;
|
|
13953
13953
|
for (let j = 0; j <= seg; j++) {
|
|
@@ -13959,7 +13959,7 @@ var GameVehiclesThree = (() => {
|
|
|
13959
13959
|
});
|
|
13960
13960
|
for (let i = 0; i < st.length - 1; i++)
|
|
13961
13961
|
for (let k = 0; k < seg; k++) {
|
|
13962
|
-
const A = i *
|
|
13962
|
+
const A = i * ring2 + k, B = A + ring2;
|
|
13963
13963
|
if (axisY) idx.push(A, B, A + 1, A + 1, B, B + 1);
|
|
13964
13964
|
else idx.push(A, A + 1, B, A + 1, B + 1, B);
|
|
13965
13965
|
}
|
|
@@ -13971,7 +13971,7 @@ var GameVehiclesThree = (() => {
|
|
|
13971
13971
|
if (axisY) pos.push(cc, s[0], s[5] || 0);
|
|
13972
13972
|
else pos.push(s[0], cc, s[5] || 0);
|
|
13973
13973
|
for (let k = 0; k < seg; k++) {
|
|
13974
|
-
const a = si *
|
|
13974
|
+
const a = si * ring2 + k, flip = e === 0 !== axisY;
|
|
13975
13975
|
if (flip) idx.push(ci, a + 1, a);
|
|
13976
13976
|
else idx.push(ci, a, a + 1);
|
|
13977
13977
|
}
|
|
@@ -14158,8 +14158,8 @@ var GameVehiclesThree = (() => {
|
|
|
14158
14158
|
});
|
|
14159
14159
|
return GRM[kind];
|
|
14160
14160
|
}
|
|
14161
|
-
function mkSurf(
|
|
14162
|
-
const geo =
|
|
14161
|
+
function mkSurf(mesh2, W) {
|
|
14162
|
+
const geo = mesh2.geometry, pos = geo.attributes.position, ix = geo.index, n = ix ? ix.count : pos.count;
|
|
14163
14163
|
geo.computeBoundingBox();
|
|
14164
14164
|
const bb = geo.boundingBox.clone();
|
|
14165
14165
|
const T = [], BY = {}, BX = {}, Q = 0.02;
|
|
@@ -14176,11 +14176,11 @@ var GameVehiclesThree = (() => {
|
|
|
14176
14176
|
S.hit = function(o, dd) {
|
|
14177
14177
|
const d = dd.clone().normalize();
|
|
14178
14178
|
ray.set(o, d);
|
|
14179
|
-
const
|
|
14180
|
-
if (!
|
|
14179
|
+
const list2 = Math.abs(d.y) < 0.5 ? BY[Math.floor(o.y / Q)] : BX[Math.floor(o.x / Q)];
|
|
14180
|
+
if (!list2) return null;
|
|
14181
14181
|
let best = 1e9, bt = null;
|
|
14182
|
-
for (let k = 0; k <
|
|
14183
|
-
const t = T[
|
|
14182
|
+
for (let k = 0; k < list2.length; k++) {
|
|
14183
|
+
const t = T[list2[k]];
|
|
14184
14184
|
if (!ray.intersectTriangle(t[0], t[1], t[2], false, tmp)) continue;
|
|
14185
14185
|
const dist = tmp.distanceTo(o);
|
|
14186
14186
|
if (dist < best) {
|
|
@@ -14355,8 +14355,8 @@ var GameVehiclesThree = (() => {
|
|
|
14355
14355
|
t.castShadow = false;
|
|
14356
14356
|
return t;
|
|
14357
14357
|
}
|
|
14358
|
-
function lineOn(c, Gd,
|
|
14359
|
-
const pts =
|
|
14358
|
+
function lineOn(c, Gd, list2, r, mat, off) {
|
|
14359
|
+
const pts = list2.map(function(q) {
|
|
14360
14360
|
const s = Gd.at(q[0], q[1]);
|
|
14361
14361
|
return s.p.addScaledVector(s.n, off || 3e-3);
|
|
14362
14362
|
});
|
|
@@ -14427,8 +14427,8 @@ var GameVehiclesThree = (() => {
|
|
|
14427
14427
|
const r = sh(q[0]), y = (r[0] + r[1]) / 2 + (q[1] || 0), s = Gd.at(q[0], y), rad = q[2] || Math.min(0.034, (r[1] - r[0]) * 0.4);
|
|
14428
14428
|
const cup = onSurf(c.cylinder(rad * 1.35, rad * 1.2, 0.012, LH, 0, 0, 0), s, 8e-3);
|
|
14429
14429
|
cup.castShadow = false;
|
|
14430
|
-
const
|
|
14431
|
-
|
|
14430
|
+
const ring2 = onSurf(c.add(new THREE.TorusGeometry(rad * 1.05, 4e-3, 6, 22), MT.chrome), s, 0.012, new V3(0, 0, 1));
|
|
14431
|
+
ring2.castShadow = false;
|
|
14432
14432
|
const b = onSurf(c.sphere(rad, MT.head, 0, 0, 0, 1, 0.55, 1), s, 0.01);
|
|
14433
14433
|
b.castShadow = false;
|
|
14434
14434
|
inner.push(b);
|
|
@@ -16505,9 +16505,9 @@ var GameVehiclesThree = (() => {
|
|
|
16505
16505
|
L.inner.push(m);
|
|
16506
16506
|
return m;
|
|
16507
16507
|
}
|
|
16508
|
-
function bendSet(
|
|
16508
|
+
function bendSet(list2, piv, axis, ang) {
|
|
16509
16509
|
const q = new THREE.Quaternion().setFromAxisAngle(axis.clone().normalize(), ang);
|
|
16510
|
-
|
|
16510
|
+
list2.forEach(function(m) {
|
|
16511
16511
|
if (!m.parent) return;
|
|
16512
16512
|
m.position.sub(piv).applyQuaternion(q).add(piv);
|
|
16513
16513
|
m.quaternion.premultiply(q);
|
|
@@ -17554,7 +17554,7 @@ var GameVehiclesThree = (() => {
|
|
|
17554
17554
|
);
|
|
17555
17555
|
[1, -1].forEach(function(s) {
|
|
17556
17556
|
const z = s * (s > 0 ? 0.44 : 0.4);
|
|
17557
|
-
const
|
|
17557
|
+
const box2 = c.roundBox(0.5, 0.38, 0.2, 0.03, aluBox, -0.7, 0.8, z, { def: true }), luggageCase = [box2, c.roundBox(0.52, 0.04, 0.21, 0.015, blk, -0.7, 0.98, z)];
|
|
17558
17558
|
[-0.88, -0.52].forEach(function(x) {
|
|
17559
17559
|
luggageCase.push(c.roundBox(0.04, 0.06, 0.03, 0.01, blk, x, 0.95, z + s * 0.1));
|
|
17560
17560
|
});
|
|
@@ -17568,7 +17568,7 @@ var GameVehiclesThree = (() => {
|
|
|
17568
17568
|
blk,
|
|
17569
17569
|
{ seg: 12 }
|
|
17570
17570
|
);
|
|
17571
|
-
c.part("cargo", s > 0 ? trl("labels.right_pannier") : trl("labels.left_pannier"),
|
|
17571
|
+
c.part("cargo", s > 0 ? trl("labels.right_pannier") : trl("labels.left_pannier"), box2, new V3(-0.7, 0.8, z), 0.6);
|
|
17572
17572
|
c.zone(
|
|
17573
17573
|
s > 0 ? "case_right" : "case_left",
|
|
17574
17574
|
s > 0 ? trl("labels.right_pannier") : trl("labels.left_pannier"),
|
|
@@ -18216,7 +18216,7 @@ var GameVehiclesThree = (() => {
|
|
|
18216
18216
|
function sloft(st, o) {
|
|
18217
18217
|
o = o || {};
|
|
18218
18218
|
if (kit.lod.on) o = Object.assign({}, o, { seg: Math.max(kit.lod.minLoftSegments, Math.round((o.seg || 24) * kit.lod.loftSegmentFraction)) });
|
|
18219
|
-
const seg = o.seg || 24, pos = [], idx = [],
|
|
18219
|
+
const seg = o.seg || 24, pos = [], idx = [], ring2 = seg + 1, axisY = o.axis === "y";
|
|
18220
18220
|
st.forEach(function(s) {
|
|
18221
18221
|
const a0 = s[1], b0 = s[2], cc = (a0 + b0) / 2, hh = Math.abs(a0 - b0) / 2, w = s[3] / 2, e = 2 / (s[4] || o.p || 2.4), zc = s[5] || 0;
|
|
18222
18222
|
for (let j = 0; j <= seg; j++) {
|
|
@@ -18228,7 +18228,7 @@ var GameVehiclesThree = (() => {
|
|
|
18228
18228
|
});
|
|
18229
18229
|
for (let i = 0; i < st.length - 1; i++)
|
|
18230
18230
|
for (let k = 0; k < seg; k++) {
|
|
18231
|
-
const A = i *
|
|
18231
|
+
const A = i * ring2 + k, B = A + ring2;
|
|
18232
18232
|
if (axisY) idx.push(A, B, A + 1, A + 1, B, B + 1);
|
|
18233
18233
|
else idx.push(A, A + 1, B, A + 1, B + 1, B);
|
|
18234
18234
|
}
|
|
@@ -18240,7 +18240,7 @@ var GameVehiclesThree = (() => {
|
|
|
18240
18240
|
if (axisY) pos.push(cc, s[0], s[5] || 0);
|
|
18241
18241
|
else pos.push(s[0], cc, s[5] || 0);
|
|
18242
18242
|
for (let k = 0; k < seg; k++) {
|
|
18243
|
-
const a = si *
|
|
18243
|
+
const a = si * ring2 + k, flip = e === 0 !== axisY;
|
|
18244
18244
|
if (flip) idx.push(ci, a + 1, a);
|
|
18245
18245
|
else idx.push(ci, a, a + 1);
|
|
18246
18246
|
}
|
|
@@ -19471,12 +19471,12 @@ var GameVehiclesThree = (() => {
|
|
|
19471
19471
|
});
|
|
19472
19472
|
Z.fairing = grab(c, n0).concat([fendF]);
|
|
19473
19473
|
const HL = lamp(c, { style: "round", x: 0.72, y: 0.84, z: 0, w: 0.19, h: 0.19, d: 0.1, side: 1, label: trl("labels.headlight") });
|
|
19474
|
-
const
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
HL.group.add(
|
|
19479
|
-
HL.inner.push(
|
|
19474
|
+
const ring2 = new THREE.Mesh(new THREE.TorusGeometry(0.075, 7e-3, 6, 32), DRL);
|
|
19475
|
+
ring2.rotation.y = PI / 2;
|
|
19476
|
+
ring2.position.set(0.052, 0, 0);
|
|
19477
|
+
ring2.castShadow = false;
|
|
19478
|
+
HL.group.add(ring2);
|
|
19479
|
+
HL.inner.push(ring2);
|
|
19480
19480
|
n0 = c.vehicle.children.length;
|
|
19481
19481
|
const TK = [
|
|
19482
19482
|
[0.46, 0.89, 0.76, 0.18, 2.2],
|
|
@@ -22525,7 +22525,7 @@ var GameVehiclesThree = (() => {
|
|
|
22525
22525
|
});
|
|
22526
22526
|
}
|
|
22527
22527
|
function roofLining(c, extra) {
|
|
22528
|
-
const m = c.meta, yb = (m.glasshouse ? m.glasshouse.belt : m.belt) + 0.25, bb = new THREE.Box3(), sz = new V3(), ce = new V3(), gl = new Set(c.glass),
|
|
22528
|
+
const m = c.meta, yb = (m.glasshouse ? m.glasshouse.belt : m.belt) + 0.25, bb = new THREE.Box3(), sz = new V3(), ce = new V3(), gl = new Set(c.glass), list2 = [];
|
|
22529
22529
|
const cols = [m.color, m.roofCol].filter(Boolean).map(function(h) {
|
|
22530
22530
|
return new THREE.Color(h).getHex();
|
|
22531
22531
|
});
|
|
@@ -22537,14 +22537,14 @@ var GameVehiclesThree = (() => {
|
|
|
22537
22537
|
bb.copy(o.geometry.boundingBox).applyMatrix4(o.matrix);
|
|
22538
22538
|
bb.getSize(sz);
|
|
22539
22539
|
bb.getCenter(ce);
|
|
22540
|
-
if (sz.x > 0.5 && sz.z > 0.6 && sz.y < 0.08 && ce.y > yb)
|
|
22540
|
+
if (sz.x > 0.5 && sz.z > 0.6 && sz.y < 0.08 && ce.y > yb) list2.push(o);
|
|
22541
22541
|
});
|
|
22542
22542
|
extra = extra || [];
|
|
22543
|
-
if (
|
|
22543
|
+
if (list2.length || extra.length)
|
|
22544
22544
|
c.zone("roof", null, null, null, {
|
|
22545
22545
|
onBand: function(c2, b) {
|
|
22546
22546
|
if (b >= 4)
|
|
22547
|
-
|
|
22547
|
+
list2.concat(extra).forEach(function(o) {
|
|
22548
22548
|
o.visible = false;
|
|
22549
22549
|
});
|
|
22550
22550
|
}
|
|
@@ -24329,7 +24329,7 @@ var GameVehiclesThree = (() => {
|
|
|
24329
24329
|
}
|
|
24330
24330
|
return pts;
|
|
24331
24331
|
}
|
|
24332
|
-
const
|
|
24332
|
+
const ring2 = 2 * (m1 + m2) + 1;
|
|
24333
24333
|
for (let i = 0; i <= n; i++) {
|
|
24334
24334
|
const t = i / n, x = o.x0 + t * o.L, P = sec(t), row = [];
|
|
24335
24335
|
for (let k = P.length - 1; k >= 1; k--) row.push([-P[k][0], P[k][1]]);
|
|
@@ -24345,8 +24345,8 @@ var GameVehiclesThree = (() => {
|
|
|
24345
24345
|
});
|
|
24346
24346
|
}
|
|
24347
24347
|
for (let a = 0; a < n; a++)
|
|
24348
|
-
for (let k2 = 0; k2 <
|
|
24349
|
-
const p0 = a *
|
|
24348
|
+
for (let k2 = 0; k2 < ring2 - 1; k2++) {
|
|
24349
|
+
const p0 = a * ring2 + k2, p1 = p0 + ring2;
|
|
24350
24350
|
idx.push(p0, p0 + 1, p1, p0 + 1, p1 + 1, p1);
|
|
24351
24351
|
}
|
|
24352
24352
|
const ci = pos.length / 3, sh0 = o.sheer(0), ky0 = o.keel(0);
|
|
@@ -24355,7 +24355,7 @@ var GameVehiclesThree = (() => {
|
|
|
24355
24355
|
const c0 = o.col(o.x0, (sh0[1] + ky0) / 2, 0);
|
|
24356
24356
|
col.push(c0.r, c0.g, c0.b);
|
|
24357
24357
|
}
|
|
24358
|
-
for (let r = 0; r <
|
|
24358
|
+
for (let r = 0; r < ring2 - 1; r++) idx.push(ci, r + 1, r);
|
|
24359
24359
|
let g = new THREE.BufferGeometry();
|
|
24360
24360
|
g.setAttribute("position", new THREE.Float32BufferAttribute(pos, 3));
|
|
24361
24361
|
if (o.col) g.setAttribute("color", new THREE.Float32BufferAttribute(col, 3));
|
|
@@ -24428,7 +24428,7 @@ var GameVehiclesThree = (() => {
|
|
|
24428
24428
|
function foilGeo(sts, o) {
|
|
24429
24429
|
o = o || {};
|
|
24430
24430
|
const n = o.n || 12, up = o.up || "y", pos = [], idx = [];
|
|
24431
|
-
let
|
|
24431
|
+
let ring2;
|
|
24432
24432
|
const cnt = 0;
|
|
24433
24433
|
function prof(st) {
|
|
24434
24434
|
const out = [], cam = st.cam || 0;
|
|
@@ -24448,14 +24448,14 @@ var GameVehiclesThree = (() => {
|
|
|
24448
24448
|
}
|
|
24449
24449
|
sts.forEach(function(st) {
|
|
24450
24450
|
const P = prof(st);
|
|
24451
|
-
|
|
24451
|
+
ring2 = P.length;
|
|
24452
24452
|
P.forEach(function(p) {
|
|
24453
24453
|
pos.push(p[0], p[1], p[2]);
|
|
24454
24454
|
});
|
|
24455
24455
|
});
|
|
24456
24456
|
for (let a = 0; a < sts.length - 1; a++)
|
|
24457
|
-
for (let k = 0; k <
|
|
24458
|
-
const k1 = (k + 1) %
|
|
24457
|
+
for (let k = 0; k < ring2; k++) {
|
|
24458
|
+
const k1 = (k + 1) % ring2, p0 = a * ring2 + k, p1 = (a + 1) * ring2 + k, q0 = a * ring2 + k1, q1 = (a + 1) * ring2 + k1;
|
|
24459
24459
|
idx.push(p0, q0, p1, q0, q1, p1);
|
|
24460
24460
|
}
|
|
24461
24461
|
;
|
|
@@ -24463,8 +24463,8 @@ var GameVehiclesThree = (() => {
|
|
|
24463
24463
|
if (sts[si].noCap) return;
|
|
24464
24464
|
const ci = pos.length / 3, st = sts[si];
|
|
24465
24465
|
pos.push(st.p[0] - st.c * 0.35, st.p[1], st.p[2]);
|
|
24466
|
-
for (let k = 0; k <
|
|
24467
|
-
const a0 = si *
|
|
24466
|
+
for (let k = 0; k < ring2; k++) {
|
|
24467
|
+
const a0 = si * ring2 + k, a1 = si * ring2 + (k + 1) % ring2;
|
|
24468
24468
|
if (e === 0) idx.push(ci, a1, a0);
|
|
24469
24469
|
else idx.push(ci, a0, a1);
|
|
24470
24470
|
}
|
|
@@ -24692,7 +24692,7 @@ var GameVehiclesThree = (() => {
|
|
|
24692
24692
|
blue: CM("#1d4f9a", { emissive: new THREE.Color("#3a7cff"), emissiveIntensity: 1.4, roughness: 0.3 })
|
|
24693
24693
|
};
|
|
24694
24694
|
const HALO = { red: "#ff3a2a", green: "#3aff7a", white: "#fff1d0", amber: "#ffb040", blue: "#4a8cff" };
|
|
24695
|
-
function navLight(c, x, y, z,
|
|
24695
|
+
function navLight(c, x, y, z, color2, label, o) {
|
|
24696
24696
|
o = o || {};
|
|
24697
24697
|
const r = o.r || 0.045, g = new THREE.Group();
|
|
24698
24698
|
g.position.set(x, y, z);
|
|
@@ -24702,11 +24702,11 @@ var GameVehiclesThree = (() => {
|
|
|
24702
24702
|
base.position.y = -r * 0.4;
|
|
24703
24703
|
if (o.rot) base.rotation.set(o.rot[0], o.rot[1], o.rot[2]);
|
|
24704
24704
|
g.add(base);
|
|
24705
|
-
const bulb = new THREE.Mesh(new THREE.SphereGeometry(r * 0.55, 10, 8), NAV[
|
|
24705
|
+
const bulb = new THREE.Mesh(new THREE.SphereGeometry(r * 0.55, 10, 8), NAV[color2] || NAV.white);
|
|
24706
24706
|
g.add(bulb);
|
|
24707
24707
|
const lens = new THREE.Mesh(
|
|
24708
24708
|
new THREE.SphereGeometry(r, 12, 8),
|
|
24709
|
-
|
|
24709
|
+
color2 === "red" ? MT.lensRed : color2 === "amber" ? MT.lensAmber : MT.lens
|
|
24710
24710
|
);
|
|
24711
24711
|
lens.renderOrder = 3;
|
|
24712
24712
|
g.add(lens);
|
|
@@ -24715,10 +24715,10 @@ var GameVehiclesThree = (() => {
|
|
|
24715
24715
|
inner: [bulb],
|
|
24716
24716
|
lens: [lens],
|
|
24717
24717
|
kind: o.front ? "headlight" : "taillight",
|
|
24718
|
-
tint:
|
|
24718
|
+
tint: color2 === "red" ? "red" : "clear",
|
|
24719
24719
|
broken: false
|
|
24720
24720
|
};
|
|
24721
|
-
if (o.halo !== false) L.halo = [kit.halo(g, 0, 0, 0, o.hs || 0.35, HALO[
|
|
24721
|
+
if (o.halo !== false) L.halo = [kit.halo(g, 0, 0, 0, o.hs || 0.35, HALO[color2] || "#ffffff", 0.5)];
|
|
24722
24722
|
c.lights.push(L);
|
|
24723
24723
|
const pt = c.part(o.front ? "headlight" : "taillight", label, g, new V3(x, y, z), o.reach || 0.5);
|
|
24724
24724
|
pt.light = L;
|
|
@@ -24840,15 +24840,15 @@ var GameVehiclesThree = (() => {
|
|
|
24840
24840
|
c.roundBox(0.16 * r, 0.03, 0.04, 0.012, MT.chrome, x, y + 0.04, z);
|
|
24841
24841
|
c.roundBox(0.04, 0.04, 0.03, 0.01, MT.chrome, x, y + 0.02, z);
|
|
24842
24842
|
}
|
|
24843
|
-
function skinOf2(c,
|
|
24843
|
+
function skinOf2(c, mesh2, keep, mat, o) {
|
|
24844
24844
|
o = o || {};
|
|
24845
|
-
const g =
|
|
24845
|
+
const g = mesh2.geometry.clone(), p = g.attributes.position, sz = o.sz || 1.006, dy = o.dy || 0;
|
|
24846
24846
|
for (let i = 0; i < p.count; i++) {
|
|
24847
24847
|
p.setZ(i, p.getZ(i) * sz);
|
|
24848
24848
|
p.setY(i, p.getY(i) + dy * Math.sign(p.getY(i)));
|
|
24849
24849
|
}
|
|
24850
24850
|
if (g.attributes.color) g.deleteAttribute("color");
|
|
24851
|
-
const m = c.add(g, mat,
|
|
24851
|
+
const m = c.add(g, mat, mesh2.position.x, mesh2.position.y, mesh2.position.z);
|
|
24852
24852
|
m.castShadow = false;
|
|
24853
24853
|
kit.cutMesh(m, [keep], 40, o.sub ? { sub: o.sub } : void 0);
|
|
24854
24854
|
c.deform.push(m);
|
|
@@ -27604,9 +27604,9 @@ var GameVehiclesThree = (() => {
|
|
|
27604
27604
|
for (const name of LITE_CLASSES) acc[name] = { P: [], N: [], C: [], U: [], I: [], nv: 0, alpha: name === "glass", uv: name === "plate", map: null };
|
|
27605
27605
|
return acc;
|
|
27606
27606
|
};
|
|
27607
|
-
function classify(mat,
|
|
27607
|
+
function classify(mat, mesh2, c) {
|
|
27608
27608
|
if (mat.map) {
|
|
27609
|
-
if (
|
|
27609
|
+
if (mesh2.userData.plate) return "plate";
|
|
27610
27610
|
if (mat.userData && mat.userData.grille || mat.name === "grille" || mat.metalness != null && mat.roughness != null && !mat.transparent) return "trim";
|
|
27611
27611
|
return null;
|
|
27612
27612
|
}
|
|
@@ -27752,11 +27752,11 @@ var GameVehiclesThree = (() => {
|
|
|
27752
27752
|
mt.map = A.map;
|
|
27753
27753
|
if (mt.map) mt.map.needsUpdate = true;
|
|
27754
27754
|
}
|
|
27755
|
-
const
|
|
27756
|
-
|
|
27757
|
-
|
|
27758
|
-
|
|
27759
|
-
meshes.push(
|
|
27755
|
+
const mesh2 = new THREE.Mesh(g, mt);
|
|
27756
|
+
mesh2.name = name;
|
|
27757
|
+
mesh2.castShadow = name !== "glass" && name !== "light";
|
|
27758
|
+
mesh2.receiveShadow = name !== "light";
|
|
27759
|
+
meshes.push(mesh2);
|
|
27760
27760
|
}
|
|
27761
27761
|
return meshes;
|
|
27762
27762
|
}
|
|
@@ -27805,7 +27805,7 @@ var GameVehiclesThree = (() => {
|
|
|
27805
27805
|
const spec = kit.find(key);
|
|
27806
27806
|
if (!spec) throw new Error(`createVehiclesThree: unknown vehicle "${key}"`);
|
|
27807
27807
|
const seed = o.seed == null ? null : o.seed;
|
|
27808
|
-
const
|
|
27808
|
+
const color2 = o.color || (seed != null ? colorFromSeed(seed, isMilitary(key) ? paintPalettes.military : paintPalettes.civil) : null);
|
|
27809
27809
|
const c = kit.build(key, o.state || "intact", void 0, { lod: quality === "lite" });
|
|
27810
27810
|
c.root.updateMatrixWorld(true);
|
|
27811
27811
|
const primary = primaryPaint(c);
|
|
@@ -27836,9 +27836,9 @@ var GameVehiclesThree = (() => {
|
|
|
27836
27836
|
c.vehicle.matrixAutoUpdate = true;
|
|
27837
27837
|
pivot.add(c.vehicle);
|
|
27838
27838
|
group.add(pivot);
|
|
27839
|
-
if (
|
|
27839
|
+
if (color2 && primary) {
|
|
27840
27840
|
const repainted = primary.clone();
|
|
27841
|
-
repainted.color.set(
|
|
27841
|
+
repainted.color.set(color2);
|
|
27842
27842
|
c.vehicle.traverse((m) => {
|
|
27843
27843
|
if (!m.isMesh) return;
|
|
27844
27844
|
if (Array.isArray(m.material)) m.material = m.material.map((x) => x === primary ? repainted : x);
|
|
@@ -27848,8 +27848,8 @@ var GameVehiclesThree = (() => {
|
|
|
27848
27848
|
markDamageables(c, damageables);
|
|
27849
27849
|
group.updateMatrixWorld(true);
|
|
27850
27850
|
} else {
|
|
27851
|
-
const fusion = fuse(THREE, c, pivotMatrix,
|
|
27852
|
-
for (const
|
|
27851
|
+
const fusion = fuse(THREE, c, pivotMatrix, color2 ? new THREE.Color(color2) : null, primary, kit.lodHiddenMaterials());
|
|
27852
|
+
for (const mesh2 of liteMeshes(THREE, fusion, liteMaterials(THREE, kit.studioEnvironment()))) group.add(mesh2);
|
|
27853
27853
|
pruned = fusion.pruned;
|
|
27854
27854
|
}
|
|
27855
27855
|
const size = new THREE.Box3().setFromObject(group).getSize(new THREE.Vector3());
|
|
@@ -27860,7 +27860,7 @@ var GameVehiclesThree = (() => {
|
|
|
27860
27860
|
return {
|
|
27861
27861
|
key,
|
|
27862
27862
|
quality,
|
|
27863
|
-
color,
|
|
27863
|
+
color: color2,
|
|
27864
27864
|
seed,
|
|
27865
27865
|
group,
|
|
27866
27866
|
damageables,
|
|
@@ -27895,6 +27895,1594 @@ var GameVehiclesThree = (() => {
|
|
|
27895
27895
|
}
|
|
27896
27896
|
}
|
|
27897
27897
|
|
|
27898
|
+
// ../game-shapes/dist/chunk-R4RY23RH.js
|
|
27899
|
+
function canonicalJson(value) {
|
|
27900
|
+
if (value === null) return "null";
|
|
27901
|
+
if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
|
|
27902
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
27903
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
27904
|
+
if (typeof value === "function") throw new Error("game-shapes: a function cannot be part of a shape (register it as a generator)");
|
|
27905
|
+
if (ArrayBuffer.isView(value)) return canonicalJson(Array.from(value));
|
|
27906
|
+
if (Array.isArray(value)) return `[${value.map((item) => item === void 0 ? "null" : canonicalJson(item)).join(",")}]`;
|
|
27907
|
+
if (typeof value === "object") {
|
|
27908
|
+
const record = value;
|
|
27909
|
+
const keys = Object.keys(record).filter((key) => record[key] !== void 0).sort();
|
|
27910
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
|
|
27911
|
+
}
|
|
27912
|
+
return "null";
|
|
27913
|
+
}
|
|
27914
|
+
function needsUint32(array) {
|
|
27915
|
+
for (let i = array.length - 1; i >= 0; --i) if (array[i] >= 65535) return true;
|
|
27916
|
+
return false;
|
|
27917
|
+
}
|
|
27918
|
+
var indexArray = (indices) => needsUint32(indices) ? new Uint32Array(indices) : new Uint16Array(indices);
|
|
27919
|
+
function pack(type, parameters, a) {
|
|
27920
|
+
return {
|
|
27921
|
+
type,
|
|
27922
|
+
parameters,
|
|
27923
|
+
positions: new Float32Array(a.vertices),
|
|
27924
|
+
normals: new Float32Array(a.normals),
|
|
27925
|
+
uvs: new Float32Array(a.uvs),
|
|
27926
|
+
...a.indices ? { indices: indexArray(a.indices) } : {},
|
|
27927
|
+
groups: a.groups
|
|
27928
|
+
};
|
|
27929
|
+
}
|
|
27930
|
+
var normalize3 = (x, y, z) => {
|
|
27931
|
+
const length = Math.sqrt(x * x + y * y + z * z);
|
|
27932
|
+
const s = 1 / (length || 1);
|
|
27933
|
+
return [x * s, y * s, z * s];
|
|
27934
|
+
};
|
|
27935
|
+
function box(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) {
|
|
27936
|
+
const parameters = { width, height, depth, widthSegments, heightSegments, depthSegments };
|
|
27937
|
+
widthSegments = Math.floor(widthSegments);
|
|
27938
|
+
heightSegments = Math.floor(heightSegments);
|
|
27939
|
+
depthSegments = Math.floor(depthSegments);
|
|
27940
|
+
const indices = [];
|
|
27941
|
+
const vertices = [];
|
|
27942
|
+
const normals = [];
|
|
27943
|
+
const uvs = [];
|
|
27944
|
+
const groups = [];
|
|
27945
|
+
let numberOfVertices = 0;
|
|
27946
|
+
let groupStart = 0;
|
|
27947
|
+
const buildPlane = (u, v, w, udir, vdir, width2, height2, depth2, gridX, gridY, materialIndex) => {
|
|
27948
|
+
const segmentWidth = width2 / gridX;
|
|
27949
|
+
const segmentHeight = height2 / gridY;
|
|
27950
|
+
const widthHalf = width2 / 2;
|
|
27951
|
+
const heightHalf = height2 / 2;
|
|
27952
|
+
const depthHalf = depth2 / 2;
|
|
27953
|
+
const gridX1 = gridX + 1;
|
|
27954
|
+
const gridY1 = gridY + 1;
|
|
27955
|
+
let vertexCounter = 0;
|
|
27956
|
+
let groupCount = 0;
|
|
27957
|
+
const vector = { x: 0, y: 0, z: 0 };
|
|
27958
|
+
for (let iy = 0; iy < gridY1; iy++) {
|
|
27959
|
+
const y = iy * segmentHeight - heightHalf;
|
|
27960
|
+
for (let ix = 0; ix < gridX1; ix++) {
|
|
27961
|
+
const x = ix * segmentWidth - widthHalf;
|
|
27962
|
+
vector[u] = x * udir;
|
|
27963
|
+
vector[v] = y * vdir;
|
|
27964
|
+
vector[w] = depthHalf;
|
|
27965
|
+
vertices.push(vector.x, vector.y, vector.z);
|
|
27966
|
+
vector[u] = 0;
|
|
27967
|
+
vector[v] = 0;
|
|
27968
|
+
vector[w] = depth2 > 0 ? 1 : -1;
|
|
27969
|
+
normals.push(vector.x, vector.y, vector.z);
|
|
27970
|
+
uvs.push(ix / gridX);
|
|
27971
|
+
uvs.push(1 - iy / gridY);
|
|
27972
|
+
vertexCounter += 1;
|
|
27973
|
+
}
|
|
27974
|
+
}
|
|
27975
|
+
for (let iy = 0; iy < gridY; iy++) {
|
|
27976
|
+
for (let ix = 0; ix < gridX; ix++) {
|
|
27977
|
+
const a = numberOfVertices + ix + gridX1 * iy;
|
|
27978
|
+
const b = numberOfVertices + ix + gridX1 * (iy + 1);
|
|
27979
|
+
const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1);
|
|
27980
|
+
const d = numberOfVertices + (ix + 1) + gridX1 * iy;
|
|
27981
|
+
indices.push(a, b, d);
|
|
27982
|
+
indices.push(b, c, d);
|
|
27983
|
+
groupCount += 6;
|
|
27984
|
+
}
|
|
27985
|
+
}
|
|
27986
|
+
groups.push({ start: groupStart, count: groupCount, materialIndex });
|
|
27987
|
+
groupStart += groupCount;
|
|
27988
|
+
numberOfVertices += vertexCounter;
|
|
27989
|
+
};
|
|
27990
|
+
buildPlane("z", "y", "x", -1, -1, depth, height, width, depthSegments, heightSegments, 0);
|
|
27991
|
+
buildPlane("z", "y", "x", 1, -1, depth, height, -width, depthSegments, heightSegments, 1);
|
|
27992
|
+
buildPlane("x", "z", "y", 1, 1, width, depth, height, widthSegments, depthSegments, 2);
|
|
27993
|
+
buildPlane("x", "z", "y", 1, -1, width, depth, -height, widthSegments, depthSegments, 3);
|
|
27994
|
+
buildPlane("x", "y", "z", 1, -1, width, height, depth, widthSegments, heightSegments, 4);
|
|
27995
|
+
buildPlane("x", "y", "z", -1, -1, width, height, -depth, widthSegments, heightSegments, 5);
|
|
27996
|
+
return pack("BoxGeometry", parameters, { vertices, normals, uvs, indices, groups });
|
|
27997
|
+
}
|
|
27998
|
+
function cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) {
|
|
27999
|
+
radialSegments = Math.floor(radialSegments);
|
|
28000
|
+
heightSegments = Math.floor(heightSegments);
|
|
28001
|
+
const indices = [];
|
|
28002
|
+
const vertices = [];
|
|
28003
|
+
const normals = [];
|
|
28004
|
+
const uvs = [];
|
|
28005
|
+
const groups = [];
|
|
28006
|
+
let index = 0;
|
|
28007
|
+
const indexArray2 = [];
|
|
28008
|
+
const halfHeight = height / 2;
|
|
28009
|
+
let groupStart = 0;
|
|
28010
|
+
const generateTorso = () => {
|
|
28011
|
+
let groupCount = 0;
|
|
28012
|
+
const slope = (radiusBottom - radiusTop) / height;
|
|
28013
|
+
for (let y = 0; y <= heightSegments; y++) {
|
|
28014
|
+
const indexRow = [];
|
|
28015
|
+
const v = y / heightSegments;
|
|
28016
|
+
const radius = v * (radiusBottom - radiusTop) + radiusTop;
|
|
28017
|
+
for (let x = 0; x <= radialSegments; x++) {
|
|
28018
|
+
const u = x / radialSegments;
|
|
28019
|
+
const theta = u * thetaLength + thetaStart;
|
|
28020
|
+
const sinTheta = Math.sin(theta);
|
|
28021
|
+
const cosTheta = Math.cos(theta);
|
|
28022
|
+
vertices.push(radius * sinTheta, -v * height + halfHeight, radius * cosTheta);
|
|
28023
|
+
const n = normalize3(sinTheta, slope, cosTheta);
|
|
28024
|
+
normals.push(n[0], n[1], n[2]);
|
|
28025
|
+
uvs.push(u, 1 - v);
|
|
28026
|
+
indexRow.push(index++);
|
|
28027
|
+
}
|
|
28028
|
+
indexArray2.push(indexRow);
|
|
28029
|
+
}
|
|
28030
|
+
for (let x = 0; x < radialSegments; x++) {
|
|
28031
|
+
for (let y = 0; y < heightSegments; y++) {
|
|
28032
|
+
const a = indexArray2[y][x];
|
|
28033
|
+
const b = indexArray2[y + 1][x];
|
|
28034
|
+
const c = indexArray2[y + 1][x + 1];
|
|
28035
|
+
const d = indexArray2[y][x + 1];
|
|
28036
|
+
indices.push(a, b, d);
|
|
28037
|
+
indices.push(b, c, d);
|
|
28038
|
+
groupCount += 6;
|
|
28039
|
+
}
|
|
28040
|
+
}
|
|
28041
|
+
groups.push({ start: groupStart, count: groupCount, materialIndex: 0 });
|
|
28042
|
+
groupStart += groupCount;
|
|
28043
|
+
};
|
|
28044
|
+
const generateCap = (top) => {
|
|
28045
|
+
const centerIndexStart = index;
|
|
28046
|
+
let groupCount = 0;
|
|
28047
|
+
const radius = top === true ? radiusTop : radiusBottom;
|
|
28048
|
+
const sign2 = top === true ? 1 : -1;
|
|
28049
|
+
for (let x = 1; x <= radialSegments; x++) {
|
|
28050
|
+
vertices.push(0, halfHeight * sign2, 0);
|
|
28051
|
+
normals.push(0, sign2, 0);
|
|
28052
|
+
uvs.push(0.5, 0.5);
|
|
28053
|
+
index++;
|
|
28054
|
+
}
|
|
28055
|
+
const centerIndexEnd = index;
|
|
28056
|
+
for (let x = 0; x <= radialSegments; x++) {
|
|
28057
|
+
const u = x / radialSegments;
|
|
28058
|
+
const theta = u * thetaLength + thetaStart;
|
|
28059
|
+
const cosTheta = Math.cos(theta);
|
|
28060
|
+
const sinTheta = Math.sin(theta);
|
|
28061
|
+
vertices.push(radius * sinTheta, halfHeight * sign2, radius * cosTheta);
|
|
28062
|
+
normals.push(0, sign2, 0);
|
|
28063
|
+
uvs.push(cosTheta * 0.5 + 0.5, sinTheta * 0.5 * sign2 + 0.5);
|
|
28064
|
+
index++;
|
|
28065
|
+
}
|
|
28066
|
+
for (let x = 0; x < radialSegments; x++) {
|
|
28067
|
+
const c = centerIndexStart + x;
|
|
28068
|
+
const i = centerIndexEnd + x;
|
|
28069
|
+
if (top === true) indices.push(i, i + 1, c);
|
|
28070
|
+
else indices.push(i + 1, i, c);
|
|
28071
|
+
groupCount += 3;
|
|
28072
|
+
}
|
|
28073
|
+
groups.push({ start: groupStart, count: groupCount, materialIndex: top === true ? 1 : 2 });
|
|
28074
|
+
groupStart += groupCount;
|
|
28075
|
+
};
|
|
28076
|
+
generateTorso();
|
|
28077
|
+
if (openEnded === false) {
|
|
28078
|
+
if (radiusTop > 0) generateCap(true);
|
|
28079
|
+
if (radiusBottom > 0) generateCap(false);
|
|
28080
|
+
}
|
|
28081
|
+
return { vertices, normals, uvs, indices, groups };
|
|
28082
|
+
}
|
|
28083
|
+
function cylinder(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
28084
|
+
const parameters = { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength };
|
|
28085
|
+
return pack("CylinderGeometry", parameters, cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength));
|
|
28086
|
+
}
|
|
28087
|
+
function cone(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
28088
|
+
const parameters = { radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength };
|
|
28089
|
+
return pack("ConeGeometry", parameters, cylinderArrays(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength));
|
|
28090
|
+
}
|
|
28091
|
+
function sphere(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) {
|
|
28092
|
+
const parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength };
|
|
28093
|
+
widthSegments = Math.max(3, Math.floor(widthSegments));
|
|
28094
|
+
heightSegments = Math.max(2, Math.floor(heightSegments));
|
|
28095
|
+
const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
|
|
28096
|
+
let index = 0;
|
|
28097
|
+
const grid = [];
|
|
28098
|
+
const indices = [];
|
|
28099
|
+
const vertices = [];
|
|
28100
|
+
const normals = [];
|
|
28101
|
+
const uvs = [];
|
|
28102
|
+
for (let iy = 0; iy <= heightSegments; iy++) {
|
|
28103
|
+
const verticesRow = [];
|
|
28104
|
+
const v = iy / heightSegments;
|
|
28105
|
+
let uOffset = 0;
|
|
28106
|
+
if (iy === 0 && thetaStart === 0) uOffset = 0.5 / widthSegments;
|
|
28107
|
+
else if (iy === heightSegments && thetaEnd === Math.PI) uOffset = -0.5 / widthSegments;
|
|
28108
|
+
for (let ix = 0; ix <= widthSegments; ix++) {
|
|
28109
|
+
const u = ix / widthSegments;
|
|
28110
|
+
const x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
|
|
28111
|
+
const y = radius * Math.cos(thetaStart + v * thetaLength);
|
|
28112
|
+
const z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
|
|
28113
|
+
vertices.push(x, y, z);
|
|
28114
|
+
const n = normalize3(x, y, z);
|
|
28115
|
+
normals.push(n[0], n[1], n[2]);
|
|
28116
|
+
uvs.push(u + uOffset, 1 - v);
|
|
28117
|
+
verticesRow.push(index++);
|
|
28118
|
+
}
|
|
28119
|
+
grid.push(verticesRow);
|
|
28120
|
+
}
|
|
28121
|
+
for (let iy = 0; iy < heightSegments; iy++) {
|
|
28122
|
+
for (let ix = 0; ix < widthSegments; ix++) {
|
|
28123
|
+
const a = grid[iy][ix + 1];
|
|
28124
|
+
const b = grid[iy][ix];
|
|
28125
|
+
const c = grid[iy + 1][ix];
|
|
28126
|
+
const d = grid[iy + 1][ix + 1];
|
|
28127
|
+
if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
|
|
28128
|
+
if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
|
|
28129
|
+
}
|
|
28130
|
+
}
|
|
28131
|
+
return pack("SphereGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28132
|
+
}
|
|
28133
|
+
function plane(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
|
|
28134
|
+
const parameters = { width, height, widthSegments, heightSegments };
|
|
28135
|
+
const widthHalf = width / 2;
|
|
28136
|
+
const heightHalf = height / 2;
|
|
28137
|
+
const gridX = Math.floor(widthSegments);
|
|
28138
|
+
const gridY = Math.floor(heightSegments);
|
|
28139
|
+
const gridX1 = gridX + 1;
|
|
28140
|
+
const gridY1 = gridY + 1;
|
|
28141
|
+
const segmentWidth = width / gridX;
|
|
28142
|
+
const segmentHeight = height / gridY;
|
|
28143
|
+
const indices = [];
|
|
28144
|
+
const vertices = [];
|
|
28145
|
+
const normals = [];
|
|
28146
|
+
const uvs = [];
|
|
28147
|
+
for (let iy = 0; iy < gridY1; iy++) {
|
|
28148
|
+
const y = iy * segmentHeight - heightHalf;
|
|
28149
|
+
for (let ix = 0; ix < gridX1; ix++) {
|
|
28150
|
+
const x = ix * segmentWidth - widthHalf;
|
|
28151
|
+
vertices.push(x, -y, 0);
|
|
28152
|
+
normals.push(0, 0, 1);
|
|
28153
|
+
uvs.push(ix / gridX);
|
|
28154
|
+
uvs.push(1 - iy / gridY);
|
|
28155
|
+
}
|
|
28156
|
+
}
|
|
28157
|
+
for (let iy = 0; iy < gridY; iy++) {
|
|
28158
|
+
for (let ix = 0; ix < gridX; ix++) {
|
|
28159
|
+
const a = ix + gridX1 * iy;
|
|
28160
|
+
const b = ix + gridX1 * (iy + 1);
|
|
28161
|
+
const c = ix + 1 + gridX1 * (iy + 1);
|
|
28162
|
+
const d = ix + 1 + gridX1 * iy;
|
|
28163
|
+
indices.push(a, b, d);
|
|
28164
|
+
indices.push(b, c, d);
|
|
28165
|
+
}
|
|
28166
|
+
}
|
|
28167
|
+
return pack("PlaneGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28168
|
+
}
|
|
28169
|
+
function circle(radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
28170
|
+
const parameters = { radius, segments, thetaStart, thetaLength };
|
|
28171
|
+
segments = Math.max(3, segments);
|
|
28172
|
+
const indices = [];
|
|
28173
|
+
const vertices = [];
|
|
28174
|
+
const normals = [];
|
|
28175
|
+
const uvs = [];
|
|
28176
|
+
vertices.push(0, 0, 0);
|
|
28177
|
+
normals.push(0, 0, 1);
|
|
28178
|
+
uvs.push(0.5, 0.5);
|
|
28179
|
+
for (let s = 0, i = 3; s <= segments; s++, i += 3) {
|
|
28180
|
+
const segment = thetaStart + s / segments * thetaLength;
|
|
28181
|
+
vertices.push(radius * Math.cos(segment), radius * Math.sin(segment), 0);
|
|
28182
|
+
normals.push(0, 0, 1);
|
|
28183
|
+
uvs.push((vertices[i] / radius + 1) / 2, (vertices[i + 1] / radius + 1) / 2);
|
|
28184
|
+
}
|
|
28185
|
+
for (let i = 1; i <= segments; i++) indices.push(i, i + 1, 0);
|
|
28186
|
+
return pack("CircleGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28187
|
+
}
|
|
28188
|
+
function ring(innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
28189
|
+
const parameters = { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength };
|
|
28190
|
+
thetaSegments = Math.max(3, thetaSegments);
|
|
28191
|
+
phiSegments = Math.max(1, phiSegments);
|
|
28192
|
+
const indices = [];
|
|
28193
|
+
const vertices = [];
|
|
28194
|
+
const normals = [];
|
|
28195
|
+
const uvs = [];
|
|
28196
|
+
let radius = innerRadius;
|
|
28197
|
+
const radiusStep = (outerRadius - innerRadius) / phiSegments;
|
|
28198
|
+
for (let j = 0; j <= phiSegments; j++) {
|
|
28199
|
+
for (let i = 0; i <= thetaSegments; i++) {
|
|
28200
|
+
const segment = thetaStart + i / thetaSegments * thetaLength;
|
|
28201
|
+
const x = radius * Math.cos(segment);
|
|
28202
|
+
const y = radius * Math.sin(segment);
|
|
28203
|
+
vertices.push(x, y, 0);
|
|
28204
|
+
normals.push(0, 0, 1);
|
|
28205
|
+
uvs.push((x / outerRadius + 1) / 2, (y / outerRadius + 1) / 2);
|
|
28206
|
+
}
|
|
28207
|
+
radius += radiusStep;
|
|
28208
|
+
}
|
|
28209
|
+
for (let j = 0; j < phiSegments; j++) {
|
|
28210
|
+
const thetaSegmentLevel = j * (thetaSegments + 1);
|
|
28211
|
+
for (let i = 0; i < thetaSegments; i++) {
|
|
28212
|
+
const segment = i + thetaSegmentLevel;
|
|
28213
|
+
const a = segment;
|
|
28214
|
+
const b = segment + thetaSegments + 1;
|
|
28215
|
+
const c = segment + thetaSegments + 2;
|
|
28216
|
+
const d = segment + 1;
|
|
28217
|
+
indices.push(a, b, d);
|
|
28218
|
+
indices.push(b, c, d);
|
|
28219
|
+
}
|
|
28220
|
+
}
|
|
28221
|
+
return pack("RingGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28222
|
+
}
|
|
28223
|
+
function lathe(points, segments = 12, phiStart = 0, phiLength = Math.PI * 2) {
|
|
28224
|
+
const parameters = { points: points.map(([x, y]) => ({ x, y })), segments, phiStart, phiLength };
|
|
28225
|
+
segments = Math.floor(segments);
|
|
28226
|
+
phiLength = Math.max(0, Math.min(Math.PI * 2, phiLength));
|
|
28227
|
+
const indices = [];
|
|
28228
|
+
const vertices = [];
|
|
28229
|
+
const uvs = [];
|
|
28230
|
+
const initNormals = [];
|
|
28231
|
+
const normals = [];
|
|
28232
|
+
const inverseSegments = 1 / segments;
|
|
28233
|
+
const normal = { x: 0, y: 0, z: 0 };
|
|
28234
|
+
const curNormal = { x: 0, y: 0, z: 0 };
|
|
28235
|
+
const prevNormal = { x: 0, y: 0, z: 0 };
|
|
28236
|
+
let dx = 0;
|
|
28237
|
+
let dy = 0;
|
|
28238
|
+
const last = points.length - 1;
|
|
28239
|
+
const px = (j) => points[j][0];
|
|
28240
|
+
const py = (j) => points[j][1];
|
|
28241
|
+
const setNormalized = () => {
|
|
28242
|
+
const n = normalize3(normal.x, normal.y, normal.z);
|
|
28243
|
+
normal.x = n[0];
|
|
28244
|
+
normal.y = n[1];
|
|
28245
|
+
normal.z = n[2];
|
|
28246
|
+
};
|
|
28247
|
+
for (let j = 0; j <= last; j++) {
|
|
28248
|
+
if (j === 0) {
|
|
28249
|
+
dx = px(j + 1) - px(j);
|
|
28250
|
+
dy = py(j + 1) - py(j);
|
|
28251
|
+
normal.x = dy * 1;
|
|
28252
|
+
normal.y = -dx;
|
|
28253
|
+
normal.z = dy * 0;
|
|
28254
|
+
prevNormal.x = normal.x;
|
|
28255
|
+
prevNormal.y = normal.y;
|
|
28256
|
+
prevNormal.z = normal.z;
|
|
28257
|
+
setNormalized();
|
|
28258
|
+
initNormals.push(normal.x, normal.y, normal.z);
|
|
28259
|
+
} else if (j === last) {
|
|
28260
|
+
initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z);
|
|
28261
|
+
} else {
|
|
28262
|
+
dx = px(j + 1) - px(j);
|
|
28263
|
+
dy = py(j + 1) - py(j);
|
|
28264
|
+
normal.x = dy * 1;
|
|
28265
|
+
normal.y = -dx;
|
|
28266
|
+
normal.z = dy * 0;
|
|
28267
|
+
curNormal.x = normal.x;
|
|
28268
|
+
curNormal.y = normal.y;
|
|
28269
|
+
curNormal.z = normal.z;
|
|
28270
|
+
normal.x += prevNormal.x;
|
|
28271
|
+
normal.y += prevNormal.y;
|
|
28272
|
+
normal.z += prevNormal.z;
|
|
28273
|
+
setNormalized();
|
|
28274
|
+
initNormals.push(normal.x, normal.y, normal.z);
|
|
28275
|
+
prevNormal.x = curNormal.x;
|
|
28276
|
+
prevNormal.y = curNormal.y;
|
|
28277
|
+
prevNormal.z = curNormal.z;
|
|
28278
|
+
}
|
|
28279
|
+
}
|
|
28280
|
+
for (let i = 0; i <= segments; i++) {
|
|
28281
|
+
const phi = phiStart + i * inverseSegments * phiLength;
|
|
28282
|
+
const sin = Math.sin(phi);
|
|
28283
|
+
const cos = Math.cos(phi);
|
|
28284
|
+
for (let j = 0; j <= last; j++) {
|
|
28285
|
+
vertices.push(px(j) * sin, py(j), px(j) * cos);
|
|
28286
|
+
uvs.push(i / segments, j / (points.length - 1));
|
|
28287
|
+
const x = initNormals[3 * j + 0] * sin;
|
|
28288
|
+
const y = initNormals[3 * j + 1];
|
|
28289
|
+
const z = initNormals[3 * j + 0] * cos;
|
|
28290
|
+
normals.push(x, y, z);
|
|
28291
|
+
}
|
|
28292
|
+
}
|
|
28293
|
+
for (let i = 0; i < segments; i++) {
|
|
28294
|
+
for (let j = 0; j < points.length - 1; j++) {
|
|
28295
|
+
const base = j + i * points.length;
|
|
28296
|
+
const a = base;
|
|
28297
|
+
const b = base + points.length;
|
|
28298
|
+
const c = base + points.length + 1;
|
|
28299
|
+
const d = base + 1;
|
|
28300
|
+
indices.push(a, b, d);
|
|
28301
|
+
indices.push(c, d, b);
|
|
28302
|
+
}
|
|
28303
|
+
}
|
|
28304
|
+
return pack("LatheGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28305
|
+
}
|
|
28306
|
+
function torus(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2) {
|
|
28307
|
+
const parameters = { radius, tube, radialSegments, tubularSegments, arc };
|
|
28308
|
+
radialSegments = Math.floor(radialSegments);
|
|
28309
|
+
tubularSegments = Math.floor(tubularSegments);
|
|
28310
|
+
const indices = [];
|
|
28311
|
+
const vertices = [];
|
|
28312
|
+
const normals = [];
|
|
28313
|
+
const uvs = [];
|
|
28314
|
+
for (let j = 0; j <= radialSegments; j++) {
|
|
28315
|
+
for (let i = 0; i <= tubularSegments; i++) {
|
|
28316
|
+
const u = i / tubularSegments * arc;
|
|
28317
|
+
const v = j / radialSegments * Math.PI * 2;
|
|
28318
|
+
const x = (radius + tube * Math.cos(v)) * Math.cos(u);
|
|
28319
|
+
const y = (radius + tube * Math.cos(v)) * Math.sin(u);
|
|
28320
|
+
const z = tube * Math.sin(v);
|
|
28321
|
+
vertices.push(x, y, z);
|
|
28322
|
+
const cx = radius * Math.cos(u);
|
|
28323
|
+
const cy = radius * Math.sin(u);
|
|
28324
|
+
const n = normalize3(x - cx, y - cy, z - 0);
|
|
28325
|
+
normals.push(n[0], n[1], n[2]);
|
|
28326
|
+
uvs.push(i / tubularSegments);
|
|
28327
|
+
uvs.push(j / radialSegments);
|
|
28328
|
+
}
|
|
28329
|
+
}
|
|
28330
|
+
for (let j = 1; j <= radialSegments; j++) {
|
|
28331
|
+
for (let i = 1; i <= tubularSegments; i++) {
|
|
28332
|
+
const a = (tubularSegments + 1) * j + i - 1;
|
|
28333
|
+
const b = (tubularSegments + 1) * (j - 1) + i - 1;
|
|
28334
|
+
const c = (tubularSegments + 1) * (j - 1) + i;
|
|
28335
|
+
const d = (tubularSegments + 1) * j + i;
|
|
28336
|
+
indices.push(a, b, d);
|
|
28337
|
+
indices.push(b, c, d);
|
|
28338
|
+
}
|
|
28339
|
+
}
|
|
28340
|
+
return pack("TorusGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
|
|
28341
|
+
}
|
|
28342
|
+
function difference(size, subtract) {
|
|
28343
|
+
const [w, h, d] = size;
|
|
28344
|
+
const hw = w / 2;
|
|
28345
|
+
const hh = h / 2;
|
|
28346
|
+
const hd = d / 2;
|
|
28347
|
+
const holes = subtract.map((hole) => ({ x0: Math.max(-hw, Math.min(hole.min[0], hole.max[0])), x1: Math.min(hw, Math.max(hole.min[0], hole.max[0])), y0: Math.max(-hh, Math.min(hole.min[1], hole.max[1])), y1: Math.min(hh, Math.max(hole.min[1], hole.max[1])) })).filter((hole) => hole.x1 > hole.x0 && hole.y1 > hole.y0);
|
|
28348
|
+
const cuts = (lo, hi, values) => [.../* @__PURE__ */ new Set([lo, hi, ...values.filter((v) => v > lo && v < hi)])].sort((a, b) => a - b);
|
|
28349
|
+
const xs = cuts(-hw, hw, holes.flatMap((hole) => [hole.x0, hole.x1]));
|
|
28350
|
+
const ys = cuts(-hh, hh, holes.flatMap((hole) => [hole.y0, hole.y1]));
|
|
28351
|
+
const nx = xs.length - 1;
|
|
28352
|
+
const ny = ys.length - 1;
|
|
28353
|
+
const solid = (i, j) => {
|
|
28354
|
+
if (i < 0 || j < 0 || i >= nx || j >= ny) return false;
|
|
28355
|
+
const cx = (xs[i] + xs[i + 1]) / 2;
|
|
28356
|
+
const cy = (ys[j] + ys[j + 1]) / 2;
|
|
28357
|
+
return !holes.some((hole) => cx > hole.x0 && cx < hole.x1 && cy > hole.y0 && cy < hole.y1);
|
|
28358
|
+
};
|
|
28359
|
+
const positions = [];
|
|
28360
|
+
const normals = [];
|
|
28361
|
+
const uvs = [];
|
|
28362
|
+
const indices = [];
|
|
28363
|
+
const quad = (corners, normal, uv) => {
|
|
28364
|
+
const base = positions.length / 3;
|
|
28365
|
+
for (let k = 0; k < 4; k++) {
|
|
28366
|
+
positions.push(...corners[k]);
|
|
28367
|
+
normals.push(...normal);
|
|
28368
|
+
uvs.push(...uv[k]);
|
|
28369
|
+
}
|
|
28370
|
+
indices.push(base, base + 1, base + 2, base, base + 2, base + 3);
|
|
28371
|
+
};
|
|
28372
|
+
const fu = (x) => (x + hw) / w;
|
|
28373
|
+
const fv = (y) => (y + hh) / h;
|
|
28374
|
+
for (let j = 0; j < ny; j++) {
|
|
28375
|
+
for (let i = 0; i < nx; i++) {
|
|
28376
|
+
if (!solid(i, j)) continue;
|
|
28377
|
+
const x0 = xs[i];
|
|
28378
|
+
const x1 = xs[i + 1];
|
|
28379
|
+
const y0 = ys[j];
|
|
28380
|
+
const y1 = ys[j + 1];
|
|
28381
|
+
quad([[x0, y0, hd], [x1, y0, hd], [x1, y1, hd], [x0, y1, hd]], [0, 0, 1], [[fu(x0), fv(y0)], [fu(x1), fv(y0)], [fu(x1), fv(y1)], [fu(x0), fv(y1)]]);
|
|
28382
|
+
quad([[x1, y0, -hd], [x0, y0, -hd], [x0, y1, -hd], [x1, y1, -hd]], [0, 0, -1], [[1 - fu(x1), fv(y0)], [1 - fu(x0), fv(y0)], [1 - fu(x0), fv(y1)], [1 - fu(x1), fv(y1)]]);
|
|
28383
|
+
const zu = (z) => (z + hd) / d;
|
|
28384
|
+
if (!solid(i - 1, j)) quad([[x0, y0, -hd], [x0, y0, hd], [x0, y1, hd], [x0, y1, -hd]], [-1, 0, 0], [[zu(-hd), fv(y0)], [zu(hd), fv(y0)], [zu(hd), fv(y1)], [zu(-hd), fv(y1)]]);
|
|
28385
|
+
if (!solid(i + 1, j)) quad([[x1, y0, hd], [x1, y0, -hd], [x1, y1, -hd], [x1, y1, hd]], [1, 0, 0], [[zu(hd), fv(y0)], [zu(-hd), fv(y0)], [zu(-hd), fv(y1)], [zu(hd), fv(y1)]]);
|
|
28386
|
+
if (!solid(i, j - 1)) quad([[x0, y0, -hd], [x1, y0, -hd], [x1, y0, hd], [x0, y0, hd]], [0, -1, 0], [[fu(x0), zu(-hd)], [fu(x1), zu(-hd)], [fu(x1), zu(hd)], [fu(x0), zu(hd)]]);
|
|
28387
|
+
if (!solid(i, j + 1)) quad([[x0, y1, hd], [x1, y1, hd], [x1, y1, -hd], [x0, y1, -hd]], [0, 1, 0], [[fu(x0), zu(hd)], [fu(x1), zu(hd)], [fu(x1), zu(-hd)], [fu(x0), zu(-hd)]]);
|
|
28388
|
+
}
|
|
28389
|
+
}
|
|
28390
|
+
return {
|
|
28391
|
+
type: "BufferGeometry",
|
|
28392
|
+
parameters: { size: [w, h, d], subtract: holes.map((hole) => ({ min: [hole.x0, hole.y0], max: [hole.x1, hole.y1] })) },
|
|
28393
|
+
positions: new Float32Array(positions),
|
|
28394
|
+
normals: new Float32Array(normals),
|
|
28395
|
+
uvs: new Float32Array(uvs),
|
|
28396
|
+
indices: indexArray(indices),
|
|
28397
|
+
groups: []
|
|
28398
|
+
};
|
|
28399
|
+
}
|
|
28400
|
+
var Earcut = {
|
|
28401
|
+
triangulate: function(data, holeIndices, dim = 2) {
|
|
28402
|
+
const hasHoles = holeIndices && holeIndices.length;
|
|
28403
|
+
const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
|
|
28404
|
+
let outerNode = linkedList(data, 0, outerLen, dim, true);
|
|
28405
|
+
const triangles = [];
|
|
28406
|
+
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
|
|
28407
|
+
let minX, minY, maxX, maxY, x, y, invSize;
|
|
28408
|
+
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
|
|
28409
|
+
if (data.length > 80 * dim) {
|
|
28410
|
+
minX = maxX = data[0];
|
|
28411
|
+
minY = maxY = data[1];
|
|
28412
|
+
for (let i = dim; i < outerLen; i += dim) {
|
|
28413
|
+
x = data[i];
|
|
28414
|
+
y = data[i + 1];
|
|
28415
|
+
if (x < minX) minX = x;
|
|
28416
|
+
if (y < minY) minY = y;
|
|
28417
|
+
if (x > maxX) maxX = x;
|
|
28418
|
+
if (y > maxY) maxY = y;
|
|
28419
|
+
}
|
|
28420
|
+
invSize = Math.max(maxX - minX, maxY - minY);
|
|
28421
|
+
invSize = invSize !== 0 ? 32767 / invSize : 0;
|
|
28422
|
+
}
|
|
28423
|
+
earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
|
|
28424
|
+
return triangles;
|
|
28425
|
+
}
|
|
28426
|
+
};
|
|
28427
|
+
function linkedList(data, start, end, dim, clockwise) {
|
|
28428
|
+
let i, last;
|
|
28429
|
+
if (clockwise === signedArea(data, start, end, dim) > 0) {
|
|
28430
|
+
for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
|
|
28431
|
+
} else {
|
|
28432
|
+
for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
|
|
28433
|
+
}
|
|
28434
|
+
if (last && equals(last, last.next)) {
|
|
28435
|
+
removeNode(last);
|
|
28436
|
+
last = last.next;
|
|
28437
|
+
}
|
|
28438
|
+
return last;
|
|
28439
|
+
}
|
|
28440
|
+
function filterPoints(start, end) {
|
|
28441
|
+
if (!start) return start;
|
|
28442
|
+
if (!end) end = start;
|
|
28443
|
+
let p = start, again;
|
|
28444
|
+
do {
|
|
28445
|
+
again = false;
|
|
28446
|
+
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
28447
|
+
removeNode(p);
|
|
28448
|
+
p = end = p.prev;
|
|
28449
|
+
if (p === p.next) break;
|
|
28450
|
+
again = true;
|
|
28451
|
+
} else {
|
|
28452
|
+
p = p.next;
|
|
28453
|
+
}
|
|
28454
|
+
} while (again || p !== end);
|
|
28455
|
+
return end;
|
|
28456
|
+
}
|
|
28457
|
+
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
28458
|
+
if (!ear) return;
|
|
28459
|
+
if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
|
|
28460
|
+
let stop = ear, prev, next;
|
|
28461
|
+
while (ear.prev !== ear.next) {
|
|
28462
|
+
prev = ear.prev;
|
|
28463
|
+
next = ear.next;
|
|
28464
|
+
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
|
|
28465
|
+
triangles.push(prev.i / dim | 0);
|
|
28466
|
+
triangles.push(ear.i / dim | 0);
|
|
28467
|
+
triangles.push(next.i / dim | 0);
|
|
28468
|
+
removeNode(ear);
|
|
28469
|
+
ear = next.next;
|
|
28470
|
+
stop = next.next;
|
|
28471
|
+
continue;
|
|
28472
|
+
}
|
|
28473
|
+
ear = next;
|
|
28474
|
+
if (ear === stop) {
|
|
28475
|
+
if (!pass) {
|
|
28476
|
+
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
|
|
28477
|
+
} else if (pass === 1) {
|
|
28478
|
+
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
|
|
28479
|
+
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
|
|
28480
|
+
} else if (pass === 2) {
|
|
28481
|
+
splitEarcut(ear, triangles, dim, minX, minY, invSize);
|
|
28482
|
+
}
|
|
28483
|
+
break;
|
|
28484
|
+
}
|
|
28485
|
+
}
|
|
28486
|
+
}
|
|
28487
|
+
function isEar(ear) {
|
|
28488
|
+
const a = ear.prev, b = ear, c = ear.next;
|
|
28489
|
+
if (area(a, b, c) >= 0) return false;
|
|
28490
|
+
const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
|
|
28491
|
+
const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
|
|
28492
|
+
let p = c.next;
|
|
28493
|
+
while (p !== a) {
|
|
28494
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
28495
|
+
p = p.next;
|
|
28496
|
+
}
|
|
28497
|
+
return true;
|
|
28498
|
+
}
|
|
28499
|
+
function isEarHashed(ear, minX, minY, invSize) {
|
|
28500
|
+
const a = ear.prev, b = ear, c = ear.next;
|
|
28501
|
+
if (area(a, b, c) >= 0) return false;
|
|
28502
|
+
const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
|
|
28503
|
+
const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
|
|
28504
|
+
const minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
|
|
28505
|
+
let p = ear.prevZ, n = ear.nextZ;
|
|
28506
|
+
while (p && p.z >= minZ && n && n.z <= maxZ) {
|
|
28507
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
28508
|
+
p = p.prevZ;
|
|
28509
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
|
28510
|
+
n = n.nextZ;
|
|
28511
|
+
}
|
|
28512
|
+
while (p && p.z >= minZ) {
|
|
28513
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
28514
|
+
p = p.prevZ;
|
|
28515
|
+
}
|
|
28516
|
+
while (n && n.z <= maxZ) {
|
|
28517
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
|
28518
|
+
n = n.nextZ;
|
|
28519
|
+
}
|
|
28520
|
+
return true;
|
|
28521
|
+
}
|
|
28522
|
+
function cureLocalIntersections(start, triangles, dim) {
|
|
28523
|
+
let p = start;
|
|
28524
|
+
do {
|
|
28525
|
+
const a = p.prev, b = p.next.next;
|
|
28526
|
+
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
28527
|
+
triangles.push(a.i / dim | 0);
|
|
28528
|
+
triangles.push(p.i / dim | 0);
|
|
28529
|
+
triangles.push(b.i / dim | 0);
|
|
28530
|
+
removeNode(p);
|
|
28531
|
+
removeNode(p.next);
|
|
28532
|
+
p = start = b;
|
|
28533
|
+
}
|
|
28534
|
+
p = p.next;
|
|
28535
|
+
} while (p !== start);
|
|
28536
|
+
return filterPoints(p);
|
|
28537
|
+
}
|
|
28538
|
+
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
28539
|
+
let a = start;
|
|
28540
|
+
do {
|
|
28541
|
+
let b = a.next.next;
|
|
28542
|
+
while (b !== a.prev) {
|
|
28543
|
+
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
28544
|
+
let c = splitPolygon(a, b);
|
|
28545
|
+
a = filterPoints(a, a.next);
|
|
28546
|
+
c = filterPoints(c, c.next);
|
|
28547
|
+
earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
|
|
28548
|
+
earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
|
|
28549
|
+
return;
|
|
28550
|
+
}
|
|
28551
|
+
b = b.next;
|
|
28552
|
+
}
|
|
28553
|
+
a = a.next;
|
|
28554
|
+
} while (a !== start);
|
|
28555
|
+
}
|
|
28556
|
+
function eliminateHoles(data, holeIndices, outerNode, dim) {
|
|
28557
|
+
const queue = [];
|
|
28558
|
+
let i, len, start, end, list2;
|
|
28559
|
+
for (i = 0, len = holeIndices.length; i < len; i++) {
|
|
28560
|
+
start = holeIndices[i] * dim;
|
|
28561
|
+
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
28562
|
+
list2 = linkedList(data, start, end, dim, false);
|
|
28563
|
+
if (list2 === list2.next) list2.steiner = true;
|
|
28564
|
+
queue.push(getLeftmost(list2));
|
|
28565
|
+
}
|
|
28566
|
+
queue.sort(compareX);
|
|
28567
|
+
for (i = 0; i < queue.length; i++) {
|
|
28568
|
+
outerNode = eliminateHole(queue[i], outerNode);
|
|
28569
|
+
}
|
|
28570
|
+
return outerNode;
|
|
28571
|
+
}
|
|
28572
|
+
function compareX(a, b) {
|
|
28573
|
+
return a.x - b.x;
|
|
28574
|
+
}
|
|
28575
|
+
function eliminateHole(hole, outerNode) {
|
|
28576
|
+
const bridge = findHoleBridge(hole, outerNode);
|
|
28577
|
+
if (!bridge) {
|
|
28578
|
+
return outerNode;
|
|
28579
|
+
}
|
|
28580
|
+
const bridgeReverse = splitPolygon(bridge, hole);
|
|
28581
|
+
filterPoints(bridgeReverse, bridgeReverse.next);
|
|
28582
|
+
return filterPoints(bridge, bridge.next);
|
|
28583
|
+
}
|
|
28584
|
+
function findHoleBridge(hole, outerNode) {
|
|
28585
|
+
let p = outerNode, qx = -Infinity, m;
|
|
28586
|
+
const hx = hole.x, hy = hole.y;
|
|
28587
|
+
do {
|
|
28588
|
+
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
28589
|
+
const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
28590
|
+
if (x <= hx && x > qx) {
|
|
28591
|
+
qx = x;
|
|
28592
|
+
m = p.x < p.next.x ? p : p.next;
|
|
28593
|
+
if (x === hx) return m;
|
|
28594
|
+
}
|
|
28595
|
+
}
|
|
28596
|
+
p = p.next;
|
|
28597
|
+
} while (p !== outerNode);
|
|
28598
|
+
if (!m) return null;
|
|
28599
|
+
const stop = m, mx = m.x, my = m.y;
|
|
28600
|
+
let tanMin = Infinity, tan;
|
|
28601
|
+
p = m;
|
|
28602
|
+
do {
|
|
28603
|
+
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
|
28604
|
+
tan = Math.abs(hy - p.y) / (hx - p.x);
|
|
28605
|
+
if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
|
28606
|
+
m = p;
|
|
28607
|
+
tanMin = tan;
|
|
28608
|
+
}
|
|
28609
|
+
}
|
|
28610
|
+
p = p.next;
|
|
28611
|
+
} while (p !== stop);
|
|
28612
|
+
return m;
|
|
28613
|
+
}
|
|
28614
|
+
function sectorContainsSector(m, p) {
|
|
28615
|
+
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
28616
|
+
}
|
|
28617
|
+
function indexCurve(start, minX, minY, invSize) {
|
|
28618
|
+
let p = start;
|
|
28619
|
+
do {
|
|
28620
|
+
if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
28621
|
+
p.prevZ = p.prev;
|
|
28622
|
+
p.nextZ = p.next;
|
|
28623
|
+
p = p.next;
|
|
28624
|
+
} while (p !== start);
|
|
28625
|
+
p.prevZ.nextZ = null;
|
|
28626
|
+
p.prevZ = null;
|
|
28627
|
+
sortLinked(p);
|
|
28628
|
+
}
|
|
28629
|
+
function sortLinked(list2) {
|
|
28630
|
+
let i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1;
|
|
28631
|
+
do {
|
|
28632
|
+
p = list2;
|
|
28633
|
+
list2 = null;
|
|
28634
|
+
tail = null;
|
|
28635
|
+
numMerges = 0;
|
|
28636
|
+
while (p) {
|
|
28637
|
+
numMerges++;
|
|
28638
|
+
q = p;
|
|
28639
|
+
pSize = 0;
|
|
28640
|
+
for (i = 0; i < inSize; i++) {
|
|
28641
|
+
pSize++;
|
|
28642
|
+
q = q.nextZ;
|
|
28643
|
+
if (!q) break;
|
|
28644
|
+
}
|
|
28645
|
+
qSize = inSize;
|
|
28646
|
+
while (pSize > 0 || qSize > 0 && q) {
|
|
28647
|
+
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
|
|
28648
|
+
e = p;
|
|
28649
|
+
p = p.nextZ;
|
|
28650
|
+
pSize--;
|
|
28651
|
+
} else {
|
|
28652
|
+
e = q;
|
|
28653
|
+
q = q.nextZ;
|
|
28654
|
+
qSize--;
|
|
28655
|
+
}
|
|
28656
|
+
if (tail) tail.nextZ = e;
|
|
28657
|
+
else list2 = e;
|
|
28658
|
+
e.prevZ = tail;
|
|
28659
|
+
tail = e;
|
|
28660
|
+
}
|
|
28661
|
+
p = q;
|
|
28662
|
+
}
|
|
28663
|
+
tail.nextZ = null;
|
|
28664
|
+
inSize *= 2;
|
|
28665
|
+
} while (numMerges > 1);
|
|
28666
|
+
return list2;
|
|
28667
|
+
}
|
|
28668
|
+
function zOrder(x, y, minX, minY, invSize) {
|
|
28669
|
+
x = (x - minX) * invSize | 0;
|
|
28670
|
+
y = (y - minY) * invSize | 0;
|
|
28671
|
+
x = (x | x << 8) & 16711935;
|
|
28672
|
+
x = (x | x << 4) & 252645135;
|
|
28673
|
+
x = (x | x << 2) & 858993459;
|
|
28674
|
+
x = (x | x << 1) & 1431655765;
|
|
28675
|
+
y = (y | y << 8) & 16711935;
|
|
28676
|
+
y = (y | y << 4) & 252645135;
|
|
28677
|
+
y = (y | y << 2) & 858993459;
|
|
28678
|
+
y = (y | y << 1) & 1431655765;
|
|
28679
|
+
return x | y << 1;
|
|
28680
|
+
}
|
|
28681
|
+
function getLeftmost(start) {
|
|
28682
|
+
let p = start, leftmost = start;
|
|
28683
|
+
do {
|
|
28684
|
+
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
|
|
28685
|
+
p = p.next;
|
|
28686
|
+
} while (p !== start);
|
|
28687
|
+
return leftmost;
|
|
28688
|
+
}
|
|
28689
|
+
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
28690
|
+
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
|
|
28691
|
+
}
|
|
28692
|
+
function isValidDiagonal(a, b) {
|
|
28693
|
+
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
|
|
28694
|
+
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
|
|
28695
|
+
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
|
|
28696
|
+
equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
|
|
28697
|
+
}
|
|
28698
|
+
function area(p, q, r) {
|
|
28699
|
+
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
28700
|
+
}
|
|
28701
|
+
function equals(p1, p2) {
|
|
28702
|
+
return p1.x === p2.x && p1.y === p2.y;
|
|
28703
|
+
}
|
|
28704
|
+
function intersects(p1, q1, p2, q2) {
|
|
28705
|
+
const o1 = sign(area(p1, q1, p2));
|
|
28706
|
+
const o2 = sign(area(p1, q1, q2));
|
|
28707
|
+
const o3 = sign(area(p2, q2, p1));
|
|
28708
|
+
const o4 = sign(area(p2, q2, q1));
|
|
28709
|
+
if (o1 !== o2 && o3 !== o4) return true;
|
|
28710
|
+
if (o1 === 0 && onSegment(p1, p2, q1)) return true;
|
|
28711
|
+
if (o2 === 0 && onSegment(p1, q2, q1)) return true;
|
|
28712
|
+
if (o3 === 0 && onSegment(p2, p1, q2)) return true;
|
|
28713
|
+
if (o4 === 0 && onSegment(p2, q1, q2)) return true;
|
|
28714
|
+
return false;
|
|
28715
|
+
}
|
|
28716
|
+
function onSegment(p, q, r) {
|
|
28717
|
+
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
28718
|
+
}
|
|
28719
|
+
function sign(num2) {
|
|
28720
|
+
return num2 > 0 ? 1 : num2 < 0 ? -1 : 0;
|
|
28721
|
+
}
|
|
28722
|
+
function intersectsPolygon(a, b) {
|
|
28723
|
+
let p = a;
|
|
28724
|
+
do {
|
|
28725
|
+
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
|
|
28726
|
+
p = p.next;
|
|
28727
|
+
} while (p !== a);
|
|
28728
|
+
return false;
|
|
28729
|
+
}
|
|
28730
|
+
function locallyInside(a, b) {
|
|
28731
|
+
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
|
|
28732
|
+
}
|
|
28733
|
+
function middleInside(a, b) {
|
|
28734
|
+
let p = a, inside = false;
|
|
28735
|
+
const px = (a.x + b.x) / 2, py = (a.y + b.y) / 2;
|
|
28736
|
+
do {
|
|
28737
|
+
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
|
|
28738
|
+
inside = !inside;
|
|
28739
|
+
p = p.next;
|
|
28740
|
+
} while (p !== a);
|
|
28741
|
+
return inside;
|
|
28742
|
+
}
|
|
28743
|
+
function splitPolygon(a, b) {
|
|
28744
|
+
const a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev;
|
|
28745
|
+
a.next = b;
|
|
28746
|
+
b.prev = a;
|
|
28747
|
+
a2.next = an;
|
|
28748
|
+
an.prev = a2;
|
|
28749
|
+
b2.next = a2;
|
|
28750
|
+
a2.prev = b2;
|
|
28751
|
+
bp.next = b2;
|
|
28752
|
+
b2.prev = bp;
|
|
28753
|
+
return b2;
|
|
28754
|
+
}
|
|
28755
|
+
function insertNode(i, x, y, last) {
|
|
28756
|
+
const p = new Node(i, x, y);
|
|
28757
|
+
if (!last) {
|
|
28758
|
+
p.prev = p;
|
|
28759
|
+
p.next = p;
|
|
28760
|
+
} else {
|
|
28761
|
+
p.next = last.next;
|
|
28762
|
+
p.prev = last;
|
|
28763
|
+
last.next.prev = p;
|
|
28764
|
+
last.next = p;
|
|
28765
|
+
}
|
|
28766
|
+
return p;
|
|
28767
|
+
}
|
|
28768
|
+
function removeNode(p) {
|
|
28769
|
+
p.next.prev = p.prev;
|
|
28770
|
+
p.prev.next = p.next;
|
|
28771
|
+
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
|
|
28772
|
+
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
|
|
28773
|
+
}
|
|
28774
|
+
function Node(i, x, y) {
|
|
28775
|
+
this.i = i;
|
|
28776
|
+
this.x = x;
|
|
28777
|
+
this.y = y;
|
|
28778
|
+
this.prev = null;
|
|
28779
|
+
this.next = null;
|
|
28780
|
+
this.z = 0;
|
|
28781
|
+
this.prevZ = null;
|
|
28782
|
+
this.nextZ = null;
|
|
28783
|
+
this.steiner = false;
|
|
28784
|
+
}
|
|
28785
|
+
function signedArea(data, start, end, dim) {
|
|
28786
|
+
let sum = 0;
|
|
28787
|
+
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
28788
|
+
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
|
|
28789
|
+
j = i;
|
|
28790
|
+
}
|
|
28791
|
+
return sum;
|
|
28792
|
+
}
|
|
28793
|
+
var equals2 = (a, b) => a.x === b.x && a.y === b.y;
|
|
28794
|
+
var linePoint = (v1, v2, t) => t === 1 ? { x: v2.x, y: v2.y } : { x: (v2.x - v1.x) * t + v1.x, y: (v2.y - v1.y) * t + v1.y };
|
|
28795
|
+
function pathPoints(points) {
|
|
28796
|
+
const out = [];
|
|
28797
|
+
let last;
|
|
28798
|
+
for (let i = 1; i < points.length; i++) {
|
|
28799
|
+
const v1 = { x: points[i - 1][0], y: points[i - 1][1] };
|
|
28800
|
+
const v2 = { x: points[i][0], y: points[i][1] };
|
|
28801
|
+
for (let d = 0; d <= 1; d++) {
|
|
28802
|
+
const point = linePoint(v1, v2, d / 1);
|
|
28803
|
+
if (last && equals2(last, point)) continue;
|
|
28804
|
+
out.push(point);
|
|
28805
|
+
last = point;
|
|
28806
|
+
}
|
|
28807
|
+
}
|
|
28808
|
+
return out;
|
|
28809
|
+
}
|
|
28810
|
+
function area2(contour) {
|
|
28811
|
+
const n = contour.length;
|
|
28812
|
+
let a = 0;
|
|
28813
|
+
for (let p = n - 1, q = 0; q < n; p = q++) a += contour[p].x * contour[q].y - contour[q].x * contour[p].y;
|
|
28814
|
+
return a * 0.5;
|
|
28815
|
+
}
|
|
28816
|
+
var isClockWise = (pts) => area2(pts) < 0;
|
|
28817
|
+
function removeDupEndPts(points) {
|
|
28818
|
+
const l = points.length;
|
|
28819
|
+
if (l > 2 && equals2(points[l - 1], points[0])) points.pop();
|
|
28820
|
+
}
|
|
28821
|
+
function triangulateShape(contour, holes) {
|
|
28822
|
+
const vertices = [];
|
|
28823
|
+
const holeIndices = [];
|
|
28824
|
+
const faces = [];
|
|
28825
|
+
removeDupEndPts(contour);
|
|
28826
|
+
for (const p of contour) vertices.push(p.x, p.y);
|
|
28827
|
+
let holeIndex = contour.length;
|
|
28828
|
+
holes.forEach(removeDupEndPts);
|
|
28829
|
+
for (let i = 0; i < holes.length; i++) {
|
|
28830
|
+
holeIndices.push(holeIndex);
|
|
28831
|
+
holeIndex += holes[i].length;
|
|
28832
|
+
for (const p of holes[i]) vertices.push(p.x, p.y);
|
|
28833
|
+
}
|
|
28834
|
+
const triangles = Earcut.triangulate(vertices, holeIndices);
|
|
28835
|
+
for (let i = 0; i < triangles.length; i += 3) faces.push(triangles.slice(i, i + 3));
|
|
28836
|
+
return faces;
|
|
28837
|
+
}
|
|
28838
|
+
function computeVertexNormals(positions, indices) {
|
|
28839
|
+
const normals = new Float32Array(positions.length);
|
|
28840
|
+
const get = (array, i) => [array[i * 3], array[i * 3 + 1], array[i * 3 + 2]];
|
|
28841
|
+
const face = (vA, vB, vC) => {
|
|
28842
|
+
const pA = get(positions, vA);
|
|
28843
|
+
const pB = get(positions, vB);
|
|
28844
|
+
const pC = get(positions, vC);
|
|
28845
|
+
const cb = [pC[0] - pB[0], pC[1] - pB[1], pC[2] - pB[2]];
|
|
28846
|
+
const ab = [pA[0] - pB[0], pA[1] - pB[1], pA[2] - pB[2]];
|
|
28847
|
+
return [cb[1] * ab[2] - cb[2] * ab[1], cb[2] * ab[0] - cb[0] * ab[2], cb[0] * ab[1] - cb[1] * ab[0]];
|
|
28848
|
+
};
|
|
28849
|
+
const set = (i, x, y, z) => {
|
|
28850
|
+
normals[i * 3] = x;
|
|
28851
|
+
normals[i * 3 + 1] = y;
|
|
28852
|
+
normals[i * 3 + 2] = z;
|
|
28853
|
+
};
|
|
28854
|
+
if (indices) {
|
|
28855
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
28856
|
+
const vA = indices[i];
|
|
28857
|
+
const vB = indices[i + 1];
|
|
28858
|
+
const vC = indices[i + 2];
|
|
28859
|
+
const cb = face(vA, vB, vC);
|
|
28860
|
+
for (const v of [vA, vB, vC]) {
|
|
28861
|
+
const n = get(normals, v);
|
|
28862
|
+
set(v, n[0] + cb[0], n[1] + cb[1], n[2] + cb[2]);
|
|
28863
|
+
}
|
|
28864
|
+
}
|
|
28865
|
+
} else {
|
|
28866
|
+
for (let i = 0; i < positions.length / 3; i += 3) {
|
|
28867
|
+
const cb = face(i, i + 1, i + 2);
|
|
28868
|
+
set(i, cb[0], cb[1], cb[2]);
|
|
28869
|
+
set(i + 1, cb[0], cb[1], cb[2]);
|
|
28870
|
+
set(i + 2, cb[0], cb[1], cb[2]);
|
|
28871
|
+
}
|
|
28872
|
+
}
|
|
28873
|
+
for (let i = 0; i < normals.length / 3; i++) {
|
|
28874
|
+
const [x, y, z] = get(normals, i);
|
|
28875
|
+
const s = 1 / (Math.sqrt(x * x + y * y + z * z) || 1);
|
|
28876
|
+
set(i, x * s, y * s, z * s);
|
|
28877
|
+
}
|
|
28878
|
+
return normals;
|
|
28879
|
+
}
|
|
28880
|
+
function extrude(outline, depth = 1, steps = 1, bevel = void 0) {
|
|
28881
|
+
const parameters = { shape: outline, depth, steps, bevel: bevel ?? {} };
|
|
28882
|
+
const verticesArray = [];
|
|
28883
|
+
const uvArray = [];
|
|
28884
|
+
const groups = [];
|
|
28885
|
+
const placeholder = [];
|
|
28886
|
+
const bevelEnabled = bevel !== false;
|
|
28887
|
+
const spec = bevel === false || bevel === void 0 ? {} : bevel;
|
|
28888
|
+
let bevelThickness = spec.thickness !== void 0 ? spec.thickness : 0.2;
|
|
28889
|
+
let bevelSize = spec.size !== void 0 ? spec.size : bevelThickness - 0.1;
|
|
28890
|
+
let bevelOffset = spec.offset !== void 0 ? spec.offset : 0;
|
|
28891
|
+
let bevelSegments = spec.segments !== void 0 ? spec.segments : 3;
|
|
28892
|
+
if (!bevelEnabled) {
|
|
28893
|
+
bevelSegments = 0;
|
|
28894
|
+
bevelThickness = 0;
|
|
28895
|
+
bevelSize = 0;
|
|
28896
|
+
bevelOffset = 0;
|
|
28897
|
+
}
|
|
28898
|
+
let vertices = pathPoints(outline.outer);
|
|
28899
|
+
const holes = (outline.holes ?? []).map(pathPoints);
|
|
28900
|
+
const reverse = !isClockWise(vertices);
|
|
28901
|
+
if (reverse) {
|
|
28902
|
+
vertices = vertices.reverse();
|
|
28903
|
+
for (let h = 0; h < holes.length; h++) {
|
|
28904
|
+
const ahole = holes[h];
|
|
28905
|
+
if (isClockWise(ahole)) holes[h] = ahole.reverse();
|
|
28906
|
+
}
|
|
28907
|
+
}
|
|
28908
|
+
const faces = triangulateShape(vertices, holes);
|
|
28909
|
+
const contour = vertices;
|
|
28910
|
+
for (const ahole of holes) vertices = vertices.concat(ahole);
|
|
28911
|
+
const scalePt2 = (pt, vec, size) => ({ x: pt.x + vec.x * size, y: pt.y + vec.y * size });
|
|
28912
|
+
const vlen = vertices.length;
|
|
28913
|
+
const flen = faces.length;
|
|
28914
|
+
const getBevelVec = (inPt, inPrev, inNext) => {
|
|
28915
|
+
let vTransX;
|
|
28916
|
+
let vTransY;
|
|
28917
|
+
let shrinkBy;
|
|
28918
|
+
const vPrevX = inPt.x - inPrev.x;
|
|
28919
|
+
const vPrevY = inPt.y - inPrev.y;
|
|
28920
|
+
const vNextX = inNext.x - inPt.x;
|
|
28921
|
+
const vNextY = inNext.y - inPt.y;
|
|
28922
|
+
const vPrevLensq = vPrevX * vPrevX + vPrevY * vPrevY;
|
|
28923
|
+
const collinear0 = vPrevX * vNextY - vPrevY * vNextX;
|
|
28924
|
+
if (Math.abs(collinear0) > Number.EPSILON) {
|
|
28925
|
+
const vPrevLen = Math.sqrt(vPrevLensq);
|
|
28926
|
+
const vNextLen = Math.sqrt(vNextX * vNextX + vNextY * vNextY);
|
|
28927
|
+
const ptPrevShiftX = inPrev.x - vPrevY / vPrevLen;
|
|
28928
|
+
const ptPrevShiftY = inPrev.y + vPrevX / vPrevLen;
|
|
28929
|
+
const ptNextShiftX = inNext.x - vNextY / vNextLen;
|
|
28930
|
+
const ptNextShiftY = inNext.y + vNextX / vNextLen;
|
|
28931
|
+
const sf = ((ptNextShiftX - ptPrevShiftX) * vNextY - (ptNextShiftY - ptPrevShiftY) * vNextX) / (vPrevX * vNextY - vPrevY * vNextX);
|
|
28932
|
+
vTransX = ptPrevShiftX + vPrevX * sf - inPt.x;
|
|
28933
|
+
vTransY = ptPrevShiftY + vPrevY * sf - inPt.y;
|
|
28934
|
+
const vTransLensq = vTransX * vTransX + vTransY * vTransY;
|
|
28935
|
+
if (vTransLensq <= 2) return { x: vTransX, y: vTransY };
|
|
28936
|
+
shrinkBy = Math.sqrt(vTransLensq / 2);
|
|
28937
|
+
} else {
|
|
28938
|
+
let directionEq = false;
|
|
28939
|
+
if (vPrevX > Number.EPSILON) {
|
|
28940
|
+
if (vNextX > Number.EPSILON) directionEq = true;
|
|
28941
|
+
} else if (vPrevX < -Number.EPSILON) {
|
|
28942
|
+
if (vNextX < -Number.EPSILON) directionEq = true;
|
|
28943
|
+
} else if (Math.sign(vPrevY) === Math.sign(vNextY)) {
|
|
28944
|
+
directionEq = true;
|
|
28945
|
+
}
|
|
28946
|
+
if (directionEq) {
|
|
28947
|
+
vTransX = -vPrevY;
|
|
28948
|
+
vTransY = vPrevX;
|
|
28949
|
+
shrinkBy = Math.sqrt(vPrevLensq);
|
|
28950
|
+
} else {
|
|
28951
|
+
vTransX = vPrevX;
|
|
28952
|
+
vTransY = vPrevY;
|
|
28953
|
+
shrinkBy = Math.sqrt(vPrevLensq / 2);
|
|
28954
|
+
}
|
|
28955
|
+
}
|
|
28956
|
+
return { x: vTransX / shrinkBy, y: vTransY / shrinkBy };
|
|
28957
|
+
};
|
|
28958
|
+
const movements = (ring2) => {
|
|
28959
|
+
const out = [];
|
|
28960
|
+
for (let i = 0, il = ring2.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
|
|
28961
|
+
if (j === il) j = 0;
|
|
28962
|
+
if (k === il) k = 0;
|
|
28963
|
+
out[i] = getBevelVec(ring2[i], ring2[j], ring2[k]);
|
|
28964
|
+
}
|
|
28965
|
+
return out;
|
|
28966
|
+
};
|
|
28967
|
+
const contourMovements = movements(contour);
|
|
28968
|
+
const holesMovements = [];
|
|
28969
|
+
let verticesMovements = contourMovements.concat();
|
|
28970
|
+
for (const ahole of holes) {
|
|
28971
|
+
const oneHoleMovements = movements(ahole);
|
|
28972
|
+
holesMovements.push(oneHoleMovements);
|
|
28973
|
+
verticesMovements = verticesMovements.concat(oneHoleMovements);
|
|
28974
|
+
}
|
|
28975
|
+
const v = (x, y, z) => {
|
|
28976
|
+
placeholder.push(x);
|
|
28977
|
+
placeholder.push(y);
|
|
28978
|
+
placeholder.push(z);
|
|
28979
|
+
};
|
|
28980
|
+
const bevelLayer = (b, zOf) => {
|
|
28981
|
+
const t = b / bevelSegments;
|
|
28982
|
+
const z = bevelThickness * Math.cos(t * Math.PI / 2);
|
|
28983
|
+
const bs2 = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset;
|
|
28984
|
+
for (let i = 0; i < contour.length; i++) {
|
|
28985
|
+
const vert = scalePt2(contour[i], contourMovements[i], bs2);
|
|
28986
|
+
v(vert.x, vert.y, zOf(z));
|
|
28987
|
+
}
|
|
28988
|
+
for (let h = 0; h < holes.length; h++) {
|
|
28989
|
+
const ahole = holes[h];
|
|
28990
|
+
const oneHoleMovements = holesMovements[h];
|
|
28991
|
+
for (let i = 0; i < ahole.length; i++) {
|
|
28992
|
+
const vert = scalePt2(ahole[i], oneHoleMovements[i], bs2);
|
|
28993
|
+
v(vert.x, vert.y, zOf(z));
|
|
28994
|
+
}
|
|
28995
|
+
}
|
|
28996
|
+
};
|
|
28997
|
+
for (let b = 0; b < bevelSegments; b++) bevelLayer(b, (z) => -z);
|
|
28998
|
+
const bs = bevelSize + bevelOffset;
|
|
28999
|
+
for (let i = 0; i < vlen; i++) {
|
|
29000
|
+
const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
|
|
29001
|
+
v(vert.x, vert.y, 0);
|
|
29002
|
+
}
|
|
29003
|
+
for (let s = 1; s <= steps; s++) {
|
|
29004
|
+
for (let i = 0; i < vlen; i++) {
|
|
29005
|
+
const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
|
|
29006
|
+
v(vert.x, vert.y, depth / steps * s);
|
|
29007
|
+
}
|
|
29008
|
+
}
|
|
29009
|
+
for (let b = bevelSegments - 1; b >= 0; b--) bevelLayer(b, (z) => depth + z);
|
|
29010
|
+
const addVertex = (index) => {
|
|
29011
|
+
verticesArray.push(placeholder[index * 3 + 0]);
|
|
29012
|
+
verticesArray.push(placeholder[index * 3 + 1]);
|
|
29013
|
+
verticesArray.push(placeholder[index * 3 + 2]);
|
|
29014
|
+
};
|
|
29015
|
+
const addUV = (x, y) => {
|
|
29016
|
+
uvArray.push(x);
|
|
29017
|
+
uvArray.push(y);
|
|
29018
|
+
};
|
|
29019
|
+
const at = (index, axis) => verticesArray[index * 3 + axis];
|
|
29020
|
+
const f3 = (a, b, c) => {
|
|
29021
|
+
addVertex(a);
|
|
29022
|
+
addVertex(b);
|
|
29023
|
+
addVertex(c);
|
|
29024
|
+
const nextIndex = verticesArray.length / 3;
|
|
29025
|
+
for (const index of [nextIndex - 3, nextIndex - 2, nextIndex - 1]) addUV(at(index, 0), at(index, 1));
|
|
29026
|
+
};
|
|
29027
|
+
const f4 = (a, b, c, d) => {
|
|
29028
|
+
addVertex(a);
|
|
29029
|
+
addVertex(b);
|
|
29030
|
+
addVertex(d);
|
|
29031
|
+
addVertex(b);
|
|
29032
|
+
addVertex(c);
|
|
29033
|
+
addVertex(d);
|
|
29034
|
+
const nextIndex = verticesArray.length / 3;
|
|
29035
|
+
const iA = nextIndex - 6;
|
|
29036
|
+
const iB = nextIndex - 3;
|
|
29037
|
+
const iC = nextIndex - 2;
|
|
29038
|
+
const iD = nextIndex - 1;
|
|
29039
|
+
const byX = Math.abs(at(iA, 1) - at(iB, 1)) < Math.abs(at(iA, 0) - at(iB, 0));
|
|
29040
|
+
const uv = (index) => [byX ? at(index, 0) : at(index, 1), 1 - at(index, 2)];
|
|
29041
|
+
const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)];
|
|
29042
|
+
for (const k of [0, 1, 3, 1, 2, 3]) addUV(...uvs[k]);
|
|
29043
|
+
};
|
|
29044
|
+
let start = verticesArray.length / 3;
|
|
29045
|
+
if (bevelEnabled) {
|
|
29046
|
+
let offset = 0;
|
|
29047
|
+
for (let i = 0; i < flen; i++) {
|
|
29048
|
+
const face = faces[i];
|
|
29049
|
+
f3(face[2] + offset, face[1] + offset, face[0] + offset);
|
|
29050
|
+
}
|
|
29051
|
+
const layer = steps + bevelSegments * 2;
|
|
29052
|
+
offset = vlen * layer;
|
|
29053
|
+
for (let i = 0; i < flen; i++) {
|
|
29054
|
+
const face = faces[i];
|
|
29055
|
+
f3(face[0] + offset, face[1] + offset, face[2] + offset);
|
|
29056
|
+
}
|
|
29057
|
+
} else {
|
|
29058
|
+
for (let i = 0; i < flen; i++) {
|
|
29059
|
+
const face = faces[i];
|
|
29060
|
+
f3(face[2], face[1], face[0]);
|
|
29061
|
+
}
|
|
29062
|
+
for (let i = 0; i < flen; i++) {
|
|
29063
|
+
const face = faces[i];
|
|
29064
|
+
f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
|
|
29065
|
+
}
|
|
29066
|
+
}
|
|
29067
|
+
groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 0 });
|
|
29068
|
+
start = verticesArray.length / 3;
|
|
29069
|
+
const sidewalls = (ring2, layeroffset2) => {
|
|
29070
|
+
let i = ring2.length;
|
|
29071
|
+
while (--i >= 0) {
|
|
29072
|
+
const j = i;
|
|
29073
|
+
let k = i - 1;
|
|
29074
|
+
if (k < 0) k = ring2.length - 1;
|
|
29075
|
+
for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {
|
|
29076
|
+
const slen1 = vlen * s;
|
|
29077
|
+
const slen2 = vlen * (s + 1);
|
|
29078
|
+
f4(layeroffset2 + j + slen1, layeroffset2 + k + slen1, layeroffset2 + k + slen2, layeroffset2 + j + slen2);
|
|
29079
|
+
}
|
|
29080
|
+
}
|
|
29081
|
+
};
|
|
29082
|
+
let layeroffset = 0;
|
|
29083
|
+
sidewalls(contour, layeroffset);
|
|
29084
|
+
layeroffset += contour.length;
|
|
29085
|
+
for (const ahole of holes) {
|
|
29086
|
+
sidewalls(ahole, layeroffset);
|
|
29087
|
+
layeroffset += ahole.length;
|
|
29088
|
+
}
|
|
29089
|
+
groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 1 });
|
|
29090
|
+
const positions = new Float32Array(verticesArray);
|
|
29091
|
+
return { type: "ExtrudeGeometry", parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups };
|
|
29092
|
+
}
|
|
29093
|
+
var PARAMETER_KEYS = {
|
|
29094
|
+
box: ["size", "segments"],
|
|
29095
|
+
cylinder: ["radiusTop", "radiusBottom", "height", "radialSegments", "heightSegments", "openEnded", "thetaStart", "thetaLength"],
|
|
29096
|
+
cone: ["radius", "height", "radialSegments", "heightSegments", "openEnded", "thetaStart", "thetaLength"],
|
|
29097
|
+
sphere: ["radius", "widthSegments", "heightSegments", "phiStart", "phiLength", "thetaStart", "thetaLength"],
|
|
29098
|
+
plane: ["width", "height", "widthSegments", "heightSegments"],
|
|
29099
|
+
circle: ["radius", "segments", "thetaStart", "thetaLength"],
|
|
29100
|
+
ring: ["innerRadius", "outerRadius", "thetaSegments", "phiSegments", "thetaStart", "thetaLength"],
|
|
29101
|
+
lathe: ["points", "segments", "phiStart", "phiLength"],
|
|
29102
|
+
torus: ["radius", "tube", "radialSegments", "tubularSegments", "arc"],
|
|
29103
|
+
extrude: ["shape", "depth", "steps", "bevel"],
|
|
29104
|
+
difference: ["size", "subtract"],
|
|
29105
|
+
mesh: ["positions", "normals", "uvs", "indices"]
|
|
29106
|
+
};
|
|
29107
|
+
var SEGMENT_KEYS = {
|
|
29108
|
+
cylinder: ["radialSegments"],
|
|
29109
|
+
cone: ["radialSegments"],
|
|
29110
|
+
sphere: ["widthSegments", "heightSegments"],
|
|
29111
|
+
circle: ["segments"],
|
|
29112
|
+
ring: ["thetaSegments"],
|
|
29113
|
+
lathe: ["segments"],
|
|
29114
|
+
torus: ["radialSegments", "tubularSegments"]
|
|
29115
|
+
};
|
|
29116
|
+
var SEGMENT_DEFAULTS = { radialSegments: 32, widthSegments: 32, heightSegments: 16, segments: 12, thetaSegments: 32, tubularSegments: 48 };
|
|
29117
|
+
var segmentDefault = (kind, key) => kind === "circle" && key === "segments" ? 32 : kind === "torus" && key === "radialSegments" ? 12 : SEGMENT_DEFAULTS[key];
|
|
29118
|
+
function primitiveParameters(node, options = {}) {
|
|
29119
|
+
const out = {};
|
|
29120
|
+
const source = node;
|
|
29121
|
+
for (const key of PARAMETER_KEYS[node.kind]) if (source[key] !== void 0) out[key] = source[key];
|
|
29122
|
+
const detail = options.detail ?? 1;
|
|
29123
|
+
if (detail !== 1) {
|
|
29124
|
+
const floor = options.minSegments ?? 3;
|
|
29125
|
+
for (const key of SEGMENT_KEYS[node.kind] ?? []) {
|
|
29126
|
+
const given = out[key] ?? segmentDefault(node.kind, key);
|
|
29127
|
+
out[key] = Math.max(floor, Math.round(given * detail));
|
|
29128
|
+
}
|
|
29129
|
+
}
|
|
29130
|
+
return out;
|
|
29131
|
+
}
|
|
29132
|
+
function mesh(p) {
|
|
29133
|
+
const positions = new Float32Array(p.positions);
|
|
29134
|
+
const indices = p.indices ? indexArray(p.indices) : void 0;
|
|
29135
|
+
return {
|
|
29136
|
+
type: "BufferGeometry",
|
|
29137
|
+
parameters: {},
|
|
29138
|
+
positions,
|
|
29139
|
+
normals: p.normals ? new Float32Array(p.normals) : computeVertexNormals(positions, indices),
|
|
29140
|
+
uvs: p.uvs ? new Float32Array(p.uvs) : new Float32Array(positions.length / 3 * 2),
|
|
29141
|
+
...indices ? { indices } : {},
|
|
29142
|
+
groups: []
|
|
29143
|
+
};
|
|
29144
|
+
}
|
|
29145
|
+
function make(kind, p) {
|
|
29146
|
+
switch (kind) {
|
|
29147
|
+
case "box": {
|
|
29148
|
+
const size = p.size ?? [1, 1, 1];
|
|
29149
|
+
const segments = p.segments ?? [1, 1, 1];
|
|
29150
|
+
return box(size[0], size[1], size[2], segments[0], segments[1], segments[2]);
|
|
29151
|
+
}
|
|
29152
|
+
case "cylinder":
|
|
29153
|
+
return cylinder(p.radiusTop, p.radiusBottom, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength);
|
|
29154
|
+
case "cone":
|
|
29155
|
+
return cone(p.radius, p.height, p.radialSegments, p.heightSegments, p.openEnded, p.thetaStart, p.thetaLength);
|
|
29156
|
+
case "sphere":
|
|
29157
|
+
return sphere(p.radius, p.widthSegments, p.heightSegments, p.phiStart, p.phiLength, p.thetaStart, p.thetaLength);
|
|
29158
|
+
case "plane":
|
|
29159
|
+
return plane(p.width, p.height, p.widthSegments, p.heightSegments);
|
|
29160
|
+
case "circle":
|
|
29161
|
+
return circle(p.radius, p.segments, p.thetaStart, p.thetaLength);
|
|
29162
|
+
case "ring":
|
|
29163
|
+
return ring(p.innerRadius, p.outerRadius, p.thetaSegments, p.phiSegments, p.thetaStart, p.thetaLength);
|
|
29164
|
+
case "lathe":
|
|
29165
|
+
return lathe(p.points, p.segments, p.phiStart, p.phiLength);
|
|
29166
|
+
case "torus":
|
|
29167
|
+
return torus(p.radius, p.tube, p.radialSegments, p.tubularSegments, p.arc);
|
|
29168
|
+
case "extrude":
|
|
29169
|
+
return extrude(p.shape, p.depth, p.steps, p.bevel);
|
|
29170
|
+
case "difference":
|
|
29171
|
+
return difference(p.size, p.subtract ?? []);
|
|
29172
|
+
case "mesh":
|
|
29173
|
+
return mesh(p);
|
|
29174
|
+
default:
|
|
29175
|
+
throw new Error(`game-shapes: unknown primitive kind "${String(kind)}"`);
|
|
29176
|
+
}
|
|
29177
|
+
}
|
|
29178
|
+
var templates = /* @__PURE__ */ new Map();
|
|
29179
|
+
var templateLimit = 4096;
|
|
29180
|
+
var stats = { hits: 0, misses: 0 };
|
|
29181
|
+
function buildPrimitive(node, options = {}) {
|
|
29182
|
+
const parameters = primitiveParameters(node, options);
|
|
29183
|
+
if (node.kind === "mesh" || templateLimit === 0) return make(node.kind, parameters);
|
|
29184
|
+
const key = `${node.kind}:${canonicalJson(parameters)}`;
|
|
29185
|
+
const cached = templates.get(key);
|
|
29186
|
+
if (cached) {
|
|
29187
|
+
stats.hits++;
|
|
29188
|
+
templates.delete(key);
|
|
29189
|
+
templates.set(key, cached);
|
|
29190
|
+
return cached;
|
|
29191
|
+
}
|
|
29192
|
+
stats.misses++;
|
|
29193
|
+
const built = make(node.kind, parameters);
|
|
29194
|
+
templates.set(key, built);
|
|
29195
|
+
if (templates.size > templateLimit) templates.delete(templates.keys().next().value);
|
|
29196
|
+
return built;
|
|
29197
|
+
}
|
|
29198
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? null : "expected a finite number";
|
|
29199
|
+
var bool = (v) => typeof v === "boolean" ? null : "expected a boolean";
|
|
29200
|
+
var str = (v) => typeof v === "string" ? null : "expected a string";
|
|
29201
|
+
var int = (min) => (v) => typeof v === "number" && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`;
|
|
29202
|
+
var range = (lo, hi, loOpen = false) => (v) => typeof v === "number" && (loOpen ? v > lo : v >= lo) && v <= hi ? null : `expected a number in ${loOpen ? "(" : "["}${lo}, ${hi}]`;
|
|
29203
|
+
var tuple = (n, item = num) => (v) => {
|
|
29204
|
+
if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`;
|
|
29205
|
+
for (const x of v) if (item(x)) return `expected an array of ${n} numbers`;
|
|
29206
|
+
return null;
|
|
29207
|
+
};
|
|
29208
|
+
var list = (item, min = 0) => (v) => {
|
|
29209
|
+
if (!Array.isArray(v)) return "expected an array";
|
|
29210
|
+
if (v.length < min) return `expected at least ${min} items`;
|
|
29211
|
+
for (let i = 0; i < v.length; i++) {
|
|
29212
|
+
const e = item(v[i]);
|
|
29213
|
+
if (e) return `[${i}]: ${e}`;
|
|
29214
|
+
}
|
|
29215
|
+
return null;
|
|
29216
|
+
};
|
|
29217
|
+
var color = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0 && v <= 16777215 || typeof v === "string" && /^#[0-9a-fA-F]{6}$/.test(v) ? null : 'expected 0xRRGGBB or "#rrggbb"';
|
|
29218
|
+
var oneOf = (values) => (v) => values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(", ")}`;
|
|
29219
|
+
var object = (fields, required = []) => (v) => {
|
|
29220
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return "expected an object";
|
|
29221
|
+
const record = v;
|
|
29222
|
+
for (const key of required) if (record[key] === void 0) return `${key}: required`;
|
|
29223
|
+
for (const key of Object.keys(record)) {
|
|
29224
|
+
if (record[key] === void 0) continue;
|
|
29225
|
+
const check = fields[key];
|
|
29226
|
+
if (!check) return `${key}: unknown field`;
|
|
29227
|
+
const e = check(record[key]);
|
|
29228
|
+
if (e) return `${key}: ${e}`;
|
|
29229
|
+
}
|
|
29230
|
+
return null;
|
|
29231
|
+
};
|
|
29232
|
+
var ORDERS = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"];
|
|
29233
|
+
var TRANSFORM = {
|
|
29234
|
+
position: tuple(3),
|
|
29235
|
+
rotation: tuple(3),
|
|
29236
|
+
rotationOrder: oneOf(ORDERS),
|
|
29237
|
+
scale: (v) => typeof v === "number" ? num(v) : tuple(3)(v),
|
|
29238
|
+
heading: num,
|
|
29239
|
+
matrix: tuple(16)
|
|
29240
|
+
};
|
|
29241
|
+
var UV = object({ u0: num, v0: num, u1: num, v1: num }, ["u0", "v0", "u1", "v1"]);
|
|
29242
|
+
var INSTANCE = object({ ...TRANSFORM, color });
|
|
29243
|
+
var COMMON = {
|
|
29244
|
+
...TRANSFORM,
|
|
29245
|
+
kind: str,
|
|
29246
|
+
name: str,
|
|
29247
|
+
part: str,
|
|
29248
|
+
material: str,
|
|
29249
|
+
color,
|
|
29250
|
+
uv: UV,
|
|
29251
|
+
instances: list(INSTANCE),
|
|
29252
|
+
minDetail: range(0, 1, true),
|
|
29253
|
+
tags: list(str)
|
|
29254
|
+
};
|
|
29255
|
+
var vec2 = tuple(2);
|
|
29256
|
+
var BEVEL = (v) => v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v);
|
|
29257
|
+
var KINDS = {
|
|
29258
|
+
group: { fields: {} },
|
|
29259
|
+
box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },
|
|
29260
|
+
cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
|
|
29261
|
+
cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
|
|
29262
|
+
sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },
|
|
29263
|
+
plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },
|
|
29264
|
+
circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },
|
|
29265
|
+
ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },
|
|
29266
|
+
lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ["points"] },
|
|
29267
|
+
torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },
|
|
29268
|
+
extrude: {
|
|
29269
|
+
fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ["outer"]), depth: num, steps: int(1), bevel: BEVEL },
|
|
29270
|
+
required: ["shape"]
|
|
29271
|
+
},
|
|
29272
|
+
difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ["min", "max"])) }, required: ["size", "subtract"] },
|
|
29273
|
+
mesh: {
|
|
29274
|
+
fields: {
|
|
29275
|
+
positions: (v) => list(num)(v) ?? (v.length % 3 === 0 ? null : "expected a multiple of 3 numbers"),
|
|
29276
|
+
normals: list(num),
|
|
29277
|
+
uvs: list(num),
|
|
29278
|
+
indices: list(int(0))
|
|
29279
|
+
},
|
|
29280
|
+
required: ["positions"]
|
|
29281
|
+
},
|
|
29282
|
+
point: { fields: { data: () => null } },
|
|
29283
|
+
custom: { fields: { generator: str, params: () => null }, required: ["generator"] }
|
|
29284
|
+
};
|
|
29285
|
+
|
|
29286
|
+
// ../game-shapes-three/dist/index.js
|
|
29287
|
+
var UV_BEFORE_NORMAL = /* @__PURE__ */ new Set(["LatheGeometry", "ExtrudeGeometry"]);
|
|
29288
|
+
var INDEX_FIRST = /* @__PURE__ */ new Set(["BoxGeometry", "CylinderGeometry", "ConeGeometry", "SphereGeometry", "PlaneGeometry", "CircleGeometry", "RingGeometry", "LatheGeometry", "TorusGeometry"]);
|
|
29289
|
+
var isPrimitive = (value) => typeof value.type === "string";
|
|
29290
|
+
function threeParameters(THREE, p) {
|
|
29291
|
+
if (p.type === "LatheGeometry") {
|
|
29292
|
+
const points = p.parameters.points.map(({ x, y }) => new THREE.Vector2(x, y));
|
|
29293
|
+
return { ...p.parameters, points };
|
|
29294
|
+
}
|
|
29295
|
+
return { ...p.parameters };
|
|
29296
|
+
}
|
|
29297
|
+
function toGeometry(THREE, source, options = {}) {
|
|
29298
|
+
const copy = options.copy !== false;
|
|
29299
|
+
const primitive = isPrimitive(source) ? source : null;
|
|
29300
|
+
const ThreeClass = primitive && primitive.type !== "BufferGeometry" ? THREE[primitive.type] : void 0;
|
|
29301
|
+
const geometry = ThreeClass ? Reflect.construct(THREE.BufferGeometry, [], ThreeClass) : new THREE.BufferGeometry();
|
|
29302
|
+
if (primitive && ThreeClass) {
|
|
29303
|
+
Object.assign(geometry, { type: primitive.type, parameters: threeParameters(THREE, primitive) });
|
|
29304
|
+
}
|
|
29305
|
+
const attribute = (array, size) => copy ? new THREE.Float32BufferAttribute(array, size) : new THREE.BufferAttribute(array, size);
|
|
29306
|
+
const index = source.indices;
|
|
29307
|
+
const setIndex = () => {
|
|
29308
|
+
if (!index) return;
|
|
29309
|
+
geometry.setIndex(copy ? index instanceof Uint32Array ? new THREE.Uint32BufferAttribute(index, 1) : new THREE.Uint16BufferAttribute(index, 1) : new THREE.BufferAttribute(index, 1));
|
|
29310
|
+
};
|
|
29311
|
+
const type = primitive?.type ?? "BufferGeometry";
|
|
29312
|
+
if (INDEX_FIRST.has(type)) setIndex();
|
|
29313
|
+
geometry.setAttribute("position", attribute(source.positions, 3));
|
|
29314
|
+
if (UV_BEFORE_NORMAL.has(type)) {
|
|
29315
|
+
geometry.setAttribute("uv", attribute(source.uvs, 2));
|
|
29316
|
+
geometry.setAttribute("normal", attribute(source.normals, 3));
|
|
29317
|
+
} else {
|
|
29318
|
+
geometry.setAttribute("normal", attribute(source.normals, 3));
|
|
29319
|
+
geometry.setAttribute("uv", attribute(source.uvs, 2));
|
|
29320
|
+
}
|
|
29321
|
+
if (!primitive && source.colors) geometry.setAttribute("color", attribute(source.colors, 3));
|
|
29322
|
+
if (!INDEX_FIRST.has(type)) setIndex();
|
|
29323
|
+
if (primitive) for (const group of primitive.groups) geometry.addGroup(group.start, group.count, group.materialIndex);
|
|
29324
|
+
return geometry;
|
|
29325
|
+
}
|
|
29326
|
+
var SHAPE_GEOMETRY_TYPES = ["BoxGeometry", "CylinderGeometry", "ConeGeometry", "SphereGeometry", "PlaneGeometry", "CircleGeometry", "RingGeometry", "LatheGeometry", "TorusGeometry", "ExtrudeGeometry"];
|
|
29327
|
+
function linePoints(path) {
|
|
29328
|
+
if (path.autoClose || path.curves.length === 0) return null;
|
|
29329
|
+
const points = [];
|
|
29330
|
+
for (const [index, curve] of path.curves.entries()) {
|
|
29331
|
+
if (!curve.isLineCurve || !curve.v1 || !curve.v2) return null;
|
|
29332
|
+
if (index === 0) points.push([curve.v1.x, curve.v1.y]);
|
|
29333
|
+
else {
|
|
29334
|
+
const last = points[points.length - 1];
|
|
29335
|
+
if (last[0] !== curve.v1.x || last[1] !== curve.v1.y) return null;
|
|
29336
|
+
}
|
|
29337
|
+
points.push([curve.v2.x, curve.v2.y]);
|
|
29338
|
+
}
|
|
29339
|
+
return points;
|
|
29340
|
+
}
|
|
29341
|
+
function extrudeOf(shapes, options = {}) {
|
|
29342
|
+
if (Array.isArray(shapes) || !shapes || options.extrudePath !== void 0 || options.UVGenerator !== void 0) return null;
|
|
29343
|
+
const shape = shapes;
|
|
29344
|
+
const outer = linePoints(shape);
|
|
29345
|
+
if (!outer) return null;
|
|
29346
|
+
const holes = [];
|
|
29347
|
+
for (const hole of shape.holes ?? []) {
|
|
29348
|
+
const points = linePoints(hole);
|
|
29349
|
+
if (!points) return null;
|
|
29350
|
+
holes.push(points);
|
|
29351
|
+
}
|
|
29352
|
+
const outline = holes.length ? { outer, holes } : { outer };
|
|
29353
|
+
const bevel = options.bevelEnabled === false ? false : {
|
|
29354
|
+
...options.bevelThickness !== void 0 ? { thickness: options.bevelThickness } : {},
|
|
29355
|
+
...options.bevelSize !== void 0 ? { size: options.bevelSize } : {},
|
|
29356
|
+
...options.bevelOffset !== void 0 ? { offset: options.bevelOffset } : {},
|
|
29357
|
+
...options.bevelSegments !== void 0 ? { segments: options.bevelSegments } : {}
|
|
29358
|
+
};
|
|
29359
|
+
return extrude(outline, options.depth, options.steps, bevel);
|
|
29360
|
+
}
|
|
29361
|
+
var namespaces = /* @__PURE__ */ new WeakMap();
|
|
29362
|
+
var shims = /* @__PURE__ */ new WeakSet();
|
|
29363
|
+
function shapeGeometries(THREE, options = {}) {
|
|
29364
|
+
if (shims.has(THREE)) return THREE;
|
|
29365
|
+
const cache = options.cache !== false;
|
|
29366
|
+
const key = cache ? "cache" : "nocache";
|
|
29367
|
+
let byKey = namespaces.get(THREE);
|
|
29368
|
+
if (!byKey) {
|
|
29369
|
+
byKey = /* @__PURE__ */ new Map();
|
|
29370
|
+
namespaces.set(THREE, byKey);
|
|
29371
|
+
}
|
|
29372
|
+
const existing = byKey.get(key);
|
|
29373
|
+
if (existing) return existing;
|
|
29374
|
+
const made = (p) => toGeometry(THREE, p);
|
|
29375
|
+
const viaCache = (node, direct) => cache ? buildPrimitive(node) : direct();
|
|
29376
|
+
const defined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
29377
|
+
const constructors = {
|
|
29378
|
+
BoxGeometry: (width, height, depth, ws = 1, hs = 1, ds = 1) => made(viaCache({ kind: "box", size: [width ?? 1, height ?? 1, depth ?? 1], segments: [ws, hs, ds] }, () => box(width, height, depth, ws, hs, ds))),
|
|
29379
|
+
CylinderGeometry: (radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) => made(viaCache({ kind: "cylinder", ...defined({ radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cylinder(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),
|
|
29380
|
+
ConeGeometry: (radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) => made(viaCache({ kind: "cone", ...defined({ radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cone(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),
|
|
29381
|
+
SphereGeometry: (radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) => made(viaCache({ kind: "sphere", ...defined({ radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }) }, () => sphere(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength))),
|
|
29382
|
+
PlaneGeometry: (width, height, widthSegments, heightSegments) => made(viaCache({ kind: "plane", ...defined({ width, height, widthSegments, heightSegments }) }, () => plane(width, height, widthSegments, heightSegments))),
|
|
29383
|
+
CircleGeometry: (radius, segments, thetaStart, thetaLength) => made(viaCache({ kind: "circle", ...defined({ radius, segments, thetaStart, thetaLength }) }, () => circle(radius, segments, thetaStart, thetaLength))),
|
|
29384
|
+
RingGeometry: (innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) => made(viaCache({ kind: "ring", ...defined({ innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }) }, () => ring(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength))),
|
|
29385
|
+
LatheGeometry: (points, segments, phiStart, phiLength) => {
|
|
29386
|
+
if (!points) return new THREE.LatheGeometry(void 0, segments, phiStart, phiLength);
|
|
29387
|
+
const profile = points.map((p) => [p.x, p.y]);
|
|
29388
|
+
return made(viaCache({ kind: "lathe", points: profile, ...defined({ segments, phiStart, phiLength }) }, () => lathe(profile, segments, phiStart, phiLength)));
|
|
29389
|
+
},
|
|
29390
|
+
TorusGeometry: (radius, tube, radialSegments, tubularSegments, arc) => made(viaCache({ kind: "torus", ...defined({ radius, tube, radialSegments, tubularSegments, arc }) }, () => torus(radius, tube, radialSegments, tubularSegments, arc))),
|
|
29391
|
+
ExtrudeGeometry: (shapes, extrudeOptions) => {
|
|
29392
|
+
const buffers = shapes === void 0 ? null : extrudeOf(shapes, extrudeOptions);
|
|
29393
|
+
if (!buffers) return new THREE.ExtrudeGeometry(shapes, extrudeOptions);
|
|
29394
|
+
const geometry = toGeometry(THREE, buffers);
|
|
29395
|
+
geometry.parameters = { shapes, options: extrudeOptions ?? {} };
|
|
29396
|
+
return geometry;
|
|
29397
|
+
}
|
|
29398
|
+
};
|
|
29399
|
+
const namespace = { ...THREE };
|
|
29400
|
+
for (const type of SHAPE_GEOMETRY_TYPES) {
|
|
29401
|
+
const make2 = constructors[type];
|
|
29402
|
+
const Constructor = function(...args) {
|
|
29403
|
+
return make2(...args);
|
|
29404
|
+
};
|
|
29405
|
+
Constructor.prototype = THREE[type].prototype;
|
|
29406
|
+
Object.defineProperty(Constructor, "name", { value: type });
|
|
29407
|
+
namespace[type] = Constructor;
|
|
29408
|
+
}
|
|
29409
|
+
const result = namespace;
|
|
29410
|
+
byKey.set(key, result);
|
|
29411
|
+
shims.add(result);
|
|
29412
|
+
return result;
|
|
29413
|
+
}
|
|
29414
|
+
|
|
29415
|
+
// ../game-contracts/dist/index.js
|
|
29416
|
+
var DEFAULT_IGNITION_RULES = {
|
|
29417
|
+
fillCurve: [
|
|
29418
|
+
[0, 0.6],
|
|
29419
|
+
[0.1, 1],
|
|
29420
|
+
[0.35, 0.6],
|
|
29421
|
+
[0.65, 0.3],
|
|
29422
|
+
[0.9, 0.15],
|
|
29423
|
+
[1, 0.12]
|
|
29424
|
+
],
|
|
29425
|
+
flameFillInfluence: 0.5,
|
|
29426
|
+
flameDefaults: { incendiary: 0.7, tracer: 0.2 },
|
|
29427
|
+
sparkTarget: { steel: 1, iron: 1, aluminium: 0.25 },
|
|
29428
|
+
sparkMetalDefault: 0.5,
|
|
29429
|
+
sparkFluid: { diesel: 0.15 },
|
|
29430
|
+
fireNear: { radius: 1.5, chancePerSecond: 0.5 }
|
|
29431
|
+
};
|
|
29432
|
+
var resolveIgnitionRules = (rules) => ({
|
|
29433
|
+
...DEFAULT_IGNITION_RULES,
|
|
29434
|
+
...rules,
|
|
29435
|
+
flameDefaults: { ...DEFAULT_IGNITION_RULES.flameDefaults, ...rules?.flameDefaults },
|
|
29436
|
+
sparkTarget: { ...DEFAULT_IGNITION_RULES.sparkTarget, ...rules?.sparkTarget },
|
|
29437
|
+
sparkFluid: { ...DEFAULT_IGNITION_RULES.sparkFluid, ...rules?.sparkFluid },
|
|
29438
|
+
fireNear: { ...DEFAULT_IGNITION_RULES.fireNear, ...rules?.fireNear }
|
|
29439
|
+
});
|
|
29440
|
+
var fillFactor = (fill2, curve = DEFAULT_IGNITION_RULES.fillCurve) => {
|
|
29441
|
+
if (curve.length === 0) return 1;
|
|
29442
|
+
const f = Math.min(1, Math.max(0, fill2));
|
|
29443
|
+
if (f <= curve[0][0]) return curve[0][1];
|
|
29444
|
+
for (let i = 1; i < curve.length; i++) {
|
|
29445
|
+
const [x1, y1] = curve[i];
|
|
29446
|
+
const [x0, y0] = curve[i - 1];
|
|
29447
|
+
if (f <= x1) return x1 === x0 ? y1 : y0 + (y1 - y0) * (f - x0) / (x1 - x0);
|
|
29448
|
+
}
|
|
29449
|
+
return curve[curve.length - 1][1];
|
|
29450
|
+
};
|
|
29451
|
+
var sparkTargetFactor = (materialId, metal, rules = DEFAULT_IGNITION_RULES) => !metal ? 0 : rules.sparkTarget[materialId] ?? rules.sparkMetalDefault;
|
|
29452
|
+
var ignitionChance = (hit, target, rules = DEFAULT_IGNITION_RULES) => {
|
|
29453
|
+
const k = fillFactor(target.fill, rules.fillCurve);
|
|
29454
|
+
const spark = (hit.ignition?.spark ?? 0) * target.sparkTarget * (target.fluid === void 0 ? 1 : rules.sparkFluid[target.fluid] ?? 1) * k;
|
|
29455
|
+
const flameBase = hit.ignition?.flame ?? Math.max(hit.incendiary ? rules.flameDefaults.incendiary : 0, hit.tracer ? rules.flameDefaults.tracer : 0);
|
|
29456
|
+
const flame = flameBase * (1 - rules.flameFillInfluence * (1 - k));
|
|
29457
|
+
return 1 - (1 - Math.min(1, Math.max(0, spark))) * (1 - Math.min(1, Math.max(0, flame)));
|
|
29458
|
+
};
|
|
29459
|
+
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
29460
|
+
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
29461
|
+
var deepMerge = (base, patch) => {
|
|
29462
|
+
if (!patch) return base;
|
|
29463
|
+
const result = { ...base };
|
|
29464
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
29465
|
+
if (value === void 0 || UNSAFE_KEYS.has(key)) continue;
|
|
29466
|
+
const current = result[key];
|
|
29467
|
+
result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;
|
|
29468
|
+
}
|
|
29469
|
+
return result;
|
|
29470
|
+
};
|
|
29471
|
+
var mergeById = (shipped, extra) => {
|
|
29472
|
+
const entries = /* @__PURE__ */ new Map();
|
|
29473
|
+
for (const entry of [...shipped, ...extra ?? []]) entries.set(entry.id, entry);
|
|
29474
|
+
return entries;
|
|
29475
|
+
};
|
|
29476
|
+
var applyPatches = (entries, patches) => {
|
|
29477
|
+
for (const [id, patch] of Object.entries(patches ?? {})) {
|
|
29478
|
+
const entry = entries.get(id);
|
|
29479
|
+
if (entry) entries.set(id, deepMerge(entry, patch));
|
|
29480
|
+
}
|
|
29481
|
+
};
|
|
29482
|
+
var removeIds = (entries, ids) => {
|
|
29483
|
+
for (const id of ids ?? []) entries.delete(id);
|
|
29484
|
+
};
|
|
29485
|
+
|
|
27898
29486
|
// ../game-vehicles/dist/index.js
|
|
27899
29487
|
var __defProp2 = Object.defineProperty;
|
|
27900
29488
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -28580,9 +30168,9 @@ var GameVehiclesThree = (() => {
|
|
|
28580
30168
|
return envTex;
|
|
28581
30169
|
}
|
|
28582
30170
|
kit.studioEnvironment = studioEnvironment;
|
|
28583
|
-
function makeMaterial(
|
|
30171
|
+
function makeMaterial(color2, o) {
|
|
28584
30172
|
o = o || {};
|
|
28585
|
-
const c =
|
|
30173
|
+
const c = color2 instanceof THREE.Color ? color2 : new THREE.Color(color2);
|
|
28586
30174
|
const key = "s" + c.getHexString() + JSON.stringify(o, function(k, v) {
|
|
28587
30175
|
return v && v.isColor ? "#" + v.getHexString() : v && v.isTexture ? v.uuid : v;
|
|
28588
30176
|
});
|
|
@@ -28598,8 +30186,8 @@ var GameVehiclesThree = (() => {
|
|
|
28598
30186
|
}
|
|
28599
30187
|
return cache[key];
|
|
28600
30188
|
}
|
|
28601
|
-
function makeFlatMaterial(
|
|
28602
|
-
return makeMaterial(
|
|
30189
|
+
function makeFlatMaterial(color2, o) {
|
|
30190
|
+
return makeMaterial(color2, Object.assign({ flatShading: true, roughness: 0.92 }, o || {}));
|
|
28603
30191
|
}
|
|
28604
30192
|
const DOUBLE_SIDE = THREE.DoubleSide;
|
|
28605
30193
|
function toColor(hex) {
|
|
@@ -28845,10 +30433,10 @@ var GameVehiclesThree = (() => {
|
|
|
28845
30433
|
const s = new V3();
|
|
28846
30434
|
for (let i = 0; i < n; i++) {
|
|
28847
30435
|
const fi = i / 3 | 0;
|
|
28848
|
-
const
|
|
30436
|
+
const list2 = map[keys[i]];
|
|
28849
30437
|
s.set(0, 0, 0);
|
|
28850
|
-
for (let j = 0; j <
|
|
28851
|
-
const g = FN[
|
|
30438
|
+
for (let j = 0; j < list2.length; j++) {
|
|
30439
|
+
const g = FN[list2[j]];
|
|
28852
30440
|
if (g.dot(FN[fi]) >= cs) s.add(g);
|
|
28853
30441
|
}
|
|
28854
30442
|
if (s.lengthSq() < 1e-20) s.copy(FN[fi]);
|
|
@@ -28914,7 +30502,7 @@ var GameVehiclesThree = (() => {
|
|
|
28914
30502
|
const pos = [];
|
|
28915
30503
|
const col = [];
|
|
28916
30504
|
const idx = [];
|
|
28917
|
-
const
|
|
30505
|
+
const ring2 = seg + 1;
|
|
28918
30506
|
st.forEach(function(s) {
|
|
28919
30507
|
for (let j = 0; j <= seg; j++) {
|
|
28920
30508
|
const a = j / seg * PI * 2;
|
|
@@ -28932,8 +30520,8 @@ var GameVehiclesThree = (() => {
|
|
|
28932
30520
|
});
|
|
28933
30521
|
for (let i = 0; i < st.length - 1; i++)
|
|
28934
30522
|
for (let k = 0; k < seg; k++) {
|
|
28935
|
-
const a0 = i *
|
|
28936
|
-
const b0 = a0 +
|
|
30523
|
+
const a0 = i * ring2 + k;
|
|
30524
|
+
const b0 = a0 + ring2;
|
|
28937
30525
|
idx.push(a0, a0 + 1, b0, a0 + 1, b0 + 1, b0);
|
|
28938
30526
|
}
|
|
28939
30527
|
;
|
|
@@ -28947,7 +30535,7 @@ var GameVehiclesThree = (() => {
|
|
|
28947
30535
|
col.push(cc.r, cc.g, cc.b);
|
|
28948
30536
|
}
|
|
28949
30537
|
for (let k = 0; k < seg; k++) {
|
|
28950
|
-
const a = si *
|
|
30538
|
+
const a = si * ring2 + k;
|
|
28951
30539
|
if (e === 0) idx.push(ci, a + 1, a);
|
|
28952
30540
|
else idx.push(ci, a, a + 1);
|
|
28953
30541
|
}
|
|
@@ -29085,13 +30673,13 @@ var GameVehiclesThree = (() => {
|
|
|
29085
30673
|
});
|
|
29086
30674
|
tris = next;
|
|
29087
30675
|
});
|
|
29088
|
-
function build(
|
|
30676
|
+
function build(list2) {
|
|
29089
30677
|
const g = new THREE.BufferGeometry();
|
|
29090
30678
|
let off = 0;
|
|
29091
30679
|
names.forEach(function(nm, a) {
|
|
29092
|
-
const arr = new Float32Array(
|
|
30680
|
+
const arr = new Float32Array(list2.length * 3 * sizes[a]);
|
|
29093
30681
|
let w = 0;
|
|
29094
|
-
|
|
30682
|
+
list2.forEach(function(t) {
|
|
29095
30683
|
for (let k = 0; k < 3; k++) for (let q = 0; q < sizes[a]; q++) arr[w++] = t[k][off + q];
|
|
29096
30684
|
});
|
|
29097
30685
|
g.setAttribute(nm, new THREE.BufferAttribute(arr, sizes[a]));
|
|
@@ -29106,10 +30694,10 @@ var GameVehiclesThree = (() => {
|
|
|
29106
30694
|
});
|
|
29107
30695
|
return out;
|
|
29108
30696
|
}
|
|
29109
|
-
function mergeGeometries(
|
|
30697
|
+
function mergeGeometries(list2) {
|
|
29110
30698
|
const pos = [];
|
|
29111
30699
|
const nor = [];
|
|
29112
|
-
|
|
30700
|
+
list2.forEach(function(g2) {
|
|
29113
30701
|
const n = g2.index ? g2.toNonIndexed() : g2;
|
|
29114
30702
|
if (!n.attributes.normal) n.computeVertexNormals();
|
|
29115
30703
|
const pa = n.attributes.position.array;
|
|
@@ -29168,13 +30756,13 @@ var GameVehiclesThree = (() => {
|
|
|
29168
30756
|
};
|
|
29169
30757
|
kit.holeSide = function(poly, o) {
|
|
29170
30758
|
o = o || {};
|
|
29171
|
-
let
|
|
30759
|
+
let area3 = 0;
|
|
29172
30760
|
for (let i = 0; i < poly.length; i++) {
|
|
29173
30761
|
const a = poly[i];
|
|
29174
30762
|
const b = poly[(i + 1) % poly.length];
|
|
29175
|
-
|
|
30763
|
+
area3 += a[0] * b[1] - b[0] * a[1];
|
|
29176
30764
|
}
|
|
29177
|
-
const sg =
|
|
30765
|
+
const sg = area3 > 0 ? 1 : -1;
|
|
29178
30766
|
const E2 = poly.map(function(a, i) {
|
|
29179
30767
|
const b = poly[(i + 1) % poly.length];
|
|
29180
30768
|
const dx = b[0] - a[0];
|
|
@@ -29475,11 +31063,11 @@ var GameVehiclesThree = (() => {
|
|
|
29475
31063
|
return d.clone().applyQuaternion(this.vehicle.quaternion);
|
|
29476
31064
|
}
|
|
29477
31065
|
/** Declares or refines a damage zone: `c.zone(id, label, box, parts, options)`. Pass `label === false` to remove an auto-derived zone. */
|
|
29478
|
-
zone(id, label,
|
|
31066
|
+
zone(id, label, box2, parts, o) {
|
|
29479
31067
|
const d = Object.assign({ id }, o || {});
|
|
29480
31068
|
if (label === false) d.remove = true;
|
|
29481
31069
|
else if (label) d.name = label;
|
|
29482
|
-
if (
|
|
31070
|
+
if (box2) d.box = I.normalizeBox(box2);
|
|
29483
31071
|
if (parts) d.objs = Array.isArray(parts) ? parts.slice() : [parts];
|
|
29484
31072
|
this.zoneDefs.push(d);
|
|
29485
31073
|
return d;
|
|
@@ -29628,7 +31216,7 @@ var GameVehiclesThree = (() => {
|
|
|
29628
31216
|
const seg = o.seg || 24;
|
|
29629
31217
|
const pos = [];
|
|
29630
31218
|
const idx = [];
|
|
29631
|
-
const
|
|
31219
|
+
const ring2 = seg + 1;
|
|
29632
31220
|
const axisY = o.axis === "y";
|
|
29633
31221
|
st.forEach(function(s) {
|
|
29634
31222
|
const a0 = s[1];
|
|
@@ -29650,8 +31238,8 @@ var GameVehiclesThree = (() => {
|
|
|
29650
31238
|
});
|
|
29651
31239
|
for (let i = 0; i < st.length - 1; i++)
|
|
29652
31240
|
for (let k = 0; k < seg; k++) {
|
|
29653
|
-
const A = i *
|
|
29654
|
-
const B = A +
|
|
31241
|
+
const A = i * ring2 + k;
|
|
31242
|
+
const B = A + ring2;
|
|
29655
31243
|
if (axisY) idx.push(A, B, A + 1, A + 1, B, B + 1);
|
|
29656
31244
|
else idx.push(A, A + 1, B, A + 1, B + 1, B);
|
|
29657
31245
|
}
|
|
@@ -29664,7 +31252,7 @@ var GameVehiclesThree = (() => {
|
|
|
29664
31252
|
if (axisY) pos.push(cc, s[0], s[5] || 0);
|
|
29665
31253
|
else pos.push(s[0], cc, s[5] || 0);
|
|
29666
31254
|
for (let k = 0; k < seg; k++) {
|
|
29667
|
-
const a = si *
|
|
31255
|
+
const a = si * ring2 + k;
|
|
29668
31256
|
const flip = e === 0 !== axisY;
|
|
29669
31257
|
if (flip) idx.push(ci, a + 1, a);
|
|
29670
31258
|
else idx.push(ci, a, a + 1);
|
|
@@ -29892,15 +31480,15 @@ var GameVehiclesThree = (() => {
|
|
|
29892
31480
|
c.part("glass", L, m, pos, o.reach || 0.9);
|
|
29893
31481
|
return m;
|
|
29894
31482
|
};
|
|
29895
|
-
kit.asGlass = function(c,
|
|
31483
|
+
kit.asGlass = function(c, mesh2, label, type, o) {
|
|
29896
31484
|
o = o || {};
|
|
29897
|
-
const i = c.deform.indexOf(
|
|
31485
|
+
const i = c.deform.indexOf(mesh2);
|
|
29898
31486
|
if (i >= 0) c.deform.splice(i, 1);
|
|
29899
|
-
if (
|
|
29900
|
-
const geo =
|
|
29901
|
-
geo.applyMatrix4(new THREE.Matrix4().compose(
|
|
31487
|
+
if (mesh2.parent) mesh2.parent.remove(mesh2);
|
|
31488
|
+
const geo = mesh2.geometry;
|
|
31489
|
+
geo.applyMatrix4(new THREE.Matrix4().compose(mesh2.position, mesh2.quaternion, mesh2.scale));
|
|
29902
31490
|
if (o.reuv !== false) o.reuv = true;
|
|
29903
|
-
return kit.addGlass(c, geo, label, type, Object.assign({ mat:
|
|
31491
|
+
return kit.addGlass(c, geo, label, type, Object.assign({ mat: mesh2.material }, o));
|
|
29904
31492
|
};
|
|
29905
31493
|
kit.sideWindows = function(c, polys, Wg, T, label, o) {
|
|
29906
31494
|
o = o || {};
|
|
@@ -29946,12 +31534,12 @@ var GameVehiclesThree = (() => {
|
|
|
29946
31534
|
});
|
|
29947
31535
|
});
|
|
29948
31536
|
};
|
|
29949
|
-
kit.cutMesh = function(
|
|
29950
|
-
const src = o && o.sub ? subdivide(
|
|
31537
|
+
kit.cutMesh = function(mesh2, tests, deg, o) {
|
|
31538
|
+
const src = o && o.sub ? subdivide(mesh2.geometry, o.sub) : mesh2.geometry;
|
|
29951
31539
|
const r = cutGeometry(src, tests);
|
|
29952
31540
|
crease(r.geo, deg || 42);
|
|
29953
|
-
|
|
29954
|
-
|
|
31541
|
+
mesh2.geometry.dispose();
|
|
31542
|
+
mesh2.geometry = r.geo;
|
|
29955
31543
|
return r.cut;
|
|
29956
31544
|
};
|
|
29957
31545
|
kit.quadDef = function(pb, pt, Wg, T, which, bev, o) {
|
|
@@ -30149,8 +31737,8 @@ var GameVehiclesThree = (() => {
|
|
|
30149
31737
|
const pz = nR === 1 ? 0 : (i ? 1 : -1) * w / 4;
|
|
30150
31738
|
const back = gm(g, new THREE.CylinderGeometry(r * 1.06, r * 1.06, d * 0.8, 22), MATERIALS.housing, 0, 0, pz);
|
|
30151
31739
|
back.rotation.z = PI / 2;
|
|
30152
|
-
const
|
|
30153
|
-
|
|
31740
|
+
const ring2 = gm(g, new THREE.TorusGeometry(r * 1.02, 0.013, 8, 30), MATERIALS.chrome, d / 2 - 6e-3, 0, pz);
|
|
31741
|
+
ring2.rotation.y = PI / 2;
|
|
30154
31742
|
const bowl = gm(g, new THREE.SphereGeometry(r * 0.96, 18, 10, 0, PI * 2, 0, PI / 2), MATERIALS.reflectorLit, d / 2 - 0.012, 0, pz);
|
|
30155
31743
|
bowl.rotation.z = PI / 2;
|
|
30156
31744
|
bowl.scale.y = 0.55;
|
|
@@ -30227,8 +31815,8 @@ var GameVehiclesThree = (() => {
|
|
|
30227
31815
|
const e = gm(g, new THREE.CylinderGeometry(r * 0.9, r * 0.9, 0.012, 20), q * ls > 0 ? MATERIALS.tail : MATERIALS.tail, d / 2 - 0.02, 0, pz);
|
|
30228
31816
|
e.rotation.z = PI / 2;
|
|
30229
31817
|
inner.push(e);
|
|
30230
|
-
const
|
|
30231
|
-
|
|
31818
|
+
const ring2 = gm(g, new THREE.TorusGeometry(r, 0.01, 6, 24), MATERIALS.chrome, d / 2 - 4e-3, 0, pz);
|
|
31819
|
+
ring2.rotation.y = PI / 2;
|
|
30232
31820
|
const ln = gm(g, new THREE.SphereGeometry(r, 16, 8, 0, PI * 2, 0, PI / 2), MATERIALS.lensRed, d / 2 - 0.01, 0, pz);
|
|
30233
31821
|
ln.rotation.z = -PI / 2;
|
|
30234
31822
|
ln.scale.y = 0.25;
|
|
@@ -30321,7 +31909,7 @@ var GameVehiclesThree = (() => {
|
|
|
30321
31909
|
} else if (st === "mesh") {
|
|
30322
31910
|
gm(g, roundedBoxGeometry(0.05, h, w, Math.min(0.03, h * 0.3)), MATERIALS.housing);
|
|
30323
31911
|
const cell = 0.026;
|
|
30324
|
-
const
|
|
31912
|
+
const list2 = [];
|
|
30325
31913
|
const rows = Math.floor(h * 0.85 / (cell * 1.6));
|
|
30326
31914
|
const cols = Math.floor(w * 0.9 / (cell * 1.8));
|
|
30327
31915
|
for (let rI = 0; rI < rows; rI++)
|
|
@@ -30330,9 +31918,9 @@ var GameVehiclesThree = (() => {
|
|
|
30330
31918
|
hg.rotateZ(PI / 2);
|
|
30331
31919
|
hg.rotateX(PI / 6);
|
|
30332
31920
|
hg.translate(0.026, -h * 0.42 + (rI + 0.5) * h * 0.85 / rows, -w * 0.45 + (cI + 0.5 + rI % 2 * 0.5 - 0.25) * w * 0.9 / cols);
|
|
30333
|
-
|
|
31921
|
+
list2.push(hg);
|
|
30334
31922
|
}
|
|
30335
|
-
if (
|
|
31923
|
+
if (list2.length) gm(g, mergeGeometries(list2), MATERIALS.trim);
|
|
30336
31924
|
gm(g, roundedBoxGeometry(0.022, 0.014, w, 6e-3), MATERIALS.chrome, 0.03, h / 2 - 8e-3, 0);
|
|
30337
31925
|
} else if (st === "big") {
|
|
30338
31926
|
const fr = roundedBoxGeometry(0.06, h, w, 0.03);
|
|
@@ -31167,7 +32755,7 @@ var GameVehiclesThree = (() => {
|
|
|
31167
32755
|
m.underbodyGroup = ug;
|
|
31168
32756
|
const DK = makeMaterial("#1a1b1c", { roughness: 0.75, metalness: 0.3 });
|
|
31169
32757
|
const ST = MATERIALS.steel;
|
|
31170
|
-
function
|
|
32758
|
+
function box2(w, h, d, mat, x, y, z) {
|
|
31171
32759
|
return c.roundBox(w, h, d, Math.min(0.02, h * 0.4), mat, x, y, z, { parent: ug });
|
|
31172
32760
|
}
|
|
31173
32761
|
function rod(a, b, r, mat) {
|
|
@@ -31184,9 +32772,9 @@ var GameVehiclesThree = (() => {
|
|
|
31184
32772
|
rod(new V3(rx, rr, -zW), new V3(rx, rr, zW), 0.045, ST);
|
|
31185
32773
|
c.sphere(0.13, ST, rx, rr, 0, 1, 0.85, 1, { parent: ug });
|
|
31186
32774
|
rod(new V3(rx + 0.1, rr, 0), new V3(fx - 0.6, yU + 0.04, 0), 0.035, ST);
|
|
31187
|
-
} else
|
|
32775
|
+
} else box2(0.09, 0.08, zW * 2, DK, rx + 0.08, Math.max(yU, rr - 0.12), 0);
|
|
31188
32776
|
if (!ev) {
|
|
31189
|
-
|
|
32777
|
+
box2(Math.min(0.5, (fx - rx) * 0.2), 0.1, 0.38, DK, fx - 0.25, yU + 0.01, -0.05);
|
|
31190
32778
|
const tz = W * 0.3;
|
|
31191
32779
|
const mx = rx - 0.15;
|
|
31192
32780
|
const ty = Math.max(0.14, by - 0.06);
|
|
@@ -31203,10 +32791,10 @@ var GameVehiclesThree = (() => {
|
|
|
31203
32791
|
{ parent: ug, seg: 30, rs: 6 }
|
|
31204
32792
|
);
|
|
31205
32793
|
c.cylinder(0.1, 0.1, 0.42, ST, mx, ty + 0.02, tz, "x", { parent: ug });
|
|
31206
|
-
|
|
31207
|
-
|
|
32794
|
+
box2(0.24, 0.06, 0.2, DK, (fx + rx) / 2 + 0.1, ty, 0.16);
|
|
32795
|
+
box2(0.55, 0.18, W * 0.5, makeMaterial("#232527", { roughness: 0.7 }), rx + 0.62, Math.max(0.16, by - 0.02), -W * 0.1);
|
|
31208
32796
|
} else {
|
|
31209
|
-
|
|
32797
|
+
box2(
|
|
31210
32798
|
(fx - rx) * 0.72,
|
|
31211
32799
|
0.1,
|
|
31212
32800
|
W - 0.4,
|
|
@@ -31215,7 +32803,7 @@ var GameVehiclesThree = (() => {
|
|
|
31215
32803
|
Math.max(0.14, by - 0.03),
|
|
31216
32804
|
0
|
|
31217
32805
|
);
|
|
31218
|
-
for (let k = 0; k < 6; k++)
|
|
32806
|
+
for (let k = 0; k < 6; k++) box2(0.03, 0.02, W - 0.45, ST, rx + 0.4 + k * (fx - rx - 0.8) / 5, Math.max(0.14, by - 0.03) - 0.06, 0);
|
|
31219
32807
|
}
|
|
31220
32808
|
if (o.spare && m.rear < rx - 0.7) {
|
|
31221
32809
|
c.cylinder(0.32, 0.32, 0.2, MATERIALS.rubber, rx - 0.55, Math.max(0.2, by - 0.05), 0, null, { parent: ug });
|
|
@@ -31539,16 +33127,16 @@ var GameVehiclesThree = (() => {
|
|
|
31539
33127
|
}
|
|
31540
33128
|
} else {
|
|
31541
33129
|
const ns = o.spokes || 28;
|
|
31542
|
-
const
|
|
33130
|
+
const list2 = [];
|
|
31543
33131
|
for (let jj = 0; jj < ns; jj++) {
|
|
31544
33132
|
const a2 = jj / ns * PI * 2;
|
|
31545
33133
|
const cg = new THREE.CylinderGeometry(25e-4, 25e-4, sl, 4);
|
|
31546
33134
|
cg.applyMatrix4(
|
|
31547
33135
|
new THREE.Matrix4().makeRotationZ(a2 - PI / 2).setPosition(Math.cos(a2) * sl / 2, Math.sin(a2) * sl / 2, (jj % 2 ? 1 : -1) * 0.012)
|
|
31548
33136
|
);
|
|
31549
|
-
|
|
33137
|
+
list2.push(cg);
|
|
31550
33138
|
}
|
|
31551
|
-
g.add(new THREE.Mesh(mergeGeometries(
|
|
33139
|
+
g.add(new THREE.Mesh(mergeGeometries(list2), MATERIALS.chrome));
|
|
31552
33140
|
}
|
|
31553
33141
|
const hub = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.1, 12), MATERIALS.steel);
|
|
31554
33142
|
hub.rotation.x = PI / 2;
|
|
@@ -31728,9 +33316,9 @@ var GameVehiclesThree = (() => {
|
|
|
31728
33316
|
return puffTexture(k * 17, true);
|
|
31729
33317
|
});
|
|
31730
33318
|
}
|
|
31731
|
-
const
|
|
33319
|
+
const list2 = fire ? FIRE_TEXTURES : SMOKE_TEXTURES;
|
|
31732
33320
|
const mat = new THREE.SpriteMaterial({
|
|
31733
|
-
map:
|
|
33321
|
+
map: list2[Math.floor(Math.random() * list2.length)],
|
|
31734
33322
|
color: new THREE.Color(col),
|
|
31735
33323
|
transparent: true,
|
|
31736
33324
|
depthWrite: false,
|
|
@@ -33033,7 +34621,7 @@ var GameVehiclesThree = (() => {
|
|
|
33033
34621
|
}
|
|
33034
34622
|
});
|
|
33035
34623
|
const dset = new Set(c.deform);
|
|
33036
|
-
const
|
|
34624
|
+
const box2 = new THREE.Box3();
|
|
33037
34625
|
c.vehicle.children.forEach(function(o) {
|
|
33038
34626
|
if (dset.has(o) || o.userData.noFollow) return;
|
|
33039
34627
|
if (!(o.isMesh || o.isGroup && o.userData.rigid)) return;
|
|
@@ -33044,10 +34632,10 @@ var GameVehiclesThree = (() => {
|
|
|
33044
34632
|
if (!o.geometry.boundingBox) o.geometry.computeBoundingBox();
|
|
33045
34633
|
o.userData.bb0 = o.geometry.boundingBox.clone().applyMatrix4(o.matrix);
|
|
33046
34634
|
} else {
|
|
33047
|
-
|
|
33048
|
-
|
|
33049
|
-
o.userData.c0 =
|
|
33050
|
-
o.userData.bb0 =
|
|
34635
|
+
box2.setFromObject(o);
|
|
34636
|
+
box2.applyMatrix4(gInv);
|
|
34637
|
+
o.userData.c0 = box2.getCenter(new V3());
|
|
34638
|
+
o.userData.bb0 = box2.clone();
|
|
33051
34639
|
}
|
|
33052
34640
|
o.userData.pos0 = o.position.clone();
|
|
33053
34641
|
}
|
|
@@ -33341,11 +34929,11 @@ var GameVehiclesThree = (() => {
|
|
|
33341
34929
|
[12, "#d8322a", kit.t("blast.lethal", { m: 12 })],
|
|
33342
34930
|
[30, "#e0a548", kit.t("blast.injury", { m: 30 })]
|
|
33343
34931
|
].forEach(function(r) {
|
|
33344
|
-
const
|
|
33345
|
-
|
|
33346
|
-
|
|
33347
|
-
|
|
33348
|
-
g.add(
|
|
34932
|
+
const ring2 = new THREE.Mesh(new THREE.RingGeometry(r[0] - 0.25, r[0], 96), boomMat(r[1], 0.85));
|
|
34933
|
+
ring2.rotation.x = -PI / 2;
|
|
34934
|
+
ring2.position.y = 0.06;
|
|
34935
|
+
ring2.renderOrder = 5;
|
|
34936
|
+
g.add(ring2);
|
|
33349
34937
|
const fill2 = new THREE.Mesh(new THREE.CircleGeometry(r[0], 96), boomMat(r[1], 0.07));
|
|
33350
34938
|
fill2.rotation.x = -PI / 2;
|
|
33351
34939
|
fill2.position.y = 0.05;
|
|
@@ -33362,7 +34950,7 @@ var GameVehiclesThree = (() => {
|
|
|
33362
34950
|
lb.rotation.x = -PI / 2;
|
|
33363
34951
|
lb.position.set(0, 0.08, r[0] + r[0] * 0.06);
|
|
33364
34952
|
g.add(lb);
|
|
33365
|
-
c.bigFx.rings.push(
|
|
34953
|
+
c.bigFx.rings.push(ring2, fill2, lb);
|
|
33366
34954
|
});
|
|
33367
34955
|
}
|
|
33368
34956
|
function detonate(c) {
|
|
@@ -33635,7 +35223,7 @@ var GameVehiclesThree = (() => {
|
|
|
33635
35223
|
const I = kit._;
|
|
33636
35224
|
const { MATERIALS } = I;
|
|
33637
35225
|
function rollMeshes(c) {
|
|
33638
|
-
const
|
|
35226
|
+
const list2 = [];
|
|
33639
35227
|
const thin = [];
|
|
33640
35228
|
c.root.updateMatrixWorld(true);
|
|
33641
35229
|
const inv = new THREE.Matrix4().copy(c.vehicle.matrixWorld).invert();
|
|
@@ -33653,9 +35241,9 @@ var GameVehiclesThree = (() => {
|
|
|
33653
35241
|
thin.push({ o: ob, M });
|
|
33654
35242
|
return;
|
|
33655
35243
|
}
|
|
33656
|
-
|
|
35244
|
+
list2.push({ o: ob, M });
|
|
33657
35245
|
});
|
|
33658
|
-
return { list, thin };
|
|
35246
|
+
return { list: list2, thin };
|
|
33659
35247
|
}
|
|
33660
35248
|
function convexHull(pts) {
|
|
33661
35249
|
pts.sort(function(a, b) {
|
|
@@ -33738,7 +35326,7 @@ var GameVehiclesThree = (() => {
|
|
|
33738
35326
|
};
|
|
33739
35327
|
function rollContact(c, A, q) {
|
|
33740
35328
|
const m = c.meta;
|
|
33741
|
-
const
|
|
35329
|
+
const list2 = [];
|
|
33742
35330
|
const dy = A.cen[0] - q[0];
|
|
33743
35331
|
const dz = A.cen[1] - q[1];
|
|
33744
35332
|
const dl = Math.hypot(dy, dz) || 1;
|
|
@@ -33746,17 +35334,17 @@ var GameVehiclesThree = (() => {
|
|
|
33746
35334
|
const f = 0.75;
|
|
33747
35335
|
const bike = m.kind === "bike";
|
|
33748
35336
|
(bike ? [0] : [-0.28, 0, 0.28]).forEach(function(k) {
|
|
33749
|
-
|
|
35337
|
+
list2.push([new V3(A.x + k * A.L, q[0], q[1]), dir]);
|
|
33750
35338
|
});
|
|
33751
35339
|
if (!bike && Math.abs(dir.z) > 0.75 && m.top - m.belt > 0.25 && A.hits < 3) {
|
|
33752
35340
|
const sd = -Math.sign(dir.z);
|
|
33753
35341
|
const yw = m.belt + (m.top - m.belt) * 0.45;
|
|
33754
35342
|
[-0.25, 0.2].forEach(function(k) {
|
|
33755
35343
|
const h = I.probe(c, new V3(A.x + k * A.L, yw, sd * (m.width / 2 + 2)), new V3(0, 0, -sd), 2 + m.width);
|
|
33756
|
-
if (h)
|
|
35344
|
+
if (h) list2.push([h.p, new V3(0, 0, -sd)]);
|
|
33757
35345
|
});
|
|
33758
35346
|
}
|
|
33759
|
-
|
|
35347
|
+
list2.forEach(function(e) {
|
|
33760
35348
|
I.impact(c, e[0], e[1], f, { noStain: true, maxDepth: 0.1 });
|
|
33761
35349
|
const pf = c.toEffects(e[0]);
|
|
33762
35350
|
pf.y = Math.max(0.03, pf.y);
|
|
@@ -33766,15 +35354,15 @@ var GameVehiclesThree = (() => {
|
|
|
33766
35354
|
});
|
|
33767
35355
|
A.hits++;
|
|
33768
35356
|
A.bounce = A.hits === 1 ? 0.06 : 0.1;
|
|
33769
|
-
if (m.kind === "boat") I.burst(c, "water", c.toEffects(
|
|
35357
|
+
if (m.kind === "boat") I.burst(c, "water", c.toEffects(list2[0][0]).setY(0.05), 30, { speed: 3 });
|
|
33770
35358
|
}
|
|
33771
|
-
function exactMinY(c,
|
|
35359
|
+
function exactMinY(c, list2) {
|
|
33772
35360
|
c.root.updateMatrixWorld(true);
|
|
33773
35361
|
const inv = new THREE.Matrix4().copy(c.root.matrixWorld).invert();
|
|
33774
35362
|
const M = new THREE.Matrix4();
|
|
33775
35363
|
const v = new V3();
|
|
33776
35364
|
let mn = 1e9;
|
|
33777
|
-
|
|
35365
|
+
list2.forEach(function(e) {
|
|
33778
35366
|
const ob = e.o;
|
|
33779
35367
|
if (!ob.parent || !I.shown(c, ob)) return;
|
|
33780
35368
|
M.multiplyMatrices(inv, ob.matrixWorld);
|
|
@@ -35954,9 +37542,9 @@ var GameVehiclesThree = (() => {
|
|
|
35954
37542
|
down: new V3(0, 1, 0)
|
|
35955
37543
|
}[d] || null;
|
|
35956
37544
|
}
|
|
35957
|
-
function resolveObjs(c,
|
|
37545
|
+
function resolveObjs(c, list2, z) {
|
|
35958
37546
|
const out = [];
|
|
35959
|
-
(
|
|
37547
|
+
(list2 || []).forEach(function(o) {
|
|
35960
37548
|
if (!o) return;
|
|
35961
37549
|
if (typeof o === "string") {
|
|
35962
37550
|
c.parts.forEach(function(p) {
|
|
@@ -35984,22 +37572,22 @@ var GameVehiclesThree = (() => {
|
|
|
35984
37572
|
}
|
|
35985
37573
|
function deriveZones(c) {
|
|
35986
37574
|
const m = c.meta;
|
|
35987
|
-
let
|
|
37575
|
+
let list2 = [];
|
|
35988
37576
|
const byId = {};
|
|
35989
37577
|
(m.zones === false ? [] : I.autoZones(c)).forEach(function(z) {
|
|
35990
37578
|
byId[z.id] = z;
|
|
35991
|
-
|
|
37579
|
+
list2.push(z);
|
|
35992
37580
|
});
|
|
35993
37581
|
(c.zoneDefs || []).forEach(function(d) {
|
|
35994
37582
|
let z = byId[d.id];
|
|
35995
37583
|
if (d.remove) {
|
|
35996
37584
|
if (z) {
|
|
35997
|
-
|
|
37585
|
+
list2.splice(list2.indexOf(z), 1);
|
|
35998
37586
|
delete byId[d.id];
|
|
35999
37587
|
}
|
|
36000
|
-
|
|
37588
|
+
list2.slice().forEach(function(q) {
|
|
36001
37589
|
if (q.id.indexOf(d.id + "_") === 0 && /^\d+$/.test(q.id.slice(d.id.length + 1))) {
|
|
36002
|
-
|
|
37590
|
+
list2.splice(list2.indexOf(q), 1);
|
|
36003
37591
|
delete byId[q.id];
|
|
36004
37592
|
}
|
|
36005
37593
|
});
|
|
@@ -36012,7 +37600,7 @@ var GameVehiclesThree = (() => {
|
|
|
36012
37600
|
} else {
|
|
36013
37601
|
z = Object.assign({ type: "panel" }, d);
|
|
36014
37602
|
byId[d.id] = z;
|
|
36015
|
-
|
|
37603
|
+
list2.push(z);
|
|
36016
37604
|
}
|
|
36017
37605
|
});
|
|
36018
37606
|
const inv = I.worldInverseOf(c);
|
|
@@ -36045,10 +37633,10 @@ var GameVehiclesThree = (() => {
|
|
|
36045
37633
|
}
|
|
36046
37634
|
z.box = I.normalizeBox(bb);
|
|
36047
37635
|
});
|
|
36048
|
-
|
|
37636
|
+
list2 = list2.filter(function(z) {
|
|
36049
37637
|
return z.box && z.name;
|
|
36050
37638
|
});
|
|
36051
|
-
|
|
37639
|
+
list2.forEach(function(z) {
|
|
36052
37640
|
z.glass = (z.glass || []).slice();
|
|
36053
37641
|
z.lights = (z.lights || []).slice();
|
|
36054
37642
|
z.wheels = (z.wheels || []).slice();
|
|
@@ -36085,7 +37673,7 @@ var GameVehiclesThree = (() => {
|
|
|
36085
37673
|
if (owner.has(g) || !g.parent || !g.userData.glass || g.userData.ghost) return;
|
|
36086
37674
|
const cg = I.localBox(c, g, inv).getCenter(new V3());
|
|
36087
37675
|
let best = null;
|
|
36088
|
-
|
|
37676
|
+
list2.forEach(function(z) {
|
|
36089
37677
|
if (z.internal || z.type === "wheel" || z.type === "light") return;
|
|
36090
37678
|
if (I.boxContains(z.box, cg.x, cg.y, cg.z, 0.05) && (!best || I.boxVolume(z.box) < I.boxVolume(best.box))) best = z;
|
|
36091
37679
|
});
|
|
@@ -36094,7 +37682,7 @@ var GameVehiclesThree = (() => {
|
|
|
36094
37682
|
owner.set(g, best);
|
|
36095
37683
|
}
|
|
36096
37684
|
});
|
|
36097
|
-
const looseParts =
|
|
37685
|
+
const looseParts = list2.filter(function(z) {
|
|
36098
37686
|
return z.type === "part";
|
|
36099
37687
|
});
|
|
36100
37688
|
if (looseParts.length)
|
|
@@ -36119,7 +37707,7 @@ var GameVehiclesThree = (() => {
|
|
|
36119
37707
|
});
|
|
36120
37708
|
}
|
|
36121
37709
|
});
|
|
36122
|
-
|
|
37710
|
+
list2.forEach(function(z) {
|
|
36123
37711
|
if (!z.mirror) return;
|
|
36124
37712
|
z.mirrors = [];
|
|
36125
37713
|
const B = z.box;
|
|
@@ -36151,21 +37739,21 @@ var GameVehiclesThree = (() => {
|
|
|
36151
37739
|
});
|
|
36152
37740
|
}
|
|
36153
37741
|
});
|
|
36154
|
-
|
|
37742
|
+
list2.forEach(function(z) {
|
|
36155
37743
|
const B = z.box;
|
|
36156
37744
|
z.map = z.map || [Math.max(B.x0, R - 0.3), Math.min(B.x1, F + 0.3), Math.max(B.z0, -W / 2 - 0.35), Math.min(B.z1, W / 2 + 0.35)];
|
|
36157
37745
|
});
|
|
36158
|
-
carMap(c,
|
|
37746
|
+
carMap(c, list2);
|
|
36159
37747
|
c.zoneOwners = owner;
|
|
36160
|
-
return
|
|
37748
|
+
return list2;
|
|
36161
37749
|
}
|
|
36162
|
-
function carMap(c,
|
|
37750
|
+
function carMap(c, list2) {
|
|
36163
37751
|
const m = c.meta;
|
|
36164
37752
|
const W = m.width || 1.7;
|
|
36165
37753
|
const hw = W / 2;
|
|
36166
37754
|
const gh = m.glasshouse;
|
|
36167
37755
|
if ((m.kind || "car") !== "car" || !gh || gh.fb == null) return;
|
|
36168
|
-
|
|
37756
|
+
list2.forEach(function(z) {
|
|
36169
37757
|
if (z.mapSet) return;
|
|
36170
37758
|
const B = z.box;
|
|
36171
37759
|
const s = z.side;
|
|
@@ -36228,8 +37816,8 @@ var GameVehiclesThree = (() => {
|
|
|
36228
37816
|
const top = m.top || belt + 0.5;
|
|
36229
37817
|
const hw = W / 2;
|
|
36230
37818
|
const WH = I.wheelInfo(c);
|
|
36231
|
-
function add2(id, name, type,
|
|
36232
|
-
const z = Object.assign({ id, name, type, box: I.normalizeBox(
|
|
37819
|
+
function add2(id, name, type, box2, o) {
|
|
37820
|
+
const z = Object.assign({ id, name, type, box: I.normalizeBox(box2) }, o || {});
|
|
36233
37821
|
Z.push(z);
|
|
36234
37822
|
return z;
|
|
36235
37823
|
}
|
|
@@ -37723,9 +39311,9 @@ var GameVehiclesThree = (() => {
|
|
|
37723
39311
|
const kind = kindOf2(zone);
|
|
37724
39312
|
if (!kind || !zone.box) continue;
|
|
37725
39313
|
const b = zone.box;
|
|
37726
|
-
const
|
|
37727
|
-
if (matrix)
|
|
37728
|
-
out.push({ material: kind.material, zone: zone.id, part: kind.part, side: zone.side === 0 ? "center" : zone.side < 0 ? "left" : "right", box });
|
|
39314
|
+
const box2 = new THREE.Box3(new THREE.Vector3(b.x0, b.y0, b.z0), new THREE.Vector3(b.x1, b.y1, b.z1));
|
|
39315
|
+
if (matrix) box2.applyMatrix4(matrix);
|
|
39316
|
+
out.push({ material: kind.material, zone: zone.id, part: kind.part, side: zone.side === 0 ? "center" : zone.side < 0 ? "left" : "right", box: box2 });
|
|
37729
39317
|
}
|
|
37730
39318
|
return out;
|
|
37731
39319
|
};
|
|
@@ -37734,7 +39322,7 @@ var GameVehiclesThree = (() => {
|
|
|
37734
39322
|
const opts = options || {};
|
|
37735
39323
|
if (!opts.THREE || !opts.THREE.Vector3) throw new Error("createVehicleKit: options.THREE (the three.js namespace) is required");
|
|
37736
39324
|
const lod = createLod(opts.lod);
|
|
37737
|
-
const THREE = wrapThreeForLod(opts.THREE, lod);
|
|
39325
|
+
const THREE = wrapThreeForLod(shapeGeometries(opts.THREE), lod);
|
|
37738
39326
|
const strings = resolveStrings(opts.locale);
|
|
37739
39327
|
const t = createTranslate(strings);
|
|
37740
39328
|
const doc = opts.document || (typeof document !== "undefined" ? document : void 0);
|
|
@@ -38120,19 +39708,19 @@ var GameVehiclesThree = (() => {
|
|
|
38120
39708
|
for (const z of zones) {
|
|
38121
39709
|
let role = roleOfZone(z);
|
|
38122
39710
|
if (z === hubZone) role = "frame";
|
|
38123
|
-
const
|
|
38124
|
-
const
|
|
39711
|
+
const box2 = boxOf(z);
|
|
39712
|
+
const area3 = areaOf(box2.size);
|
|
38125
39713
|
const id = z.id;
|
|
38126
39714
|
const label = String(z.name ?? id);
|
|
38127
39715
|
const tags = [...z.tags ?? []];
|
|
38128
39716
|
if (role === "rim") {
|
|
38129
39717
|
const wheels = z.wheels ?? [];
|
|
38130
39718
|
const r = Math.max(0.2, ...wheels.map((w) => w.userData?.r ?? 0.3));
|
|
38131
|
-
const sz = Math.sign(
|
|
38132
|
-
const rimBox = { center: [
|
|
39719
|
+
const sz = Math.sign(box2.center[2]) || 1;
|
|
39720
|
+
const rimBox = { center: [box2.center[0], box2.center[1], box2.center[2] - sz * box2.size[2] * 0.25], size: [box2.size[0] * 0.7, box2.size[1] * 0.7, box2.size[2] * 0.5] };
|
|
38133
39721
|
add2({ id, role, name: label, material: kind === "plane" || kind === "heli" ? "aluminium" : "steel", box: rimBox, mass: 22 * r * Math.max(1, wheels.length), hp: 12e3 * armour, zoneId: id, visual: kind !== "plane" && !/landing/.test(id), tags: ["wheel", ...tags] });
|
|
38134
39722
|
const tyreId = id.replace(/^wheels?/, "tyre").replace(/^(?!tyre)/, "tyre_");
|
|
38135
|
-
const tyreBox = { center:
|
|
39723
|
+
const tyreBox = { center: box2.center, size: [box2.size[0] * 0.98, box2.size[1] * 0.98, box2.size[2]] };
|
|
38136
39724
|
add2({
|
|
38137
39725
|
id: tyreId,
|
|
38138
39726
|
role: "tyre",
|
|
@@ -38152,29 +39740,29 @@ var GameVehiclesThree = (() => {
|
|
|
38152
39740
|
if (role === "glass") {
|
|
38153
39741
|
const glass = (z.glass ?? [])[0];
|
|
38154
39742
|
const laminated = glass?.userData?.glass?.type === "laminated" || m.bullet;
|
|
38155
|
-
add2({ id, role, name: label, material: "glass", box, mass: 10 *
|
|
39743
|
+
add2({ id, role, name: label, material: "glass", box: box2, mass: 10 * area3, hp: laminated ? 4e3 : 450, zoneId: id, visual: false, tags: ["glass", ...tags] });
|
|
38156
39744
|
continue;
|
|
38157
39745
|
}
|
|
38158
39746
|
if (role === "light") {
|
|
38159
|
-
add2({ id, role, name: label, material: "glass", box, mass: 1.2 + 4 *
|
|
39747
|
+
add2({ id, role, name: label, material: "glass", box: box2, mass: 1.2 + 4 * area3, hp: 320, zoneId: id, visual: true, tags: ["light", ...tags] });
|
|
38160
39748
|
continue;
|
|
38161
39749
|
}
|
|
38162
39750
|
if (role === "bumper") {
|
|
38163
|
-
add2({ id, role, name: label, material: "plastic", box, mass: 6 + 5 *
|
|
39751
|
+
add2({ id, role, name: label, material: "plastic", box: box2, mass: 6 + 5 * area3, hp: 9e3, ignitionC: 400, zoneId: id, visual: true, tags: ["bumper", ...tags] });
|
|
38164
39752
|
continue;
|
|
38165
39753
|
}
|
|
38166
39754
|
if (role === "engine") {
|
|
38167
39755
|
const kg2 = { bike: 55, quad: 90, car: 150, tractor: 450, truck: 600, bus: 450, tank: 900, boat: 90, plane: 160, heli: 150 }[kind];
|
|
38168
|
-
add2({ id, role, name: label, material: kind === "plane" || kind === "heli" ? "aluminium" : "steel", box, mass: kg2, hp: 6e4 * armour, ignitionC: 260, zoneId: id, visual: false, tags: ["engine", ...tags] });
|
|
39756
|
+
add2({ id, role, name: label, material: kind === "plane" || kind === "heli" ? "aluminium" : "steel", box: box2, mass: kg2, hp: 6e4 * armour, ignitionC: 260, zoneId: id, visual: false, tags: ["engine", ...tags] });
|
|
38169
39757
|
continue;
|
|
38170
39758
|
}
|
|
38171
39759
|
if (role === "radiator") {
|
|
38172
|
-
add2({ id, role, name: label, material: "aluminium", box, mass: 8, hp: 3e3, zoneId: id, visual: false, contains: { fluid: "coolant", liters: kind === "truck" || kind === "bus" ? 18 : 7, pressurized: true }, tags: ["radiator", ...tags] });
|
|
39760
|
+
add2({ id, role, name: label, material: "aluminium", box: box2, mass: 8, hp: 3e3, zoneId: id, visual: false, contains: { fluid: "coolant", liters: kind === "truck" || kind === "bus" ? 18 : 7, pressurized: true }, tags: ["radiator", ...tags] });
|
|
38173
39761
|
continue;
|
|
38174
39762
|
}
|
|
38175
39763
|
if (role === "fuel_tank") {
|
|
38176
39764
|
if (fuelless) {
|
|
38177
|
-
add2({ id, role: "other", name: label, material: "steel", box, mass: 20, hp: 25e3, zoneId: id, visual: false, tags });
|
|
39765
|
+
add2({ id, role: "other", name: label, material: "steel", box: box2, mass: 20, hp: 25e3, zoneId: id, visual: false, tags });
|
|
38178
39766
|
continue;
|
|
38179
39767
|
}
|
|
38180
39768
|
const liters = { bike: 14, quad: 16, car: 55, tractor: 150, truck: 300, bus: 200, tank: 600, boat: 90, plane: 120, heli: 300 }[kind];
|
|
@@ -38184,7 +39772,7 @@ var GameVehiclesThree = (() => {
|
|
|
38184
39772
|
role,
|
|
38185
39773
|
name: label,
|
|
38186
39774
|
material: "steel",
|
|
38187
|
-
box,
|
|
39775
|
+
box: box2,
|
|
38188
39776
|
mass: 14 + liters * 0.8,
|
|
38189
39777
|
hp: 25e3 * armour,
|
|
38190
39778
|
zoneId: id,
|
|
@@ -38197,21 +39785,21 @@ var GameVehiclesThree = (() => {
|
|
|
38197
39785
|
continue;
|
|
38198
39786
|
}
|
|
38199
39787
|
if (role === "battery") {
|
|
38200
|
-
add2({ id, role, name: label, material: "plastic", box, mass: 14, hp: 1500, zoneId: id, visual: true, ignitionC: 200, tags: ["battery", ...tags] });
|
|
39788
|
+
add2({ id, role, name: label, material: "plastic", box: box2, mass: 14, hp: 1500, zoneId: id, visual: true, ignitionC: 200, tags: ["battery", ...tags] });
|
|
38201
39789
|
continue;
|
|
38202
39790
|
}
|
|
38203
39791
|
if (role === "frame") {
|
|
38204
|
-
add2({ id, role, name: label, material: "steel", box: floorPan(
|
|
39792
|
+
add2({ id, role, name: label, material: "steel", box: floorPan(box2), mass: mass * 0.25, hp: 15e4 * armour, zoneId: id, visual: false, tags: ["frame", ...tags] });
|
|
38205
39793
|
continue;
|
|
38206
39794
|
}
|
|
38207
39795
|
const roofLike = role === "roof";
|
|
38208
|
-
const kg = (skin === "steel" ? STEEL_KG_M2 : ALU_KG_M2) *
|
|
39796
|
+
const kg = (skin === "steel" ? STEEL_KG_M2 : ALU_KG_M2) * area3 * (role === "door" ? 1.6 : 1);
|
|
38209
39797
|
add2({
|
|
38210
39798
|
id,
|
|
38211
39799
|
role,
|
|
38212
39800
|
name: label,
|
|
38213
39801
|
material: skin,
|
|
38214
|
-
box,
|
|
39802
|
+
box: box2,
|
|
38215
39803
|
mass: Math.max(2, kg),
|
|
38216
39804
|
hp: (roofLike ? 3e4 : 2e4) * armour,
|
|
38217
39805
|
zoneId: id,
|
|
@@ -38433,7 +40021,7 @@ var GameVehiclesThree = (() => {
|
|
|
38433
40021
|
const my = kind === "bike" || kind === "quad" ? (m.top ?? belt + 0.25) - 0.1 : belt + 0.12;
|
|
38434
40022
|
for (const s of [-1, 1]) {
|
|
38435
40023
|
const door = zones.find((z) => z.type === "door" && z.side === s && (z.mirrors ?? []).length);
|
|
38436
|
-
let
|
|
40024
|
+
let box2 = { center: [mx, my, s * half], size: [0.14, 0.12, 0.2] };
|
|
38437
40025
|
if (door) {
|
|
38438
40026
|
const bb = door.mirrors.reduce(
|
|
38439
40027
|
(acc, o) => {
|
|
@@ -38446,14 +40034,14 @@ var GameVehiclesThree = (() => {
|
|
|
38446
40034
|
},
|
|
38447
40035
|
null
|
|
38448
40036
|
);
|
|
38449
|
-
if (bb)
|
|
40037
|
+
if (bb) box2 = { center: [(bb[0] + bb[1]) / 2, (bb[2] + bb[3]) / 2, (bb[4] + bb[5]) / 2], size: [Math.max(0.06, bb[1] - bb[0]), Math.max(0.06, bb[3] - bb[2]), Math.max(0.06, bb[5] - bb[4])] };
|
|
38450
40038
|
}
|
|
38451
40039
|
add2({
|
|
38452
40040
|
id: `mirror_${side(s)}`,
|
|
38453
40041
|
role: "mirror",
|
|
38454
40042
|
name: t("mechanics.mirror", { side: t(`sides.${side(s)}`), sideM: t(`sides.${side(s)}M`) }),
|
|
38455
40043
|
material: "plastic",
|
|
38456
|
-
box,
|
|
40044
|
+
box: box2,
|
|
38457
40045
|
mass: 1.1,
|
|
38458
40046
|
hp: 1500,
|
|
38459
40047
|
ignitionC: 400,
|
|
@@ -38639,13 +40227,13 @@ var GameVehiclesThree = (() => {
|
|
|
38639
40227
|
(parent ?? this.c.vehicle).add(m);
|
|
38640
40228
|
return m;
|
|
38641
40229
|
}
|
|
38642
|
-
surface(axis,
|
|
40230
|
+
surface(axis, sign2, B, samples) {
|
|
38643
40231
|
const V3 = this.THREE.Vector3;
|
|
38644
40232
|
const hits = [];
|
|
38645
40233
|
const far = 3;
|
|
38646
40234
|
for (const [u, v] of samples) {
|
|
38647
|
-
const o = axis === "z" ? new V3(u, v,
|
|
38648
|
-
const d = axis === "z" ? new V3(0, 0, -
|
|
40235
|
+
const o = axis === "z" ? new V3(u, v, sign2 * (Math.max(Math.abs(B.z0), Math.abs(B.z1)) + 1)) : new V3(sign2 * (Math.max(Math.abs(B.x0), Math.abs(B.x1)) + 1), u, v);
|
|
40236
|
+
const d = axis === "z" ? new V3(0, 0, -sign2) : new V3(-sign2, 0, 0);
|
|
38649
40237
|
const h = this.I.probe(this.c, o, d, far);
|
|
38650
40238
|
if (h) hits.push(axis === "z" ? h.p.z : h.p.x);
|
|
38651
40239
|
}
|
|
@@ -38795,12 +40383,12 @@ var GameVehiclesThree = (() => {
|
|
|
38795
40383
|
const z = this.zone(p);
|
|
38796
40384
|
if (!z) return false;
|
|
38797
40385
|
const V3 = this.THREE.Vector3;
|
|
38798
|
-
const
|
|
38799
|
-
if (!
|
|
40386
|
+
const list2 = z.glass.filter((g) => g.parent && g.visible);
|
|
40387
|
+
if (!list2.length) return false;
|
|
38800
40388
|
const pt = new V3(...point);
|
|
38801
|
-
let best =
|
|
40389
|
+
let best = list2[0];
|
|
38802
40390
|
let bd = Infinity;
|
|
38803
|
-
for (const g of
|
|
40391
|
+
for (const g of list2) {
|
|
38804
40392
|
g.geometry.computeBoundingBox();
|
|
38805
40393
|
const bb = g.geometry.boundingBox.clone().applyMatrix4(g.matrix);
|
|
38806
40394
|
const d = bb.distanceToPoint(pt);
|
|
@@ -39097,6 +40685,9 @@ var GameVehiclesThree = (() => {
|
|
|
39097
40685
|
const headless = !!options.headless;
|
|
39098
40686
|
const seedBase = strHash(`${c.key}|${id}|${options.seed ?? 0}`);
|
|
39099
40687
|
let rand = rng(seedBase);
|
|
40688
|
+
const ignitionRules = resolveIgnitionRules(options.ignition);
|
|
40689
|
+
const fuelFraction = clamp(options.fuel ?? 1, 0, 1);
|
|
40690
|
+
let igniteRand = rng(strHash(`${c.key}|${id}|ignition|${options.seed ?? 0}`));
|
|
39100
40691
|
let clock = 0;
|
|
39101
40692
|
let model;
|
|
39102
40693
|
let vis = null;
|
|
@@ -39164,7 +40755,7 @@ var GameVehiclesThree = (() => {
|
|
|
39164
40755
|
dents: [],
|
|
39165
40756
|
holes: [],
|
|
39166
40757
|
cracks: [],
|
|
39167
|
-
liters: d.contains
|
|
40758
|
+
liters: d.contains ? d.role === "fuel_tank" ? d.contains.liters * fuelFraction : d.contains.liters : void 0,
|
|
39168
40759
|
lost: false,
|
|
39169
40760
|
status: "intact",
|
|
39170
40761
|
flat: false,
|
|
@@ -39182,6 +40773,7 @@ var GameVehiclesThree = (() => {
|
|
|
39182
40773
|
wasLit = true;
|
|
39183
40774
|
deadEngine = false;
|
|
39184
40775
|
rand = rng(seedBase);
|
|
40776
|
+
igniteRand = rng(strHash(`${c.key}|${id}|ignition|${options.seed ?? 0}`));
|
|
39185
40777
|
steerSign = rand() < 0.5 ? -1 : 1;
|
|
39186
40778
|
vis = headless ? null : new VehicleVisuals(kit, c, model);
|
|
39187
40779
|
recomputeGroups();
|
|
@@ -39203,8 +40795,8 @@ var GameVehiclesThree = (() => {
|
|
|
39203
40795
|
comps.get(r).push(p);
|
|
39204
40796
|
}
|
|
39205
40797
|
const hubRoot = parent.has(model.hub) ? find(model.hub) : "";
|
|
39206
|
-
const
|
|
39207
|
-
groupsCache =
|
|
40798
|
+
const list2 = [...comps.entries()].sort((a, b) => a[0] === hubRoot ? -1 : b[0] === hubRoot ? 1 : 0);
|
|
40799
|
+
groupsCache = list2.map(([, v]) => v);
|
|
39208
40800
|
groupOf = /* @__PURE__ */ new Map();
|
|
39209
40801
|
groupsCache.forEach((g, i) => g.forEach((p) => groupOf.set(p, i)));
|
|
39210
40802
|
return groupsCache;
|
|
@@ -39476,8 +41068,19 @@ var GameVehiclesThree = (() => {
|
|
|
39476
41068
|
if (!p.burning && p.temp > AMBIENT) p.temp = Math.max(AMBIENT, p.temp - dt * 6);
|
|
39477
41069
|
}
|
|
39478
41070
|
for (const f of flames) heat(centreOf(f.def), 0.8, 500, dt * 0.5, out, 0);
|
|
41071
|
+
fireNearLeak(flames, dt, out);
|
|
39479
41072
|
thermal(out);
|
|
39480
41073
|
};
|
|
41074
|
+
const fireNearLeak = (flames, dt, out) => {
|
|
41075
|
+
const tank = tankPart();
|
|
41076
|
+
const leak = tank ? leaks.get(tank.def.id) : void 0;
|
|
41077
|
+
if (!tank || !leak || tank.lost || tank.burning || exploded || leak.fluid !== "fuel" && leak.fluid !== "diesel") return;
|
|
41078
|
+
if (leak.pud?.fire) return light(tank, out);
|
|
41079
|
+
const { radius, chancePerSecond } = ignitionRules.fireNear;
|
|
41080
|
+
if (chancePerSecond <= 0) return;
|
|
41081
|
+
const near = flames.some((f) => f !== tank && distToBox(tank.def, centreOf(f.def)) - Math.max(...f.def.box.size) / 2 <= radius);
|
|
41082
|
+
if (near && igniteRand() < 1 - Math.exp(-chancePerSecond * dt)) light(tank, out);
|
|
41083
|
+
};
|
|
39481
41084
|
const normalOf = (d, v) => faceNormal(d, v);
|
|
39482
41085
|
const ballistic = (h, out) => {
|
|
39483
41086
|
sync();
|
|
@@ -39545,10 +41148,21 @@ var GameVehiclesThree = (() => {
|
|
|
39545
41148
|
let amount = through ? E * 0.6 : E * 0.25;
|
|
39546
41149
|
if (through && (d.role === "battery" || d.role === "alternator")) amount = Math.max(amount, p.hp * 0.65);
|
|
39547
41150
|
damage(p, amount, "ballistic", h.source, out, worldPoint);
|
|
39548
|
-
if (d.role === "fuel_tank"
|
|
41151
|
+
if (through && d.role === "fuel_tank") rollIgnition(p, h, metal, out);
|
|
39549
41152
|
}
|
|
39550
41153
|
}
|
|
39551
41154
|
};
|
|
41155
|
+
const light = (tank, out) => {
|
|
41156
|
+
tank.temp = Math.max(tank.temp, (tank.def.ignitionC ?? 260) + 1);
|
|
41157
|
+
if ((tank.liters ?? 0) > 0.5) ignite(tank, out);
|
|
41158
|
+
};
|
|
41159
|
+
const rollIgnition = (tank, h, metal, out) => {
|
|
41160
|
+
const d = tank.def;
|
|
41161
|
+
if (!d.contains || tank.burning || (tank.liters ?? 0) <= 0.05) return;
|
|
41162
|
+
const fill2 = d.contains.liters > 0 ? (tank.liters ?? 0) / d.contains.liters : 0;
|
|
41163
|
+
const chance = ignitionChance(h, { sparkTarget: sparkTargetFactor(d.material, metal, ignitionRules), fill: fill2, fluid: d.contains.fluid }, ignitionRules);
|
|
41164
|
+
if (chance > 0 && igniteRand() < chance) light(tank, out);
|
|
41165
|
+
};
|
|
39552
41166
|
const blunt = (h, out) => {
|
|
39553
41167
|
sync();
|
|
39554
41168
|
const M = toFrameMatrix();
|
|
@@ -39612,7 +41226,7 @@ var GameVehiclesThree = (() => {
|
|
|
39612
41226
|
const verdict = kit.blastDamage(c, E / (1 + dist * dist * 4) / 50);
|
|
39613
41227
|
if (verdict === "explosion") explode(tank, h.source, out);
|
|
39614
41228
|
else if (verdict === "fire") {
|
|
39615
|
-
|
|
41229
|
+
light(tank, out);
|
|
39616
41230
|
startLeak(tank, centreOf(tank.def).setY(tank.def.box.center[1] - tank.def.box.size[1] / 2 + 0.05), 12, out, dir);
|
|
39617
41231
|
}
|
|
39618
41232
|
}
|
|
@@ -39626,9 +41240,9 @@ var GameVehiclesThree = (() => {
|
|
|
39626
41240
|
thermal(out);
|
|
39627
41241
|
};
|
|
39628
41242
|
const sound = (role) => {
|
|
39629
|
-
const
|
|
39630
|
-
if (!
|
|
39631
|
-
return
|
|
41243
|
+
const list2 = [...ps.values()].filter((p) => p.def.role === role);
|
|
41244
|
+
if (!list2.length) return true;
|
|
41245
|
+
return list2.every((p) => !p.lost && attached(p.def.id) && p.hp >= p.def.hp * 0.5);
|
|
39632
41246
|
};
|
|
39633
41247
|
const tankPart = () => [...ps.values()].find((p) => p.def.role === "fuel_tank" && p.def.contains);
|
|
39634
41248
|
const computeStatus = () => {
|
|
@@ -39820,8 +41434,8 @@ var GameVehiclesThree = (() => {
|
|
|
39820
41434
|
queue = [];
|
|
39821
41435
|
const hood = c.hood;
|
|
39822
41436
|
if (hood) {
|
|
39823
|
-
const
|
|
39824
|
-
const cur = hood.piv.rotation.z /
|
|
41437
|
+
const sign2 = hood.sign || 1;
|
|
41438
|
+
const cur = hood.piv.rotation.z / sign2;
|
|
39825
41439
|
if (Math.abs(cur - hood.ang) > 1e-4) {
|
|
39826
41440
|
hood.ang = cur;
|
|
39827
41441
|
hood.target = cur;
|
|
@@ -39942,34 +41556,6 @@ var GameVehiclesThree = (() => {
|
|
|
39942
41556
|
return { root, vehicle };
|
|
39943
41557
|
}
|
|
39944
41558
|
|
|
39945
|
-
// ../game-contracts/dist/index.js
|
|
39946
|
-
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
39947
|
-
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
39948
|
-
var deepMerge = (base, patch) => {
|
|
39949
|
-
if (!patch) return base;
|
|
39950
|
-
const result = { ...base };
|
|
39951
|
-
for (const [key, value] of Object.entries(patch)) {
|
|
39952
|
-
if (value === void 0 || UNSAFE_KEYS.has(key)) continue;
|
|
39953
|
-
const current = result[key];
|
|
39954
|
-
result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;
|
|
39955
|
-
}
|
|
39956
|
-
return result;
|
|
39957
|
-
};
|
|
39958
|
-
var mergeById = (shipped, extra) => {
|
|
39959
|
-
const entries = /* @__PURE__ */ new Map();
|
|
39960
|
-
for (const entry of [...shipped, ...extra ?? []]) entries.set(entry.id, entry);
|
|
39961
|
-
return entries;
|
|
39962
|
-
};
|
|
39963
|
-
var applyPatches = (entries, patches) => {
|
|
39964
|
-
for (const [id, patch] of Object.entries(patches ?? {})) {
|
|
39965
|
-
const entry = entries.get(id);
|
|
39966
|
-
if (entry) entries.set(id, deepMerge(entry, patch));
|
|
39967
|
-
}
|
|
39968
|
-
};
|
|
39969
|
-
var removeIds = (entries, ids) => {
|
|
39970
|
-
for (const id of ids ?? []) entries.delete(id);
|
|
39971
|
-
};
|
|
39972
|
-
|
|
39973
41559
|
// ../game-vehicles-driving/dist/index.js
|
|
39974
41560
|
var defaultArcadeSpec = {
|
|
39975
41561
|
length: 4.3,
|
|
@@ -40105,7 +41691,7 @@ var GameVehiclesThree = (() => {
|
|
|
40105
41691
|
{ id: "blood", grip: 0.5 }
|
|
40106
41692
|
];
|
|
40107
41693
|
function createSurfaces(options = {}) {
|
|
40108
|
-
const entries = mergeById(defaultSurfaces, options.packs?.flatMap((
|
|
41694
|
+
const entries = mergeById(defaultSurfaces, options.packs?.flatMap((pack2) => pack2.surfaces ?? []));
|
|
40109
41695
|
applyPatches(entries, options.patch);
|
|
40110
41696
|
removeIds(entries, options.remove);
|
|
40111
41697
|
const fallback = entries.get("dry_asphalt") ?? { id: "dry_asphalt", grip: 1 };
|
|
@@ -40986,6 +42572,7 @@ var GameVehiclesThree = (() => {
|
|
|
40986
42572
|
glass: "glass_burst",
|
|
40987
42573
|
sparks: "impact_metal",
|
|
40988
42574
|
leak: "vehicle_leak",
|
|
42575
|
+
leakIgnited: "vehicle_leak_ignited",
|
|
40989
42576
|
exhaust: "vehicle_exhaust"
|
|
40990
42577
|
};
|
|
40991
42578
|
var defaultSoundIds = { engine: "engine_saw", horn: "horn", crash: "sfx_impact" };
|
|
@@ -41036,24 +42623,26 @@ var GameVehiclesThree = (() => {
|
|
|
41036
42623
|
const paletteFor = (key) => settings.palette === "civil" ? paintPalettes.civil : settings.palette === "military" ? paintPalettes.military : paletteOf(key);
|
|
41037
42624
|
const paintOf = (entry) => {
|
|
41038
42625
|
if (!settings.paint) return;
|
|
41039
|
-
const
|
|
42626
|
+
const color2 = colorFromSeed(settings.seed + entry.index, paletteFor(entry.key));
|
|
41040
42627
|
if (!entry.paint) {
|
|
41041
42628
|
const vehicle = entry.item.vehicle;
|
|
41042
42629
|
const primary = primaryPaint(entry.item.vehicle);
|
|
41043
42630
|
if (!primary) return;
|
|
41044
42631
|
entry.paint = primary.clone();
|
|
41045
|
-
vehicle.vehicle.traverse((
|
|
41046
|
-
if (!
|
|
41047
|
-
if (Array.isArray(
|
|
41048
|
-
else if (
|
|
42632
|
+
vehicle.vehicle.traverse((mesh2) => {
|
|
42633
|
+
if (!mesh2.isMesh) return;
|
|
42634
|
+
if (Array.isArray(mesh2.material)) mesh2.material = mesh2.material.map((m) => m === primary ? entry.paint : m);
|
|
42635
|
+
else if (mesh2.material === primary) mesh2.material = entry.paint;
|
|
41049
42636
|
});
|
|
41050
42637
|
}
|
|
41051
|
-
entry.paint.color.set(
|
|
42638
|
+
entry.paint.color.set(color2);
|
|
41052
42639
|
};
|
|
41053
42640
|
const item = (key) => ({
|
|
41054
42641
|
id: itemId(key),
|
|
41055
42642
|
name: text.items[itemId(key)] ?? key,
|
|
41056
42643
|
movable: false,
|
|
42644
|
+
// the first build of a vehicle takes most of a second
|
|
42645
|
+
slow: true,
|
|
41057
42646
|
build: (THREE) => {
|
|
41058
42647
|
const kit = kitFor(THREE);
|
|
41059
42648
|
const built = buildVehicleItem(kit, key, { lod: settings.quality === "lite" });
|
|
@@ -41094,7 +42683,7 @@ var GameVehiclesThree = (() => {
|
|
|
41094
42683
|
for (const e of events) {
|
|
41095
42684
|
const position = e.point ?? e.worldPoint;
|
|
41096
42685
|
if (!position) continue;
|
|
41097
|
-
if (e.type === "ignite") fx.play({ effect: effectIds.ignite, point: position });
|
|
42686
|
+
if (e.type === "ignite") fx.play({ effect: /fuel_tank|tank/.test(e.part ?? "") ? effectIds.leakIgnited : effectIds.ignite, point: position });
|
|
41098
42687
|
else if (e.type === "explode") fx.play({ effect: effectIds.explode, point: position });
|
|
41099
42688
|
else if (e.type === "leak") fx.play({ effect: effectIds.leak, point: position });
|
|
41100
42689
|
else if (e.type === "fracture" && /glass|window|windshield/.test(e.part ?? "")) fx.play({ effect: effectIds.glass, point: position });
|
|
@@ -41127,12 +42716,12 @@ var GameVehiclesThree = (() => {
|
|
|
41127
42716
|
const bounds = new three.Box3();
|
|
41128
42717
|
const piece = new three.Box3();
|
|
41129
42718
|
const matrix = new three.Matrix4();
|
|
41130
|
-
entry.root.traverse((
|
|
41131
|
-
if (!
|
|
41132
|
-
for (let p =
|
|
41133
|
-
if (
|
|
41134
|
-
|
|
41135
|
-
piece.copy(
|
|
42719
|
+
entry.root.traverse((mesh2) => {
|
|
42720
|
+
if (!mesh2.isMesh || !mesh2.geometry || mesh2.userData.ghost) return;
|
|
42721
|
+
for (let p = mesh2; p; p = p.parent) if (p.visible === false) return;
|
|
42722
|
+
if (mesh2.userData.helper) return;
|
|
42723
|
+
mesh2.geometry.computeBoundingBox();
|
|
42724
|
+
piece.copy(mesh2.geometry.boundingBox).applyMatrix4(matrix.multiplyMatrices(inverse, mesh2.matrixWorld));
|
|
41136
42725
|
bounds.union(piece);
|
|
41137
42726
|
});
|
|
41138
42727
|
const size = bounds.getSize(new three.Vector3());
|
|
@@ -41153,8 +42742,8 @@ var GameVehiclesThree = (() => {
|
|
|
41153
42742
|
if (!host?.bench || !three) return;
|
|
41154
42743
|
clearHelpers();
|
|
41155
42744
|
const kit = [...placed.values()][0] && ([...placed.values()][0].root.userData.kit ?? void 0);
|
|
41156
|
-
const mark = (entry,
|
|
41157
|
-
const helper = new three.Box3Helper(
|
|
42745
|
+
const mark = (entry, box2, color2) => {
|
|
42746
|
+
const helper = new three.Box3Helper(box2, color2);
|
|
41158
42747
|
helper.userData.helper = true;
|
|
41159
42748
|
entry.root.add(helper);
|
|
41160
42749
|
entry.helpers.push(helper);
|
|
@@ -41168,8 +42757,8 @@ var GameVehiclesThree = (() => {
|
|
|
41168
42757
|
if (host.bench.layer("zones")) {
|
|
41169
42758
|
for (const zone of entry.item.vehicle.zones ?? []) {
|
|
41170
42759
|
if (!zone.box || zone.type === "internal") continue;
|
|
41171
|
-
const
|
|
41172
|
-
mark(entry,
|
|
42760
|
+
const box2 = new three.Box3(new three.Vector3(zone.box.x0, zone.box.y0, zone.box.z0), new three.Vector3(zone.box.x1, zone.box.y1, zone.box.z1)).applyMatrix4(matrix);
|
|
42761
|
+
mark(entry, box2, ZONE_COLOURS[zone.type] ?? 16777215);
|
|
41173
42762
|
}
|
|
41174
42763
|
}
|
|
41175
42764
|
}
|
|
@@ -41318,11 +42907,11 @@ var GameVehiclesThree = (() => {
|
|
|
41318
42907
|
let drawCalls = 0;
|
|
41319
42908
|
let triangles = 0;
|
|
41320
42909
|
for (const entry of placed.values()) {
|
|
41321
|
-
entry.root.traverse((
|
|
41322
|
-
if (!
|
|
41323
|
-
for (let p =
|
|
42910
|
+
entry.root.traverse((mesh2) => {
|
|
42911
|
+
if (!mesh2.isMesh || mesh2.userData.helper) return;
|
|
42912
|
+
for (let p = mesh2; p; p = p.parent) if (p.visible === false) return;
|
|
41324
42913
|
drawCalls += 1;
|
|
41325
|
-
const g =
|
|
42914
|
+
const g = mesh2.geometry;
|
|
41326
42915
|
triangles += (g.index ? g.index.count : g.attributes.position.count) / 3;
|
|
41327
42916
|
});
|
|
41328
42917
|
}
|
|
@@ -41357,9 +42946,9 @@ var GameVehiclesThree = (() => {
|
|
|
41357
42946
|
area: () => {
|
|
41358
42947
|
const gap = 1.6;
|
|
41359
42948
|
const WIDE = 6;
|
|
41360
|
-
const rowOf = (
|
|
42949
|
+
const rowOf = (list2, z) => {
|
|
41361
42950
|
let cursor = 0;
|
|
41362
|
-
const spots =
|
|
42951
|
+
const spots = list2.map((key) => {
|
|
41363
42952
|
const width = fleetDims(key)?.width ?? 2;
|
|
41364
42953
|
const x = cursor + width / 2;
|
|
41365
42954
|
cursor += width + gap;
|