@adatechnology/game-destruction 0.12.0 → 0.13.1

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.js CHANGED
@@ -2706,6 +2706,7 @@ var CONFINEMENT_DEFAULTS = { rays: 26, reach: 1.5, gain: 1.5, power: 2, max: 3 }
2706
2706
  var FLAMMABLE_FLUIDS = ["gas", "fuel"];
2707
2707
  var VENT_DIAMETER = 8e-3;
2708
2708
  var FLAME_LIGHTS_LEAK_C = 470;
2709
+ var RESTING_HOLD_COS = Math.cos(Math.PI / 6);
2709
2710
  var BREACH_RADIUS = 0.55;
2710
2711
  var BREACH_BLAST_FACTOR = 6;
2711
2712
  var BREACH_AREA = 0.25;
@@ -2721,6 +2722,8 @@ var UNIT_FRAGMENT_FACTOR = 4;
2721
2722
  var BREACH_GRID_CAP = 4096;
2722
2723
  var CHIP_ENERGY = 200;
2723
2724
  var CHIP_SPLASH = 0.5;
2725
+ var CRATER_SPENT = 0.6;
2726
+ var EDGE_REACH = 1.5;
2724
2727
  var BAR_BOW = 0.08;
2725
2728
  var BULLET_JOINT_SPAN = 0.3;
2726
2729
  var CUT_SLICE = 1;
@@ -2741,12 +2744,22 @@ var sectionLoss = (p) => {
2741
2744
  const cells = p.st.chipped;
2742
2745
  if (!cells?.length) return 0;
2743
2746
  const [u, v] = planeAxes(p.thin);
2744
- const along = p.dims[u] >= p.dims[v] ? u : v;
2747
+ const role = p.spec.structure?.role;
2748
+ const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
2749
+ 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;
2750
+ const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
2745
2751
  const across = along === u ? v : u;
2746
2752
  let worst = 0;
2747
2753
  for (const c of cells) {
2748
- let gone = 0;
2749
- for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) gone += d.size[across];
2754
+ const spans = [];
2755
+ 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]);
2756
+ spans.sort((a, b) => a[0] - b[0]);
2757
+ let gone = 0, end = -Infinity;
2758
+ for (const [a, b] of spans) {
2759
+ if (b <= end) continue;
2760
+ gone += b - Math.max(a, end);
2761
+ end = b;
2762
+ }
2750
2763
  worst = Math.max(worst, gone / Math.max(p.dims[across], 1e-6));
2751
2764
  }
2752
2765
  return Math.min(1, worst);
@@ -3042,7 +3055,18 @@ var createDestruction = (options = {}) => {
3042
3055
  if (k < 0 || j.spec.kind !== "tie") return k;
3043
3056
  return partXf(o, o.parts[k]).c[1] > partXf(o, o.parts[r]).c[1] + 1e-6 ? k : -1;
3044
3057
  };
3058
+ let poseVersion = 0;
3059
+ const contactMemo = /* @__PURE__ */ new WeakMap();
3045
3060
  const contactBox = (p, support) => {
3061
+ let byTouching = contactMemo.get(p);
3062
+ if (!byTouching) contactMemo.set(p, byTouching = /* @__PURE__ */ new Map());
3063
+ const known = byTouching.get(support);
3064
+ if (known && known.version === poseVersion) return known.box;
3065
+ const box = measureContact(p, support);
3066
+ byTouching.set(support, { version: poseVersion, box });
3067
+ return box;
3068
+ };
3069
+ const measureContact = (p, support) => {
3046
3070
  const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
3047
3071
  const lo = [0, 0, 0], hi = [0, 0, 0];
3048
3072
  for (let k = 0; k < 3; k++) {
@@ -3837,7 +3861,7 @@ var createDestruction = (options = {}) => {
3837
3861
  p.st.holes.push(hole);
3838
3862
  if (p.st.holes.length > maxHoles) p.st.holes.shift();
3839
3863
  markDamaged(p);
3840
- emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {} });
3864
+ emit({ ...base(o, src), type: "hole", part: p.spec.id, hole, worldPoint: wp, ...exit ? { exitPoint: exit } : {}, ...p.spec.powder ? { powder: { ...p.spec.powder } } : {} });
3841
3865
  setStage(o, p, 1, {}, src);
3842
3866
  return hole;
3843
3867
  };
@@ -3854,6 +3878,22 @@ var createDestruction = (options = {}) => {
3854
3878
  const detachEvents = (o, opened, by, src) => {
3855
3879
  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]) });
