@adatechnology/game-floorplan-three 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.global.js +734 -92
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +167 -28
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -66,8 +66,8 @@ function createTranslator(locale) {
|
|
|
66
66
|
var OPEN_ROOM_TYPES = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
|
|
67
67
|
var rectsOf = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
|
|
68
68
|
var isOpenArea = (c) => OPEN_ROOM_TYPES.has(c.type) || c.outdoor === true;
|
|
69
|
-
function planLod(
|
|
70
|
-
const l =
|
|
69
|
+
function planLod(houses2, focus, budget) {
|
|
70
|
+
const l = houses2.map((c) => ({ c, d: c.distance(focus), n0: c.stats.drawCalls, n1: c.stats.drawCallsLOD1, level: 0 })).sort((a, b) => a.d - b.d);
|
|
71
71
|
let total = l.reduce((s, x) => s + x.n0, 0);
|
|
72
72
|
for (let i = l.length - 1; i >= 0 && total > budget; i--) {
|
|
73
73
|
total -= l[i].n0 - l[i].n1;
|
|
@@ -5872,12 +5872,12 @@ function installLightsRoomLight(K, shared) {
|
|
|
5872
5872
|
A.invalidate = () => {
|
|
5873
5873
|
for (let i = 0; i < NS; i++) PL[i].shadow.needsUpdate = true;
|
|
5874
5874
|
};
|
|
5875
|
-
A.update = function(
|
|
5875
|
+
A.update = function(houses2, focus, op) {
|
|
5876
5876
|
op = op || {};
|
|
5877
|
-
|
|
5877
|
+
houses2 = (Array.isArray(houses2) ? houses2 : [houses2]).filter(Boolean);
|
|
5878
5878
|
_f.set(focus.x, focus.y, focus.z);
|
|
5879
5879
|
const rooms = [], exterior = [];
|
|
5880
|
-
for (const house of
|
|
5880
|
+
for (const house of houses2) {
|
|
5881
5881
|
if (house.group && !house.group.visible) continue;
|
|
5882
5882
|
house.house.updateMatrixWorld(true);
|
|
5883
5883
|
const M = house.house.matrixWorld, by = /* @__PURE__ */ new Map();
|
|
@@ -6030,7 +6030,7 @@ function installLightsRoomLight(K, shared) {
|
|
|
6030
6030
|
|
|
6031
6031
|
// src/destruction/pieces.ts
|
|
6032
6032
|
import { assemblyPart, getAssembly } from "@adatechnology/game-destruction";
|
|
6033
|
-
import { DENSITY, toDestructibleSpec } from "@adatechnology/game-floorplan-structure";
|
|
6033
|
+
import { DENSITY, MEMBER_CAGE, toDestructibleSpec } from "@adatechnology/game-floorplan-structure";
|
|
6034
6034
|
|
|
6035
6035
|
// src/destruction/panels.ts
|
|
6036
6036
|
import { resolveSlabPanels, slabPanelView } from "@adatechnology/game-floorplan-structure";
|
|
@@ -6210,7 +6210,11 @@ function installDestructionPieces(K, shared) {
|
|
|
6210
6210
|
if (!pc || pc.unit) return sp;
|
|
6211
6211
|
if (pc.role !== "wall" && pc.role !== "partition") {
|
|
6212
6212
|
const def = getAssembly(pc.assembly || (pc.material === "concrete" && ["slab", "beam", "column", "stair"].includes(pc.role) ? "reinforced_concrete" : ""));
|
|
6213
|
-
|
|
6213
|
+
const out = def && def.reinforcement && !sp.reinforcement ? { ...sp, reinforcement: { ...def.reinforcement } } : sp;
|
|
6214
|
+
if (out.reinforcement && !out.units && pc.material === "concrete" && (pc.role === "beam" || pc.role === "column") && sp.shape.kind === "box") {
|
|
6215
|
+
return { ...out, units: { size: [MEMBER_CAGE.unit, MEMBER_CAGE.unit, Math.min(...sp.shape.size)], bond: "stack", mortar: "concrete" } };
|
|
6216
|
+
}
|
|
6217
|
+
return out;
|
|
6214
6218
|
}
|
|
6215
6219
|
if (!pc.assembly) return sp;
|
|
6216
6220
|
const [u0, v0, u1, v1] = pc.aabb, alongU = u1 - u0 >= v1 - v0;
|
|
@@ -6267,7 +6271,12 @@ function installDestructionBreach(K, _shared) {
|
|
|
6267
6271
|
}
|
|
6268
6272
|
return null;
|
|
6269
6273
|
};
|
|
6270
|
-
|
|
6274
|
+
const local = (p) => {
|
|
6275
|
+
house.updateMatrixWorld(true);
|
|
6276
|
+
const v = house.worldToLocal(tmp.p.set(p[0], p[1], p[2]));
|
|
6277
|
+
return [v.x, v.y, v.z];
|
|
6278
|
+
};
|
|
6279
|
+
function courses(part, units, opening, chips, paint) {
|
|
6271
6280
|
const [u0, v0, u1, v1] = part.aabb;
|
|
6272
6281
|
const alongU = u1 - u0 >= v1 - v0;
|
|
6273
6282
|
const len = alongU ? u1 - u0 : v1 - v0;
|
|
@@ -6291,23 +6300,54 @@ function installDestructionBreach(K, _shared) {
|
|
|
6291
6300
|
const x = alongU ? u0 + mid : (u0 + u1) / 2;
|
|
6292
6301
|
const z = alongU ? (v0 + v1) / 2 : v0 + mid;
|
|
6293
6302
|
const y = part.y0 + (r + 0.5) * rowH;
|
|
6294
|
-
const d = Math.hypot(x - opening.center[0], y - opening.center[1], z - opening.center[2]);
|
|
6295
|
-
if (d < opening.radius) continue;
|
|
6296
|
-
|
|
6303
|
+
const d = opening ? Math.hypot(x - opening.center[0], y - opening.center[1], z - opening.center[2]) : Infinity;
|
|
6304
|
+
if (opening && d < opening.radius) continue;
|
|
6305
|
+
const gone = (c) => Math.abs(c[1] - y) <= rowH / 2 && (alongU ? c[0] >= u0 + a && c[0] <= u0 + b : c[2] >= v0 + a && c[2] <= v0 + b);
|
|
6306
|
+
if (chips.some(gone)) continue;
|
|
6307
|
+
const near = opening && d < opening.radius + 0.25 || chips.some((c) => Math.hypot(c[0] - x, c[1] - y, c[2] - z) < 0.15);
|
|
6308
|
+
list.push({ x, y, z, sx: alongU ? b - a : thick, sy: rowH, sz: alongU ? thick : b - a, colour: near || paint === null ? edge : paint });
|
|
6297
6309
|
}
|
|
6298
6310
|
}
|
|
6299
6311
|
return list;
|
|
6300
6312
|
}
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6313
|
+
const specOf = (id) => opts.spec()?.parts?.find((q) => q.id === id);
|
|
6314
|
+
const same = (a, b) => a.every((x, k) => Math.abs(x - b[k]) < 1e-3);
|
|
6315
|
+
function hostOf(partId) {
|
|
6316
|
+
if (structure.meshesOf(partId).some((it) => it.mesh)) return partId;
|
|
6317
|
+
const part = structure.byId.get(partId);
|
|
6318
|
+
if (!part) return null;
|
|
6319
|
+
for (const q of structure.parts) {
|
|
6320
|
+
if (q.id !== partId && same(q.aabb, part.aabb) && Math.abs(q.y1 - part.y0) < 0.01 && structure.meshesOf(q.id).some((it) => it.mesh)) return q.id;
|
|
6321
|
+
}
|
|
6322
|
+
return null;
|
|
6323
|
+
}
|
|
6324
|
+
const riders = (hostId) => structure.parts.filter((q) => q.id !== hostId && specOf(q.id)?.units && hostOf(q.id) === hostId && !structure.meshesOf(q.id).some((it) => it.mesh)).map((q) => q.id);
|
|
6325
|
+
function draw2(partId, change) {
|
|
6326
|
+
if (lod !== 0) return false;
|
|
6327
|
+
const hostId = hostOf(partId);
|
|
6328
|
+
if (!hostId || !specOf(partId)?.units) return false;
|
|
6329
|
+
let view = views.get(hostId);
|
|
6330
|
+
if (!view) {
|
|
6331
|
+
const items = structure.meshesOf(hostId).filter((it) => it.mesh);
|
|
6332
|
+
if (!items.length) return false;
|
|
6333
|
+
const parts = [hostId, ...riders(hostId)].filter((id) => structure.byId.get(id) && specOf(id)?.units);
|
|
6334
|
+
view = { mesh: null, saved: null, items, paint: wallColour(items), units: 0, opening: null, chips: new Map(parts.map((id) => [id, []])), openings: /* @__PURE__ */ new Map() };
|
|
6335
|
+
}
|
|
6336
|
+
if (!view.chips.has(partId)) return false;
|
|
6337
|
+
if (change.opening) {
|
|
6338
|
+
if (view.openings.has(partId)) return false;
|
|
6339
|
+
view.openings.set(partId, { center: local(change.opening.center), radius: change.opening.radius });
|
|
6340
|
+
if (partId === hostId) view.opening = view.openings.get(partId);
|
|
6341
|
+
}
|
|
6342
|
+
if (change.chip) view.chips.get(partId).push(local(change.chip));
|
|
6343
|
+
const list = [];
|
|
6344
|
+
for (const [id, chips] of view.chips) list.push(...courses(structure.byId.get(id), specOf(id).units, view.openings.get(id) ?? null, chips, view.paint));
|
|
6345
|
+
if (view.mesh) {
|
|
6346
|
+
view.mesh.removeFromParent();
|
|
6347
|
+
view.mesh.dispose();
|
|
6348
|
+
}
|
|
6309
6349
|
const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1, list.length));
|
|
6310
|
-
mesh.name = "breach:" +
|
|
6350
|
+
mesh.name = "breach:" + hostId;
|
|
6311
6351
|
list.forEach((u, i) => {
|
|
6312
6352
|
tmp.m.compose(tmp.p.set(u.x, u.y, u.z), tmp.q.identity(), tmp.s.set(u.sx, u.sy, u.sz));
|
|
6313
6353
|
mesh.setMatrixAt(i, tmp.m);
|
|
@@ -6319,8 +6359,10 @@ function installDestructionBreach(K, _shared) {
|
|
|
6319
6359
|
mesh.castShadow = true;
|
|
6320
6360
|
mesh.receiveShadow = true;
|
|
6321
6361
|
house.add(mesh);
|
|
6322
|
-
|
|
6323
|
-
|
|
6362
|
+
if (!view.saved) view.saved = view.items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
|
|
6363
|
+
view.mesh = mesh;
|
|
6364
|
+
view.units = list.length;
|
|
6365
|
+
views.set(hostId, view);
|
|
6324
6366
|
invalidate();
|
|
6325
6367
|
invalidateShadow();
|
|
6326
6368
|
return true;
|
|
@@ -6334,7 +6376,11 @@ function installDestructionBreach(K, _shared) {
|
|
|
6334
6376
|
return {
|
|
6335
6377
|
/** Handles a `stage` event of the house's object. Returns true when the wall was redrawn as courses. */
|
|
6336
6378
|
stage(event) {
|
|
6337
|
-
return event.stage === 2 ?
|
|
6379
|
+
return event.stage === 2 && !!event.opening ? draw2(event.part, { opening: event.opening }) : false;
|
|
6380
|
+
},
|
|
6381
|
+
/** Handles a `chip` event: the unit that came out leaves a gap in the courses. Returns true when the wall was redrawn. */
|
|
6382
|
+
chip(event) {
|
|
6383
|
+
return draw2(event.part, { chip: event.center });
|
|
6338
6384
|
},
|
|
6339
6385
|
/** The part broke or fell: the courses go (the plain range stays collapsed, the renderer hides the part). */
|
|
6340
6386
|
drop(partId) {
|
|
@@ -6566,6 +6612,9 @@ function installDestructionWorld(K, shared) {
|
|
|
6566
6612
|
case "stage":
|
|
6567
6613
|
breach.stage(e);
|
|
6568
6614
|
break;
|
|
6615
|
+
case "chip":
|
|
6616
|
+
breach.chip(e);
|
|
6617
|
+
break;
|
|
6569
6618
|
case "collapse":
|
|
6570
6619
|
for (const id of e.parts) {
|
|
6571
6620
|
breach.drop(id);
|
|
@@ -6620,6 +6669,32 @@ function installDestructionWorld(K, shared) {
|
|
|
6620
6669
|
if (D.active && D.world.has(D.id)) D.world.remove(D.id);
|
|
6621
6670
|
D.active = false;
|
|
6622
6671
|
};
|
|
6672
|
+
D.follow = (world, id, spec) => {
|
|
6673
|
+
D.spec = spec;
|
|
6674
|
+
const offFollow = world.on("*", (e) => {
|
|
6675
|
+
if (e.object !== id) return;
|
|
6676
|
+
switch (e.type) {
|
|
6677
|
+
case "stage":
|
|
6678
|
+
breach.stage(e);
|
|
6679
|
+
break;
|
|
6680
|
+
case "chip":
|
|
6681
|
+
breach.chip(e);
|
|
6682
|
+
break;
|
|
6683
|
+
case "fracture":
|
|
6684
|
+
breach.drop(e.part);
|
|
6685
|
+
break;
|
|
6686
|
+
case "collapse":
|
|
6687
|
+
for (const p of e.parts) breach.drop(p);
|
|
6688
|
+
break;
|
|
6689
|
+
default:
|
|
6690
|
+
break;
|
|
6691
|
+
}
|
|
6692
|
+
});
|
|
6693
|
+
return { restore: () => breach.restore(), dispose: () => {
|
|
6694
|
+
offFollow();
|
|
6695
|
+
breach.restore();
|
|
6696
|
+
} };
|
|
6697
|
+
};
|
|
6623
6698
|
D.piece = (id) => D.active ? D.world.part(D.id, id) : null;
|
|
6624
6699
|
D.state = () => D.active ? D.world.state(D.id) : null;
|
|
6625
6700
|
D.reset = () => {
|
|
@@ -8459,6 +8534,7 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8459
8534
|
return {
|
|
8460
8535
|
id: FLOORPLAN_AREA_ID,
|
|
8461
8536
|
name: text.name,
|
|
8537
|
+
ground: { surface: "lawn" },
|
|
8462
8538
|
group: text.group,
|
|
8463
8539
|
get houses() {
|
|
8464
8540
|
return placed;
|
|
@@ -8566,6 +8642,56 @@ import { inferJoints } from "@adatechnology/game-destruction";
|
|
|
8566
8642
|
import { markKitOrigin as markKitOrigin2 } from "@adatechnology/game-contracts";
|
|
8567
8643
|
import { residentialItems } from "@adatechnology/game-floorplan-residential";
|
|
8568
8644
|
var WOOD_THIN = 0.035;
|
|
8645
|
+
var BOARD_TOP_THICK = 0.07;
|
|
8646
|
+
var BOARD_TOP_WIDTH = 0.5;
|
|
8647
|
+
var BOARD_WIDTH = 0.16;
|
|
8648
|
+
var SHELF_SPAN = 1.5;
|
|
8649
|
+
var SHELVING = /shelf|bookcase|rack/;
|
|
8650
|
+
function carcass(parts, drawn) {
|
|
8651
|
+
const all = [...drawn.values()];
|
|
8652
|
+
const width = Math.max(...all.map((p) => p.max[0])) - Math.min(...all.map((p) => p.min[0]));
|
|
8653
|
+
for (const part of parts) {
|
|
8654
|
+
if (LOOSE.has(part.material) || part.shape.kind !== "box" || part.rotation) continue;
|
|
8655
|
+
const [x, y, z] = part.shape.size;
|
|
8656
|
+
if (y >= x && y >= z) {
|
|
8657
|
+
if (z < x && x >= 0.6 * width) continue;
|
|
8658
|
+
part.structure = { role: "column" };
|
|
8659
|
+
} else if (y <= x && y <= z) part.structure = { role: "beam", maxSpan: SHELF_SPAN * Math.max(x, z) };
|
|
8660
|
+
}
|
|
8661
|
+
}
|
|
8662
|
+
function splitTopsIntoBoards(drawn, materialOf, carcassed) {
|
|
8663
|
+
const tops = /* @__PURE__ */ new Map();
|
|
8664
|
+
if (carcassed) return tops;
|
|
8665
|
+
for (let i = drawn.length - 1; i >= 0; i--) {
|
|
8666
|
+
const p = drawn[i];
|
|
8667
|
+
if (p.key !== "wood" || materialOf.wood !== "wood_hard" || p.shape.kind !== "box" || p.rotation) continue;
|
|
8668
|
+
const [sx, sy, sz] = p.shape.size;
|
|
8669
|
+
const across = sx < sz ? 0 : 2;
|
|
8670
|
+
const width = Math.min(sx, sz);
|
|
8671
|
+
if (sy < WOOD_THIN || sy > BOARD_TOP_THICK || sy >= width || width < BOARD_TOP_WIDTH) continue;
|
|
8672
|
+
const count = Math.round(width / BOARD_WIDTH);
|
|
8673
|
+
const boards = [];
|
|
8674
|
+
for (let b = 0; b < count; b++) {
|
|
8675
|
+
const size = [sx, sy, sz];
|
|
8676
|
+
size[across] = width / count;
|
|
8677
|
+
const position = [...p.position];
|
|
8678
|
+
position[across] += (b + 0.5) * size[across] - width / 2;
|
|
8679
|
+
const min = [...p.min];
|
|
8680
|
+
const max = [...p.max];
|
|
8681
|
+
min[across] = position[across] - size[across] / 2;
|
|
8682
|
+
max[across] = position[across] + size[across] / 2;
|
|
8683
|
+
boards.push({ ...p, id: `${p.id}_b${b}`, shape: { kind: "box", size }, position, min, max, color: shadeBoard(p.color, b) });
|
|
8684
|
+
}
|
|
8685
|
+
drawn.splice(i, 1, ...boards);
|
|
8686
|
+
tops.set(p.id, boards);
|
|
8687
|
+
}
|
|
8688
|
+
return tops;
|
|
8689
|
+
}
|
|
8690
|
+
function shadeBoard(color, board) {
|
|
8691
|
+
const k = [1, 0.94, 1.05, 0.97, 1.03][board % 5];
|
|
8692
|
+
const channel = (shift) => Math.min(255, Math.round((color >> shift & 255) * k)) << shift;
|
|
8693
|
+
return channel(16) | channel(8) | channel(0);
|
|
8694
|
+
}
|
|
8569
8695
|
var FLOOR_TOUCH = 5e-3;
|
|
8570
8696
|
var LOOSE = /* @__PURE__ */ new Set(["paper"]);
|
|
8571
8697
|
var BASE_MATERIAL = {
|
|
@@ -8643,10 +8769,12 @@ function recordSpec(THREE, name, root, run, opts) {
|
|
|
8643
8769
|
};
|
|
8644
8770
|
run(A);
|
|
8645
8771
|
if (!drawn.length) throw new Error(`game-floorplan-three: the builder of "${name}" drew no box or cylinder`);
|
|
8772
|
+
const boardsOf = splitTopsIntoBoards(drawn, materialOf, Boolean(opts.carcass));
|
|
8646
8773
|
const parts = drawn.map((p) => {
|
|
8647
8774
|
const thin = Math.min(...p.shape.kind === "box" ? p.shape.size : p.shape.kind === "cylinder" ? [p.shape.radius * 2, p.shape.height] : [p.shape.radius * 2]);
|
|
8648
8775
|
let material = materialOf[p.key] ?? "plastic";
|
|
8649
|
-
if (p.key === "wood" && material === "wood_hard" &&
|
|
8776
|
+
if (p.key === "wood" && material === "wood_hard" && opts.carcass && !opts.materials?.wood) material = "mdf";
|
|
8777
|
+
else if (p.key === "wood" && material === "wood_hard" && thin < WOOD_THIN) material = "wood_soft";
|
|
8650
8778
|
const part = { id: p.id, material, shape: p.shape, position: p.position };
|
|
8651
8779
|
if (p.rotation) part.rotation = p.rotation;
|
|
8652
8780
|
if (!LOOSE.has(material) && p.min[1] <= FLOOR_TOUCH) part.anchored = true;
|
|
@@ -8681,6 +8809,14 @@ function recordSpec(THREE, name, root, run, opts) {
|
|
|
8681
8809
|
if (area < 0.6 * footprint || p.max[1] < 0.2) continue;
|
|
8682
8810
|
if (!top || p.max[1] > top.y + 1e-6) top = { part: p.id, y: p.max[1] };
|
|
8683
8811
|
}
|
|
8812
|
+
for (const boards of boardsOf.values()) {
|
|
8813
|
+
if (top && boards[0].max[1] <= top.y - 1e-6) continue;
|
|
8814
|
+
const mid = boards[boards.length >> 1];
|
|
8815
|
+
const min = [Math.min(...boards.map((b) => b.min[0])), Math.min(...boards.map((b) => b.min[2]))];
|
|
8816
|
+
const max = [Math.max(...boards.map((b) => b.max[0])), Math.max(...boards.map((b) => b.max[2]))];
|
|
8817
|
+
if ((max[0] - min[0]) * (max[1] - min[1]) >= 0.6 * footprint && mid.max[1] >= 0.2) top = { part: mid.id, y: mid.max[1], parts: boards.map((b) => b.id) };
|
|
8818
|
+
}
|
|
8819
|
+
if (opts.carcass) carcass(parts, byId);
|
|
8684
8820
|
const spec = { name, parts, joints, tags: ["furniture"] };
|
|
8685
8821
|
const colors = new Map(drawn.map((p) => [p.id, p.color]));
|
|
8686
8822
|
const build = (T3) => {
|
|
@@ -8724,7 +8860,7 @@ function furnitureSpec(THREE, type, opts = {}) {
|
|
|
8724
8860
|
if (w === void 0 || d === void 0 || h === void 0) throw new Error(`game-floorplan-three: furniture type "${type}" is not in the catalogue, so give w, d and h`);
|
|
8725
8861
|
const o = opts.options ?? {};
|
|
8726
8862
|
const seed = Math.round(opts.seed ?? 1);
|
|
8727
|
-
const plain =
|
|
8863
|
+
const plain = SHELVING.test(type) ? "paper" : "plastic";
|
|
8728
8864
|
const root = { x: seed, z: 0, ry: 0, w, d, h, y: 0, base: 0, palette: o.palette, seed: `furniture_${type}_${seed}` };
|
|
8729
8865
|
const { K, shared } = renderer.internals;
|
|
8730
8866
|
const before = K.PARTS.length;
|
|
@@ -8743,7 +8879,7 @@ function furnitureSpec(THREE, type, opts = {}) {
|
|
|
8743
8879
|
shared.ctx = saved.ctx;
|
|
8744
8880
|
}
|
|
8745
8881
|
},
|
|
8746
|
-
{ materials: { plain, ...o.materials }, chairs: o.chairs }
|
|
8882
|
+
{ materials: { plain, ...o.materials }, chairs: o.chairs, carcass: SHELVING.test(type) }
|
|
8747
8883
|
);
|
|
8748
8884
|
const spouts = K.PARTS.slice(before).filter((p) => p.type === "water_tap").map((p) => [p.pos[0] - root.x, p.pos[1], p.pos[2] - root.z]);
|
|
8749
8885
|
K.PARTS.length = before;
|
|
@@ -8811,7 +8947,9 @@ function wallPlan(options) {
|
|
|
8811
8947
|
function draw(THREE, plan, options) {
|
|
8812
8948
|
return create(THREE, { ...options, fleet: null }).build(plan, { quality: "game", terrain: false, noPerimeter: true, pieces: "meshes" });
|
|
8813
8949
|
}
|
|
8950
|
+
var houses = /* @__PURE__ */ new WeakMap();
|
|
8814
8951
|
function label(house) {
|
|
8952
|
+
houses.set(house.group, house);
|
|
8815
8953
|
for (const [id, items] of Object.entries(house.destruction.ranges())) {
|
|
8816
8954
|
for (const item of items) {
|
|
8817
8955
|
const object = item.isObject3D ? item : item.mesh;
|
|
@@ -8824,12 +8962,13 @@ function wallPiece(THREE, options) {
|
|
|
8824
8962
|
const plan = wallPlan(options);
|
|
8825
8963
|
const houseOptions = options.house ?? {};
|
|
8826
8964
|
const probe = draw(THREE, plan, { ...houseOptions, destruction: void 0, destructionRenderer: void 0 });
|
|
8827
|
-
const spec = probe.structure.spec(
|
|
8965
|
+
const spec = probe.structure.spec();
|
|
8828
8966
|
probe.dispose();
|
|
8829
8967
|
return {
|
|
8830
8968
|
plan,
|
|
8831
8969
|
spec,
|
|
8832
|
-
build: (T) => label(draw(T, plan, houseOptions))
|
|
8970
|
+
build: (T) => label(draw(T, plan, houseOptions)),
|
|
8971
|
+
follow: (root, world, objectId) => houses.get(root)?.destruction?.follow?.(world, objectId, spec) ?? null
|
|
8833
8972
|
};
|
|
8834
8973
|
}
|
|
8835
8974
|
export {
|