@adatechnology/game-floorplan-three 0.5.0 → 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 +2 -0
- package/dist/index.global.js +468 -43
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +80 -15
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -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;
|
|
@@ -6306,29 +6310,44 @@ function installDestructionBreach(K, _shared) {
|
|
|
6306
6310
|
}
|
|
6307
6311
|
return list;
|
|
6308
6312
|
}
|
|
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);
|
|
6309
6325
|
function draw2(partId, change) {
|
|
6310
6326
|
if (lod !== 0) return false;
|
|
6311
|
-
const
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
let view = views.get(partId);
|
|
6327
|
+
const hostId = hostOf(partId);
|
|
6328
|
+
if (!hostId || !specOf(partId)?.units) return false;
|
|
6329
|
+
let view = views.get(hostId);
|
|
6315
6330
|
if (!view) {
|
|
6316
|
-
const items = structure.meshesOf(
|
|
6331
|
+
const items = structure.meshesOf(hostId).filter((it) => it.mesh);
|
|
6317
6332
|
if (!items.length) return false;
|
|
6318
|
-
|
|
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() };
|
|
6319
6335
|
}
|
|
6336
|
+
if (!view.chips.has(partId)) return false;
|
|
6320
6337
|
if (change.opening) {
|
|
6321
|
-
if (view.
|
|
6322
|
-
view.
|
|
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);
|
|
6323
6341
|
}
|
|
6324
|
-
if (change.chip) view.chips.push(local(change.chip));
|
|
6325
|
-
const list =
|
|
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));
|
|
6326
6345
|
if (view.mesh) {
|
|
6327
6346
|
view.mesh.removeFromParent();
|
|
6328
6347
|
view.mesh.dispose();
|
|
6329
6348
|
}
|
|
6330
6349
|
const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1, list.length));
|
|
6331
|
-
mesh.name = "breach:" +
|
|
6350
|
+
mesh.name = "breach:" + hostId;
|
|
6332
6351
|
list.forEach((u, i) => {
|
|
6333
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));
|
|
6334
6353
|
mesh.setMatrixAt(i, tmp.m);
|
|
@@ -6343,7 +6362,7 @@ function installDestructionBreach(K, _shared) {
|
|
|
6343
6362
|
if (!view.saved) view.saved = view.items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
|
|
6344
6363
|
view.mesh = mesh;
|
|
6345
6364
|
view.units = list.length;
|
|
6346
|
-
views.set(
|
|
6365
|
+
views.set(hostId, view);
|
|
6347
6366
|
invalidate();
|
|
6348
6367
|
invalidateShadow();
|
|
6349
6368
|
return true;
|
|
@@ -8515,6 +8534,7 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8515
8534
|
return {
|
|
8516
8535
|
id: FLOORPLAN_AREA_ID,
|
|
8517
8536
|
name: text.name,
|
|
8537
|
+
ground: { surface: "lawn" },
|
|
8518
8538
|
group: text.group,
|
|
8519
8539
|
get houses() {
|
|
8520
8540
|
return placed;
|
|
@@ -8622,6 +8642,9 @@ import { inferJoints } from "@adatechnology/game-destruction";
|
|
|
8622
8642
|
import { markKitOrigin as markKitOrigin2 } from "@adatechnology/game-contracts";
|
|
8623
8643
|
import { residentialItems } from "@adatechnology/game-floorplan-residential";
|
|
8624
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;
|
|
8625
8648
|
var SHELF_SPAN = 1.5;
|
|
8626
8649
|
var SHELVING = /shelf|bookcase|rack/;
|
|
8627
8650
|
function carcass(parts, drawn) {
|
|
@@ -8636,6 +8659,39 @@ function carcass(parts, drawn) {
|
|
|
8636
8659
|
} else if (y <= x && y <= z) part.structure = { role: "beam", maxSpan: SHELF_SPAN * Math.max(x, z) };
|
|
8637
8660
|
}
|
|
8638
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
|
+
}
|
|
8639
8695
|
var FLOOR_TOUCH = 5e-3;
|
|
8640
8696
|
var LOOSE = /* @__PURE__ */ new Set(["paper"]);
|
|
8641
8697
|
var BASE_MATERIAL = {
|
|
@@ -8713,10 +8769,12 @@ function recordSpec(THREE, name, root, run, opts) {
|
|
|
8713
8769
|
};
|
|
8714
8770
|
run(A);
|
|
8715
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));
|
|
8716
8773
|
const parts = drawn.map((p) => {
|
|
8717
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]);
|
|
8718
8775
|
let material = materialOf[p.key] ?? "plastic";
|
|
8719
|
-
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";
|
|
8720
8778
|
const part = { id: p.id, material, shape: p.shape, position: p.position };
|
|
8721
8779
|
if (p.rotation) part.rotation = p.rotation;
|
|
8722
8780
|
if (!LOOSE.has(material) && p.min[1] <= FLOOR_TOUCH) part.anchored = true;
|
|
@@ -8751,6 +8809,13 @@ function recordSpec(THREE, name, root, run, opts) {
|
|
|
8751
8809
|
if (area < 0.6 * footprint || p.max[1] < 0.2) continue;
|
|
8752
8810
|
if (!top || p.max[1] > top.y + 1e-6) top = { part: p.id, y: p.max[1] };
|
|
8753
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
|
+
}
|
|
8754
8819
|
if (opts.carcass) carcass(parts, byId);
|
|
8755
8820
|
const spec = { name, parts, joints, tags: ["furniture"] };
|
|
8756
8821
|
const colors = new Map(drawn.map((p) => [p.id, p.color]));
|