3856
3880
  };
3881
+ const slideOffResting = (o, rotation) => {
3882
+ const upY = 1 - 2 * (rotation[0] * rotation[0] + rotation[2] * rotation[2]);
3883
+ if (upY >= RESTING_HOLD_COS) return;
3884
+ const opened = o.joints.filter((j) => j.spec.kind === "resting" && !j.st.open);
3885
+ if (opened.length === 0) return;
3886
+ run(() => {
3887
+ for (const j of opened) {
3888
+ j.st.open = true;
3889
+ j.st.openedBy = "break";
3890
+ }
3891
+ solveStructure(o);
3892
+ recomputeGroups(o);
3893
+ detachEvents(o, opened, "break");
3894
+ collapseCheck(o);
3895
+ });
3896
+ };
3857
3897
  const checkDestroyed = (o, src) => {
3858
3898
  if (!o.st.destroyed && o.parts.length > 0 && o.parts.every(isLost)) {
3859
3899
  o.st.destroyed = true;
@@ -3954,7 +3994,7 @@ var createDestruction = (options = {}) => {
3954
3994
  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 }));
3955
3995
  const unitsOf = (p) => p.spec.units ?? { size: [p.mat.fragmentSize?.[1] ?? 0.2, p.mat.fragmentSize?.[1] ?? 0.2, p.thickness], bond: "stack" };
3956
3996
  const FRAGMENT_SHAPE = { shatter: "shard", splinter: "splinter", tear: "scrap" };
3957
- const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag) => {
3997
+ const cellFragments = (o, p, cells, hitW, dir, speed, mass, tag, inner = false) => {
3958
3998
  const { c, q } = partXf(o, p);
3959
3999
  const holes = p.st.holes.length > 0 ? localHolesOf(p) : [];
3960
4000
  const [u, v] = planeAxes(p.thin);
@@ -3978,7 +4018,8 @@ var createDestruction = (options = {}) => {
3978
4018
  velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd(), dv[2] * k],
3979
4019
  angularVelocity: [(rnd() - 0.5) * 8, (rnd() - 0.5) * 8, (rnd() - 0.5) * 8],
3980
4020
  mass: mass * faceArea(cell) / total,
3981
- ...marks.length > 0 ? { marks } : {}
4021
+ ...marks.length > 0 ? { marks } : {},
4022
+ ...inner ? { inner } : {}
3982
4023
  };
3983
4024
  });
3984
4025
  };
@@ -4019,7 +4060,7 @@ var createDestruction = (options = {}) => {
4019
4060
  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);
4020
4061
  };
4021
4062
  const chipUnits = (o, p, kind, wp, hitEnergy, dir, radius, src) => {
4022
- var _a, _b;
4063
+ var _a, _b, _c;
4023
4064
  if (!p.spec.units || !p.staged || chipEnergy <= 0 || p.st.stripped || isLost(p) || (p.st.stage ?? 0) >= 2) return;
4024
4065
  const rule = p.mat.hits?.[kind];
4025
4066
  const perKg = rule?.unitJoules ?? chipEnergy;
@@ -4029,7 +4070,9 @@ var createDestruction = (options = {}) => {
4029
4070
  const lp = toLocal(p.pos, p.q, objLocal(o, wp));
4030
4071
  const grid = gridOf(p);
4031
4072
  const worn = (_a = p.rt).chips ?? (_a.chips = {});
4073
+ const cut = (_b = p.rt).craters ?? (_b.craters = {});
4032
4074
  const out = [];
4075
+ const shot = kind === "ballistic";
4033
4076
  for (let i = 0; i < grid.length; i++) {
4034
4077
  const cell = grid[i];
4035
4078
  if (worn[i] === -1) continue;
@@ -4042,18 +4085,42 @@ var createDestruction = (options = {}) => {
4042
4085
  worn[i] = total;
4043
4086
  continue;
4044
4087
  }
4045
- worn[i] = -1;
4046
- out.push(cell);
4088
+ if (!shot) {
4089
+ worn[i] = -1;
4090
+ out.push(cell);
4091
+ continue;
4092
+ }
4093
+ const size = [cell.size[0], cell.size[1], cell.size[2]];
4094
+ const center = [cell.center[0], cell.center[1], cell.center[2]];
4095
+ for (const a of [u, v]) {
4096
+ const w = Math.min(cell.size[a], craterAcross(hitEnergy) * (0.85 + 0.3 * rnd()));
4097
+ const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
4098
+ size[a] = w;
4099
+ center[a] = clamp2(lp[a], lo, hi);
4100
+ 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 });
4101
+ size[a] = to - from;
4102
+ center[a] = (from + to) / 2;
4103
+ }
4104
+ const taken2 = (cut[i] ?? 0) + size[u] * size[v];
4105
+ if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
4106
+ worn[i] = -1;
4107
+ out.push({ ...cell, crater: true });
4108
+ continue;
4109
+ }
4110
+ worn[i] = 0;
4111
+ cut[i] = taken2;
4112
+ out.push({ center, size, crater: true });
4047
4113
  }
