@adatechnology/game-floorplan-structure 1.3.1 → 1.3.3

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.
@@ -5047,6 +5047,7 @@ var GameFloorplanStructure = (() => {
5047
5047
  var FLAMMABLE_FLUIDS = ["gas", "fuel"];
5048
5048
  var VENT_DIAMETER = 8e-3;
5049
5049
  var FLAME_LIGHTS_LEAK_C = 470;
5050
+ var RESTING_HOLD_COS = Math.cos(Math.PI / 6);
5050
5051
  var BREACH_RADIUS = 0.55;
5051
5052
  var BREACH_BLAST_FACTOR = 6;
5052
5053
  var BREACH_AREA = 0.25;
@@ -5062,6 +5063,8 @@ var GameFloorplanStructure = (() => {
5062
5063
  var BREACH_GRID_CAP = 4096;
5063
5064
  var CHIP_ENERGY = 200;
5064
5065
  var CHIP_SPLASH = 0.5;
5066
+ var CRATER_SPENT = 0.6;
5067
+ var EDGE_REACH = 1.5;
5065
5068
  var BAR_BOW = 0.08;
5066
5069
  var BULLET_JOINT_SPAN = 0.3;
5067
5070
  var CUT_SLICE = 1;
@@ -5082,12 +5085,22 @@ var GameFloorplanStructure = (() => {
5082
5085
  const cells = p.st.chipped;
5083
5086
  if (!cells?.length) return 0;
5084
5087
  const [u, v] = planeAxes(p.thin);
5085
- const along = p.dims[u] >= p.dims[v] ? u : v;
5088
+ const role = p.spec.structure?.role;
5089
+ const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
5090
+ const upright = Math.abs(up[1]) > 0.7 ? v : Math.abs(rotateVec(p.q, [0, 0, 0].map((_, k) => k === u ? 1 : 0))[1]) > 0.7 ? u : -1;
5091
+ const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
5086
5092
  const across = along === u ? v : u;
5087
5093
  let worst = 0;
5088
5094
  for (const c of cells) {
5089
- let gone = 0;
5090
- for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) gone += d.size[across];
5095
+ const spans = [];
5096
+ for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) spans.push([d.center[across] - d.size[across] / 2, d.center[across] + d.size[across] / 2]);
5097
+ spans.sort((a, b) => a[0] - b[0]);
5098
+ let gone = 0, end = -Infinity;
5099
+ for (const [a, b] of spans) {
5100
+ if (b <= end) continue;
5101
+ gone += b - Math.max(a, end);
5102
+ end = b;
5103
+ }
5091
5104
  worst = Math.max(worst, gone / Math.max(p.dims[across], 1e-6));
5092
5105
  }
5093
5106
  return Math.min(1, worst);
@@ -5383,7 +5396,18 @@ var GameFloorplanStructure = (() => {
5383
5396
  if (k < 0 || j.spec.kind !== "tie") return k;
5384
5397
  return partXf(o, o.parts[k]).c[1] > partXf(o, o.parts[r]).c[1] + 1e-6 ? k : -1;
5385
5398
  };
5399
+ let poseVersion = 0;
5400
+ const contactMemo = /* @__PURE__ */ new WeakMap();
5386
5401
  const contactBox = (p, support) => {
5402
+ let byTouching = contactMemo.get(p);
5403
+ if (!byTouching) contactMemo.set(p, byTouching = /* @__PURE__ */ new Map());
5404
+ const known = byTouching.get(support);
5405
+ if (known && known.version === poseVersion) return known.box;
5406
+ const box2 = measureContact(p, support);
5407
+ byTouching.set(support, { version: poseVersion, box: box2 });
5408
+ return box2;
5409
+ };
5410
+ const measureContact = (p, support) => {
5387
5411
  const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
5388
5412
  const lo = [0, 0, 0], hi = [0, 0, 0];
5389
5413
  for (let k = 0; k < 3; k++) {
@@ -6178,7 +6202,7 @@ var GameFloorplanStructure = (() => {
6178
6202
  p.st.holes.push(hole);
6179
6203
  if (p.st.holes.length > maxHoles) p.st.holes.shift();
6180
6204
  markDamaged(p);
6181
- emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {} });
6205
+ emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {}, ...p.spec.powder ? { powder: { ...p.spec.powder } } : {} });
6182
6206
  setStage(o, p, 1, {}, src);
6183
6207
  return hole;
6184
6208
  };
@@ -6195,6 +6219,22 @@ var GameFloorplanStructure = (() => {
6195
6219
  const detachEvents = (o, opened, by, src) => {
6196
6220
  for (const j of opened) emit({ ...base(o, src), type: "detach", joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) });
6197
6221
  };
6222
+ const slideOffResting = (o, rotation) => {
6223
+ const upY = 1 - 2 * (rotation[0] * rotation[0] + rotation[2] * rotation[2]);
6224
+ if (upY >= RESTING_HOLD_COS) return;
6225
+ const opened = o.joints.filter((j) => j.spec.kind === "resting" && !j.st.open);
6226
+ if (opened.length === 0) return;
6227
+ run(() => {
6228
+ for (const j of opened) {
6229
+ j.st.open = true;
6230
+ j.st.openedBy = "break";
6231
+ }
6232
+ solveStructure(o);
6233
+ recomputeGroups(o);
6234
+ detachEvents(o, opened, "break");
6235
+ collapseCheck(o);
6236
+ });
6237
+ };
6198
6238
  const checkDestroyed = (o, src) => {
6199
6239
  if (!o.st.destroyed && o.parts.length > 0 && o.parts.every(isLost)) {
6200
6240
  o.st.destroyed = true;
@@ -6295,7 +6335,7 @@ var GameFloorplanStructure = (() => {
6295
6335
  const localHolesOf = (p) => p.st.holes.map((h) => ({ point: toLocal(p.pos, p.q, h.point), normal: rotateVec(quat.conjugate(p.q), h.normal), diameter: h.diameter }));
6296
6336
  const unitsOf2 = (p) => p.spec.units ?? { size: [p.mat.fragmentSize?.[1] ?? 0.2, p.mat.fragmentSize?.[1] ?? 0.2, p.thickness], bond: "stack" };
6297
6337
  const FRAGMENT_SHAPE = { shatter: "shard", splinter: "splinter", tear: "scrap" };
6298
- const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag) => {
6338
+ const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag, inner2 = false) => {
6299
6339
  const { c, q } = partXf(o, p);
6300
6340
  const holes = p.st.holes.length > 0 ? localHolesOf(p) : [];
6301
6341
  const [u, v] = planeAxes(p.thin);
@@ -6319,7 +6359,8 @@ var GameFloorplanStructure = (() => {
6319
6359
  velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k],
6320
6360
  angularVelocity: [(rnd() - 0.5) * 8, (rnd() - 0.5) * 8, (rnd() - 0.5) * 8],
6321
6361
  mass: mass * faceArea(cell) / total,
6322
- ...marks.length > 0 ? { marks } : {}
6362
+ ...marks.length > 0 ? { marks } : {},
6363
+ ...inner2 ? { inner: inner2 } : {}
6323
6364
  };
6324
6365
  });
6325
6366
  };
@@ -6360,7 +6401,7 @@ var GameFloorplanStructure = (() => {
6360
6401
  return cells.some((c) => Math.abs(lp[u] - c.center[u]) <= c.size[u] / 2 && Math.abs(lp[v] - c.center[v]) <= c.size[v] / 2);
6361
6402
  };
6362
6403
  const chipUnits = (o, p, kind, wp, hitEnergy, dir, radius, src) => {
6363
- var _a, _b;
6404
+ var _a, _b, _c;
6364
6405
  if (!p.spec.units || !p.staged || chipEnergy <= 0 || p.st.stripped || isLost(p) || (p.st.stage ?? 0) >= 2) return;
6365
6406
  const rule = p.mat.hits?.[kind];
6366
6407
  const perKg = rule?.unitJoules ?? chipEnergy;
@@ -6370,7 +6411,9 @@ var GameFloorplanStructure = (() => {
6370
6411
  const lp = toLocal(p.pos, p.q, objLocal(o, wp));
6371
6412
  const grid = gridOf(p);
6372
6413
  const worn = (_a = p.rt).chips ?? (_a.chips = {});
6414
+ const cut = (_b = p.rt).craters ?? (_b.craters = {});
6373
6415
  const out = [];
6416
+ const shot = kind === "ballistic";
6374
6417
  for (let i = 0; i < grid.length; i++) {
6375
6418
  const cell = grid[i];
6376
6419
  if (worn[i] === -1) continue;
@@ -6383,18 +6426,42 @@ var GameFloorplanStructure = (() => {
6383
6426
  worn[i] = total;
6384
6427
  continue;
6385
6428
  }
6386
- worn[i] = -1;
6387
- out.push(cell);
6429
+ if (!shot) {
6430
+ worn[i] = -1;
6431
+ out.push(cell);
6432
+ continue;
6433
+ }
6434
+ const size = [cell.size[0], cell.size[1], cell.size[2]];
6435
+ const center = [cell.center[0], cell.center[1], cell.center[2]];
6436
+ for (const a of [u, v]) {
6437
+ const w = Math.min(cell.size[a], craterAcross(hitEnergy) * (0.85 + 0.3 * rnd()));
6438
+ const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
6439
+ size[a] = w;
6440
+ center[a] = clamp22(lp[a], lo, hi);
6441
+ const [from, to] = tornToEdge({ p, cell, a, b: a === u ? v : u, at: lp[a], crater: [center[a] - w / 2, center[a] + w / 2], reach: w * EDGE_REACH, gone: (k) => worn[k] === -1 });
6442
+ size[a] = to - from;
6443
+ center[a] = (from + to) / 2;
6444
+ }
6445
+ const taken2 = (cut[i] ?? 0) + size[u] * size[v];
6446
+ if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
6447
+ worn[i] = -1;
6448
+ out.push({ ...cell, crater: true });
6449
+ continue;
6450
+ }
6451
+ worn[i] = 0;
6452
+ cut[i] = taken2;
6453
+ out.push({ center, size, crater: true });
6388
6454
  }
6389
6455
  if (out.length === 0) return;
6390
6456
  const { c, q } = partXf(o, p);
6391
- const chipped = (_b = p.st).chipped ?? (_b.chipped = []);
6457
+ const chipped = (_c = p.st).chipped ?? (_c.chipped = []);
6392
6458
  const holes = localHolesOf(p);
6393
6459
  for (const cell of out) {
6394
6460
  const mass = Math.min(p.st.mass, p.mat.density * cell.size[0] * cell.size[1] * cell.size[2]);
6395
6461
  const center = toWorld(c, q, cell.center);
6396
6462
  const speed = clamp22(Math.sqrt(2 * energy * 0.05 / Math.max(mass, 0.05)), 0.5, 6);
6397
- const fragments = cellFragments(o, p, [cell], wp, dir, speed, mass, `c${chipped.length}_`);
6463
+ const tag = `c${chipped.length}_`;
6464
+ const fragments = cell.crater ? craterFragments(o, p, cell, dir, speed, mass, tag) : cellFragments(o, p, [cell], wp, dir, speed, mass, tag, true);
6398
6465
  p.st.holes = p.st.holes.filter((_, k) => marksInBox(cell.center, cell.size, void 0, [holes[k]]).length === 0);
6399
6466
  chipped.push({ center: [cell.center[0], cell.center[1], cell.center[2]], size: [cell.size[0], cell.size[1], cell.size[2]] });
6400
6467
  p.st.mass = Math.max(0, p.st.mass - mass);
@@ -6411,6 +6478,57 @@ var GameFloorplanStructure = (() => {
6411
6478
  collapseCheck(o, src);
6412
6479
  }
6413
6480
  };
6481
+ const tornToEdge = (o) => {
6482
+ const { p, cell, a, b, at: at2, crater: crater2, reach, gone } = o;
6483
+ const half = p.dims[a] / 2;
6484
+ const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
6485
+ const free = (side, sign) => {
6486
+ if (sign > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign > 0 || a !== planeAxes(p.thin)[1];
6487
+ const probe = side + sign * 1e-3;
6488
+ return gridOf(p).some((c, k) => gone(k) && Math.abs(probe - c.center[a]) <= c.size[a] / 2 && Math.abs(cell.center[b] - c.center[b]) <= c.size[b] / 2);
6489
+ };
6490
+ if (at2 - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
6491
+ if (hi - at2 <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
6492
+ return crater2;
6493
+ };
6494
+ const craterAcross = (energy) => clamp22(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
6495
+ const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
6496
+ const { c, q } = partXf(o, p);
6497
+ const [u, v] = planeAxes(p.thin);
6498
+ const d = dir ?? rotateVec(q, [p.thin === 0 ? 1 : 0, p.thin === 1 ? 1 : 0, p.thin === 2 ? 1 : 0]);
6499
+ const exitSign = Math.sign(rotateVec(quat.conjugate(q), d)[p.thin]) || 1;
6500
+ const bit = Math.max(0.01, Math.min(cell.size[u], cell.size[v]) / 3);
6501
+ const n = clamp22(Math.round(cell.size[u] * cell.size[v] / (bit * bit * 3)), 4, 10) + Math.floor(rnd() * 3);
6502
+ const out = [];
6503
+ for (let i = 0; i < n; i++) {
6504
+ const back = i % 3 === 2;
6505
+ const lc = [cell.center[0], cell.center[1], cell.center[2]];
6506
+ lc[u] += (rnd() - 0.5) * cell.size[u] * 0.7;
6507
+ lc[v] += (rnd() - 0.5) * cell.size[v] * 0.7;
6508
+ lc[p.thin] += (back ? -exitSign : exitSign) * (p.thickness / 2 + 0.01);
6509
+ const size = [0, 0, 0];
6510
+ size[u] = bit * (0.6 + 0.8 * rnd());
6511
+ size[v] = bit * (0.5 + 0.7 * rnd());
6512
+ size[p.thin] = bit * (0.4 + 0.6 * rnd());
6513
+ const spread3 = [(rnd() - 0.5) * 0.9, (rnd() - 0.3) * 0.9, (rnd() - 0.5) * 0.9];
6514
+ const k = speed * (back ? 0.4 + 0.4 * rnd() : 0.7 + 0.8 * rnd());
6515
+ const vdir = vec.normalize(vec.add(back ? vec.scale(d, -1) : d, spread3));
6516
+ out.push({
6517
+ id: `${p.spec.id}#${tag}${i}`,
6518
+ part: p.spec.id,
6519
+ material: p.spec.material,
6520
+ shape: "chunk",
6521
+ center: toWorld(c, q, lc),
6522
+ size,
6523
+ rotation: q,
6524
+ velocity: [vdir[0] * k, vdir[1] * k + 0.5 * rnd(), vdir[2] * k],
6525
+ angularVelocity: [(rnd() - 0.5) * 20, (rnd() - 0.5) * 20, (rnd() - 0.5) * 20],
6526
+ mass: mass / n,
6527
+ inner: true
6528
+ });
6529
+ }
6530
+ return out;
6531
+ };
6414
6532
  const exposeRebar = (o, p, src) => {
6415
6533
  const r = p.spec.reinforcement;
6416
6534
  if (!r) return;
@@ -6698,7 +6816,7 @@ var GameFloorplanStructure = (() => {
6698
6816
  });
6699
6817
  }
6700
6818
  const patch = [scale * 4, scale * 4, scale * 4];
6701
- emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry2, size: patch, rotation: q, fragments });
6819
+ emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry2, size: patch, rotation: q, fragments, torn: true });
6702
6820
  };
6703
6821
  const ballistic = (o, p, entry2, n, d, E, caliber, pathLen, src, round3 = {}) => {
6704
6822
  const mat = p.mat;
@@ -6757,12 +6875,13 @@ var GameFloorplanStructure = (() => {
6757
6875
  } else if (mat.ductility >= 0.5) {
6758
6876
  addDent(o, p, entry2, n, Math.max(caliber * 3 / 1e3, 0.012), clamp22(Math.min(Math.max(p.thickness * 3, 3e-3), ratio * 0.01), 1e-3, 0.05), src);
6759
6877
  } else if (brittle) {
6760
- addCrack(o, p, entry2, n, crackLen, src);
6878
+ if (!p.spec.units) addCrack(o, p, entry2, n, crackLen, src);
6761
6879
  if (mat.fracture !== "shatter") addHole(o, p, entry2, n, caliber / 1e3, false, void 0, src);
6762
6880
  } else addHole(o, p, entry2, n, caliber / 1e3, false, void 0, src);
6763
6881
  debris(o, p, mat.hitDebris, entry2, n, clamp22(Math.round(E / 60) + 2, 2, 14), clamp22(Math.sqrt(E) / 6, 1, 8), src);
6764
6882
  wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true, BULLET_JOINT_SPAN);
6765
- const absorbed = penetrated && mat.ductility >= 0.5 && mat.fracture !== "tear" ? Math.min(E, thr) : E;
6883
+ const hollowTear = mat.fracture === "tear" && p.spec.fill !== void 0 && p.spec.fill < 0.5;
6884
+ const absorbed = penetrated && (mat.ductility >= 0.5 && mat.fracture !== "tear" || hollowTear) ? Math.min(E, thr) : E;
6766
6885
  const dmg = applyDamage(o, p, absorbed * DMG_PER_J * scale, "ballistic", entry2, d, absorbed * 0.1, 12, src);
6767
6886
  if (!isLost(p)) tearAt(o, p, "ballistic", entry2, penetrated ? exitPoint : void 0, d, E, caliber / 1e3, src);
6768
6887
  chipUnits(o, p, "ballistic", entry2, penetrated ? Math.min(E, Math.max(thr, E * 0.5)) : E, d, Math.max(0.05, caliber / 1e3 * 8), src);
@@ -6847,10 +6966,25 @@ var GameFloorplanStructure = (() => {
6847
6966
  if (dist <= BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3)) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
6848
6967
  return reach;
6849
6968
  };
6969
+ const blastProbe = { partsTested: 0, partsNear: 0 };
6970
+ const blastCandidates = (o, point, radius) => {
6971
+ const local = toLocal(o.st.position, o.st.rotation, point);
6972
+ const near = [];
6973
+ for (const p of o.parts) {
6974
+ const reach = radius + p.bound;
6975
+ const dx = local[0] - p.pos[0];
6976
+ const dy = local[1] - p.pos[1];
6977
+ const dz = local[2] - p.pos[2];
6978
+ if (dx * dx + dy * dy + dz * dz < reach * reach) near.push(p);
6979
+ }
6980
+ blastProbe.partsTested += o.parts.length;
6981
+ blastProbe.partsNear += near.length;
6982
+ return near;
6983
+ };
6850
6984
  const blastObject = (o, point, energy, radius, src) => {
6851
6985
  const start = cur.length;
6852
6986
  const res = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] };
6853
- for (const p of o.parts) blastPart(o, p, point, energy, radius, src, res);
6987
+ for (const p of blastCandidates(o, point, radius)) blastPart(o, p, point, energy, radius, src, res);
6854
6988
  res.events = cur.slice(start);
6855
6989
  return res;
6856
6990
  };
@@ -6974,7 +7108,7 @@ var GameFloorplanStructure = (() => {
6974
7108
  let order = 0;
6975
7109
  for (const o of inRange) {
6976
7110
  if (only && only !== o) continue;
6977
- for (const p of o.parts) {
7111
+ for (const p of blastCandidates(o, point, radius)) {
6978
7112
  if (isLost(p)) continue;
6979
7113
  const dist = distToPart(o, p, point);
6980
7114
  if (dist < radius) items.push({ dist, order: order++, o, p });
@@ -7521,6 +7655,7 @@ var GameFloorplanStructure = (() => {
7521
7655
  const p = getPart(o, partId);
7522
7656
  p.pos = [position[0], position[1], position[2]];
7523
7657
  p.q = q;
7658
+ poseVersion++;
7524
7659
  updateBound(o);
7525
7660
  },
7526
7661
  remove(id) {
@@ -7539,6 +7674,7 @@ var GameFloorplanStructure = (() => {
7539
7674
  const o = getObj(id);
7540
7675
  o.base = { pos: [position[0], position[1], position[2]], rot: [rotation[0], rotation[1], rotation[2], rotation[3]] };
7541
7676
  applySoilPose(o);
7677
+ slideOffResting(o, rotation);
7542
7678
  },
7543
7679
  splitGroup(id, group, newId) {
7544
7680
  if (impls.has(id)) throw new Error(`object "${id}" is a registered DestructibleImpl and cannot be split; its module owns its pieces`);
@@ -7562,7 +7698,7 @@ var GameFloorplanStructure = (() => {
7562
7698
  if (o.spec.name !== void 0) s.name = o.spec.name;
7563
7699
  if (o.spec.tags) s.tags = [...o.spec.tags];
7564
7700
  if (o.spec.soil !== void 0) s.soil = o.spec.soil;
7565
- return clone(s);
7701
+ return s;
7566
7702
  };
7567
7703
  const inNew = (pid) => moved.has(pid);
7568
7704
  const inOld = (pid) => !moved.has(pid);
@@ -7589,7 +7725,12 @@ var GameFloorplanStructure = (() => {
7589
7725
  const p = getPart(o, partId);
7590
7726
  return whole(() => doHit(o, h, p));
7591
7727
  },
7728
+ blastProbe() {
7729
+ return { ...blastProbe };
7730
+ },
7592
7731
  explode(point, energy, radius, source, blast) {
7732
+ blastProbe.partsTested = 0;
7733
+ blastProbe.partsNear = 0;
7593
7734
  return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
7594
7735
  },
7595
7736
  raycast(origin, direction, maxDistance = Infinity) {
@@ -7599,7 +7740,8 @@ var GameFloorplanStructure = (() => {
7599
7740
  sweepBox(box2, direction, distance2, options2 = {}) {
7600
7741
  const d = vec.normalize(direction);
7601
7742
  const ignored = options2.ignore === void 0 ? void 0 : objects.get(options2.ignore);
7602
- const ignore = ignored ? new Set(ignored.parts.map((p) => `${ignored.id}\0${p.spec.id}`)) : void 0;
7743
+ const hosted = options2.ignore === void 0 || ignored ? void 0 : impls.get(options2.ignore);
7744
+ const ignore = ignored ? new Set(ignored.parts.map((p) => `${ignored.id}\0${p.spec.id}`)) : hosted ? new Set(hosted.impl.describe().parts.map((p) => `${hosted.impl.id}\0${p.id}`)) : void 0;
7603
7745
  let best = null;
7604
7746
  for (const origin of sweepOrigins(box2, d, options2.spacing ?? 0.2)) {
7605
7747
  const r = raycastInternal(origin, d, distance2 + SWEEP_BACK, ignore);