@adatechnology/game-vehicles-three 0.3.5 → 0.3.6

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.
@@ -5236,7 +5236,7 @@ var GameVehiclesThree = (() => {
5236
5236
  for (q = y0; q <= y1; q++) (BY[q] || (BY[q] = [])).push(k);
5237
5237
  for (q = x0; q <= x1; q++) (BX[q] || (BX[q] = [])).push(k);
5238
5238
  }
5239
- const ray = new THREE.Ray(), tmp = new V3(), e1 = new V3(), e2 = new V3(), cache = {};
5239
+ const ray = new THREE.Ray(), tmp = new V3(), e1 = new V3(), e2 = new V3(), cache2 = {};
5240
5240
  const S = { bb, hw: W / 2 };
5241
5241
  S.hit = function(o, dd) {
5242
5242
  const d = dd.clone().normalize();
@@ -5260,9 +5260,9 @@ var GameVehiclesThree = (() => {
5260
5260
  };
5261
5261
  S.endX = function(E, y) {
5262
5262
  const k = E + ":" + y.toFixed(3);
5263
- if (cache[k] != null) return cache[k];
5263
+ if (cache2[k] != null) return cache2[k];
5264
5264
  const h = S.hit(new V3(E * 10, y, 0), new V3(-E, 0, 0), E > 0 ? "F" : "R");
5265
- return cache[k] = h ? h.p.x : E > 0 ? bb.max.x : bb.min.x;
5265
+ return cache2[k] = h ? h.p.x : E > 0 ? bb.max.x : bb.min.x;
5266
5266
  };
5267
5267
  return S;
5268
5268
  }
@@ -14266,7 +14266,7 @@ var GameVehiclesThree = (() => {
14266
14266
  for (q = y0; q <= y1; q++) (BY[q] || (BY[q] = [])).push(k);
14267
14267
  for (q = x0; q <= x1; q++) (BX[q] || (BX[q] = [])).push(k);
14268
14268
  }
14269
- const ray = new THREE.Ray(), tmp = new V3(), e1 = new V3(), e2 = new V3(), cache = {};
14269
+ const ray = new THREE.Ray(), tmp = new V3(), e1 = new V3(), e2 = new V3(), cache2 = {};
14270
14270
  const S = { bb, hw: W / 2 };
14271
14271
  S.hit = function(o, dd) {
14272
14272
  const d = dd.clone().normalize();
@@ -14290,9 +14290,9 @@ var GameVehiclesThree = (() => {
14290
14290
  };
14291
14291
  S.endX = function(E, y) {
14292
14292
  const k = E + ":" + y.toFixed(3);
14293
- if (cache[k] != null) return cache[k];
14293
+ if (cache2[k] != null) return cache2[k];
14294
14294
  const h = S.hit(new V3(E * 10, y, 0), new V3(-E, 0, 0), E > 0 ? "F" : "R");
14295
- return cache[k] = h ? h.p.x : E > 0 ? bb.max.x : bb.min.x;
14295
+ return cache2[k] = h ? h.p.x : E > 0 ? bb.max.x : bb.min.x;
14296
14296
  };
14297
14297
  return S;
14298
14298
  }
@@ -28520,12 +28520,12 @@ var GameVehiclesThree = (() => {
28520
28520
  return triangles;
28521
28521
  }
28522
28522
  };
28523
- function linkedList(data, start, end, dim, clockwise) {
28523
+ function linkedList(data, start2, end, dim, clockwise) {
28524
28524
  let i, last;
28525
- if (clockwise === signedArea(data, start, end, dim) > 0) {
28526
- for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
28525
+ if (clockwise === signedArea(data, start2, end, dim) > 0) {
28526
+ for (i = start2; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
28527
28527
  } else {
28528
- for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
28528
+ for (i = end - dim; i >= start2; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
28529
28529
  }
28530
28530
  if (last && equals(last, last.next)) {
28531
28531
  removeNode(last);
@@ -28533,10 +28533,10 @@ var GameVehiclesThree = (() => {
28533
28533
  }
28534
28534
  return last;
28535
28535
  }
28536
- function filterPoints(start, end) {
28537
- if (!start) return start;
28538
- if (!end) end = start;
28539
- let p = start, again;
28536
+ function filterPoints(start2, end) {
28537
+ if (!start2) return start2;
28538
+ if (!end) end = start2;
28539
+ let p = start2, again;
28540
28540
  do {
28541
28541
  again = false;
28542
28542
  if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
@@ -28615,8 +28615,8 @@ var GameVehiclesThree = (() => {
28615
28615
  }
28616
28616
  return true;
28617
28617
  }
28618
- function cureLocalIntersections(start, triangles, dim) {
28619
- let p = start;
28618
+ function cureLocalIntersections(start2, triangles, dim) {
28619
+ let p = start2;
28620
28620
  do {
28621
28621
  const a = p.prev, b = p.next.next;
28622
28622
  if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
@@ -28625,14 +28625,14 @@ var GameVehiclesThree = (() => {
28625
28625
  triangles.push(b.i / dim | 0);
28626
28626
  removeNode(p);
28627
28627
  removeNode(p.next);
28628
- p = start = b;
28628
+ p = start2 = b;
28629
28629
  }
28630
28630
  p = p.next;
28631
- } while (p !== start);
28631
+ } while (p !== start2);
28632
28632
  return filterPoints(p);
28633
28633
  }
28634
- function splitEarcut(start, triangles, dim, minX, minY, invSize) {
28635
- let a = start;
28634
+ function splitEarcut(start2, triangles, dim, minX, minY, invSize) {
28635
+ let a = start2;
28636
28636
  do {
28637
28637
  let b = a.next.next;
28638
28638
  while (b !== a.prev) {
@@ -28647,15 +28647,15 @@ var GameVehiclesThree = (() => {
28647
28647
  b = b.next;
28648
28648
  }
28649
28649
  a = a.next;
28650
- } while (a !== start);
28650
+ } while (a !== start2);
28651
28651
  }
28652
28652
  function eliminateHoles(data, holeIndices, outerNode, dim) {
28653
28653
  const queue = [];
28654
- let i, len, start, end, list2;
28654
+ let i, len, start2, end, list2;
28655
28655
  for (i = 0, len = holeIndices.length; i < len; i++) {
28656
- start = holeIndices[i] * dim;
28656
+ start2 = holeIndices[i] * dim;
28657
28657
  end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
28658
- list2 = linkedList(data, start, end, dim, false);
28658
+ list2 = linkedList(data, start2, end, dim, false);
28659
28659
  if (list2 === list2.next) list2.steiner = true;
28660
28660
  queue.push(getLeftmost(list2));
28661
28661
  }
@@ -28710,14 +28710,14 @@ var GameVehiclesThree = (() => {
28710
28710
  function sectorContainsSector(m, p) {
28711
28711
  return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
28712
28712
  }
28713
- function indexCurve(start, minX, minY, invSize) {
28714
- let p = start;
28713
+ function indexCurve(start2, minX, minY, invSize) {
28714
+ let p = start2;
28715
28715
  do {
28716
28716
  if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
28717
28717
  p.prevZ = p.prev;
28718
28718
  p.nextZ = p.next;
28719
28719
  p = p.next;
28720
- } while (p !== start);
28720
+ } while (p !== start2);
28721
28721
  p.prevZ.nextZ = null;
28722
28722
  p.prevZ = null;
28723
28723
  sortLinked(p);
@@ -28774,12 +28774,12 @@ var GameVehiclesThree = (() => {
28774
28774
  y = (y | y << 1) & 1431655765;
28775
28775
  return x | y << 1;
28776
28776
  }
28777
- function getLeftmost(start) {
28778
- let p = start, leftmost = start;
28777
+ function getLeftmost(start2) {
28778
+ let p = start2, leftmost = start2;
28779
28779
  do {
28780
28780
  if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
28781
28781
  p = p.next;
28782
- } while (p !== start);
28782
+ } while (p !== start2);
28783
28783
  return leftmost;
28784
28784
  }
28785
28785
  function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
@@ -28878,9 +28878,9 @@ var GameVehiclesThree = (() => {
28878
28878
  this.nextZ = null;
28879
28879
  this.steiner = false;
28880
28880
  }
28881
- function signedArea(data, start, end, dim) {
28881
+ function signedArea(data, start2, end, dim) {
28882
28882
  let sum = 0;
28883
- for (let i = start, j = end - dim; i < end; i += dim) {
28883
+ for (let i = start2, j = end - dim; i < end; i += dim) {
28884
28884
  sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
28885
28885
  j = i;
28886
28886
  }
@@ -29137,7 +29137,7 @@ var GameVehiclesThree = (() => {
29137
29137
  const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)];
29138
29138
  for (const k of [0, 1, 3, 1, 2, 3]) addUV(...uvs[k]);
29139
29139
  };
29140
- let start = verticesArray.length / 3;
29140
+ let start2 = verticesArray.length / 3;
29141
29141
  if (bevelEnabled) {
29142
29142
  let offset = 0;
29143
29143
  for (let i = 0; i < flen; i++) {
@@ -29160,8 +29160,8 @@ var GameVehiclesThree = (() => {
29160
29160
  f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
29161
29161
  }
29162
29162
  }
29163
- groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 0 });
29164
- start = verticesArray.length / 3;
29163
+ groups.push({ start: start2, count: verticesArray.length / 3 - start2, materialIndex: 0 });
29164
+ start2 = verticesArray.length / 3;
29165
29165
  const sidewalls = (ring2, layeroffset2) => {
29166
29166
  let i = ring2.length;
29167
29167
  while (--i >= 0) {
@@ -29182,7 +29182,7 @@ var GameVehiclesThree = (() => {
29182
29182
  sidewalls(ahole, layeroffset);
29183
29183
  layeroffset += ahole.length;
29184
29184
  }
29185
- groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 1 });
29185
+ groups.push({ start: start2, count: verticesArray.length / 3 - start2, materialIndex: 1 });
29186
29186
  const positions = new Float32Array(verticesArray);
29187
29187
  return { type: "ExtrudeGeometry", parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups };
29188
29188
  }
@@ -29458,8 +29458,8 @@ var GameVehiclesThree = (() => {
29458
29458
  var shims = /* @__PURE__ */ new WeakSet();
29459
29459
  function shapeGeometries(THREE, options = {}) {
29460
29460
  if (shims.has(THREE)) return THREE;
29461
- const cache = options.cache !== false;
29462
- const key = cache ? "cache" : "nocache";
29461
+ const cache2 = options.cache !== false;
29462
+ const key = cache2 ? "cache" : "nocache";
29463
29463
  let byKey = namespaces.get(THREE);
29464
29464
  if (!byKey) {
29465
29465
  byKey = /* @__PURE__ */ new Map();
@@ -29468,7 +29468,7 @@ var GameVehiclesThree = (() => {
29468
29468
  const existing = byKey.get(key);
29469
29469
  if (existing) return existing;
29470
29470
  const made = (p) => toGeometry(THREE, p);
29471
- const viaCache = (node, direct) => cache ? buildPrimitive(node) : direct();
29471
+ const viaCache = (node, direct) => cache2 ? buildPrimitive(node) : direct();
29472
29472
  const defined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
29473
29473
  const constructors = {
29474
29474
  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))),
@@ -30154,7 +30154,7 @@ var GameVehiclesThree = (() => {
30154
30154
  const I = kit._;
30155
30155
  const document2 = kit.document;
30156
30156
  const RUST = new THREE.Color("#5e3220");
30157
- const cache = {};
30157
+ const cache2 = {};
30158
30158
  let envTex = null;
30159
30159
  function studioEnvironment() {
30160
30160
  if (envTex) return envTex;
@@ -30199,7 +30199,7 @@ var GameVehiclesThree = (() => {
30199
30199
  const key = "s" + c.getHexString() + JSON.stringify(o, function(k, v) {
30200
30200
  return v && v.isColor ? "#" + v.getHexString() : v && v.isTexture ? v.uuid : v;
30201
30201
  });
30202
- if (!cache[key]) {
30202
+ if (!cache2[key]) {
30203
30203
  const o2 = Object.assign({}, o);
30204
30204
  delete o2.noEnv;
30205
30205
  const mt = new THREE.MeshStandardMaterial(Object.assign({ color: c, roughness: 0.8, metalness: 0, flatShading: false }, o2));
@@ -30207,9 +30207,9 @@ var GameVehiclesThree = (() => {
30207
30207
  mt.envMap = studioEnvironment();
30208
30208
  if (o.envMapIntensity == null) mt.envMapIntensity = 0.55 + (mt.metalness - 0.6) * 1.6;
30209
30209
  }
30210
- cache[key] = mt;
30210
+ cache2[key] = mt;
30211
30211
  }
30212
- return cache[key];
30212
+ return cache2[key];
30213
30213
  }
30214
30214
  function makeFlatMaterial(color2, o) {
30215
30215
  return makeMaterial(color2, Object.assign({ flatShading: true, roughness: 0.92 }, o || {}));
@@ -30324,7 +30324,129 @@ var GameVehiclesThree = (() => {
30324
30324
  return t;
30325
30325
  }
30326
30326
  kit.textTexture = textTexture;
30327
- Object.assign(I, { RUST, cache, studioEnvironment, makeMaterial, makeFlatMaterial, DOUBLE_SIDE, toColor, MATERIALS, paintColor, texCache, textTexture });
30327
+ Object.assign(I, { RUST, cache: cache2, studioEnvironment, makeMaterial, makeFlatMaterial, DOUBLE_SIDE, toColor, MATERIALS, paintColor, texCache, textTexture });
30328
+ }
30329
+ var TRI_BLOCK = 32;
30330
+ var cache = /* @__PURE__ */ new WeakMap();
30331
+ function trianglesOf(geo) {
30332
+ return Math.floor((geo.index ? geo.index.count : geo.attributes.position.count) / 3);
30333
+ }
30334
+ function supports(geo) {
30335
+ const pos = geo.attributes && geo.attributes.position;
30336
+ return !!pos && !pos.isInterleavedBufferAttribute && pos.itemSize === 3;
30337
+ }
30338
+ function isCurrent(geo, ti) {
30339
+ const pos = geo.attributes.position;
30340
+ return ti.position === pos && ti.positionVersion === pos.version && ti.index === (geo.index || null) && ti.indexVersion === (geo.index ? geo.index.version : 0) && ti.triangles === trianglesOf(geo);
30341
+ }
30342
+ function blockCount(triangles) {
30343
+ return Math.ceil(triangles / TRI_BLOCK);
30344
+ }
30345
+ function boxBlock(ti, block) {
30346
+ const B = ti.boxes;
30347
+ const t0 = block * TRI_BLOCK;
30348
+ const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
30349
+ const o = block * 6;
30350
+ for (let k = 0; k < 3; k++) {
30351
+ ti.blocks[o + k] = Infinity;
30352
+ ti.blocks[o + 3 + k] = -Infinity;
30353
+ }
30354
+ for (let t = t0; t < t1; t++) {
30355
+ const j = t * 6;
30356
+ for (let k = 0; k < 3; k++) {
30357
+ if (B[j + k] < ti.blocks[o + k]) ti.blocks[o + k] = B[j + k];
30358
+ if (B[j + 3 + k] > ti.blocks[o + 3 + k]) ti.blocks[o + 3 + k] = B[j + 3 + k];
30359
+ }
30360
+ }
30361
+ }
30362
+ function boxTriangle(geo, ti, t) {
30363
+ const P = geo.attributes.position.array;
30364
+ const ix = geo.index ? geo.index.array : null;
30365
+ const a = (ix ? ix[t * 3] : t * 3) * 3;
30366
+ const b = (ix ? ix[t * 3 + 1] : t * 3 + 1) * 3;
30367
+ const c = (ix ? ix[t * 3 + 2] : t * 3 + 2) * 3;
30368
+ const j = t * 6;
30369
+ for (let k = 0; k < 3; k++) {
30370
+ ti.boxes[j + k] = Math.min(P[a + k], P[b + k], P[c + k]);
30371
+ ti.boxes[j + 3 + k] = Math.max(P[a + k], P[b + k], P[c + k]);
30372
+ }
30373
+ }
30374
+ function advance(geo, ti, deadline) {
30375
+ const total = blockCount(ti.triangles);
30376
+ while (ti.builtBlocks < total) {
30377
+ const block = ti.builtBlocks;
30378
+ const t1 = Math.min(ti.triangles, (block + 1) * TRI_BLOCK);
30379
+ for (let t = block * TRI_BLOCK; t < t1; t++) boxTriangle(geo, ti, t);
30380
+ boxBlock(ti, block);
30381
+ ti.builtBlocks++;
30382
+ if (deadline !== Infinity && performance.now() >= deadline) break;
30383
+ }
30384
+ return ti.builtBlocks === total;
30385
+ }
30386
+ function start(geo) {
30387
+ const pos = geo.attributes.position;
30388
+ const triangles = trianglesOf(geo);
30389
+ const ti = {
30390
+ position: pos,
30391
+ positionVersion: pos.version,
30392
+ index: geo.index || null,
30393
+ indexVersion: geo.index ? geo.index.version : 0,
30394
+ triangles,
30395
+ boxes: new Float64Array(triangles * 6),
30396
+ blocks: new Float64Array(blockCount(triangles) * 6),
30397
+ builtBlocks: 0
30398
+ };
30399
+ cache.set(geo, ti);
30400
+ return ti;
30401
+ }
30402
+ function triIndexOf(geo) {
30403
+ if (!supports(geo)) return void 0;
30404
+ let ti = cache.get(geo);
30405
+ if (!ti || !isCurrent(geo, ti)) ti = start(geo);
30406
+ advance(geo, ti, Infinity);
30407
+ return ti;
30408
+ }
30409
+ function warmTriIndex(geo, deadline) {
30410
+ if (!supports(geo)) return true;
30411
+ let ti = cache.get(geo);
30412
+ if (!ti || !isCurrent(geo, ti)) ti = start(geo);
30413
+ return advance(geo, ti, deadline);
30414
+ }
30415
+ function storeTriIndex(geo, boxes) {
30416
+ const ti = start(geo);
30417
+ ti.boxes = boxes;
30418
+ const total = blockCount(ti.triangles);
30419
+ for (let b = 0; b < total; b++) boxBlock(ti, b);
30420
+ ti.builtBlocks = total;
30421
+ }
30422
+ function liveTriIndex(geo) {
30423
+ if (geo.index || !supports(geo)) return void 0;
30424
+ const ti = cache.get(geo);
30425
+ return ti && isCurrent(geo, ti) && ti.builtBlocks === blockCount(ti.triangles) ? ti : void 0;
30426
+ }
30427
+ function touchTriIndex(geo, ti, vertices) {
30428
+ if (ti.positionVersion + 1 !== geo.attributes.position.version) return;
30429
+ const blocks = /* @__PURE__ */ new Set();
30430
+ for (const v of vertices) {
30431
+ const t = Math.floor(v / 3);
30432
+ if (t >= ti.triangles) continue;
30433
+ boxTriangle(geo, ti, t);
30434
+ blocks.add(Math.floor(t / TRI_BLOCK));
30435
+ }
30436
+ blocks.forEach((b) => boxBlock(ti, b));
30437
+ ti.positionVersion = geo.attributes.position.version;
30438
+ }
30439
+ function boundsFromIndex(geo) {
30440
+ if (geo.index || !supports(geo)) return void 0;
30441
+ const ti = cache.get(geo);
30442
+ if (!ti || !isCurrent(geo, ti) || ti.builtBlocks !== blockCount(ti.triangles) || !ti.triangles || geo.attributes.position.count !== ti.triangles * 3) return void 0;
30443
+ const box2 = new Float64Array([Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]);
30444
+ for (let b = 0, n = blockCount(ti.triangles); b < n; b++)
30445
+ for (let k = 0; k < 3; k++) {
30446
+ box2[k] = Math.min(box2[k], ti.blocks[b * 6 + k]);
30447
+ box2[3 + k] = Math.max(box2[3 + k], ti.blocks[b * 6 + 3 + k]);
30448
+ }
30449
+ return { box: box2, version: ti.positionVersion };
30328
30450
  }
30329
30451
  function installGeometry(kit) {
30330
30452
  const THREE = kit.THREE;
@@ -30419,7 +30541,8 @@ var GameVehiclesThree = (() => {
30419
30541
  g.userData.crease = true;
30420
30542
  return g;
30421
30543
  }
30422
- function crease(geo, deg) {
30544
+ const latestCrease = /* @__PURE__ */ new WeakMap();
30545
+ function creaseTask(geo, deg) {
30423
30546
  if (geo.index) {
30424
30547
  const ni = geo.toNonIndexed();
30425
30548
  Object.keys(ni.attributes).forEach(function(k) {
@@ -30427,30 +30550,22 @@ var GameVehiclesThree = (() => {
30427
30550
  });
30428
30551
  geo.setIndex(null);
30429
30552
  }
30430
- const p = geo.attributes.position;
30431
- const n = p.count;
30553
+ const P = geo.attributes.position.array;
30554
+ const n = geo.attributes.position.count;
30432
30555
  const faces = n / 3;
30433
30556
  const FN = new Float64Array(faces * 3);
30434
- const map = /* @__PURE__ */ new Map();
30435
- const RANGE = 65536;
30436
- function key(i) {
30437
- const x = Math.round(p.getX(i) * 2e3);
30438
- const y = Math.round(p.getY(i) * 2e3);
30439
- const z = Math.round(p.getZ(i) * 2e3);
30440
- if (Math.abs(x) < RANGE && Math.abs(y) < RANGE && Math.abs(z) < RANGE) return ((x + RANGE) * 131072 + (y + RANGE)) * 131072 + (z + RANGE);
30441
- return x + "," + y + "," + z;
30442
- }
30443
- const keys = new Array(n);
30557
+ const out = new Float32Array(n * 3);
30444
30558
  for (let f = 0; f < faces; f++) {
30445
- const ax = p.getX(3 * f);
30446
- const ay = p.getY(3 * f);
30447
- const az = p.getZ(3 * f);
30448
- const bx = p.getX(3 * f + 1);
30449
- const by = p.getY(3 * f + 1);
30450
- const bz = p.getZ(3 * f + 1);
30451
- const cx = p.getX(3 * f + 2);
30452
- const cy = p.getY(3 * f + 2);
30453
- const cz = p.getZ(3 * f + 2);
30559
+ const o = 9 * f;
30560
+ const ax = P[o];
30561
+ const ay = P[o + 1];
30562
+ const az = P[o + 2];
30563
+ const bx = P[o + 3];
30564
+ const by = P[o + 4];
30565
+ const bz = P[o + 5];
30566
+ const cx = P[o + 6];
30567
+ const cy = P[o + 7];
30568
+ const cz = P[o + 8];
30454
30569
  const e1x = cx - bx;
30455
30570
  const e1y = cy - by;
30456
30571
  const e1z = cz - bz;
@@ -30470,41 +30585,109 @@ var GameVehiclesThree = (() => {
30470
30585
  FN[3 * f + 1] = ny;
30471
30586
  FN[3 * f + 2] = nz;
30472
30587
  for (let k = 0; k < 3; k++) {
30473
- const kk = key(3 * f + k);
30474
- keys[3 * f + k] = kk;
30475
- const list2 = map.get(kk);
30476
- if (list2) list2.push(f);
30477
- else map.set(kk, [f]);
30588
+ out[9 * f + 3 * k] = nx;
30589
+ out[9 * f + 3 * k + 1] = ny;
30590
+ out[9 * f + 3 * k + 2] = nz;
30591
+ }
30592
+ }
30593
+ const normal = new THREE.BufferAttribute(out, 3);
30594
+ geo.setAttribute("normal", normal);
30595
+ const token = {};
30596
+ latestCrease.set(geo, token);
30597
+ let size = 16;
30598
+ while (size < n * 2) size *= 2;
30599
+ const mask = size - 1;
30600
+ const slot = new Int32Array(size).fill(-1);
30601
+ const gx = new Int32Array(n);
30602
+ const gy = new Int32Array(n);
30603
+ const gz = new Int32Array(n);
30604
+ const groupOf = new Int32Array(n);
30605
+ let groups = 0;
30606
+ let start2;
30607
+ let members;
30608
+ const cs = Math.cos(deg * PI / 180);
30609
+ let phase = 0;
30610
+ let at = 0;
30611
+ function hashSlice(deadline) {
30612
+ for (; at < n; at++) {
30613
+ if ((at & 1023) === 0 && performance.now() > deadline) return false;
30614
+ const x = Math.round(P[3 * at] * 2e3) | 0;
30615
+ const y = Math.round(P[3 * at + 1] * 2e3) | 0;
30616
+ const z = Math.round(P[3 * at + 2] * 2e3) | 0;
30617
+ let h = (Math.imul(x, 73856093) ^ Math.imul(y, 19349663) ^ Math.imul(z, 83492791)) & mask;
30618
+ let g = slot[h];
30619
+ while (g >= 0 && (gx[g] !== x || gy[g] !== y || gz[g] !== z)) {
30620
+ h = h + 1 & mask;
30621
+ g = slot[h];
30622
+ }
30623
+ if (g < 0) {
30624
+ g = groups++;
30625
+ slot[h] = g;
30626
+ gx[g] = x;
30627
+ gy[g] = y;
30628
+ gz[g] = z;
30629
+ }
30630
+ groupOf[at] = g;
30478
30631
  }
30632
+ return true;
30479
30633
  }
30480
- const cs = Math.cos(deg * PI / 180);
30481
- const out = new Float32Array(n * 3);
30482
- for (let i = 0; i < n; i++) {
30483
- const fi = (i / 3 | 0) * 3;
30484
- const list2 = map.get(keys[i]);
30485
- let sx = 0;
30486
- let sy = 0;
30487
- let sz = 0;
30488
- for (let j = 0; j < list2.length; j++) {
30489
- const g = list2[j] * 3;
30490
- if (FN[g] * FN[fi] + FN[g + 1] * FN[fi + 1] + FN[g + 2] * FN[fi + 2] >= cs) {
30491
- sx += FN[g];
30492
- sy += FN[g + 1];
30493
- sz += FN[g + 2];
30634
+ function gather() {
30635
+ start2 = new Int32Array(groups + 1);
30636
+ for (let i = 0; i < n; i++) start2[groupOf[i] + 1]++;
30637
+ for (let g = 0; g < groups; g++) start2[g + 1] += start2[g];
30638
+ const fill2 = start2.slice(0, groups);
30639
+ members = new Int32Array(n);
30640
+ for (let i = 0; i < n; i++) members[fill2[groupOf[i]]++] = i / 3 | 0;
30641
+ }
30642
+ function smoothSlice(deadline) {
30643
+ for (; at < n; at++) {
30644
+ if ((at & 1023) === 0 && performance.now() > deadline) return false;
30645
+ const fi = (at / 3 | 0) * 3;
30646
+ const g = groupOf[at];
30647
+ let sx = 0;
30648
+ let sy = 0;
30649
+ let sz = 0;
30650
+ for (let j = start2[g], end = start2[g + 1]; j < end; j++) {
30651
+ const o = members[j] * 3;
30652
+ if (FN[o] * FN[fi] + FN[o + 1] * FN[fi + 1] + FN[o + 2] * FN[fi + 2] >= cs) {
30653
+ sx += FN[o];
30654
+ sy += FN[o + 1];
30655
+ sz += FN[o + 2];
30656
+ }
30494
30657
  }
30658
+ if (sx * sx + sy * sy + sz * sz < 1e-20) {
30659
+ sx = FN[fi];
30660
+ sy = FN[fi + 1];
30661
+ sz = FN[fi + 2];
30662
+ }
30663
+ const inv = 1 / (Math.sqrt(sx * sx + sy * sy + sz * sz) || 1);
30664
+ out[3 * at] = sx * inv;
30665
+ out[3 * at + 1] = sy * inv;
30666
+ out[3 * at + 2] = sz * inv;
30495
30667
  }
30496
- if (sx * sx + sy * sy + sz * sz < 1e-20) {
30497
- sx = FN[fi];
30498
- sy = FN[fi + 1];
30499
- sz = FN[fi + 2];
30668
+ return true;
30669
+ }
30670
+ function step(deadline) {
30671
+ if (latestCrease.get(geo) !== token) return true;
30672
+ if (phase === 0) {
30673
+ if (!hashSlice(deadline)) return false;
30674
+ gather();
30675
+ phase = 1;
30676
+ at = 0;
30677
+ }
30678
+ if (phase === 1) {
30679
+ const done = smoothSlice(deadline);
30680
+ if (deadline !== Infinity) normal.needsUpdate = true;
30681
+ if (!done) return false;
30682
+ phase = 2;
30683
+ geo.userData.crease = true;
30500
30684
  }
30501
- const inv = 1 / (Math.sqrt(sx * sx + sy * sy + sz * sz) || 1);
30502
- out[3 * i] = sx * inv;
30503
- out[3 * i + 1] = sy * inv;
30504
- out[3 * i + 2] = sz * inv;
30685
+ return true;
30505
30686
  }
30506
- geo.setAttribute("normal", new THREE.BufferAttribute(out, 3));
30507
- geo.userData.crease = true;
30687
+ return { geo, step };
30688
+ }
30689
+ function crease(geo, deg) {
30690
+ creaseTask(geo, deg).step(Infinity);
30508
30691
  return geo;
30509
30692
  }
30510
30693
  function pathShape(items) {
@@ -30651,28 +30834,28 @@ var GameVehiclesThree = (() => {
30651
30834
  return g;
30652
30835
  }
30653
30836
  function cutGeometry(geo, tests) {
30654
- const src = geo.index ? geo.toNonIndexed() : geo;
30837
+ const idx = geo.index ? geo.index.array : null;
30655
30838
  const names = ["position"].concat(
30656
30839
  ["color", "uv"].filter(function(n2) {
30657
- return !!src.attributes[n2];
30840
+ return !!geo.attributes[n2];
30658
30841
  })
30659
30842
  );
30660
30843
  const sizes = names.map(function(n2) {
30661
- return src.attributes[n2].itemSize;
30844
+ return geo.attributes[n2].itemSize;
30662
30845
  });
30663
30846
  const arrs = names.map(function(n2) {
30664
- return src.attributes[n2].array;
30847
+ return geo.attributes[n2].array;
30665
30848
  });
30666
- const nv = src.attributes.position.count;
30667
- let tris = [];
30668
- for (let f = 0; f < nv; f += 3) {
30849
+ const nv = idx ? idx.length : geo.attributes.position.count;
30850
+ function readTri(f) {
30669
30851
  const t = [];
30670
30852
  for (let k = 0; k < 3; k++) {
30853
+ const vi = idx ? idx[f + k] : f + k;
30671
30854
  const v = [];
30672
- for (let a = 0; a < names.length; a++) for (let q = 0; q < sizes[a]; q++) v.push(arrs[a][(f + k) * sizes[a] + q]);
30855
+ for (let a = 0; a < names.length; a++) for (let q = 0; q < sizes[a]; q++) v.push(arrs[a][vi * sizes[a] + q]);
30673
30856
  t.push(v);
30674
30857
  }
30675
- tris.push(t);
30858
+ return t;
30676
30859
  }
30677
30860
  const cut = {};
30678
30861
  const n = new V3();
@@ -30698,60 +30881,177 @@ var GameVehiclesThree = (() => {
30698
30881
  function fan(poly, arr) {
30699
30882
  for (let i = 1; i < poly.length - 1; i++) arr.push([poly[0], poly[i], poly[i + 1]]);
30700
30883
  }
30701
- tests.forEach(function(T) {
30702
- const next = [];
30884
+ function testTri(T, t, next, rem) {
30885
+ const A = t[0];
30886
+ const B = t[1];
30887
+ const C = t[2];
30888
+ e1.set(B[0] - A[0], B[1] - A[1], B[2] - A[2]);
30889
+ e2.set(C[0] - A[0], C[1] - A[1], C[2] - A[2]);
30890
+ n.crossVectors(e1, e2);
30891
+ const len = n.length();
30892
+ if (len < 1e-12) {
30893
+ next.push(t);
30894
+ return;
30895
+ }
30896
+ n.multiplyScalar(1 / len);
30897
+ ce.set((A[0] + B[0] + C[0]) / 3, (A[1] + B[1] + C[1]) / 3, (A[2] + B[2] + C[2]) / 3);
30898
+ if (T.sel && !T.sel(n, ce)) {
30899
+ next.push(t);
30900
+ return;
30901
+ }
30902
+ const d = [T.sdf(A[0], A[1], A[2]), T.sdf(B[0], B[1], B[2]), T.sdf(C[0], C[1], C[2])];
30903
+ const ins = (d[0] < 0 ? 1 : 0) + (d[1] < 0 ? 1 : 0) + (d[2] < 0 ? 1 : 0);
30904
+ if (ins === 0) next.push(t);
30905
+ else if (ins === 3) {
30906
+ if (rem) rem.push(t);
30907
+ } else {
30908
+ fan(clip(t, d, 1), next);
30909
+ if (rem) fan(clip(t, d, -1), rem);
30910
+ }
30911
+ }
30912
+ const segments = [];
30913
+ let total = 0;
30914
+ const ti = tests.length === 1 && tests[0].bounds ? triIndexOf(geo) : void 0;
30915
+ if (ti) {
30916
+ const T = tests[0];
30917
+ const lo = T.bounds.lo;
30918
+ const hi = T.bounds.hi;
30703
30919
  const rem = T.tag ? cut[T.tag] = cut[T.tag] || [] : null;
30704
- tris.forEach(function(t) {
30705
- const A = t[0];
30706
- const B = t[1];
30707
- const C = t[2];
30708
- e1.set(B[0] - A[0], B[1] - A[1], B[2] - A[2]);
30709
- e2.set(C[0] - A[0], C[1] - A[1], C[2] - A[2]);
30710
- n.crossVectors(e1, e2);
30711
- const len = n.length();
30712
- if (len < 1e-12) {
30713
- next.push(t);
30714
- return;
30715
- }
30716
- n.multiplyScalar(1 / len);
30717
- ce.set((A[0] + B[0] + C[0]) / 3, (A[1] + B[1] + C[1]) / 3, (A[2] + B[2] + C[2]) / 3);
30718
- if (T.sel && !T.sel(n, ce)) {
30719
- next.push(t);
30720
- return;
30920
+ const boxes = ti.boxes;
30921
+ const blocks = ti.blocks;
30922
+ let runFrom = -1;
30923
+ const closeRun = function(end) {
30924
+ if (runFrom < 0) return;
30925
+ segments.push([runFrom, end]);
30926
+ total += end - runFrom;
30927
+ runFrom = -1;
30928
+ };
30929
+ for (let blk = 0, t0 = 0; t0 < ti.triangles; blk++, t0 += TRI_BLOCK) {
30930
+ const j = blk * 6;
30931
+ if (blocks[j + 3] < lo[0] || blocks[j] > hi[0] || blocks[j + 4] < lo[1] || blocks[j + 1] > hi[1] || blocks[j + 5] < lo[2] || blocks[j + 2] > hi[2]) {
30932
+ if (runFrom < 0) runFrom = t0;
30933
+ continue;
30721
30934
  }
30722
- const d = [T.sdf(A[0], A[1], A[2]), T.sdf(B[0], B[1], B[2]), T.sdf(C[0], C[1], C[2])];
30723
- const ins = (d[0] < 0 ? 1 : 0) + (d[1] < 0 ? 1 : 0) + (d[2] < 0 ? 1 : 0);
30724
- if (ins === 0) next.push(t);
30725
- else if (ins === 3) {
30726
- if (rem) rem.push(t);
30727
- } else {
30728
- fan(clip(t, d, 1), next);
30729
- if (rem) fan(clip(t, d, -1), rem);
30935
+ const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
30936
+ for (let t = t0; t < t1; t++) {
30937
+ const q = t * 6;
30938
+ if (boxes[q + 3] < lo[0] || boxes[q] > hi[0] || boxes[q + 4] < lo[1] || boxes[q + 1] > hi[1] || boxes[q + 5] < lo[2] || boxes[q + 2] > hi[2]) {
30939
+ if (runFrom < 0) runFrom = t;
30940
+ continue;
30941
+ }
30942
+ closeRun(t);
30943
+ const next = [];
30944
+ testTri(T, readTri(t * 3), next, rem);
30945
+ if (next.length) {
30946
+ segments.push(next);
30947
+ total += next.length;
30948
+ }
30730
30949
  }
30950
+ }
30951
+ closeRun(ti.triangles);
30952
+ } else {
30953
+ let tris = [];
30954
+ for (let f = 0; f < nv; f += 3) tris.push(readTri(f));
30955
+ tests.forEach(function(T) {
30956
+ const next = [];
30957
+ const rem = T.tag ? cut[T.tag] = cut[T.tag] || [] : null;
30958
+ tris.forEach(function(t) {
30959
+ testTri(T, t, next, rem);
30960
+ });
30961
+ tris = next;
30731
30962
  });
30732
- tris = next;
30733
- });
30734
- function build(list2) {
30963
+ segments.push(tris);
30964
+ total = tris.length;
30965
+ }
30966
+ function fill2(segs, count2, boxesOut2) {
30735
30967
  const g = new THREE.BufferGeometry();
30736
- let off = 0;
30737
- names.forEach(function(nm, a) {
30738
- const arr = new Float32Array(list2.length * 3 * sizes[a]);
30739
- let w = 0;
30740
- list2.forEach(function(t) {
30741
- for (let k = 0; k < 3; k++) for (let q = 0; q < sizes[a]; q++) arr[w++] = t[k][off + q];
30968
+ const dst = names.map(function(_nm, a) {
30969
+ return new Float32Array(count2 * 3 * sizes[a]);
30970
+ });
30971
+ const w = names.map(function() {
30972
+ return 0;
30973
+ });
30974
+ let wb = 0;
30975
+ segs.forEach(function(seg) {
30976
+ if (typeof seg[0] === "number") {
30977
+ for (let a = 0; a < names.length; a++) {
30978
+ const size = sizes[a];
30979
+ if (!idx) {
30980
+ dst[a].set(arrs[a].subarray(seg[0] * 3 * size, seg[1] * 3 * size), w[a]);
30981
+ w[a] += (seg[1] - seg[0]) * 3 * size;
30982
+ continue;
30983
+ }
30984
+ for (let f = seg[0] * 3; f < seg[1] * 3; f++) for (let q = 0; q < size; q++) dst[a][w[a]++] = arrs[a][idx[f] * size + q];
30985
+ }
30986
+ if (boxesOut2 && ti) {
30987
+ boxesOut2.set(ti.boxes.subarray(seg[0] * 6, seg[1] * 6), wb);
30988
+ wb += (seg[1] - seg[0]) * 6;
30989
+ }
30990
+ return;
30991
+ }
30992
+ seg.forEach(function(t) {
30993
+ if (boxesOut2) {
30994
+ for (let k = 0; k < 3; k++) {
30995
+ boxesOut2[wb + k] = Math.fround(Math.min(t[0][k], t[1][k], t[2][k]));
30996
+ boxesOut2[wb + 3 + k] = Math.fround(Math.max(t[0][k], t[1][k], t[2][k]));
30997
+ }
30998
+ wb += 6;
30999
+ }
31000
+ let off = 0;
31001
+ for (let a = 0; a < names.length; a++) {
31002
+ for (let k = 0; k < 3; k++) for (let q = 0; q < sizes[a]; q++) dst[a][w[a]++] = t[k][off + q];
31003
+ off += sizes[a];
31004
+ }
30742
31005
  });
30743
- g.setAttribute(nm, new THREE.BufferAttribute(arr, sizes[a]));
30744
- off += sizes[a];
31006
+ });
31007
+ names.forEach(function(nm, a) {
31008
+ g.setAttribute(nm, new THREE.BufferAttribute(dst[a], sizes[a]));
30745
31009
  });
30746
31010
  g.userData.crease = true;
30747
31011
  return g;
30748
31012
  }
30749
- const out = { geo: build(tris), cut: {} };
31013
+ const boxesOut = ti ? new Float64Array(total * 6) : void 0;
31014
+ const out = { geo: fill2(segments, total, boxesOut), cut: {}, tasks: {} };
31015
+ if (boxesOut) storeTriIndex(out.geo, boxesOut);
30750
31016
  Object.keys(cut).forEach(function(k) {
30751
- out.cut[k] = crease(build(cut[k]), 42);
31017
+ const piece = fill2([cut[k]], cut[k].length);
31018
+ const mode = tests.find(function(T) {
31019
+ return T.tag === k;
31020
+ }).pieces;
31021
+ if (mode === "none") out.cut[k] = piece;
31022
+ else if (mode === "later") {
31023
+ out.cut[k] = piece;
31024
+ out.tasks[k] = creaseTask(piece, 42);
31025
+ } else out.cut[k] = crease(piece, 42);
30752
31026
  });
30753
31027
  return out;
30754
31028
  }
31029
+ function refreshBounds(geo) {
31030
+ const found = boundsFromIndex(geo);
31031
+ if (!found) {
31032
+ geo.computeBoundingSphere();
31033
+ geo.computeBoundingBox();
31034
+ return;
31035
+ }
31036
+ if (geo.boundingBox && geo.boundingSphere && boundsDone.get(geo) === found.version) return;
31037
+ const b = found.box;
31038
+ if (!geo.boundingBox) geo.boundingBox = new THREE.Box3();
31039
+ geo.boundingBox.min.set(b[0], b[1], b[2]);
31040
+ geo.boundingBox.max.set(b[3], b[4], b[5]);
31041
+ if (!geo.boundingSphere) geo.boundingSphere = new THREE.Sphere();
31042
+ const center = geo.boundingBox.getCenter(geo.boundingSphere.center);
31043
+ const P = geo.attributes.position.array;
31044
+ let maxRadiusSq = 0;
31045
+ for (let i = 0; i < P.length; i += 3) {
31046
+ const dx = center.x - P[i];
31047
+ const dy = center.y - P[i + 1];
31048
+ const dz = center.z - P[i + 2];
31049
+ maxRadiusSq = Math.max(maxRadiusSq, dx * dx + dy * dy + dz * dz);
31050
+ }
31051
+ geo.boundingSphere.radius = Math.sqrt(maxRadiusSq);
31052
+ boundsDone.set(geo, found.version);
31053
+ }
31054
+ const boundsDone = /* @__PURE__ */ new WeakMap();
30755
31055
  function mergeGeometries(list2) {
30756
31056
  const pos = [];
30757
31057
  const nor = [];
@@ -30882,7 +31182,7 @@ var GameVehiclesThree = (() => {
30882
31182
  }
30883
31183
  };
30884
31184
  };
30885
- Object.assign(I, { roundedBoxGeometry, taper, subdivide, crease, pathShape, tumble, loftGeometry, hullGeometry, cutGeometry, mergeGeometries, uvProject });
31185
+ Object.assign(I, { roundedBoxGeometry, taper, subdivide, crease, creaseTask, refreshBounds, pathShape, tumble, loftGeometry, hullGeometry, cutGeometry, mergeGeometries, uvProject });
30886
31186
  }
30887
31187
  function installContext(kit) {
30888
31188
  const THREE = kit.THREE;
@@ -36171,6 +36471,8 @@ var GameVehiclesThree = (() => {
36171
36471
  const pos = g && g.attributes && g.attributes.position;
36172
36472
  return o.raycast === THREE.Mesh.prototype.raycast && !o.isSkinnedMesh && !Array.isArray(o.material) && pos && !pos.isInterleavedBufferAttribute && pos.itemSize === 3 && !g.groups.length && !(g.morphAttributes && g.morphAttributes.position) && (g.index ? g.index.count : pos.count) / 3 >= PROXY_MIN_TRIANGLES;
36173
36473
  }
36474
+ let _keep = new Uint32Array(0);
36475
+ let _box = new Float32Array(0);
36174
36476
  function proxyIn(o, Mw, R) {
36175
36477
  _pm.copy(o.matrixWorld).invert().multiply(Mw);
36176
36478
  const lo = [Infinity, Infinity, Infinity];
@@ -36183,39 +36485,48 @@ var GameVehiclesThree = (() => {
36183
36485
  }
36184
36486
  }
36185
36487
  const g = o.geometry;
36186
- const P = g.attributes.position.array;
36488
+ const ti = triIndexOf(g);
36489
+ if (!ti) return null;
36187
36490
  const ix = g.index ? g.index.array : null;
36188
- const n = ix ? ix.length : P.length / 3;
36189
- const keep = new Uint32Array(n - n % 3);
36491
+ const boxes = ti.boxes;
36492
+ const blocks = ti.blocks;
36493
+ if (_keep.length < ti.triangles * 3) {
36494
+ _keep = new Uint32Array(ti.triangles * 3);
36495
+ _box = new Float32Array(ti.triangles * 6);
36496
+ }
36497
+ const keep = _keep;
36498
+ const box2 = _box;
36190
36499
  let nk = 0;
36191
- for (let t = 0; t + 2 < n; t += 3) {
36192
- const a = (ix ? ix[t] : t) * 3;
36193
- const b = (ix ? ix[t + 1] : t + 1) * 3;
36194
- const d = (ix ? ix[t + 2] : t + 2) * 3;
36195
- let out = false;
36196
- for (let k = 0; k < 3 && !out; k++) {
36197
- const u = P[a + k];
36198
- const v = P[b + k];
36199
- const w = P[d + k];
36200
- out = Math.max(u, v, w) < lo[k] || Math.min(u, v, w) > hi[k];
36201
- }
36202
- if (!out) {
36203
- keep[nk++] = ix ? ix[t] : t;
36204
- keep[nk++] = ix ? ix[t + 1] : t + 1;
36205
- keep[nk++] = ix ? ix[t + 2] : t + 2;
36500
+ let nt = 0;
36501
+ for (let blk = 0, t0 = 0; t0 < ti.triangles; blk++, t0 += TRI_BLOCK) {
36502
+ const j = blk * 6;
36503
+ if (blocks[j + 3] < lo[0] || blocks[j] > hi[0] || blocks[j + 4] < lo[1] || blocks[j + 1] > hi[1] || blocks[j + 5] < lo[2] || blocks[j + 2] > hi[2]) continue;
36504
+ const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
36505
+ for (let t = t0; t < t1; t++) {
36506
+ const q = t * 6;
36507
+ if (boxes[q + 3] < lo[0] || boxes[q] > hi[0] || boxes[q + 4] < lo[1] || boxes[q + 1] > hi[1] || boxes[q + 5] < lo[2] || boxes[q + 2] > hi[2]) continue;
36508
+ keep[nk++] = ix ? ix[t * 3] : t * 3;
36509
+ keep[nk++] = ix ? ix[t * 3 + 1] : t * 3 + 1;
36510
+ keep[nk++] = ix ? ix[t * 3 + 2] : t * 3 + 2;
36511
+ for (let k = 0; k < 6; k++) box2[nt * 6 + k] = boxes[q + k];
36512
+ nt++;
36206
36513
  }
36207
36514
  }
36208
36515
  if (!nk) return null;
36209
36516
  const kept = keep.slice(0, nk);
36210
- const box2 = new Float32Array(kept.length / 3 * 6);
36211
- for (let t = 0, j = 0; t < kept.length; t += 3, j += 6) {
36212
- const a = kept[t] * 3;
36213
- const b = kept[t + 1] * 3;
36214
- const d = kept[t + 2] * 3;
36517
+ const keptBox = box2.slice(0, nt * 6);
36518
+ const keptBlocks = new Float32Array(Math.ceil(nt / TRI_BLOCK) * 6);
36519
+ for (let blk = 0; blk * TRI_BLOCK < nt; blk++) {
36520
+ const b = blk * 6;
36215
36521
  for (let k = 0; k < 3; k++) {
36216
- box2[j + k] = Math.min(P[a + k], P[b + k], P[d + k]);
36217
- box2[j + 3 + k] = Math.max(P[a + k], P[b + k], P[d + k]);
36522
+ keptBlocks[b + k] = Infinity;
36523
+ keptBlocks[b + 3 + k] = -Infinity;
36218
36524
  }
36525
+ for (let t = blk * TRI_BLOCK, t1 = Math.min(nt, t + TRI_BLOCK); t < t1; t++)
36526
+ for (let k = 0; k < 3; k++) {
36527
+ if (keptBox[t * 6 + k] < keptBlocks[b + k]) keptBlocks[b + k] = keptBox[t * 6 + k];
36528
+ if (keptBox[t * 6 + 3 + k] > keptBlocks[b + 3 + k]) keptBlocks[b + 3 + k] = keptBox[t * 6 + 3 + k];
36529
+ }
36219
36530
  }
36220
36531
  const pg = new THREE.BufferGeometry();
36221
36532
  pg.setAttribute("position", g.attributes.position);
@@ -36226,7 +36537,8 @@ var GameVehiclesThree = (() => {
36226
36537
  proxy.layers.mask = o.layers.mask;
36227
36538
  proxy.proxyOf = o;
36228
36539
  proxy.kept = kept;
36229
- proxy.keptBox = box2;
36540
+ proxy.keptBox = keptBox;
36541
+ proxy.keptBlocks = keptBlocks;
36230
36542
  return proxy;
36231
36543
  }
36232
36544
  function narrowTo(rc, proxy) {
@@ -36246,13 +36558,21 @@ var GameVehiclesThree = (() => {
36246
36558
  const hi2 = Math.max(z0, _pv.z) + 1e-4;
36247
36559
  const K = proxy.kept;
36248
36560
  const X = proxy.keptBox;
36561
+ const KB = proxy.keptBlocks;
36562
+ const nt = K.length / 3;
36249
36563
  const dst = proxy.geometry.index.array;
36250
36564
  let m = 0;
36251
- for (let t = 0, j = 0; t < K.length; t += 3, j += 6) {
36252
- if (X[j + 3] < lo0 || X[j] > hi0 || X[j + 4] < lo1 || X[j + 1] > hi1 || X[j + 5] < lo2 || X[j + 2] > hi2) continue;
36253
- dst[m++] = K[t];
36254
- dst[m++] = K[t + 1];
36255
- dst[m++] = K[t + 2];
36565
+ for (let blk = 0, t0 = 0; t0 < nt; blk++, t0 += TRI_BLOCK) {
36566
+ const b = blk * 6;
36567
+ if (KB[b + 3] < lo0 || KB[b] > hi0 || KB[b + 4] < lo1 || KB[b + 1] > hi1 || KB[b + 5] < lo2 || KB[b + 2] > hi2) continue;
36568
+ const t1 = Math.min(nt, t0 + TRI_BLOCK);
36569
+ for (let t = t0; t < t1; t++) {
36570
+ const j = t * 6;
36571
+ if (X[j + 3] < lo0 || X[j] > hi0 || X[j + 4] < lo1 || X[j + 1] > hi1 || X[j + 5] < lo2 || X[j + 2] > hi2) continue;
36572
+ dst[m++] = K[t * 3];
36573
+ dst[m++] = K[t * 3 + 1];
36574
+ dst[m++] = K[t * 3 + 2];
36575
+ }
36256
36576
  }
36257
36577
  proxy.geometry.setDrawRange(0, m);
36258
36578
  }
@@ -36668,6 +36988,8 @@ var GameVehiclesThree = (() => {
36668
36988
  irel.copy(rel).invert();
36669
36989
  const pos = g.attributes.position;
36670
36990
  let changed = false;
36991
+ const liveIndex = liveTriIndex(g);
36992
+ const movedVertices = [];
36671
36993
  const near = boxInFrame(B, irel, v);
36672
36994
  for (let i = 0; i < pos.count; i++) {
36673
36995
  v.fromBufferAttribute(pos, i);
@@ -36679,6 +37001,7 @@ var GameVehiclesThree = (() => {
36679
37001
  if (opt.extra) opt.extra(v, f);
36680
37002
  v.applyMatrix4(irel);
36681
37003
  pos.setXYZ(i, v.x, v.y, v.z);
37004
+ movedVertices.push(i);
36682
37005
  changed = true;
36683
37006
  }
36684
37007
  if (opt.extraAll) {
@@ -36687,12 +37010,14 @@ var GameVehiclesThree = (() => {
36687
37010
  if (opt.extraAll(v)) {
36688
37011
  v.applyMatrix4(irel);
36689
37012
  pos.setXYZ(j, v.x, v.y, v.z);
37013
+ movedVertices.push(j);
36690
37014
  changed = true;
36691
37015
  }
36692
37016
  }
36693
37017
  }
36694
37018
  if (changed) {
36695
37019
  pos.needsUpdate = true;
37020
+ if (liveIndex) touchTriIndex(g, liveIndex, movedVertices);
36696
37021
  dirty.add(msh);
36697
37022
  }
36698
37023
  if (changed || boundsDue) {
@@ -36723,6 +37048,26 @@ var GameVehiclesThree = (() => {
36723
37048
  });
36724
37049
  return { field, moved, ax, a, cu, cv, hu, hv, outer };
36725
37050
  }
37051
+ function panelBoundsIn(rel, rect, B, a, ax) {
37052
+ const det = rel.determinant();
37053
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return void 0;
37054
+ const back = rel.clone().invert();
37055
+ const lo = [Infinity, Infinity, Infinity];
37056
+ const hi = [-Infinity, -Infinity, -Infinity];
37057
+ const q = new V3();
37058
+ for (let i = 0; i < 8; i++) {
37059
+ q.setComponent(ax[0], i & 1 ? rect[1] : rect[0]);
37060
+ q.setComponent(ax[1], i & 2 ? rect[3] : rect[2]);
37061
+ q.setComponent(a, i & 4 ? I.boxHi(B, a) : I.boxLo(B, a));
37062
+ q.applyMatrix4(back);
37063
+ for (let k = 0; k < 3; k++) {
37064
+ lo[k] = Math.min(lo[k], q.getComponent(k));
37065
+ hi[k] = Math.max(hi[k], q.getComponent(k));
37066
+ }
37067
+ }
37068
+ const pad = 1e-3;
37069
+ return { lo: lo.map((x) => x - pad), hi: hi.map((x) => x + pad) };
37070
+ }
36726
37071
  function cutPanel(c, z, rect, keep, dirty, o) {
36727
37072
  o = o || {};
36728
37073
  const B = z.box;
@@ -36755,6 +37100,7 @@ var GameVehiclesThree = (() => {
36755
37100
  }
36756
37101
  const test = {
36757
37102
  tag: "part",
37103
+ pieces: keep ? o.pieceTasks ? "later" : "crease" : "none",
36758
37104
  sel: o.anyN || z.cutAll ? null : function(n) {
36759
37105
  nv.copy(n).applyMatrix3(nm).normalize();
36760
37106
  return nv.dot(outN) > 0.3;
@@ -36773,13 +37119,12 @@ var GameVehiclesThree = (() => {
36773
37119
  return q;
36774
37120
  }
36775
37121
  };
36776
- const r = cutGeometry(g, [test]);
37122
+ const r = cutGeometry(g, [{ ...test, bounds: panelBoundsIn(rel, rect, B, a, ax) }]);
36777
37123
  const cg = r.cut.part;
36778
37124
  if (!cg || !cg.attributes.position.count) return;
36779
37125
  g.dispose();
36780
37126
  msh.geometry = r.geo;
36781
- r.geo.computeBoundingSphere();
36782
- r.geo.computeBoundingBox();
37127
+ I.refreshBounds(r.geo);
36783
37128
  dirty.add(msh);
36784
37129
  if (!keep) {
36785
37130
  cg.dispose();
@@ -36792,6 +37137,7 @@ var GameVehiclesThree = (() => {
36792
37137
  rel.decompose(pm.position, pm.quaternion, pm.scale);
36793
37138
  c.vehicle.add(pm);
36794
37139
  pm.updateMatrixWorld(true);
37140
+ if (o.pieceTasks) o.pieceTasks.set(pm, r.tasks.part);
36795
37141
  pieces.push({ mesh: pm, cut: true });
36796
37142
  });
36797
37143
  return pieces;
@@ -40401,7 +40747,11 @@ var GameVehiclesThree = (() => {
40401
40747
  __publicField(this, "plates", /* @__PURE__ */ new Map());
40402
40748
  __publicField(this, "gone", /* @__PURE__ */ new Set());
40403
40749
  __publicField(this, "syncPlates", /* @__PURE__ */ new Map());
40750
+ __publicField(this, "skins", /* @__PURE__ */ new Map());
40404
40751
  __publicField(this, "lightsOn", true);
40752
+ __publicField(this, "warming");
40753
+ __publicField(this, "tornThisFrame", false);
40754
+ __publicField(this, "smoothing", /* @__PURE__ */ new Map());
40405
40755
  __publicField(this, "hood");
40406
40756
  this.kit = kit;
40407
40757
  this.c = c;
@@ -40411,6 +40761,8 @@ var GameVehiclesThree = (() => {
40411
40761
  for (const p of model.parts) this.byId.set(p.id, p);
40412
40762
  c.root.updateMatrixWorld(true);
40413
40763
  this.hood = this.nameHood();
40764
+ this.warming = c.deform.filter((msh) => msh.geometry && msh.geometry.attributes.position && msh.geometry.attributes.position.count >= 1500);
40765
+ if (!this.warming.length) this.warming = null;
40414
40766
  for (const p of model.parts) {
40415
40767
  if (p.role === "door" || p.role === "lid") this.makePlate(p);
40416
40768
  else if (p.role === "mirror" && !this.mirrorObjects(p).length) this.makeMirror(p);
@@ -40546,11 +40898,21 @@ var GameVehiclesThree = (() => {
40546
40898
  * keeps the shape of its model instead of flat panels over its curved sides. Follows the hinge's rotation, whoever turns it (the clips of a host, `detach`).
40547
40899
  */
40548
40900
  showWhenOpen(id, piv, panel, recess) {
40901
+ let busy = false;
40549
40902
  const sync = () => {
40903
+ if (busy) return;
40550
40904
  const r = piv.rotation;
40551
40905
  const open = Math.abs(r.x) + Math.abs(r.y) + Math.abs(r.z) > 1e-3 || this.gone.has(id) || piv.parent !== this.c.vehicle;
40552
- panel.visible = open;
40553
- recess.visible = open;
40906
+ if (open && !this.gone.has(id) && piv.parent === this.c.vehicle && !this.skins.has(id)) {
40907
+ busy = true;
40908
+ try {
40909
+ this.skins.set(id, this.takeSkin(id, piv));
40910
+ } finally {
40911
+ busy = false;
40912
+ }
40913
+ }
40914
+ panel.visible = open && !this.skins.get(id);
40915
+ recess.visible = open && !this.skins.get(id);
40554
40916
  };
40555
40917
  const euler = piv.rotation;
40556
40918
  const quaternion = piv.quaternion;
@@ -40567,6 +40929,58 @@ var GameVehiclesThree = (() => {
40567
40929
  this.syncPlates.set(id, sync);
40568
40930
  sync();
40569
40931
  }
40932
+ /**
40933
+ * Cuts the skin of a door or lid zone out of the body (as the damage's hanging door does) and hangs it, with the thin parts on it (trim, handle) and, for a door, the side
40934
+ * window over it, on the hinge. Done with the hinge closed, so every piece keeps its place; answers whether there was skin to take.
40935
+ */
40936
+ takeSkin(id, piv) {
40937
+ const p = this.byId.get(id);
40938
+ const z = p && this.zone(p);
40939
+ if (!p || !z) return false;
40940
+ const I = this.I;
40941
+ const B = z.box;
40942
+ const q = piv.quaternion.clone();
40943
+ piv.quaternion.identity();
40944
+ this.c.root.updateMatrixWorld(true);
40945
+ const inv = I.worldInverseOf(this.c);
40946
+ let objs = [];
40947
+ try {
40948
+ if (p.role === "door") {
40949
+ const dirty = /* @__PURE__ */ new Set();
40950
+ const rect = [B.x0 + 0.03, B.x1 - 0.03, B.y0 + Math.min(0.08, (B.y1 - B.y0) * 0.1), B.y1 - 0.02];
40951
+ const pcs = I.cutPanel(this.c, z, rect, true, dirty).map((x) => x.mesh).filter((m) => !!m);
40952
+ this.mend(dirty);
40953
+ if (pcs.length) objs = [...pcs, ...I.followersIn(this.c, z, inv), ...I.windowsOver(this.c, z, inv)];
40954
+ } else {
40955
+ const pcs = this.cutZone(z);
40956
+ if (pcs.length) objs = [...pcs, ...I.followersIn(this.c, z, inv)];
40957
+ }
40958
+ } catch {
40959
+ objs = [];
40960
+ }
40961
+ const deform = this.c.deform ?? [];
40962
+ for (const o of objs) {
40963
+ if (!o.parent || o === piv) continue;
40964
+ piv.attach(o);
40965
+ o.traverse((x) => {
40966
+ x.userData.noFollow = true;
40967
+ });
40968
+ const di = deform.indexOf(o);
40969
+ if (di >= 0) deform.splice(di, 1);
40970
+ }
40971
+ piv.quaternion.copy(q);
40972
+ this.c.root.updateMatrixWorld(true);
40973
+ return objs.length > 0;
40974
+ }
40975
+ mend(dirty) {
40976
+ dirty.forEach((msh) => {
40977
+ const g = msh.geometry;
40978
+ if (g.userData.crease || !g.index) this.I.crease(g, 42);
40979
+ else g.computeVertexNormals();
40980
+ g.computeBoundingSphere();
40981
+ g.computeBoundingBox();
40982
+ });
40983
+ }
40570
40984
  makeMirror(p) {
40571
40985
  const [cx, cy, cz] = p.box.center;
40572
40986
  const s = cz < 0 ? -1 : 1;
@@ -40704,6 +41118,31 @@ var GameVehiclesThree = (() => {
40704
41118
  this.I.flattenTire(w, Math.min(0.5, 0.12 + 0.38 * melt));
40705
41119
  }
40706
41120
  }
41121
+ /** Smooths the normals of a cut mesh a slice per frame (see `pump`); until then it draws with flat face normals. */
41122
+ smoothLater(msh) {
41123
+ this.smoothing.set(msh, this.I.creaseTask(msh.geometry, 42));
41124
+ this.tornThisFrame = true;
41125
+ }
41126
+ /** Spends at most `budgetMs` finishing the pending normal smoothing. Call once per frame. */
41127
+ pump(budgetMs = 2.5) {
41128
+ if (this.tornThisFrame) {
41129
+ this.tornThisFrame = false;
41130
+ return;
41131
+ }
41132
+ if (!this.smoothing.size && !this.warming) return;
41133
+ const deadline = performance.now() + budgetMs;
41134
+ for (const [msh, task] of this.smoothing) {
41135
+ if (msh.geometry !== task.geo || task.step(deadline)) this.smoothing.delete(msh);
41136
+ if (performance.now() >= deadline) return;
41137
+ }
41138
+ this.warmIndexes(deadline);
41139
+ }
41140
+ /** Measures the triangles of the heavy body meshes once, a slice per frame, so the first panel torn off finds them ready (see `triIndexOf`). */
41141
+ warmIndexes(deadline) {
41142
+ if (!this.warming) return;
41143
+ this.warming = this.warming.filter((msh) => !warmTriIndex(msh.geometry, deadline));
41144
+ if (!this.warming.length) this.warming = null;
41145
+ }
40707
41146
  /** Moves the panel of a lost zone out of the body (the kit's torn-off look). */
40708
41147
  tearOff(p) {
40709
41148
  const z = this.zone(p);
@@ -40716,10 +41155,9 @@ var GameVehiclesThree = (() => {
40716
41155
  }
40717
41156
  dirty.forEach((msh) => {
40718
41157
  const g = msh.geometry;
40719
- if (g.userData.crease || !g.index) this.I.crease(g, 42);
41158
+ if (g.userData.crease || !g.index) this.smoothLater(msh);
40720
41159
  else g.computeVertexNormals();
40721
- g.computeBoundingSphere();
40722
- g.computeBoundingBox();
41160
+ this.I.refreshBounds(g);
40723
41161
  });
40724
41162
  this.gone.add(p.id);
40725
41163
  }
@@ -40862,17 +41300,19 @@ var GameVehiclesThree = (() => {
40862
41300
  const mg = Math.min(0.05, (u1 - u0) * 0.08, (v1 - v0) * 0.08);
40863
41301
  const dirty = /* @__PURE__ */ new Set();
40864
41302
  let pcs = [];
41303
+ const pieceTasks = /* @__PURE__ */ new Map();
40865
41304
  try {
40866
- pcs = I.cutPanel(this.c, z, [u0 + mg, u1 - mg, v0 + mg, v1 - mg], true, dirty);
41305
+ pcs = I.cutPanel(this.c, z, [u0 + mg, u1 - mg, v0 + mg, v1 - mg], true, dirty, { pieceTasks });
40867
41306
  } catch {
40868
41307
  pcs = [];
40869
41308
  }
41309
+ pieceTasks.forEach((task, mesh2) => this.smoothing.set(mesh2, task));
41310
+ this.tornThisFrame = true;
40870
41311
  dirty.forEach((msh) => {
40871
41312
  const g = msh.geometry;
40872
- if (g.userData.crease || !g.index) I.crease(g, 42);
41313
+ if (g.userData.crease || !g.index) this.smoothLater(msh);
40873
41314
  else g.computeVertexNormals();
40874
- g.computeBoundingSphere();
40875
- g.computeBoundingBox();
41315
+ I.refreshBounds(g);
40876
41316
  });
40877
41317
  return pcs.map((q) => q.mesh).filter((m) => !!m);
40878
41318
  }
@@ -41647,7 +42087,7 @@ var GameVehiclesThree = (() => {
41647
42087
  specCache = { name: options.name ?? c.spec.name ?? c.key, parts, joints, tags: ["vehicle", kindOf(c)] };
41648
42088
  return specCache;
41649
42089
  };
41650
- const state = () => {
42090
+ const buildState = () => {
41651
42091
  const parts = model.parts.map((d) => {
41652
42092
  const p = ps.get(d.id);
41653
42093
  const marked = p.dents.length > 0 || p.holes.length > 0 || p.cracks.length > 0;
@@ -41684,7 +42124,15 @@ var GameVehiclesThree = (() => {
41684
42124
  }));
41685
42125
  return { id, name: options.name ?? c.spec.name ?? c.key, position: [0, 0, 0], rotation: [0, 0, 0, 1], parts, joints, groups: groupsCache.map((g) => [...g]), destroyed: parts.every((p) => p.status === "broken" || p.status === "melted" || p.status === "ashes") };
41686
42126
  };
42127
+ let stateCache;
42128
+ const state = () => stateCache ?? (stateCache = buildState());
42129
+ const isSimulating = () => {
42130
+ if (leaks.size > 0) return true;
42131
+ for (const p of ps.values()) if (!p.lost && (p.burning || p.temp > AMBIENT)) return true;
42132
+ return false;
42133
+ };
41687
42134
  const hit = (h) => {
42135
+ stateCache = void 0;
41688
42136
  const out = [];
41689
42137
  const hh = h.space === "local" ? { ...h, space: "world", point: toWorld(h.point) } : h;
41690
42138
  if (hh.space === "local" || !hh.point) return out;
@@ -41711,6 +42159,8 @@ var GameVehiclesThree = (() => {
41711
42159
  clock += dt;
41712
42160
  const out = queue;
41713
42161
  queue = [];
42162
+ const wasSimulating = isSimulating();
42163
+ const handledBefore = (blastHandled ? 1 : 0) + (rollHandled ? 2 : 0);
41714
42164
  const hood = c.hood;
41715
42165
  if (hood) {
41716
42166
  const sign2 = hood.sign || 1;
@@ -41731,12 +42181,15 @@ var GameVehiclesThree = (() => {
41731
42181
  afterBlast(out);
41732
42182
  afterRoll(out);
41733
42183
  applyEffects();
42184
+ vis?.pump();
42185
+ if (wasSimulating || out.length > 0 || handledBefore !== (blastHandled ? 1 : 0) + (rollHandled ? 2 : 0)) stateCache = void 0;
41734
42186
  return out;
41735
42187
  };
41736
42188
  const disassemble = (jointId, tool, dt) => {
41737
42189
  const j = js.find((x) => x.def.id === jointId);
41738
42190
  if (!j || !j.def.tools.includes(tool)) return -1;
41739
42191
  if (j.open) return 1;
42192
+ stateCache = void 0;
41740
42193
  j.progress = Math.min(1, j.progress + dt / j.def.seconds);
41741
42194
  const step = Math.floor(j.progress * 4) / 4;
41742
42195
  if (step > j.reported && j.progress < 1) {
@@ -41752,6 +42205,7 @@ var GameVehiclesThree = (() => {
41752
42205
  return j.progress;
41753
42206
  };
41754
42207
  const extinguish = (partId) => {
42208
+ stateCache = void 0;
41755
42209
  for (const p of ps.values()) {
41756
42210
  if (partId && p.def.id !== partId) continue;
41757
42211
  if (p.burning) {
@@ -41765,6 +42219,7 @@ var GameVehiclesThree = (() => {
41765
42219
  }
41766
42220
  };
41767
42221
  const reset = () => {
42222
+ stateCache = void 0;
41768
42223
  const old = c;
41769
42224
  const parent = old.root.parent;
41770
42225
  const next = kit.build(old.key, old.state, old.scenario != null ? { scenario: old.scenario } : void 0);
@@ -41782,6 +42237,7 @@ var GameVehiclesThree = (() => {
41782
42237
  setup();
41783
42238
  };
41784
42239
  const rollover = (side2 = 1) => {
42240
+ stateCache = void 0;
41785
42241
  if (kit.roll(c, side2)) rolled = true;
41786
42242
  void rolled;
41787
42243
  };
@@ -42626,9 +43082,9 @@ var GameVehiclesThree = (() => {
42626
43082
  driver.state.u = 80 / 3.6;
42627
43083
  for (let t = 0; t < 1; t += dt) driver.step({ ...coast, throttle: 0.3 }, dt, world(surface));
42628
43084
  driver.state.u = 80 / 3.6;
42629
- const start = driver.state.x;
43085
+ const start2 = driver.state.x;
42630
43086
  for (let t = 0; t < 30 && driver.state.u > 0.1; t += dt) driver.step({ ...coast, brake: 1 }, dt, world(surface));
42631
- return driver.state.x - start;
43087
+ return driver.state.x - start2;
42632
43088
  };
42633
43089
  const dry = braking("dry_asphalt");
42634
43090
  const wet = braking("wet_asphalt");