4048
4114
  if (out.length === 0) return;
4049
4115
  const { c, q } = partXf(o, p);
4050
- const chipped = (_b = p.st).chipped ?? (_b.chipped = []);
4116
+ const chipped = (_c = p.st).chipped ?? (_c.chipped = []);
4051
4117
  const holes = localHolesOf(p);
4052
4118
  for (const cell of out) {
4053
4119
  const mass = Math.min(p.st.mass, p.mat.density * cell.size[0] * cell.size[1] * cell.size[2]);
4054
4120
  const center = toWorld(c, q, cell.center);
4055
4121
  const speed = clamp2(Math.sqrt(2 * energy * 0.05 / Math.max(mass, 0.05)), 0.5, 6);
4056
- const fragments = cellFragments(o, p, [cell], wp, dir, speed, mass, `c${chipped.length}_`);
4122
+ const tag = `c${chipped.length}_`;
4123
+ const fragments = cell.crater ? craterFragments(o, p, cell, dir, speed, mass, tag) : cellFragments(o, p, [cell], wp, dir, speed, mass, tag, true);
4057
4124
  p.st.holes = p.st.holes.filter((_, k) => marksInBox(cell.center, cell.size, void 0, [holes[k]]).length === 0);
4058
4125
  chipped.push({ center: [cell.center[0], cell.center[1], cell.center[2]], size: [cell.size[0], cell.size[1], cell.size[2]] });
4059
4126
  p.st.mass = Math.max(0, p.st.mass - mass);
@@ -4070,6 +4137,57 @@ var createDestruction = (options = {}) => {
4070
4137
  collapseCheck(o, src);
4071
4138
  }
4072
4139
  };
4140
+ const tornToEdge = (o) => {
4141
+ const { p, cell, a, b, at, crater: crater2, reach, gone } = o;
4142
+ const half = p.dims[a] / 2;
4143
+ const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
4144
+ const free = (side, sign) => {
4145
+ if (sign > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign > 0 || a !== planeAxes(p.thin)[1];
4146
+ const probe = side + sign * 1e-3;
4147
+ 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);
4148
+ };
4149
+ if (at - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
4150
+ if (hi - at <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
4151
+ return crater2;
4152
+ };
4153
+ const craterAcross = (energy) => clamp2(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
4154
+ const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
4155
+ const { c, q } = partXf(o, p);
4156
+ const [u, v] = planeAxes(p.thin);
4157
+ const d = dir ?? rotateVec(q, [p.thin === 0 ? 1 : 0, p.thin === 1 ? 1 : 0, p.thin === 2 ? 1 : 0]);
4158
+ const exitSign = Math.sign(rotateVec(quat.conjugate(q), d)[p.thin]) || 1;
4159
+ const bit = Math.max(0.01, Math.min(cell.size[u], cell.size[v]) / 3);
4160
+ const n = clamp2(Math.round(cell.size[u] * cell.size[v] / (bit * bit * 3)), 4, 10) + Math.floor(rnd() * 3);
4161
+ const out = [];
4162
+ for (let i = 0; i < n; i++) {
4163
+ const back = i % 3 === 2;
4164
+ const lc = [cell.center[0], cell.center[1], cell.center[2]];
4165
+ lc[u] += (rnd() - 0.5) * cell.size[u] * 0.7;
4166
+ lc[v] += (rnd() - 0.5) * cell.size[v] * 0.7;
4167
+ lc[p.thin] += (back ? -exitSign : exitSign) * (p.thickness / 2 + 0.01);
4168
+ const size = [0, 0, 0];
4169
+ size[u] = bit * (0.6 + 0.8 * rnd());
4170
+ size[v] = bit * (0.5 + 0.7 * rnd());
4171
+ size[p.thin] = bit * (0.4 + 0.6 * rnd());
4172
+ const spread3 = [(rnd() - 0.5) * 0.9, (rnd() - 0.3) * 0.9, (rnd() - 0.5) * 0.9];
4173
+ const k = speed * (back ? 0.4 + 0.4 * rnd() : 0.7 + 0.8 * rnd());
4174
+ const vdir = vec.normalize(vec.add(back ? vec.scale(d, -1) : d, spread3));
4175
+ out.push({
4176
+ id: `${p.spec.id}#${tag}${i}`,
4177
+ part: p.spec.id,
4178
+ material: p.spec.material,
4179
+ shape: "chunk",
4180
+ center: toWorld(c, q, lc),
4181
+ size,
4182
+ rotation: q,
4183
+ velocity: [vdir[0] * k, vdir[1] * k + 0.5 * rnd(), vdir[2] * k],
4184
+ angularVelocity: [(rnd() - 0.5) * 20, (rnd() - 0.5) * 20, (rnd() - 0.5) * 20],
4185
+ mass: mass / n,
4186
+ inner: true
4187
+ });
4188
+ }
4189
+ return out;
4190
+ };
4073
4191
  const exposeRebar = (o, p, src) => {
4074
4192
  const r = p.spec.reinforcement;
4075
4193
  if (!r) return;
@@ -4357,7 +4475,7 @@ var createDestruction = (options = {}) => {
4357
4475
  });
4358
4476
  }
4359
4477
  const patch = [scale * 4, scale * 4, scale * 4];
4360
- emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry, size: patch, rotation: q, fragments });
4478
+ emit({ ...base(o, src), type: "chip", part: p.spec.id, center: exit ?? entry, size: patch, rotation: q, fragments, torn: true });
4361
4479
  };
