@adatechnology/game-vehicles 0.4.4 → 0.4.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.
- package/dist/index.global.js +645 -183
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +612 -150
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.global.js
CHANGED
|
@@ -580,12 +580,12 @@ var GameVehicles = (() => {
|
|
|
580
580
|
return triangles;
|
|
581
581
|
}
|
|
582
582
|
};
|
|
583
|
-
function linkedList(data,
|
|
583
|
+
function linkedList(data, start2, end, dim, clockwise) {
|
|
584
584
|
let i, last;
|
|
585
|
-
if (clockwise === signedArea(data,
|
|
586
|
-
for (i =
|
|
585
|
+
if (clockwise === signedArea(data, start2, end, dim) > 0) {
|
|
586
|
+
for (i = start2; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
|
|
587
587
|
} else {
|
|
588
|
-
for (i = end - dim; i >=
|
|
588
|
+
for (i = end - dim; i >= start2; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
|
|
589
589
|
}
|
|
590
590
|
if (last && equals(last, last.next)) {
|
|
591
591
|
removeNode(last);
|
|
@@ -593,10 +593,10 @@ var GameVehicles = (() => {
|
|
|
593
593
|
}
|
|
594
594
|
return last;
|
|
595
595
|
}
|
|
596
|
-
function filterPoints(
|
|
597
|
-
if (!
|
|
598
|
-
if (!end) end =
|
|
599
|
-
let p =
|
|
596
|
+
function filterPoints(start2, end) {
|
|
597
|
+
if (!start2) return start2;
|
|
598
|
+
if (!end) end = start2;
|
|
599
|
+
let p = start2, again;
|
|
600
600
|
do {
|
|
601
601
|
again = false;
|
|
602
602
|
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
@@ -675,8 +675,8 @@ var GameVehicles = (() => {
|
|
|
675
675
|
}
|
|
676
676
|
return true;
|
|
677
677
|
}
|
|
678
|
-
function cureLocalIntersections(
|
|
679
|
-
let p =
|
|
678
|
+
function cureLocalIntersections(start2, triangles, dim) {
|
|
679
|
+
let p = start2;
|
|
680
680
|
do {
|
|
681
681
|
const a = p.prev, b = p.next.next;
|
|
682
682
|
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
@@ -685,14 +685,14 @@ var GameVehicles = (() => {
|
|
|
685
685
|
triangles.push(b.i / dim | 0);
|
|
686
686
|
removeNode(p);
|
|
687
687
|
removeNode(p.next);
|
|
688
|
-
p =
|
|
688
|
+
p = start2 = b;
|
|
689
689
|
}
|
|
690
690
|
p = p.next;
|
|
691
|
-
} while (p !==
|
|
691
|
+
} while (p !== start2);
|
|
692
692
|
return filterPoints(p);
|
|
693
693
|
}
|
|
694
|
-
function splitEarcut(
|
|
695
|
-
let a =
|
|
694
|
+
function splitEarcut(start2, triangles, dim, minX, minY, invSize) {
|
|
695
|
+
let a = start2;
|
|
696
696
|
do {
|
|
697
697
|
let b = a.next.next;
|
|
698
698
|
while (b !== a.prev) {
|
|
@@ -707,15 +707,15 @@ var GameVehicles = (() => {
|
|
|
707
707
|
b = b.next;
|
|
708
708
|
}
|
|
709
709
|
a = a.next;
|
|
710
|
-
} while (a !==
|
|
710
|
+
} while (a !== start2);
|
|
711
711
|
}
|
|
712
712
|
function eliminateHoles(data, holeIndices, outerNode, dim) {
|
|
713
713
|
const queue = [];
|
|
714
|
-
let i, len,
|
|
714
|
+
let i, len, start2, end, list2;
|
|
715
715
|
for (i = 0, len = holeIndices.length; i < len; i++) {
|
|
716
|
-
|
|
716
|
+
start2 = holeIndices[i] * dim;
|
|
717
717
|
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
718
|
-
list2 = linkedList(data,
|
|
718
|
+
list2 = linkedList(data, start2, end, dim, false);
|
|
719
719
|
if (list2 === list2.next) list2.steiner = true;
|
|
720
720
|
queue.push(getLeftmost(list2));
|
|
721
721
|
}
|
|
@@ -770,14 +770,14 @@ var GameVehicles = (() => {
|
|
|
770
770
|
function sectorContainsSector(m, p) {
|
|
771
771
|
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
772
772
|
}
|
|
773
|
-
function indexCurve(
|
|
774
|
-
let p =
|
|
773
|
+
function indexCurve(start2, minX, minY, invSize) {
|
|
774
|
+
let p = start2;
|
|
775
775
|
do {
|
|
776
776
|
if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
777
777
|
p.prevZ = p.prev;
|
|
778
778
|
p.nextZ = p.next;
|
|
779
779
|
p = p.next;
|
|
780
|
-
} while (p !==
|
|
780
|
+
} while (p !== start2);
|
|
781
781
|
p.prevZ.nextZ = null;
|
|
782
782
|
p.prevZ = null;
|
|
783
783
|
sortLinked(p);
|
|
@@ -834,12 +834,12 @@ var GameVehicles = (() => {
|
|
|
834
834
|
y = (y | y << 1) & 1431655765;
|
|
835
835
|
return x | y << 1;
|
|
836
836
|
}
|
|
837
|
-
function getLeftmost(
|
|
838
|
-
let p =
|
|
837
|
+
function getLeftmost(start2) {
|
|
838
|
+
let p = start2, leftmost = start2;
|
|
839
839
|
do {
|
|
840
840
|
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
|
|
841
841
|
p = p.next;
|
|
842
|
-
} while (p !==
|
|
842
|
+
} while (p !== start2);
|
|
843
843
|
return leftmost;
|
|
844
844
|
}
|
|
845
845
|
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
@@ -938,9 +938,9 @@ var GameVehicles = (() => {
|
|
|
938
938
|
this.nextZ = null;
|
|
939
939
|
this.steiner = false;
|
|
940
940
|
}
|
|
941
|
-
function signedArea(data,
|
|
941
|
+
function signedArea(data, start2, end, dim) {
|
|
942
942
|
let sum = 0;
|
|
943
|
-
for (let i =
|
|
943
|
+
for (let i = start2, j = end - dim; i < end; i += dim) {
|
|
944
944
|
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
|
|
945
945
|
j = i;
|
|
946
946
|
}
|
|
@@ -1197,7 +1197,7 @@ var GameVehicles = (() => {
|
|
|
1197
1197
|
const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)];
|
|
1198
1198
|
for (const k of [0, 1, 3, 1, 2, 3]) addUV(...uvs[k]);
|
|
1199
1199
|
};
|
|
1200
|
-
let
|
|
1200
|
+
let start2 = verticesArray.length / 3;
|
|
1201
1201
|
if (bevelEnabled) {
|
|
1202
1202
|
let offset = 0;
|
|
1203
1203
|
for (let i = 0; i < flen; i++) {
|
|
@@ -1220,8 +1220,8 @@ var GameVehicles = (() => {
|
|
|
1220
1220
|
f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
|
|
1221
1221
|
}
|
|
1222
1222
|
}
|
|
1223
|
-
groups.push({ start, count: verticesArray.length / 3 -
|
|
1224
|
-
|
|
1223
|
+
groups.push({ start: start2, count: verticesArray.length / 3 - start2, materialIndex: 0 });
|
|
1224
|
+
start2 = verticesArray.length / 3;
|
|
1225
1225
|
const sidewalls = (ring2, layeroffset2) => {
|
|
1226
1226
|
let i = ring2.length;
|
|
1227
1227
|
while (--i >= 0) {
|
|
@@ -1242,7 +1242,7 @@ var GameVehicles = (() => {
|
|
|
1242
1242
|
sidewalls(ahole, layeroffset);
|
|
1243
1243
|
layeroffset += ahole.length;
|
|
1244
1244
|
}
|
|
1245
|
-
groups.push({ start, count: verticesArray.length / 3 -
|
|
1245
|
+
groups.push({ start: start2, count: verticesArray.length / 3 - start2, materialIndex: 1 });
|
|
1246
1246
|
const positions = new Float32Array(verticesArray);
|
|
1247
1247
|
return { type: "ExtrudeGeometry", parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups };
|
|
1248
1248
|
}
|
|
@@ -1518,8 +1518,8 @@ var GameVehicles = (() => {
|
|
|
1518
1518
|
var shims = /* @__PURE__ */ new WeakSet();
|
|
1519
1519
|
function shapeGeometries(THREE, options = {}) {
|
|
1520
1520
|
if (shims.has(THREE)) return THREE;
|
|
1521
|
-
const
|
|
1522
|
-
const key =
|
|
1521
|
+
const cache2 = options.cache !== false;
|
|
1522
|
+
const key = cache2 ? "cache" : "nocache";
|
|
1523
1523
|
let byKey = namespaces.get(THREE);
|
|
1524
1524
|
if (!byKey) {
|
|
1525
1525
|
byKey = /* @__PURE__ */ new Map();
|
|
@@ -1528,7 +1528,7 @@ var GameVehicles = (() => {
|
|
|
1528
1528
|
const existing = byKey.get(key);
|
|
1529
1529
|
if (existing) return existing;
|
|
1530
1530
|
const made = (p) => toGeometry(THREE, p);
|
|
1531
|
-
const viaCache = (node, direct) =>
|
|
1531
|
+
const viaCache = (node, direct) => cache2 ? buildPrimitive(node) : direct();
|
|
1532
1532
|
const defined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
1533
1533
|
const constructors = {
|
|
1534
1534
|
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))),
|
|
@@ -2224,7 +2224,7 @@ var GameVehicles = (() => {
|
|
|
2224
2224
|
const I = kit._;
|
|
2225
2225
|
const document2 = kit.document;
|
|
2226
2226
|
const RUST = new THREE.Color("#5e3220");
|
|
2227
|
-
const
|
|
2227
|
+
const cache2 = {};
|
|
2228
2228
|
let envTex = null;
|
|
2229
2229
|
function studioEnvironment() {
|
|
2230
2230
|
if (envTex) return envTex;
|
|
@@ -2269,7 +2269,7 @@ var GameVehicles = (() => {
|
|
|
2269
2269
|
const key = "s" + c.getHexString() + JSON.stringify(o, function(k, v) {
|
|
2270
2270
|
return v && v.isColor ? "#" + v.getHexString() : v && v.isTexture ? v.uuid : v;
|
|
2271
2271
|
});
|
|
2272
|
-
if (!
|
|
2272
|
+
if (!cache2[key]) {
|
|
2273
2273
|
const o2 = Object.assign({}, o);
|
|
2274
2274
|
delete o2.noEnv;
|
|
2275
2275
|
const mt = new THREE.MeshStandardMaterial(Object.assign({ color: c, roughness: 0.8, metalness: 0, flatShading: false }, o2));
|
|
@@ -2277,9 +2277,9 @@ var GameVehicles = (() => {
|
|
|
2277
2277
|
mt.envMap = studioEnvironment();
|
|
2278
2278
|
if (o.envMapIntensity == null) mt.envMapIntensity = 0.55 + (mt.metalness - 0.6) * 1.6;
|
|
2279
2279
|
}
|
|
2280
|
-
|
|
2280
|
+
cache2[key] = mt;
|
|
2281
2281
|
}
|
|
2282
|
-
return
|
|
2282
|
+
return cache2[key];
|
|
2283
2283
|
}
|
|
2284
2284
|
function makeFlatMaterial(color2, o) {
|
|
2285
2285
|
return makeMaterial(color2, Object.assign({ flatShading: true, roughness: 0.92 }, o || {}));
|
|
@@ -2394,7 +2394,131 @@ var GameVehicles = (() => {
|
|
|
2394
2394
|
return t;
|
|
2395
2395
|
}
|
|
2396
2396
|
kit.textTexture = textTexture;
|
|
2397
|
-
Object.assign(I, { RUST, cache, studioEnvironment, makeMaterial, makeFlatMaterial, DOUBLE_SIDE, toColor, MATERIALS, paintColor, texCache, textTexture });
|
|
2397
|
+
Object.assign(I, { RUST, cache: cache2, studioEnvironment, makeMaterial, makeFlatMaterial, DOUBLE_SIDE, toColor, MATERIALS, paintColor, texCache, textTexture });
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
// src/tri-index.ts
|
|
2401
|
+
var TRI_BLOCK = 32;
|
|
2402
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
2403
|
+
function trianglesOf(geo) {
|
|
2404
|
+
return Math.floor((geo.index ? geo.index.count : geo.attributes.position.count) / 3);
|
|
2405
|
+
}
|
|
2406
|
+
function supports(geo) {
|
|
2407
|
+
const pos = geo.attributes && geo.attributes.position;
|
|
2408
|
+
return !!pos && !pos.isInterleavedBufferAttribute && pos.itemSize === 3;
|
|
2409
|
+
}
|
|
2410
|
+
function isCurrent(geo, ti) {
|
|
2411
|
+
const pos = geo.attributes.position;
|
|
2412
|
+
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);
|
|
2413
|
+
}
|
|
2414
|
+
function blockCount(triangles) {
|
|
2415
|
+
return Math.ceil(triangles / TRI_BLOCK);
|
|
2416
|
+
}
|
|
2417
|
+
function boxBlock(ti, block) {
|
|
2418
|
+
const B = ti.boxes;
|
|
2419
|
+
const t0 = block * TRI_BLOCK;
|
|
2420
|
+
const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
|
|
2421
|
+
const o = block * 6;
|
|
2422
|
+
for (let k = 0; k < 3; k++) {
|
|
2423
|
+
ti.blocks[o + k] = Infinity;
|
|
2424
|
+
ti.blocks[o + 3 + k] = -Infinity;
|
|
2425
|
+
}
|
|
2426
|
+
for (let t = t0; t < t1; t++) {
|
|
2427
|
+
const j = t * 6;
|
|
2428
|
+
for (let k = 0; k < 3; k++) {
|
|
2429
|
+
if (B[j + k] < ti.blocks[o + k]) ti.blocks[o + k] = B[j + k];
|
|
2430
|
+
if (B[j + 3 + k] > ti.blocks[o + 3 + k]) ti.blocks[o + 3 + k] = B[j + 3 + k];
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
function boxTriangle(geo, ti, t) {
|
|
2435
|
+
const P = geo.attributes.position.array;
|
|
2436
|
+
const ix = geo.index ? geo.index.array : null;
|
|
2437
|
+
const a = (ix ? ix[t * 3] : t * 3) * 3;
|
|
2438
|
+
const b = (ix ? ix[t * 3 + 1] : t * 3 + 1) * 3;
|
|
2439
|
+
const c = (ix ? ix[t * 3 + 2] : t * 3 + 2) * 3;
|
|
2440
|
+
const j = t * 6;
|
|
2441
|
+
for (let k = 0; k < 3; k++) {
|
|
2442
|
+
ti.boxes[j + k] = Math.min(P[a + k], P[b + k], P[c + k]);
|
|
2443
|
+
ti.boxes[j + 3 + k] = Math.max(P[a + k], P[b + k], P[c + k]);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
function advance(geo, ti, deadline) {
|
|
2447
|
+
const total = blockCount(ti.triangles);
|
|
2448
|
+
while (ti.builtBlocks < total) {
|
|
2449
|
+
const block = ti.builtBlocks;
|
|
2450
|
+
const t1 = Math.min(ti.triangles, (block + 1) * TRI_BLOCK);
|
|
2451
|
+
for (let t = block * TRI_BLOCK; t < t1; t++) boxTriangle(geo, ti, t);
|
|
2452
|
+
boxBlock(ti, block);
|
|
2453
|
+
ti.builtBlocks++;
|
|
2454
|
+
if (deadline !== Infinity && performance.now() >= deadline) break;
|
|
2455
|
+
}
|
|
2456
|
+
return ti.builtBlocks === total;
|
|
2457
|
+
}
|
|
2458
|
+
function start(geo) {
|
|
2459
|
+
const pos = geo.attributes.position;
|
|
2460
|
+
const triangles = trianglesOf(geo);
|
|
2461
|
+
const ti = {
|
|
2462
|
+
position: pos,
|
|
2463
|
+
positionVersion: pos.version,
|
|
2464
|
+
index: geo.index || null,
|
|
2465
|
+
indexVersion: geo.index ? geo.index.version : 0,
|
|
2466
|
+
triangles,
|
|
2467
|
+
boxes: new Float64Array(triangles * 6),
|
|
2468
|
+
blocks: new Float64Array(blockCount(triangles) * 6),
|
|
2469
|
+
builtBlocks: 0
|
|
2470
|
+
};
|
|
2471
|
+
cache.set(geo, ti);
|
|
2472
|
+
return ti;
|
|
2473
|
+
}
|
|
2474
|
+
function triIndexOf(geo) {
|
|
2475
|
+
if (!supports(geo)) return void 0;
|
|
2476
|
+
let ti = cache.get(geo);
|
|
2477
|
+
if (!ti || !isCurrent(geo, ti)) ti = start(geo);
|
|
2478
|
+
advance(geo, ti, Infinity);
|
|
2479
|
+
return ti;
|
|
2480
|
+
}
|
|
2481
|
+
function warmTriIndex(geo, deadline) {
|
|
2482
|
+
if (!supports(geo)) return true;
|
|
2483
|
+
let ti = cache.get(geo);
|
|
2484
|
+
if (!ti || !isCurrent(geo, ti)) ti = start(geo);
|
|
2485
|
+
return advance(geo, ti, deadline);
|
|
2486
|
+
}
|
|
2487
|
+
function storeTriIndex(geo, boxes) {
|
|
2488
|
+
const ti = start(geo);
|
|
2489
|
+
ti.boxes = boxes;
|
|
2490
|
+
const total = blockCount(ti.triangles);
|
|
2491
|
+
for (let b = 0; b < total; b++) boxBlock(ti, b);
|
|
2492
|
+
ti.builtBlocks = total;
|
|
2493
|
+
}
|
|
2494
|
+
function liveTriIndex(geo) {
|
|
2495
|
+
if (geo.index || !supports(geo)) return void 0;
|
|
2496
|
+
const ti = cache.get(geo);
|
|
2497
|
+
return ti && isCurrent(geo, ti) && ti.builtBlocks === blockCount(ti.triangles) ? ti : void 0;
|
|
2498
|
+
}
|
|
2499
|
+
function touchTriIndex(geo, ti, vertices) {
|
|
2500
|
+
if (ti.positionVersion + 1 !== geo.attributes.position.version) return;
|
|
2501
|
+
const blocks = /* @__PURE__ */ new Set();
|
|
2502
|
+
for (const v of vertices) {
|
|
2503
|
+
const t = Math.floor(v / 3);
|
|
2504
|
+
if (t >= ti.triangles) continue;
|
|
2505
|
+
boxTriangle(geo, ti, t);
|
|
2506
|
+
blocks.add(Math.floor(t / TRI_BLOCK));
|
|
2507
|
+
}
|
|
2508
|
+
blocks.forEach((b) => boxBlock(ti, b));
|
|
2509
|
+
ti.positionVersion = geo.attributes.position.version;
|
|
2510
|
+
}
|
|
2511
|
+
function boundsFromIndex(geo) {
|
|
2512
|
+
if (geo.index || !supports(geo)) return void 0;
|
|
2513
|
+
const ti = cache.get(geo);
|
|
2514
|
+
if (!ti || !isCurrent(geo, ti) || ti.builtBlocks !== blockCount(ti.triangles) || !ti.triangles || geo.attributes.position.count !== ti.triangles * 3) return void 0;
|
|
2515
|
+
const box2 = new Float64Array([Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]);
|
|
2516
|
+
for (let b = 0, n = blockCount(ti.triangles); b < n; b++)
|
|
2517
|
+
for (let k = 0; k < 3; k++) {
|
|
2518
|
+
box2[k] = Math.min(box2[k], ti.blocks[b * 6 + k]);
|
|
2519
|
+
box2[3 + k] = Math.max(box2[3 + k], ti.blocks[b * 6 + 3 + k]);
|
|
2520
|
+
}
|
|
2521
|
+
return { box: box2, version: ti.positionVersion };
|
|
2398
2522
|
}
|
|
2399
2523
|
|
|
2400
2524
|
// src/geometry.ts
|
|
@@ -2491,7 +2615,8 @@ var GameVehicles = (() => {
|
|
|
2491
2615
|
g.userData.crease = true;
|
|
2492
2616
|
return g;
|
|
2493
2617
|
}
|
|
2494
|
-
|
|
2618
|
+
const latestCrease = /* @__PURE__ */ new WeakMap();
|
|
2619
|
+
function creaseTask(geo, deg) {
|
|
2495
2620
|
if (geo.index) {
|
|
2496
2621
|
const ni = geo.toNonIndexed();
|
|
2497
2622
|
Object.keys(ni.attributes).forEach(function(k) {
|
|
@@ -2499,30 +2624,22 @@ var GameVehicles = (() => {
|
|
|
2499
2624
|
});
|
|
2500
2625
|
geo.setIndex(null);
|
|
2501
2626
|
}
|
|
2502
|
-
const
|
|
2503
|
-
const n =
|
|
2627
|
+
const P = geo.attributes.position.array;
|
|
2628
|
+
const n = geo.attributes.position.count;
|
|
2504
2629
|
const faces = n / 3;
|
|
2505
2630
|
const FN = new Float64Array(faces * 3);
|
|
2506
|
-
const
|
|
2507
|
-
const RANGE = 65536;
|
|
2508
|
-
function key(i) {
|
|
2509
|
-
const x = Math.round(p.getX(i) * 2e3);
|
|
2510
|
-
const y = Math.round(p.getY(i) * 2e3);
|
|
2511
|
-
const z = Math.round(p.getZ(i) * 2e3);
|
|
2512
|
-
if (Math.abs(x) < RANGE && Math.abs(y) < RANGE && Math.abs(z) < RANGE) return ((x + RANGE) * 131072 + (y + RANGE)) * 131072 + (z + RANGE);
|
|
2513
|
-
return x + "," + y + "," + z;
|
|
2514
|
-
}
|
|
2515
|
-
const keys = new Array(n);
|
|
2631
|
+
const out = new Float32Array(n * 3);
|
|
2516
2632
|
for (let f = 0; f < faces; f++) {
|
|
2517
|
-
const
|
|
2518
|
-
const
|
|
2519
|
-
const
|
|
2520
|
-
const
|
|
2521
|
-
const
|
|
2522
|
-
const
|
|
2523
|
-
const
|
|
2524
|
-
const
|
|
2525
|
-
const
|
|
2633
|
+
const o = 9 * f;
|
|
2634
|
+
const ax = P[o];
|
|
2635
|
+
const ay = P[o + 1];
|
|
2636
|
+
const az = P[o + 2];
|
|
2637
|
+
const bx = P[o + 3];
|
|
2638
|
+
const by = P[o + 4];
|
|
2639
|
+
const bz = P[o + 5];
|
|
2640
|
+
const cx = P[o + 6];
|
|
2641
|
+
const cy = P[o + 7];
|
|
2642
|
+
const cz = P[o + 8];
|
|
2526
2643
|
const e1x = cx - bx;
|
|
2527
2644
|
const e1y = cy - by;
|
|
2528
2645
|
const e1z = cz - bz;
|
|
@@ -2542,41 +2659,109 @@ var GameVehicles = (() => {
|
|
|
2542
2659
|
FN[3 * f + 1] = ny;
|
|
2543
2660
|
FN[3 * f + 2] = nz;
|
|
2544
2661
|
for (let k = 0; k < 3; k++) {
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2662
|
+
out[9 * f + 3 * k] = nx;
|
|
2663
|
+
out[9 * f + 3 * k + 1] = ny;
|
|
2664
|
+
out[9 * f + 3 * k + 2] = nz;
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
const normal = new THREE.BufferAttribute(out, 3);
|
|
2668
|
+
geo.setAttribute("normal", normal);
|
|
2669
|
+
const token = {};
|
|
2670
|
+
latestCrease.set(geo, token);
|
|
2671
|
+
let size = 16;
|
|
2672
|
+
while (size < n * 2) size *= 2;
|
|
2673
|
+
const mask = size - 1;
|
|
2674
|
+
const slot = new Int32Array(size).fill(-1);
|
|
2675
|
+
const gx = new Int32Array(n);
|
|
2676
|
+
const gy = new Int32Array(n);
|
|
2677
|
+
const gz = new Int32Array(n);
|
|
2678
|
+
const groupOf = new Int32Array(n);
|
|
2679
|
+
let groups = 0;
|
|
2680
|
+
let start2;
|
|
2681
|
+
let members;
|
|
2682
|
+
const cs = Math.cos(deg * PI / 180);
|
|
2683
|
+
let phase = 0;
|
|
2684
|
+
let at = 0;
|
|
2685
|
+
function hashSlice(deadline) {
|
|
2686
|
+
for (; at < n; at++) {
|
|
2687
|
+
if ((at & 1023) === 0 && performance.now() > deadline) return false;
|
|
2688
|
+
const x = Math.round(P[3 * at] * 2e3) | 0;
|
|
2689
|
+
const y = Math.round(P[3 * at + 1] * 2e3) | 0;
|
|
2690
|
+
const z = Math.round(P[3 * at + 2] * 2e3) | 0;
|
|
2691
|
+
let h = (Math.imul(x, 73856093) ^ Math.imul(y, 19349663) ^ Math.imul(z, 83492791)) & mask;
|
|
2692
|
+
let g = slot[h];
|
|
2693
|
+
while (g >= 0 && (gx[g] !== x || gy[g] !== y || gz[g] !== z)) {
|
|
2694
|
+
h = h + 1 & mask;
|
|
2695
|
+
g = slot[h];
|
|
2696
|
+
}
|
|
2697
|
+
if (g < 0) {
|
|
2698
|
+
g = groups++;
|
|
2699
|
+
slot[h] = g;
|
|
2700
|
+
gx[g] = x;
|
|
2701
|
+
gy[g] = y;
|
|
2702
|
+
gz[g] = z;
|
|
2703
|
+
}
|
|
2704
|
+
groupOf[at] = g;
|
|
2550
2705
|
}
|
|
2706
|
+
return true;
|
|
2551
2707
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2558
|
-
let
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
if (
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2708
|
+
function gather() {
|
|
2709
|
+
start2 = new Int32Array(groups + 1);
|
|
2710
|
+
for (let i = 0; i < n; i++) start2[groupOf[i] + 1]++;
|
|
2711
|
+
for (let g = 0; g < groups; g++) start2[g + 1] += start2[g];
|
|
2712
|
+
const fill = start2.slice(0, groups);
|
|
2713
|
+
members = new Int32Array(n);
|
|
2714
|
+
for (let i = 0; i < n; i++) members[fill[groupOf[i]]++] = i / 3 | 0;
|
|
2715
|
+
}
|
|
2716
|
+
function smoothSlice(deadline) {
|
|
2717
|
+
for (; at < n; at++) {
|
|
2718
|
+
if ((at & 1023) === 0 && performance.now() > deadline) return false;
|
|
2719
|
+
const fi = (at / 3 | 0) * 3;
|
|
2720
|
+
const g = groupOf[at];
|
|
2721
|
+
let sx = 0;
|
|
2722
|
+
let sy = 0;
|
|
2723
|
+
let sz = 0;
|
|
2724
|
+
for (let j = start2[g], end = start2[g + 1]; j < end; j++) {
|
|
2725
|
+
const o = members[j] * 3;
|
|
2726
|
+
if (FN[o] * FN[fi] + FN[o + 1] * FN[fi + 1] + FN[o + 2] * FN[fi + 2] >= cs) {
|
|
2727
|
+
sx += FN[o];
|
|
2728
|
+
sy += FN[o + 1];
|
|
2729
|
+
sz += FN[o + 2];
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
if (sx * sx + sy * sy + sz * sz < 1e-20) {
|
|
2733
|
+
sx = FN[fi];
|
|
2734
|
+
sy = FN[fi + 1];
|
|
2735
|
+
sz = FN[fi + 2];
|
|
2566
2736
|
}
|
|
2737
|
+
const inv = 1 / (Math.sqrt(sx * sx + sy * sy + sz * sz) || 1);
|
|
2738
|
+
out[3 * at] = sx * inv;
|
|
2739
|
+
out[3 * at + 1] = sy * inv;
|
|
2740
|
+
out[3 * at + 2] = sz * inv;
|
|
2567
2741
|
}
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2742
|
+
return true;
|
|
2743
|
+
}
|
|
2744
|
+
function step(deadline) {
|
|
2745
|
+
if (latestCrease.get(geo) !== token) return true;
|
|
2746
|
+
if (phase === 0) {
|
|
2747
|
+
if (!hashSlice(deadline)) return false;
|
|
2748
|
+
gather();
|
|
2749
|
+
phase = 1;
|
|
2750
|
+
at = 0;
|
|
2751
|
+
}
|
|
2752
|
+
if (phase === 1) {
|
|
2753
|
+
const done = smoothSlice(deadline);
|
|
2754
|
+
if (deadline !== Infinity) normal.needsUpdate = true;
|
|
2755
|
+
if (!done) return false;
|
|
2756
|
+
phase = 2;
|
|
2757
|
+
geo.userData.crease = true;
|
|
2572
2758
|
}
|
|
2573
|
-
|
|
2574
|
-
out[3 * i] = sx * inv;
|
|
2575
|
-
out[3 * i + 1] = sy * inv;
|
|
2576
|
-
out[3 * i + 2] = sz * inv;
|
|
2759
|
+
return true;
|
|
2577
2760
|
}
|
|
2578
|
-
geo
|
|
2579
|
-
|
|
2761
|
+
return { geo, step };
|
|
2762
|
+
}
|
|
2763
|
+
function crease(geo, deg) {
|
|
2764
|
+
creaseTask(geo, deg).step(Infinity);
|
|
2580
2765
|
return geo;
|
|
2581
2766
|
}
|
|
2582
2767
|
function pathShape(items) {
|
|
@@ -2723,28 +2908,28 @@ var GameVehicles = (() => {
|
|
|
2723
2908
|
return g;
|
|
2724
2909
|
}
|
|
2725
2910
|
function cutGeometry(geo, tests) {
|
|
2726
|
-
const
|
|
2911
|
+
const idx = geo.index ? geo.index.array : null;
|
|
2727
2912
|
const names = ["position"].concat(
|
|
2728
2913
|
["color", "uv"].filter(function(n2) {
|
|
2729
|
-
return !!
|
|
2914
|
+
return !!geo.attributes[n2];
|
|
2730
2915
|
})
|
|
2731
2916
|
);
|
|
2732
2917
|
const sizes = names.map(function(n2) {
|
|
2733
|
-
return
|
|
2918
|
+
return geo.attributes[n2].itemSize;
|
|
2734
2919
|
});
|
|
2735
2920
|
const arrs = names.map(function(n2) {
|
|
2736
|
-
return
|
|
2921
|
+
return geo.attributes[n2].array;
|
|
2737
2922
|
});
|
|
2738
|
-
const nv =
|
|
2739
|
-
|
|
2740
|
-
for (let f = 0; f < nv; f += 3) {
|
|
2923
|
+
const nv = idx ? idx.length : geo.attributes.position.count;
|
|
2924
|
+
function readTri(f) {
|
|
2741
2925
|
const t = [];
|
|
2742
2926
|
for (let k = 0; k < 3; k++) {
|
|
2927
|
+
const vi = idx ? idx[f + k] : f + k;
|
|
2743
2928
|
const v = [];
|
|
2744
|
-
for (let a = 0; a < names.length; a++) for (let q = 0; q < sizes[a]; q++) v.push(arrs[a][
|
|
2929
|
+
for (let a = 0; a < names.length; a++) for (let q = 0; q < sizes[a]; q++) v.push(arrs[a][vi * sizes[a] + q]);
|
|
2745
2930
|
t.push(v);
|
|
2746
2931
|
}
|
|
2747
|
-
|
|
2932
|
+
return t;
|
|
2748
2933
|
}
|
|
2749
2934
|
const cut = {};
|
|
2750
2935
|
const n = new V3();
|
|
@@ -2770,60 +2955,177 @@ var GameVehicles = (() => {
|
|
|
2770
2955
|
function fan(poly, arr) {
|
|
2771
2956
|
for (let i = 1; i < poly.length - 1; i++) arr.push([poly[0], poly[i], poly[i + 1]]);
|
|
2772
2957
|
}
|
|
2773
|
-
|
|
2774
|
-
const
|
|
2958
|
+
function testTri(T, t, next, rem) {
|
|
2959
|
+
const A = t[0];
|
|
2960
|
+
const B = t[1];
|
|
2961
|
+
const C = t[2];
|
|
2962
|
+
e1.set(B[0] - A[0], B[1] - A[1], B[2] - A[2]);
|
|
2963
|
+
e2.set(C[0] - A[0], C[1] - A[1], C[2] - A[2]);
|
|
2964
|
+
n.crossVectors(e1, e2);
|
|
2965
|
+
const len = n.length();
|
|
2966
|
+
if (len < 1e-12) {
|
|
2967
|
+
next.push(t);
|
|
2968
|
+
return;
|
|
2969
|
+
}
|
|
2970
|
+
n.multiplyScalar(1 / len);
|
|
2971
|
+
ce.set((A[0] + B[0] + C[0]) / 3, (A[1] + B[1] + C[1]) / 3, (A[2] + B[2] + C[2]) / 3);
|
|
2972
|
+
if (T.sel && !T.sel(n, ce)) {
|
|
2973
|
+
next.push(t);
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
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])];
|
|
2977
|
+
const ins = (d[0] < 0 ? 1 : 0) + (d[1] < 0 ? 1 : 0) + (d[2] < 0 ? 1 : 0);
|
|
2978
|
+
if (ins === 0) next.push(t);
|
|
2979
|
+
else if (ins === 3) {
|
|
2980
|
+
if (rem) rem.push(t);
|
|
2981
|
+
} else {
|
|
2982
|
+
fan(clip(t, d, 1), next);
|
|
2983
|
+
if (rem) fan(clip(t, d, -1), rem);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
const segments = [];
|
|
2987
|
+
let total = 0;
|
|
2988
|
+
const ti = tests.length === 1 && tests[0].bounds ? triIndexOf(geo) : void 0;
|
|
2989
|
+
if (ti) {
|
|
2990
|
+
const T = tests[0];
|
|
2991
|
+
const lo = T.bounds.lo;
|
|
2992
|
+
const hi = T.bounds.hi;
|
|
2775
2993
|
const rem = T.tag ? cut[T.tag] = cut[T.tag] || [] : null;
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
if (T.sel && !T.sel(n, ce)) {
|
|
2791
|
-
next.push(t);
|
|
2792
|
-
return;
|
|
2994
|
+
const boxes = ti.boxes;
|
|
2995
|
+
const blocks = ti.blocks;
|
|
2996
|
+
let runFrom = -1;
|
|
2997
|
+
const closeRun = function(end) {
|
|
2998
|
+
if (runFrom < 0) return;
|
|
2999
|
+
segments.push([runFrom, end]);
|
|
3000
|
+
total += end - runFrom;
|
|
3001
|
+
runFrom = -1;
|
|
3002
|
+
};
|
|
3003
|
+
for (let blk = 0, t0 = 0; t0 < ti.triangles; blk++, t0 += TRI_BLOCK) {
|
|
3004
|
+
const j = blk * 6;
|
|
3005
|
+
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]) {
|
|
3006
|
+
if (runFrom < 0) runFrom = t0;
|
|
3007
|
+
continue;
|
|
2793
3008
|
}
|
|
2794
|
-
const
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
3009
|
+
const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
|
|
3010
|
+
for (let t = t0; t < t1; t++) {
|
|
3011
|
+
const q = t * 6;
|
|
3012
|
+
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]) {
|
|
3013
|
+
if (runFrom < 0) runFrom = t;
|
|
3014
|
+
continue;
|
|
3015
|
+
}
|
|
3016
|
+
closeRun(t);
|
|
3017
|
+
const next = [];
|
|
3018
|
+
testTri(T, readTri(t * 3), next, rem);
|
|
3019
|
+
if (next.length) {
|
|
3020
|
+
segments.push(next);
|
|
3021
|
+
total += next.length;
|
|
3022
|
+
}
|
|
2802
3023
|
}
|
|
3024
|
+
}
|
|
3025
|
+
closeRun(ti.triangles);
|
|
3026
|
+
} else {
|
|
3027
|
+
let tris = [];
|
|
3028
|
+
for (let f = 0; f < nv; f += 3) tris.push(readTri(f));
|
|
3029
|
+
tests.forEach(function(T) {
|
|
3030
|
+
const next = [];
|
|
3031
|
+
const rem = T.tag ? cut[T.tag] = cut[T.tag] || [] : null;
|
|
3032
|
+
tris.forEach(function(t) {
|
|
3033
|
+
testTri(T, t, next, rem);
|
|
3034
|
+
});
|
|
3035
|
+
tris = next;
|
|
2803
3036
|
});
|
|
2804
|
-
tris
|
|
2805
|
-
|
|
2806
|
-
|
|
3037
|
+
segments.push(tris);
|
|
3038
|
+
total = tris.length;
|
|
3039
|
+
}
|
|
3040
|
+
function fill(segs, count, boxesOut2) {
|
|
2807
3041
|
const g = new THREE.BufferGeometry();
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
3042
|
+
const dst = names.map(function(_nm, a) {
|
|
3043
|
+
return new Float32Array(count * 3 * sizes[a]);
|
|
3044
|
+
});
|
|
3045
|
+
const w = names.map(function() {
|
|
3046
|
+
return 0;
|
|
3047
|
+
});
|
|
3048
|
+
let wb = 0;
|
|
3049
|
+
segs.forEach(function(seg) {
|
|
3050
|
+
if (typeof seg[0] === "number") {
|
|
3051
|
+
for (let a = 0; a < names.length; a++) {
|
|
3052
|
+
const size = sizes[a];
|
|
3053
|
+
if (!idx) {
|
|
3054
|
+
dst[a].set(arrs[a].subarray(seg[0] * 3 * size, seg[1] * 3 * size), w[a]);
|
|
3055
|
+
w[a] += (seg[1] - seg[0]) * 3 * size;
|
|
3056
|
+
continue;
|
|
3057
|
+
}
|
|
3058
|
+
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];
|
|
3059
|
+
}
|
|
3060
|
+
if (boxesOut2 && ti) {
|
|
3061
|
+
boxesOut2.set(ti.boxes.subarray(seg[0] * 6, seg[1] * 6), wb);
|
|
3062
|
+
wb += (seg[1] - seg[0]) * 6;
|
|
3063
|
+
}
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
seg.forEach(function(t) {
|
|
3067
|
+
if (boxesOut2) {
|
|
3068
|
+
for (let k = 0; k < 3; k++) {
|
|
3069
|
+
boxesOut2[wb + k] = Math.fround(Math.min(t[0][k], t[1][k], t[2][k]));
|
|
3070
|
+
boxesOut2[wb + 3 + k] = Math.fround(Math.max(t[0][k], t[1][k], t[2][k]));
|
|
3071
|
+
}
|
|
3072
|
+
wb += 6;
|
|
3073
|
+
}
|
|
3074
|
+
let off = 0;
|
|
3075
|
+
for (let a = 0; a < names.length; a++) {
|
|
3076
|
+
for (let k = 0; k < 3; k++) for (let q = 0; q < sizes[a]; q++) dst[a][w[a]++] = t[k][off + q];
|
|
3077
|
+
off += sizes[a];
|
|
3078
|
+
}
|
|
2814
3079
|
});
|
|
2815
|
-
|
|
2816
|
-
|
|
3080
|
+
});
|
|
3081
|
+
names.forEach(function(nm, a) {
|
|
3082
|
+
g.setAttribute(nm, new THREE.BufferAttribute(dst[a], sizes[a]));
|
|
2817
3083
|
});
|
|
2818
3084
|
g.userData.crease = true;
|
|
2819
3085
|
return g;
|
|
2820
3086
|
}
|
|
2821
|
-
const
|
|
3087
|
+
const boxesOut = ti ? new Float64Array(total * 6) : void 0;
|
|
3088
|
+
const out = { geo: fill(segments, total, boxesOut), cut: {}, tasks: {} };
|
|
3089
|
+
if (boxesOut) storeTriIndex(out.geo, boxesOut);
|
|
2822
3090
|
Object.keys(cut).forEach(function(k) {
|
|
2823
|
-
|
|
3091
|
+
const piece = fill([cut[k]], cut[k].length);
|
|
3092
|
+
const mode = tests.find(function(T) {
|
|
3093
|
+
return T.tag === k;
|
|
3094
|
+
}).pieces;
|
|
3095
|
+
if (mode === "none") out.cut[k] = piece;
|
|
3096
|
+
else if (mode === "later") {
|
|
3097
|
+
out.cut[k] = piece;
|
|
3098
|
+
out.tasks[k] = creaseTask(piece, 42);
|
|
3099
|
+
} else out.cut[k] = crease(piece, 42);
|
|
2824
3100
|
});
|
|
2825
3101
|
return out;
|
|
2826
3102
|
}
|
|
3103
|
+
function refreshBounds(geo) {
|
|
3104
|
+
const found = boundsFromIndex(geo);
|
|
3105
|
+
if (!found) {
|
|
3106
|
+
geo.computeBoundingSphere();
|
|
3107
|
+
geo.computeBoundingBox();
|
|
3108
|
+
return;
|
|
3109
|
+
}
|
|
3110
|
+
if (geo.boundingBox && geo.boundingSphere && boundsDone.get(geo) === found.version) return;
|
|
3111
|
+
const b = found.box;
|
|
3112
|
+
if (!geo.boundingBox) geo.boundingBox = new THREE.Box3();
|
|
3113
|
+
geo.boundingBox.min.set(b[0], b[1], b[2]);
|
|
3114
|
+
geo.boundingBox.max.set(b[3], b[4], b[5]);
|
|
3115
|
+
if (!geo.boundingSphere) geo.boundingSphere = new THREE.Sphere();
|
|
3116
|
+
const center = geo.boundingBox.getCenter(geo.boundingSphere.center);
|
|
3117
|
+
const P = geo.attributes.position.array;
|
|
3118
|
+
let maxRadiusSq = 0;
|
|
3119
|
+
for (let i = 0; i < P.length; i += 3) {
|
|
3120
|
+
const dx = center.x - P[i];
|
|
3121
|
+
const dy = center.y - P[i + 1];
|
|
3122
|
+
const dz = center.z - P[i + 2];
|
|
3123
|
+
maxRadiusSq = Math.max(maxRadiusSq, dx * dx + dy * dy + dz * dz);
|
|
3124
|
+
}
|
|
3125
|
+
geo.boundingSphere.radius = Math.sqrt(maxRadiusSq);
|
|
3126
|
+
boundsDone.set(geo, found.version);
|
|
3127
|
+
}
|
|
3128
|
+
const boundsDone = /* @__PURE__ */ new WeakMap();
|
|
2827
3129
|
function mergeGeometries(list2) {
|
|
2828
3130
|
const pos = [];
|
|
2829
3131
|
const nor = [];
|
|
@@ -2954,7 +3256,7 @@ var GameVehicles = (() => {
|
|
|
2954
3256
|
}
|
|
2955
3257
|
};
|
|
2956
3258
|
};
|
|
2957
|
-
Object.assign(I, { roundedBoxGeometry, taper, subdivide, crease, pathShape, tumble, loftGeometry, hullGeometry, cutGeometry, mergeGeometries, uvProject });
|
|
3259
|
+
Object.assign(I, { roundedBoxGeometry, taper, subdivide, crease, creaseTask, refreshBounds, pathShape, tumble, loftGeometry, hullGeometry, cutGeometry, mergeGeometries, uvProject });
|
|
2958
3260
|
}
|
|
2959
3261
|
|
|
2960
3262
|
// ../game-contracts/dist/index.js
|
|
@@ -8335,6 +8637,8 @@ var GameVehicles = (() => {
|
|
|
8335
8637
|
const pos = g && g.attributes && g.attributes.position;
|
|
8336
8638
|
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;
|
|
8337
8639
|
}
|
|
8640
|
+
let _keep = new Uint32Array(0);
|
|
8641
|
+
let _box = new Float32Array(0);
|
|
8338
8642
|
function proxyIn(o, Mw, R) {
|
|
8339
8643
|
_pm.copy(o.matrixWorld).invert().multiply(Mw);
|
|
8340
8644
|
const lo = [Infinity, Infinity, Infinity];
|
|
@@ -8347,39 +8651,48 @@ var GameVehicles = (() => {
|
|
|
8347
8651
|
}
|
|
8348
8652
|
}
|
|
8349
8653
|
const g = o.geometry;
|
|
8350
|
-
const
|
|
8654
|
+
const ti = triIndexOf(g);
|
|
8655
|
+
if (!ti) return null;
|
|
8351
8656
|
const ix = g.index ? g.index.array : null;
|
|
8352
|
-
const
|
|
8353
|
-
const
|
|
8657
|
+
const boxes = ti.boxes;
|
|
8658
|
+
const blocks = ti.blocks;
|
|
8659
|
+
if (_keep.length < ti.triangles * 3) {
|
|
8660
|
+
_keep = new Uint32Array(ti.triangles * 3);
|
|
8661
|
+
_box = new Float32Array(ti.triangles * 6);
|
|
8662
|
+
}
|
|
8663
|
+
const keep = _keep;
|
|
8664
|
+
const box2 = _box;
|
|
8354
8665
|
let nk = 0;
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
const
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
for (let
|
|
8361
|
-
const
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
keep[nk++] = ix ? ix[t + 1] : t + 1;
|
|
8369
|
-
keep[nk++] = ix ? ix[t + 2] : t + 2;
|
|
8666
|
+
let nt = 0;
|
|
8667
|
+
for (let blk = 0, t0 = 0; t0 < ti.triangles; blk++, t0 += TRI_BLOCK) {
|
|
8668
|
+
const j = blk * 6;
|
|
8669
|
+
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;
|
|
8670
|
+
const t1 = Math.min(ti.triangles, t0 + TRI_BLOCK);
|
|
8671
|
+
for (let t = t0; t < t1; t++) {
|
|
8672
|
+
const q = t * 6;
|
|
8673
|
+
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;
|
|
8674
|
+
keep[nk++] = ix ? ix[t * 3] : t * 3;
|
|
8675
|
+
keep[nk++] = ix ? ix[t * 3 + 1] : t * 3 + 1;
|
|
8676
|
+
keep[nk++] = ix ? ix[t * 3 + 2] : t * 3 + 2;
|
|
8677
|
+
for (let k = 0; k < 6; k++) box2[nt * 6 + k] = boxes[q + k];
|
|
8678
|
+
nt++;
|
|
8370
8679
|
}
|
|
8371
8680
|
}
|
|
8372
8681
|
if (!nk) return null;
|
|
8373
8682
|
const kept = keep.slice(0, nk);
|
|
8374
|
-
const
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
const b =
|
|
8378
|
-
const d = kept[t + 2] * 3;
|
|
8683
|
+
const keptBox = box2.slice(0, nt * 6);
|
|
8684
|
+
const keptBlocks = new Float32Array(Math.ceil(nt / TRI_BLOCK) * 6);
|
|
8685
|
+
for (let blk = 0; blk * TRI_BLOCK < nt; blk++) {
|
|
8686
|
+
const b = blk * 6;
|
|
8379
8687
|
for (let k = 0; k < 3; k++) {
|
|
8380
|
-
|
|
8381
|
-
|
|
8688
|
+
keptBlocks[b + k] = Infinity;
|
|
8689
|
+
keptBlocks[b + 3 + k] = -Infinity;
|
|
8382
8690
|
}
|
|
8691
|
+
for (let t = blk * TRI_BLOCK, t1 = Math.min(nt, t + TRI_BLOCK); t < t1; t++)
|
|
8692
|
+
for (let k = 0; k < 3; k++) {
|
|
8693
|
+
if (keptBox[t * 6 + k] < keptBlocks[b + k]) keptBlocks[b + k] = keptBox[t * 6 + k];
|
|
8694
|
+
if (keptBox[t * 6 + 3 + k] > keptBlocks[b + 3 + k]) keptBlocks[b + 3 + k] = keptBox[t * 6 + 3 + k];
|
|
8695
|
+
}
|
|
8383
8696
|
}
|
|
8384
8697
|
const pg = new THREE.BufferGeometry();
|
|
8385
8698
|
pg.setAttribute("position", g.attributes.position);
|
|
@@ -8390,7 +8703,8 @@ var GameVehicles = (() => {
|
|
|
8390
8703
|
proxy.layers.mask = o.layers.mask;
|
|
8391
8704
|
proxy.proxyOf = o;
|
|
8392
8705
|
proxy.kept = kept;
|
|
8393
|
-
proxy.keptBox =
|
|
8706
|
+
proxy.keptBox = keptBox;
|
|
8707
|
+
proxy.keptBlocks = keptBlocks;
|
|
8394
8708
|
return proxy;
|
|
8395
8709
|
}
|
|
8396
8710
|
function narrowTo(rc, proxy) {
|
|
@@ -8410,13 +8724,21 @@ var GameVehicles = (() => {
|
|
|
8410
8724
|
const hi2 = Math.max(z0, _pv.z) + 1e-4;
|
|
8411
8725
|
const K = proxy.kept;
|
|
8412
8726
|
const X = proxy.keptBox;
|
|
8727
|
+
const KB = proxy.keptBlocks;
|
|
8728
|
+
const nt = K.length / 3;
|
|
8413
8729
|
const dst = proxy.geometry.index.array;
|
|
8414
8730
|
let m = 0;
|
|
8415
|
-
for (let
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8731
|
+
for (let blk = 0, t0 = 0; t0 < nt; blk++, t0 += TRI_BLOCK) {
|
|
8732
|
+
const b = blk * 6;
|
|
8733
|
+
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;
|
|
8734
|
+
const t1 = Math.min(nt, t0 + TRI_BLOCK);
|
|
8735
|
+
for (let t = t0; t < t1; t++) {
|
|
8736
|
+
const j = t * 6;
|
|
8737
|
+
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;
|
|
8738
|
+
dst[m++] = K[t * 3];
|
|
8739
|
+
dst[m++] = K[t * 3 + 1];
|
|
8740
|
+
dst[m++] = K[t * 3 + 2];
|
|
8741
|
+
}
|
|
8420
8742
|
}
|
|
8421
8743
|
proxy.geometry.setDrawRange(0, m);
|
|
8422
8744
|
}
|
|
@@ -8834,6 +9156,8 @@ var GameVehicles = (() => {
|
|
|
8834
9156
|
irel.copy(rel).invert();
|
|
8835
9157
|
const pos = g.attributes.position;
|
|
8836
9158
|
let changed = false;
|
|
9159
|
+
const liveIndex = liveTriIndex(g);
|
|
9160
|
+
const movedVertices = [];
|
|
8837
9161
|
const near = boxInFrame(B, irel, v);
|
|
8838
9162
|
for (let i = 0; i < pos.count; i++) {
|
|
8839
9163
|
v.fromBufferAttribute(pos, i);
|
|
@@ -8845,6 +9169,7 @@ var GameVehicles = (() => {
|
|
|
8845
9169
|
if (opt.extra) opt.extra(v, f);
|
|
8846
9170
|
v.applyMatrix4(irel);
|
|
8847
9171
|
pos.setXYZ(i, v.x, v.y, v.z);
|
|
9172
|
+
movedVertices.push(i);
|
|
8848
9173
|
changed = true;
|
|
8849
9174
|
}
|
|
8850
9175
|
if (opt.extraAll) {
|
|
@@ -8853,12 +9178,14 @@ var GameVehicles = (() => {
|
|
|
8853
9178
|
if (opt.extraAll(v)) {
|
|
8854
9179
|
v.applyMatrix4(irel);
|
|
8855
9180
|
pos.setXYZ(j, v.x, v.y, v.z);
|
|
9181
|
+
movedVertices.push(j);
|
|
8856
9182
|
changed = true;
|
|
8857
9183
|
}
|
|
8858
9184
|
}
|
|
8859
9185
|
}
|
|
8860
9186
|
if (changed) {
|
|
8861
9187
|
pos.needsUpdate = true;
|
|
9188
|
+
if (liveIndex) touchTriIndex(g, liveIndex, movedVertices);
|
|
8862
9189
|
dirty.add(msh);
|
|
8863
9190
|
}
|
|
8864
9191
|
if (changed || boundsDue) {
|
|
@@ -8889,6 +9216,26 @@ var GameVehicles = (() => {
|
|
|
8889
9216
|
});
|
|
8890
9217
|
return { field, moved, ax, a, cu, cv, hu, hv, outer };
|
|
8891
9218
|
}
|
|
9219
|
+
function panelBoundsIn(rel, rect, B, a, ax) {
|
|
9220
|
+
const det = rel.determinant();
|
|
9221
|
+
if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return void 0;
|
|
9222
|
+
const back = rel.clone().invert();
|
|
9223
|
+
const lo = [Infinity, Infinity, Infinity];
|
|
9224
|
+
const hi = [-Infinity, -Infinity, -Infinity];
|
|
9225
|
+
const q = new V3();
|
|
9226
|
+
for (let i = 0; i < 8; i++) {
|
|
9227
|
+
q.setComponent(ax[0], i & 1 ? rect[1] : rect[0]);
|
|
9228
|
+
q.setComponent(ax[1], i & 2 ? rect[3] : rect[2]);
|
|
9229
|
+
q.setComponent(a, i & 4 ? I.boxHi(B, a) : I.boxLo(B, a));
|
|
9230
|
+
q.applyMatrix4(back);
|
|
9231
|
+
for (let k = 0; k < 3; k++) {
|
|
9232
|
+
lo[k] = Math.min(lo[k], q.getComponent(k));
|
|
9233
|
+
hi[k] = Math.max(hi[k], q.getComponent(k));
|
|
9234
|
+
}
|
|
9235
|
+
}
|
|
9236
|
+
const pad = 1e-3;
|
|
9237
|
+
return { lo: lo.map((x) => x - pad), hi: hi.map((x) => x + pad) };
|
|
9238
|
+
}
|
|
8892
9239
|
function cutPanel(c, z, rect, keep, dirty, o) {
|
|
8893
9240
|
o = o || {};
|
|
8894
9241
|
const B = z.box;
|
|
@@ -8921,6 +9268,7 @@ var GameVehicles = (() => {
|
|
|
8921
9268
|
}
|
|
8922
9269
|
const test = {
|
|
8923
9270
|
tag: "part",
|
|
9271
|
+
pieces: keep ? o.pieceTasks ? "later" : "crease" : "none",
|
|
8924
9272
|
sel: o.anyN || z.cutAll ? null : function(n) {
|
|
8925
9273
|
nv.copy(n).applyMatrix3(nm).normalize();
|
|
8926
9274
|
return nv.dot(outN) > 0.3;
|
|
@@ -8939,13 +9287,12 @@ var GameVehicles = (() => {
|
|
|
8939
9287
|
return q;
|
|
8940
9288
|
}
|
|
8941
9289
|
};
|
|
8942
|
-
const r = cutGeometry(g, [test]);
|
|
9290
|
+
const r = cutGeometry(g, [{ ...test, bounds: panelBoundsIn(rel, rect, B, a, ax) }]);
|
|
8943
9291
|
const cg = r.cut.part;
|
|
8944
9292
|
if (!cg || !cg.attributes.position.count) return;
|
|
8945
9293
|
g.dispose();
|
|
8946
9294
|
msh.geometry = r.geo;
|
|
8947
|
-
r.geo
|
|
8948
|
-
r.geo.computeBoundingBox();
|
|
9295
|
+
I.refreshBounds(r.geo);
|
|
8949
9296
|
dirty.add(msh);
|
|
8950
9297
|
if (!keep) {
|
|
8951
9298
|
cg.dispose();
|
|
@@ -8958,6 +9305,7 @@ var GameVehicles = (() => {
|
|
|
8958
9305
|
rel.decompose(pm.position, pm.quaternion, pm.scale);
|
|
8959
9306
|
c.vehicle.add(pm);
|
|
8960
9307
|
pm.updateMatrixWorld(true);
|
|
9308
|
+
if (o.pieceTasks) o.pieceTasks.set(pm, r.tasks.part);
|
|
8961
9309
|
pieces.push({ mesh: pm, cut: true });
|
|
8962
9310
|
});
|
|
8963
9311
|
return pieces;
|
|
@@ -12594,7 +12942,15 @@ var GameVehicles = (() => {
|
|
|
12594
12942
|
__publicField(this, "gone", /* @__PURE__ */ new Set());
|
|
12595
12943
|
/** Shows or hides the plate and the recess of a door or lid by its state (see `showWhenOpen`). */
|
|
12596
12944
|
__publicField(this, "syncPlates", /* @__PURE__ */ new Map());
|
|
12945
|
+
/** Doors and lids whose own skin was cut from the body and hung on the hinge (true), or that had none to take and keep the plate (false). */
|
|
12946
|
+
__publicField(this, "skins", /* @__PURE__ */ new Map());
|
|
12597
12947
|
__publicField(this, "lightsOn", true);
|
|
12948
|
+
/** Heavy body meshes whose triangle index is still to build (null once done). */
|
|
12949
|
+
__publicField(this, "warming");
|
|
12950
|
+
/** A panel was torn off since the last `pump`: that frame already paid for the cut, the smoothing starts on the next one. */
|
|
12951
|
+
__publicField(this, "tornThisFrame", false);
|
|
12952
|
+
/** Normal smoothing still running, by mesh: a mesh cut again gets a new task and the old one is dropped. */
|
|
12953
|
+
__publicField(this, "smoothing", /* @__PURE__ */ new Map());
|
|
12598
12954
|
__publicField(this, "hood");
|
|
12599
12955
|
this.kit = kit;
|
|
12600
12956
|
this.c = c;
|
|
@@ -12604,6 +12960,8 @@ var GameVehicles = (() => {
|
|
|
12604
12960
|
for (const p of model.parts) this.byId.set(p.id, p);
|
|
12605
12961
|
c.root.updateMatrixWorld(true);
|
|
12606
12962
|
this.hood = this.nameHood();
|
|
12963
|
+
this.warming = c.deform.filter((msh) => msh.geometry && msh.geometry.attributes.position && msh.geometry.attributes.position.count >= 1500);
|
|
12964
|
+
if (!this.warming.length) this.warming = null;
|
|
12607
12965
|
for (const p of model.parts) {
|
|
12608
12966
|
if (p.role === "door" || p.role === "lid") this.makePlate(p);
|
|
12609
12967
|
else if (p.role === "mirror" && !this.mirrorObjects(p).length) this.makeMirror(p);
|
|
@@ -12739,11 +13097,21 @@ var GameVehicles = (() => {
|
|
|
12739
13097
|
* 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`).
|
|
12740
13098
|
*/
|
|
12741
13099
|
showWhenOpen(id, piv, panel, recess) {
|
|
13100
|
+
let busy = false;
|
|
12742
13101
|
const sync = () => {
|
|
13102
|
+
if (busy) return;
|
|
12743
13103
|
const r = piv.rotation;
|
|
12744
13104
|
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;
|
|
12745
|
-
|
|
12746
|
-
|
|
13105
|
+
if (open && !this.gone.has(id) && piv.parent === this.c.vehicle && !this.skins.has(id)) {
|
|
13106
|
+
busy = true;
|
|
13107
|
+
try {
|
|
13108
|
+
this.skins.set(id, this.takeSkin(id, piv));
|
|
13109
|
+
} finally {
|
|
13110
|
+
busy = false;
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
panel.visible = open && !this.skins.get(id);
|
|
13114
|
+
recess.visible = open && !this.skins.get(id);
|
|
12747
13115
|
};
|
|
12748
13116
|
const euler = piv.rotation;
|
|
12749
13117
|
const quaternion = piv.quaternion;
|
|
@@ -12760,6 +13128,58 @@ var GameVehicles = (() => {
|
|
|
12760
13128
|
this.syncPlates.set(id, sync);
|
|
12761
13129
|
sync();
|
|
12762
13130
|
}
|
|
13131
|
+
/**
|
|
13132
|
+
* 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
|
|
13133
|
+
* window over it, on the hinge. Done with the hinge closed, so every piece keeps its place; answers whether there was skin to take.
|
|
13134
|
+
*/
|
|
13135
|
+
takeSkin(id, piv) {
|
|
13136
|
+
const p = this.byId.get(id);
|
|
13137
|
+
const z = p && this.zone(p);
|
|
13138
|
+
if (!p || !z) return false;
|
|
13139
|
+
const I = this.I;
|
|
13140
|
+
const B = z.box;
|
|
13141
|
+
const q = piv.quaternion.clone();
|
|
13142
|
+
piv.quaternion.identity();
|
|
13143
|
+
this.c.root.updateMatrixWorld(true);
|
|
13144
|
+
const inv = I.worldInverseOf(this.c);
|
|
13145
|
+
let objs = [];
|
|
13146
|
+
try {
|
|
13147
|
+
if (p.role === "door") {
|
|
13148
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
13149
|
+
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];
|
|
13150
|
+
const pcs = I.cutPanel(this.c, z, rect, true, dirty).map((x) => x.mesh).filter((m) => !!m);
|
|
13151
|
+
this.mend(dirty);
|
|
13152
|
+
if (pcs.length) objs = [...pcs, ...I.followersIn(this.c, z, inv), ...I.windowsOver(this.c, z, inv)];
|
|
13153
|
+
} else {
|
|
13154
|
+
const pcs = this.cutZone(z);
|
|
13155
|
+
if (pcs.length) objs = [...pcs, ...I.followersIn(this.c, z, inv)];
|
|
13156
|
+
}
|
|
13157
|
+
} catch {
|
|
13158
|
+
objs = [];
|
|
13159
|
+
}
|
|
13160
|
+
const deform = this.c.deform ?? [];
|
|
13161
|
+
for (const o of objs) {
|
|
13162
|
+
if (!o.parent || o === piv) continue;
|
|
13163
|
+
piv.attach(o);
|
|
13164
|
+
o.traverse((x) => {
|
|
13165
|
+
x.userData.noFollow = true;
|
|
13166
|
+
});
|
|
13167
|
+
const di = deform.indexOf(o);
|
|
13168
|
+
if (di >= 0) deform.splice(di, 1);
|
|
13169
|
+
}
|
|
13170
|
+
piv.quaternion.copy(q);
|
|
13171
|
+
this.c.root.updateMatrixWorld(true);
|
|
13172
|
+
return objs.length > 0;
|
|
13173
|
+
}
|
|
13174
|
+
mend(dirty) {
|
|
13175
|
+
dirty.forEach((msh) => {
|
|
13176
|
+
const g = msh.geometry;
|
|
13177
|
+
if (g.userData.crease || !g.index) this.I.crease(g, 42);
|
|
13178
|
+
else g.computeVertexNormals();
|
|
13179
|
+
g.computeBoundingSphere();
|
|
13180
|
+
g.computeBoundingBox();
|
|
13181
|
+
});
|
|
13182
|
+
}
|
|
12763
13183
|
makeMirror(p) {
|
|
12764
13184
|
const [cx, cy, cz] = p.box.center;
|
|
12765
13185
|
const s = cz < 0 ? -1 : 1;
|
|
@@ -12897,6 +13317,31 @@ var GameVehicles = (() => {
|
|
|
12897
13317
|
this.I.flattenTire(w, Math.min(0.5, 0.12 + 0.38 * melt));
|
|
12898
13318
|
}
|
|
12899
13319
|
}
|
|
13320
|
+
/** Smooths the normals of a cut mesh a slice per frame (see `pump`); until then it draws with flat face normals. */
|
|
13321
|
+
smoothLater(msh) {
|
|
13322
|
+
this.smoothing.set(msh, this.I.creaseTask(msh.geometry, 42));
|
|
13323
|
+
this.tornThisFrame = true;
|
|
13324
|
+
}
|
|
13325
|
+
/** Spends at most `budgetMs` finishing the pending normal smoothing. Call once per frame. */
|
|
13326
|
+
pump(budgetMs = 2.5) {
|
|
13327
|
+
if (this.tornThisFrame) {
|
|
13328
|
+
this.tornThisFrame = false;
|
|
13329
|
+
return;
|
|
13330
|
+
}
|
|
13331
|
+
if (!this.smoothing.size && !this.warming) return;
|
|
13332
|
+
const deadline = performance.now() + budgetMs;
|
|
13333
|
+
for (const [msh, task] of this.smoothing) {
|
|
13334
|
+
if (msh.geometry !== task.geo || task.step(deadline)) this.smoothing.delete(msh);
|
|
13335
|
+
if (performance.now() >= deadline) return;
|
|
13336
|
+
}
|
|
13337
|
+
this.warmIndexes(deadline);
|
|
13338
|
+
}
|
|
13339
|
+
/** Measures the triangles of the heavy body meshes once, a slice per frame, so the first panel torn off finds them ready (see `triIndexOf`). */
|
|
13340
|
+
warmIndexes(deadline) {
|
|
13341
|
+
if (!this.warming) return;
|
|
13342
|
+
this.warming = this.warming.filter((msh) => !warmTriIndex(msh.geometry, deadline));
|
|
13343
|
+
if (!this.warming.length) this.warming = null;
|
|
13344
|
+
}
|
|
12900
13345
|
/** Moves the panel of a lost zone out of the body (the kit's torn-off look). */
|
|
12901
13346
|
tearOff(p) {
|
|
12902
13347
|
const z = this.zone(p);
|
|
@@ -12909,10 +13354,9 @@ var GameVehicles = (() => {
|
|
|
12909
13354
|
}
|
|
12910
13355
|
dirty.forEach((msh) => {
|
|
12911
13356
|
const g = msh.geometry;
|
|
12912
|
-
if (g.userData.crease || !g.index) this.
|
|
13357
|
+
if (g.userData.crease || !g.index) this.smoothLater(msh);
|
|
12913
13358
|
else g.computeVertexNormals();
|
|
12914
|
-
|
|
12915
|
-
g.computeBoundingBox();
|
|
13359
|
+
this.I.refreshBounds(g);
|
|
12916
13360
|
});
|
|
12917
13361
|
this.gone.add(p.id);
|
|
12918
13362
|
}
|
|
@@ -13055,17 +13499,19 @@ var GameVehicles = (() => {
|
|
|
13055
13499
|
const mg = Math.min(0.05, (u1 - u0) * 0.08, (v1 - v0) * 0.08);
|
|
13056
13500
|
const dirty = /* @__PURE__ */ new Set();
|
|
13057
13501
|
let pcs = [];
|
|
13502
|
+
const pieceTasks = /* @__PURE__ */ new Map();
|
|
13058
13503
|
try {
|
|
13059
|
-
pcs = I.cutPanel(this.c, z, [u0 + mg, u1 - mg, v0 + mg, v1 - mg], true, dirty);
|
|
13504
|
+
pcs = I.cutPanel(this.c, z, [u0 + mg, u1 - mg, v0 + mg, v1 - mg], true, dirty, { pieceTasks });
|
|
13060
13505
|
} catch {
|
|
13061
13506
|
pcs = [];
|
|
13062
13507
|
}
|
|
13508
|
+
pieceTasks.forEach((task, mesh2) => this.smoothing.set(mesh2, task));
|
|
13509
|
+
this.tornThisFrame = true;
|
|
13063
13510
|
dirty.forEach((msh) => {
|
|
13064
13511
|
const g = msh.geometry;
|
|
13065
|
-
if (g.userData.crease || !g.index)
|
|
13512
|
+
if (g.userData.crease || !g.index) this.smoothLater(msh);
|
|
13066
13513
|
else g.computeVertexNormals();
|
|
13067
|
-
|
|
13068
|
-
g.computeBoundingBox();
|
|
13514
|
+
I.refreshBounds(g);
|
|
13069
13515
|
});
|
|
13070
13516
|
return pcs.map((q) => q.mesh).filter((m) => !!m);
|
|
13071
13517
|
}
|
|
@@ -13844,7 +14290,7 @@ var GameVehicles = (() => {
|
|
|
13844
14290
|
specCache = { name: options.name ?? c.spec.name ?? c.key, parts, joints, tags: ["vehicle", kindOf(c)] };
|
|
13845
14291
|
return specCache;
|
|
13846
14292
|
};
|
|
13847
|
-
const
|
|
14293
|
+
const buildState = () => {
|
|
13848
14294
|
const parts = model.parts.map((d) => {
|
|
13849
14295
|
const p = ps.get(d.id);
|
|
13850
14296
|
const marked = p.dents.length > 0 || p.holes.length > 0 || p.cracks.length > 0;
|
|
@@ -13881,7 +14327,15 @@ var GameVehicles = (() => {
|
|
|
13881
14327
|
}));
|
|
13882
14328
|
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") };
|
|
13883
14329
|
};
|
|
14330
|
+
let stateCache;
|
|
14331
|
+
const state = () => stateCache ?? (stateCache = buildState());
|
|
14332
|
+
const isSimulating = () => {
|
|
14333
|
+
if (leaks.size > 0) return true;
|
|
14334
|
+
for (const p of ps.values()) if (!p.lost && (p.burning || p.temp > AMBIENT)) return true;
|
|
14335
|
+
return false;
|
|
14336
|
+
};
|
|
13884
14337
|
const hit = (h) => {
|
|
14338
|
+
stateCache = void 0;
|
|
13885
14339
|
const out = [];
|
|
13886
14340
|
const hh = h.space === "local" ? { ...h, space: "world", point: toWorld(h.point) } : h;
|
|
13887
14341
|
if (hh.space === "local" || !hh.point) return out;
|
|
@@ -13908,6 +14362,8 @@ var GameVehicles = (() => {
|
|
|
13908
14362
|
clock += dt;
|
|
13909
14363
|
const out = queue;
|
|
13910
14364
|
queue = [];
|
|
14365
|
+
const wasSimulating = isSimulating();
|
|
14366
|
+
const handledBefore = (blastHandled ? 1 : 0) + (rollHandled ? 2 : 0);
|
|
13911
14367
|
const hood = c.hood;
|
|
13912
14368
|
if (hood) {
|
|
13913
14369
|
const sign2 = hood.sign || 1;
|
|
@@ -13928,12 +14384,15 @@ var GameVehicles = (() => {
|
|
|
13928
14384
|
afterBlast(out);
|
|
13929
14385
|
afterRoll(out);
|
|
13930
14386
|
applyEffects();
|
|
14387
|
+
vis?.pump();
|
|
14388
|
+
if (wasSimulating || out.length > 0 || handledBefore !== (blastHandled ? 1 : 0) + (rollHandled ? 2 : 0)) stateCache = void 0;
|
|
13931
14389
|
return out;
|
|
13932
14390
|
};
|
|
13933
14391
|
const disassemble = (jointId, tool, dt) => {
|
|
13934
14392
|
const j = js.find((x) => x.def.id === jointId);
|
|
13935
14393
|
if (!j || !j.def.tools.includes(tool)) return -1;
|
|
13936
14394
|
if (j.open) return 1;
|
|
14395
|
+
stateCache = void 0;
|
|
13937
14396
|
j.progress = Math.min(1, j.progress + dt / j.def.seconds);
|
|
13938
14397
|
const step = Math.floor(j.progress * 4) / 4;
|
|
13939
14398
|
if (step > j.reported && j.progress < 1) {
|
|
@@ -13949,6 +14408,7 @@ var GameVehicles = (() => {
|
|
|
13949
14408
|
return j.progress;
|
|
13950
14409
|
};
|
|
13951
14410
|
const extinguish = (partId) => {
|
|
14411
|
+
stateCache = void 0;
|
|
13952
14412
|
for (const p of ps.values()) {
|
|
13953
14413
|
if (partId && p.def.id !== partId) continue;
|
|
13954
14414
|
if (p.burning) {
|
|
@@ -13962,6 +14422,7 @@ var GameVehicles = (() => {
|
|
|
13962
14422
|
}
|
|
13963
14423
|
};
|
|
13964
14424
|
const reset = () => {
|
|
14425
|
+
stateCache = void 0;
|
|
13965
14426
|
const old = c;
|
|
13966
14427
|
const parent = old.root.parent;
|
|
13967
14428
|
const next = kit.build(old.key, old.state, old.scenario != null ? { scenario: old.scenario } : void 0);
|
|
@@ -13979,6 +14440,7 @@ var GameVehicles = (() => {
|
|
|
13979
14440
|
setup();
|
|
13980
14441
|
};
|
|
13981
14442
|
const rollover = (side2 = 1) => {
|
|
14443
|
+
stateCache = void 0;
|
|
13982
14444
|
if (kit.roll(c, side2)) rolled = true;
|
|
13983
14445
|
void rolled;
|
|
13984
14446
|
};
|