@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.
@@ -5128,8 +5128,8 @@ var GameVehiclesThree = (() => {
5128
5128
  });
5129
5129
  return GRM[kind];
5130
5130
  }
5131
- function mkSurf(mesh, W) {
5132
- const geo = mesh.geometry, pos = geo.attributes.position, ix = geo.index, n = ix ? ix.count : pos.count;
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 list = Math.abs(d.y) < 0.5 ? BY[Math.floor(o.y / Q)] : BX[Math.floor(o.x / Q)];
5150
- if (!list) return null;
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 < list.length; k++) {
5153
- const t = T[list[k]];
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, list, r, mat, off) {
5329
- const pts = list.map(function(q) {
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 ring = onSurf(c.add(new THREE.TorusGeometry(rad * 1.05, 4e-3, 6, 22), MT.chrome), s, 0.012, new V3(0, 0, 1));
5401
- ring.castShadow = false;
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(list) {
6018
+ function dlo(list2) {
6019
6019
  return function(def) {
6020
- return list.concat([def[def.length - 1]]);
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 box = boxBody(c, { x0: f - len - 0.1, x1: -3.72, y0: 0.98, y1: 3.38, W: 2.42, col: "#f1f1ec" });
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 box;
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 ring = c.add(new THREE.TorusGeometry(R + 0.06, 0.07, 10, 36), mat, x, y, 0);
9587
- ring.scale.z = w / 0.14;
9588
- c.deform.push(ring);
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(), box = new THREE.Box3(), tmp = new THREE.Box3();
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
- box.union(tmp);
11340
+ box2.union(tmp);
11341
11341
  });
11342
- if (!box.isEmpty() && (!riseOnly || box.min.y < -5e-3)) c.vehicle.position.y -= box.min.y;
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 box = c.roundBox(0.14, 0.12, w + 0.06, 0.02, o.mat || OLIVE_STEEL, x, y, z, { rot: [0, rot, 0] });
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 box;
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 = [], ring = seg + 1, axisY = o.axis === "y";
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 * ring + k, B = A + ring;
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 * ring + k, flip = e === 0 !== axisY;
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(mesh, W) {
14162
- const geo = mesh.geometry, pos = geo.attributes.position, ix = geo.index, n = ix ? ix.count : pos.count;
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 list = Math.abs(d.y) < 0.5 ? BY[Math.floor(o.y / Q)] : BX[Math.floor(o.x / Q)];
14180
- if (!list) return null;
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 < list.length; k++) {
14183
- const t = T[list[k]];
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, list, r, mat, off) {
14359
- const pts = list.map(function(q) {
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 ring = onSurf(c.add(new THREE.TorusGeometry(rad * 1.05, 4e-3, 6, 22), MT.chrome), s, 0.012, new V3(0, 0, 1));
14431
- ring.castShadow = false;
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(list, piv, axis, ang) {
16508
+ function bendSet(list2, piv, axis, ang) {
16509
16509
  const q = new THREE.Quaternion().setFromAxisAngle(axis.clone().normalize(), ang);
16510
- list.forEach(function(m) {
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 box = c.roundBox(0.5, 0.38, 0.2, 0.03, aluBox, -0.7, 0.8, z, { def: true }), luggageCase = [box, c.roundBox(0.52, 0.04, 0.21, 0.015, blk, -0.7, 0.98, z)];
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"), box, new V3(-0.7, 0.8, z), 0.6);
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 = [], ring = seg + 1, axisY = o.axis === "y";
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 * ring + k, B = A + ring;
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 * ring + k, flip = e === 0 !== axisY;
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 ring = new THREE.Mesh(new THREE.TorusGeometry(0.075, 7e-3, 6, 32), DRL);
19475
- ring.rotation.y = PI / 2;
19476
- ring.position.set(0.052, 0, 0);
19477
- ring.castShadow = false;
19478
- HL.group.add(ring);
19479
- HL.inner.push(ring);
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), list = [];
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) list.push(o);
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 (list.length || extra.length)
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
- list.concat(extra).forEach(function(o) {
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 ring = 2 * (m1 + m2) + 1;
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 < ring - 1; k2++) {
24349
- const p0 = a * ring + k2, p1 = p0 + ring;
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 < ring - 1; r++) idx.push(ci, r + 1, 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 ring;
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
- ring = P.length;
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 < ring; k++) {
24458
- const k1 = (k + 1) % ring, p0 = a * ring + k, p1 = (a + 1) * ring + k, q0 = a * ring + k1, q1 = (a + 1) * ring + k1;
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 < ring; k++) {
24467
- const a0 = si * ring + k, a1 = si * ring + (k + 1) % ring;
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, color, label, o) {
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[color] || NAV.white);
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
- color === "red" ? MT.lensRed : color === "amber" ? MT.lensAmber : MT.lens
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: color === "red" ? "red" : "clear",
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[color] || "#ffffff", 0.5)];
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, mesh, keep, mat, o) {
24843
+ function skinOf2(c, mesh2, keep, mat, o) {
24844
24844
  o = o || {};
24845
- const g = mesh.geometry.clone(), p = g.attributes.position, sz = o.sz || 1.006, dy = o.dy || 0;
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, mesh.position.x, mesh.position.y, mesh.position.z);
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, mesh, c) {
27607
+ function classify(mat, mesh2, c) {
27608
27608
  if (mat.map) {
27609
- if (mesh.userData.plate) return "plate";
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 mesh = new THREE.Mesh(g, mt);
27756
- mesh.name = name;
27757
- mesh.castShadow = name !== "glass" && name !== "light";
27758
- mesh.receiveShadow = name !== "light";
27759
- meshes.push(mesh);
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 color = o.color || (seed != null ? colorFromSeed(seed, isMilitary(key) ? paintPalettes.military : paintPalettes.civil) : null);
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 (color && primary) {
27839
+ if (color2 && primary) {
27840
27840
  const repainted = primary.clone();
27841
- repainted.color.set(color);
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, color ? new THREE.Color(color) : null, primary, kit.lodHiddenMaterials());
27852
- for (const mesh of liteMeshes(THREE, fusion, liteMaterials(THREE, kit.studioEnvironment()))) group.add(mesh);
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(color, o) {
30171
+ function makeMaterial(color2, o) {
28584
30172
  o = o || {};
28585
- const c = color instanceof THREE.Color ? color : new THREE.Color(color);
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(color, o) {
28602
- return makeMaterial(color, Object.assign({ flatShading: true, roughness: 0.92 }, o || {}));
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 list = map[keys[i]];
30436
+ const list2 = map[keys[i]];
28849
30437
  s.set(0, 0, 0);
28850
- for (let j = 0; j < list.length; j++) {
28851
- const g = FN[list[j]];
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 ring = seg + 1;
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 * ring + k;
28936
- const b0 = a0 + ring;
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 * ring + k;
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(list) {
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(list.length * 3 * sizes[a]);
30680
+ const arr = new Float32Array(list2.length * 3 * sizes[a]);
29093
30681
  let w = 0;
29094
- list.forEach(function(t) {
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(list) {
30697
+ function mergeGeometries(list2) {
29110
30698
  const pos = [];
29111
30699
  const nor = [];
29112
- list.forEach(function(g2) {
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 area = 0;
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
- area += a[0] * b[1] - b[0] * a[1];
30763
+ area3 += a[0] * b[1] - b[0] * a[1];
29176
30764
  }
29177
- const sg = area > 0 ? 1 : -1;
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, box, parts, o) {
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 (box) d.box = I.normalizeBox(box);
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 ring = seg + 1;
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 * ring + k;
29654
- const B = A + ring;
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 * ring + k;
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, mesh, label, type, o) {
31483
+ kit.asGlass = function(c, mesh2, label, type, o) {
29896
31484
  o = o || {};
29897
- const i = c.deform.indexOf(mesh);
31485
+ const i = c.deform.indexOf(mesh2);
29898
31486
  if (i >= 0) c.deform.splice(i, 1);
29899
- if (mesh.parent) mesh.parent.remove(mesh);
29900
- const geo = mesh.geometry;
29901
- geo.applyMatrix4(new THREE.Matrix4().compose(mesh.position, mesh.quaternion, mesh.scale));
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: mesh.material }, o));
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(mesh, tests, deg, o) {
29950
- const src = o && o.sub ? subdivide(mesh.geometry, o.sub) : mesh.geometry;
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
- mesh.geometry.dispose();
29954
- mesh.geometry = r.geo;
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 ring = gm(g, new THREE.TorusGeometry(r * 1.02, 0.013, 8, 30), MATERIALS.chrome, d / 2 - 6e-3, 0, pz);
30153
- ring.rotation.y = PI / 2;
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 ring = gm(g, new THREE.TorusGeometry(r, 0.01, 6, 24), MATERIALS.chrome, d / 2 - 4e-3, 0, pz);
30231
- ring.rotation.y = PI / 2;
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 list = [];
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
- list.push(hg);
31921
+ list2.push(hg);
30334
31922
  }
30335
- if (list.length) gm(g, mergeGeometries(list), MATERIALS.trim);
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 box(w, h, d, mat, x, y, z) {
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 box(0.09, 0.08, zW * 2, DK, rx + 0.08, Math.max(yU, rr - 0.12), 0);
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
- box(Math.min(0.5, (fx - rx) * 0.2), 0.1, 0.38, DK, fx - 0.25, yU + 0.01, -0.05);
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
- box(0.24, 0.06, 0.2, DK, (fx + rx) / 2 + 0.1, ty, 0.16);
31207
- box(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);
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
- box(
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++) box(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);
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 list = [];
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
- list.push(cg);
33137
+ list2.push(cg);
31550
33138
  }
31551
- g.add(new THREE.Mesh(mergeGeometries(list), MATERIALS.chrome));
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 list = fire ? FIRE_TEXTURES : SMOKE_TEXTURES;
33319
+ const list2 = fire ? FIRE_TEXTURES : SMOKE_TEXTURES;
31732
33320
  const mat = new THREE.SpriteMaterial({
31733
- map: list[Math.floor(Math.random() * list.length)],
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 box = new THREE.Box3();
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
- box.setFromObject(o);
33048
- box.applyMatrix4(gInv);
33049
- o.userData.c0 = box.getCenter(new V3());
33050
- o.userData.bb0 = box.clone();
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 ring = new THREE.Mesh(new THREE.RingGeometry(r[0] - 0.25, r[0], 96), boomMat(r[1], 0.85));
33345
- ring.rotation.x = -PI / 2;
33346
- ring.position.y = 0.06;
33347
- ring.renderOrder = 5;
33348
- g.add(ring);
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(ring, fill2, lb);
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 list = [];
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
- list.push({ o: ob, M });
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 list = [];
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
- list.push([new V3(A.x + k * A.L, q[0], q[1]), dir]);
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) list.push([h.p, new V3(0, 0, -sd)]);
35344
+ if (h) list2.push([h.p, new V3(0, 0, -sd)]);
33757
35345
  });
33758
35346
  }
33759
- list.forEach(function(e) {
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(list[0][0]).setY(0.05), 30, { speed: 3 });
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, list) {
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
- list.forEach(function(e) {
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, list, z) {
37545
+ function resolveObjs(c, list2, z) {
35958
37546
  const out = [];
35959
- (list || []).forEach(function(o) {
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 list = [];
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
- list.push(z);
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
- list.splice(list.indexOf(z), 1);
37585
+ list2.splice(list2.indexOf(z), 1);
35998
37586
  delete byId[d.id];
35999
37587
  }
36000
- list.slice().forEach(function(q) {
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
- list.splice(list.indexOf(q), 1);
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
- list.push(z);
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
- list = list.filter(function(z) {
37636
+ list2 = list2.filter(function(z) {
36049
37637
  return z.box && z.name;
36050
37638
  });
36051
- list.forEach(function(z) {
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
- list.forEach(function(z) {
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 = list.filter(function(z) {
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
- list.forEach(function(z) {
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
- list.forEach(function(z) {
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, list);
37746
+ carMap(c, list2);
36159
37747
  c.zoneOwners = owner;
36160
- return list;
37748
+ return list2;
36161
37749
  }
36162
- function carMap(c, list) {
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
- list.forEach(function(z) {
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, box, o) {
36232
- const z = Object.assign({ id, name, type, box: I.normalizeBox(box) }, o || {});
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 box = new THREE.Box3(new THREE.Vector3(b.x0, b.y0, b.z0), new THREE.Vector3(b.x1, b.y1, b.z1));
37727
- if (matrix) box.applyMatrix4(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 box = boxOf(z);
38124
- const area = areaOf(box.size);
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(box.center[2]) || 1;
38132
- const rimBox = { center: [box.center[0], box.center[1], box.center[2] - sz * box.size[2] * 0.25], size: [box.size[0] * 0.7, box.size[1] * 0.7, box.size[2] * 0.5] };
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: box.center, size: [box.size[0] * 0.98, box.size[1] * 0.98, box.size[2]] };
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 * area, hp: laminated ? 4e3 : 450, zoneId: id, visual: false, tags: ["glass", ...tags] });
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 * area, hp: 320, zoneId: id, visual: true, tags: ["light", ...tags] });
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 * area, hp: 9e3, ignitionC: 400, zoneId: id, visual: true, tags: ["bumper", ...tags] });
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(box), mass: mass * 0.25, hp: 15e4 * armour, zoneId: id, visual: false, tags: ["frame", ...tags] });
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) * area * (role === "door" ? 1.6 : 1);
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 box = { center: [mx, my, s * half], size: [0.14, 0.12, 0.2] };
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) box = { 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])] };
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, sign, B, samples) {
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, sign * (Math.max(Math.abs(B.z0), Math.abs(B.z1)) + 1)) : new V3(sign * (Math.max(Math.abs(B.x0), Math.abs(B.x1)) + 1), u, v);
38648
- const d = axis === "z" ? new V3(0, 0, -sign) : new V3(-sign, 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 list = z.glass.filter((g) => g.parent && g.visible);
38799
- if (!list.length) return false;
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 = list[0];
40389
+ let best = list2[0];
38802
40390
  let bd = Infinity;
38803
- for (const g of list) {
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?.liters,
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 list = [...comps.entries()].sort((a, b) => a[0] === hubRoot ? -1 : b[0] === hubRoot ? 1 : 0);
39207
- groupsCache = list.map(([, v]) => v);
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" && E > 1500 && (p.liters ?? 0) > 1) p.temp = Math.max(p.temp, d.ignitionC ?? 260);
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
- tank.temp = Math.max(tank.temp, tank.def.ignitionC ?? 260);
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 list = [...ps.values()].filter((p) => p.def.role === role);
39630
- if (!list.length) return true;
39631
- return list.every((p) => !p.lost && attached(p.def.id) && p.hp >= p.def.hp * 0.5);
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 sign = hood.sign || 1;
39824
- const cur = hood.piv.rotation.z / sign;
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((pack) => pack.surfaces ?? []));
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 color = colorFromSeed(settings.seed + entry.index, paletteFor(entry.key));
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((mesh) => {
41046
- if (!mesh.isMesh) return;
41047
- if (Array.isArray(mesh.material)) mesh.material = mesh.material.map((m) => m === primary ? entry.paint : m);
41048
- else if (mesh.material === primary) mesh.material = entry.paint;
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(color);
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((mesh) => {
41131
- if (!mesh.isMesh || !mesh.geometry || mesh.userData.ghost) return;
41132
- for (let p = mesh; p; p = p.parent) if (p.visible === false) return;
41133
- if (mesh.userData.helper) return;
41134
- mesh.geometry.computeBoundingBox();
41135
- piece.copy(mesh.geometry.boundingBox).applyMatrix4(matrix.multiplyMatrices(inverse, mesh.matrixWorld));
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, box, color) => {
41157
- const helper = new three.Box3Helper(box, color);
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 box = 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);
41172
- mark(entry, box, ZONE_COLOURS[zone.type] ?? 16777215);
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((mesh) => {
41322
- if (!mesh.isMesh || mesh.userData.helper) return;
41323
- for (let p = mesh; p; p = p.parent) if (p.visible === false) return;
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 = mesh.geometry;
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 = (list, z) => {
42949
+ const rowOf = (list2, z) => {
41361
42950
  let cursor = 0;
41362
- const spots = list.map((key) => {
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;