4362
4480
  const ballistic = (o, p, entry, n, d, E, caliber, pathLen, src, round = {}) => {
4363
4481
  const mat = p.mat;
@@ -4416,12 +4534,13 @@ var createDestruction = (options = {}) => {
4416
4534
  } else if (mat.ductility >= 0.5) {
4417
4535
  addDent(o, p, entry, n, Math.max(caliber * 3 / 1e3, 0.012), clamp2(Math.min(Math.max(p.thickness * 3, 3e-3), ratio * 0.01), 1e-3, 0.05), src);
4418
4536
  } else if (brittle) {
4419
- addCrack(o, p, entry, n, crackLen, src);
4537
+ if (!p.spec.units) addCrack(o, p, entry, n, crackLen, src);
4420
4538
  if (mat.fracture !== "shatter") addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
4421
4539
  } else addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
4422
4540
  debris(o, p, mat.hitDebris, entry, n, clamp2(Math.round(E / 60) + 2, 2, 14), clamp2(Math.sqrt(E) / 6, 1, 8), src);
4423
4541
  wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true, BULLET_JOINT_SPAN);
4424
- const absorbed = penetrated && mat.ductility >= 0.5 && mat.fracture !== "tear" ? Math.min(E, thr) : E;
4542
+ const hollowTear = mat.fracture === "tear" && p.spec.fill !== void 0 && p.spec.fill < 0.5;
4543
+ const absorbed = penetrated && (mat.ductility >= 0.5 && mat.fracture !== "tear" || hollowTear) ? Math.min(E, thr) : E;
4425
4544
  const dmg = applyDamage(o, p, absorbed * DMG_PER_J * scale, "ballistic", entry, d, absorbed * 0.1, 12, src);
4426
4545
  if (!isLost(p)) tearAt(o, p, "ballistic", entry, penetrated ? exitPoint : void 0, d, E, caliber / 1e3, src);
4427
4546
  chipUnits(o, p, "ballistic", entry, penetrated ? Math.min(E, Math.max(thr, E * 0.5)) : E, d, Math.max(0.05, caliber / 1e3 * 8), src);
@@ -4506,10 +4625,25 @@ var createDestruction = (options = {}) => {
4506
4625
  if (dist <= BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3)) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
4507
4626
  return reach;
4508
4627
  };
4628
+ const blastProbe = { partsTested: 0, partsNear: 0 };
4629
+ const blastCandidates = (o, point, radius) => {
4630
+ const local = toLocal(o.st.position, o.st.rotation, point);
4631
+ const near = [];
4632
+ for (const p of o.parts) {
4633
+ const reach = radius + p.bound;
4634
+ const dx = local[0] - p.pos[0];
4635
+ const dy = local[1] - p.pos[1];
4636
+ const dz = local[2] - p.pos[2];
4637
+ if (dx * dx + dy * dy + dz * dz < reach * reach) near.push(p);
4638
+ }
4639
+ blastProbe.partsTested += o.parts.length;
4640
+ blastProbe.partsNear += near.length;
4641
+ return near;
4642
+ };
4509
4643
  const blastObject = (o, point, energy, radius, src) => {
4510
4644
  const start = cur.length;
4511
4645
  const res = { object: o.id, damage: 0, penetrated: false, exitEnergy: 0, events: [] };
4512
- for (const p of o.parts) blastPart(o, p, point, energy, radius, src, res);
4646
+ for (const p of blastCandidates(o, point, radius)) blastPart(o, p, point, energy, radius, src, res);
4513
4647
  res.events = cur.slice(start);
4514
4648
  return res;
4515
4649
  };
@@ -4633,7 +4767,7 @@ var createDestruction = (options = {}) => {
4633
4767
  let order = 0;
4634
4768
  for (const o of inRange) {
4635
4769
  if (only && only !== o) continue;
4636
- for (const p of o.parts) {
4770
+ for (const p of blastCandidates(o, point, radius)) {
4637
4771
  if (isLost(p)) continue;
4638
4772
  const dist = distToPart(o, p, point);
4639
4773
  if (dist < radius) items.push({ dist, order: order++, o, p });
@@ -5180,6 +5314,7 @@ var createDestruction = (options = {}) => {
5180
5314
  const p = getPart(o, partId);
5181
5315
  p.pos = [position[0], position[1], position[2]];
5182
5316
  p.q = q;
5317
+ poseVersion++;
5183
5318
  updateBound(o);
5184
5319
  },
5185
5320
  remove(id) {
@@ -5198,6 +5333,7 @@ var createDestruction = (options = {}) => {
5198
5333
  const o = getObj(id);
5199
5334
  o.base = { pos: [position[0], position[1], position[2]], rot: [rotation[0], rotation[1], rotation[2], rotation[3]] };
5200
5335
  applySoilPose(o);
5336
+ slideOffResting(o, rotation);
5201
5337
  },
5202
5338
  splitGroup(id, group, newId) {
5203
5339
  if (impls.has(id)) throw new Error(`object "${id}" is a registered DestructibleImpl and cannot be split; its module owns its pieces`);
@@ -5221,7 +5357,7 @@ var createDestruction = (options = {}) => {
5221
5357
  if (o.spec.name !== void 0) s.name = o.spec.name;
5222
5358
  if (o.spec.tags) s.tags = [...o.spec.tags];
5223
5359
  if (o.spec.soil !== void 0) s.soil = o.spec.soil;
5224
- return clone(s);
5360
+ return s;
5225
5361
  };
5226
5362
  const inNew = (pid) => moved.has(pid);
5227
5363
  const inOld = (pid) => !moved.has(pid);
@@ -5248,7 +5384,12 @@ var createDestruction = (options = {}) => {
5248
5384
  const p = getPart(o, partId);
5249
5385
  return whole(() => doHit(o, h, p));
5250
5386
  },
5387
+ blastProbe() {
5388
+ return { ...blastProbe };
5389
+ },
5251
5390
  explode(point, energy, radius, source, blast) {
5391
+ blastProbe.partsTested = 0;
5392
+ blastProbe.partsNear = 0;
5252
5393
  return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
5253
5394
  },
5254
5395
  raycast(origin, direction, maxDistance = Infinity) {
@@ -5258,7 +5399,8 @@ var createDestruction = (options = {}) => {
5258
5399
  sweepBox(box, direction, distance, options2 = {}) {
5259
5400
  const d = vec.normalize(direction);
5260
5401
  const ignored = options2.ignore === void 0 ? void 0 : objects.get(options2.ignore);
5261
- const ignore = ignored ? new Set(ignored.parts.map((p) => `${ignored.id}\0${p.spec.id}`)) : void 0;
5402
+ const hosted = options2.ignore === void 0 || ignored ? void 0 : impls.get(options2.ignore);
5403
+ 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;
5262
5404
  let best = null;
5263
5405
  for (const origin of sweepOrigins(box, d, options2.spacing ?? 0.2)) {
5264
5406
  const r = raycastInternal(origin, d, distance + SWEEP_BACK, ignore);