@adatechnology/game-items-three 0.7.2 → 0.7.4
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/{chunk-WGFTVYO3.js → chunk-76GT7V27.js} +1 -1
- package/dist/chunk-76GT7V27.js.map +1 -0
- package/dist/index.global.js +1044 -347
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/testing.js +1 -1
- package/package.json +8 -8
- package/dist/chunk-WGFTVYO3.js.map +0 -1
package/dist/index.global.js
CHANGED
|
@@ -89,7 +89,7 @@ var GameItemsThree = (() => {
|
|
|
89
89
|
wearableMaterials: () => wearableMaterials
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
// ../game-shapes/dist/chunk-
|
|
92
|
+
// ../game-shapes/dist/chunk-FZQTELDQ.js
|
|
93
93
|
function canonicalJson(value) {
|
|
94
94
|
if (value === null) return "null";
|
|
95
95
|
if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
|
|
@@ -1001,17 +1001,19 @@ var GameItemsThree = (() => {
|
|
|
1001
1001
|
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
|
|
1002
1002
|
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
|
|
1003
1003
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1004
|
+
var Node = class {
|
|
1005
|
+
constructor(i, x, y) {
|
|
1006
|
+
this.i = i;
|
|
1007
|
+
this.x = x;
|
|
1008
|
+
this.y = y;
|
|
1009
|
+
this.prev = null;
|
|
1010
|
+
this.next = null;
|
|
1011
|
+
this.z = 0;
|
|
1012
|
+
this.prevZ = null;
|
|
1013
|
+
this.nextZ = null;
|
|
1014
|
+
this.steiner = false;
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1015
1017
|
function signedArea(data, start, end, dim) {
|
|
1016
1018
|
let sum = 0;
|
|
1017
1019
|
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
@@ -1969,6 +1971,9 @@ var GameItemsThree = (() => {
|
|
|
1969
1971
|
}
|
|
1970
1972
|
return releaseObject3D(list2, { keep });
|
|
1971
1973
|
}
|
|
1974
|
+
function isMesh(o) {
|
|
1975
|
+
return !!o && o.isMesh === true;
|
|
1976
|
+
}
|
|
1972
1977
|
|
|
1973
1978
|
// src/kit.ts
|
|
1974
1979
|
var WEAR_TAGS = ["metal", "wood", "cloth", "plastic", "paper", "food", "glass"];
|
|
@@ -2731,6 +2736,19 @@ var GameItemsThree = (() => {
|
|
|
2731
2736
|
"drink",
|
|
2732
2737
|
"sticky"
|
|
2733
2738
|
]
|
|
2739
|
+
},
|
|
2740
|
+
{
|
|
2741
|
+
id: "mud",
|
|
2742
|
+
color: 4008988,
|
|
2743
|
+
opacity: 0.95,
|
|
2744
|
+
stainColor: 3811866,
|
|
2745
|
+
viscosity: 40,
|
|
2746
|
+
density: 1600,
|
|
2747
|
+
dryTime: 900,
|
|
2748
|
+
gloss: 0.4,
|
|
2749
|
+
tags: [
|
|
2750
|
+
"dirty"
|
|
2751
|
+
]
|
|
2734
2752
|
}
|
|
2735
2753
|
];
|
|
2736
2754
|
var LIQUIDS = liquids_default;
|
|
@@ -13254,6 +13272,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
13254
13272
|
return angle === 0 ? q : quat.mul(q, quat.fromAxisAngle([0, 0, 1], angle));
|
|
13255
13273
|
};
|
|
13256
13274
|
var clamp = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
13275
|
+
var splitAlong = (box4, count, axis, rnd) => {
|
|
13276
|
+
const shares = Array.from({ length: count }, () => 0.25 + 1.5 * rnd());
|
|
13277
|
+
const total = shares.reduce((sum, share) => sum + share, 0);
|
|
13278
|
+
const out = [];
|
|
13279
|
+
let from = box4.c[axis] - box4.s[axis] / 2;
|
|
13280
|
+
for (const share of shares) {
|
|
13281
|
+
const length = box4.s[axis] * share / total;
|
|
13282
|
+
const c = [box4.c[0], box4.c[1], box4.c[2]];
|
|
13283
|
+
const size = [box4.s[0], box4.s[1], box4.s[2]];
|
|
13284
|
+
c[axis] = from + length / 2;
|
|
13285
|
+
size[axis] = length;
|
|
13286
|
+
out.push({ c, s: size });
|
|
13287
|
+
from += length;
|
|
13288
|
+
}
|
|
13289
|
+
return out;
|
|
13290
|
+
};
|
|
13257
13291
|
var splinterBox = (inp, box4, limit = inp.maxFragments) => {
|
|
13258
13292
|
const { rnd } = inp;
|
|
13259
13293
|
const dims = box4.s;
|
|
@@ -13263,35 +13297,81 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
13263
13297
|
const w = Math.max(fmin * 1.5, 0.01);
|
|
13264
13298
|
const c = clamp(Math.round(dims[a] * dims[b] / (w * w)), 3, Math.max(3, Math.floor(limit / 2)));
|
|
13265
13299
|
const maxLen = fmax * 4;
|
|
13266
|
-
const cells =
|
|
13300
|
+
const cells = [];
|
|
13301
|
+
for (const cell of bsp(box4, c, [a, b], rnd)) {
|
|
13302
|
+
const wide = cell.s[a] >= cell.s[b] ? a : b;
|
|
13303
|
+
if (rnd() < 0.4 && cell.s[wide] > fmin * 0.5) for (const part of splitAlong(cell, 2, wide, rnd)) cells.push(part);
|
|
13304
|
+
else cells.push(cell);
|
|
13305
|
+
}
|
|
13267
13306
|
const pieces = [];
|
|
13268
13307
|
for (const cell of cells) {
|
|
13269
|
-
const extra = rnd()
|
|
13308
|
+
const extra = Math.floor(rnd() * 3);
|
|
13270
13309
|
const k = Math.max(1, Math.ceil(dims[g] / maxLen)) + extra;
|
|
13271
|
-
for (const p of
|
|
13310
|
+
for (const p of splitAlong(cell, k, g, rnd)) pieces.push(p);
|
|
13272
13311
|
}
|
|
13273
13312
|
return pieces.slice(0, limit).map((p) => ({ center: p.c, size: [p.s[g], p.s[a], p.s[b]], q: frame(g, a, b), shape: "splinter", weight: p.s[0] * p.s[1] * p.s[2] }));
|
|
13274
13313
|
};
|
|
13314
|
+
var PLY = 3e-3;
|
|
13315
|
+
var PLY_GAP = 0.6;
|
|
13316
|
+
var PLY_SHEET = 0.012;
|
|
13317
|
+
var plyBreak = (inp, root, limit) => {
|
|
13318
|
+
const { rnd } = inp;
|
|
13319
|
+
const dims = root.s;
|
|
13320
|
+
const sorted = [0, 1, 2].sort((x, y) => dims[x] - dims[y]);
|
|
13321
|
+
const t = sorted[0];
|
|
13322
|
+
const [u, v] = [sorted[1], sorted[2]].sort((x, y) => x - y);
|
|
13323
|
+
const along = dims[u] >= dims[v] ? u : v;
|
|
13324
|
+
const across2 = along === u ? v : u;
|
|
13325
|
+
const layers = clamp(Math.round(dims[t] / PLY / 2), 2, 3);
|
|
13326
|
+
const pitch = dims[t] / layers;
|
|
13327
|
+
const th = Math.min(pitch, PLY_SHEET);
|
|
13328
|
+
const per = Math.max(2, Math.floor(limit / layers));
|
|
13329
|
+
const out = [];
|
|
13330
|
+
for (let k = 0; k < layers; k++) {
|
|
13331
|
+
const layer = { c: [root.c[0], root.c[1], root.c[2]], s: [dims[0], dims[1], dims[2]] };
|
|
13332
|
+
layer.c[t] = root.c[t] + (-dims[t] / 2 + (k + 0.5) * pitch) * (pitch > PLY_SHEET ? 1 : 1 + PLY_GAP);
|
|
13333
|
+
layer.s[t] = th;
|
|
13334
|
+
for (const cell of bsp(layer, per, [u, v], rnd)) {
|
|
13335
|
+
if (out.length >= limit) return out;
|
|
13336
|
+
if (rnd() < 0.35) {
|
|
13337
|
+
const strand = cell.s[across2] * (0.15 + 0.2 * rnd());
|
|
13338
|
+
out.push({ center: cell.c, size: [cell.s[along], strand, th * 0.7], q: frame(along, across2, t), shape: "splinter", weight: cell.s[along] * strand * th });
|
|
13339
|
+
} else {
|
|
13340
|
+
out.push({ center: cell.c, size: [cell.s[u], cell.s[v], th], q: frame(u, v, t, (rnd() - 0.5) * 0.5), shape: "scrap", weight: cell.s[u] * cell.s[v] * th });
|
|
13341
|
+
}
|
|
13342
|
+
}
|
|
13343
|
+
}
|
|
13344
|
+
return out;
|
|
13345
|
+
};
|
|
13346
|
+
var granules = (inp, box4, count) => bsp(box4, count, [0, 1, 2], inp.rnd).map((b) => ({ center: b.c, size: b.s, q: quat.identity(), shape: "chunk", weight: b.s[0] * b.s[1] * b.s[2] }));
|
|
13347
|
+
var CRUMBS = 6;
|
|
13275
13348
|
var severAt = (inp, root, at2, gap) => {
|
|
13276
13349
|
const dims = root.s;
|
|
13277
13350
|
const L = [0, 1, 2].sort((x, y) => dims[y] - dims[x])[0];
|
|
13278
13351
|
const half = dims[L] / 2;
|
|
13279
13352
|
const lo = clamp(at2 - gap / 2, -half, half), hi = clamp(at2 + gap / 2, -half, half);
|
|
13280
13353
|
const out = [];
|
|
13281
|
-
const
|
|
13354
|
+
const fibrous = inp.form === "slivers" || inp.form === "plies";
|
|
13355
|
+
const [a, b] = [0, 1, 2].filter((i) => i !== L);
|
|
13356
|
+
const stub = (from, to, breakAtEnd) => {
|
|
13282
13357
|
if (to - from < 0.02) return;
|
|
13283
13358
|
const c = [root.c[0], root.c[1], root.c[2]], sz = [dims[0], dims[1], dims[2]];
|
|
13284
13359
|
c[L] = (from + to) / 2;
|
|
13285
13360
|
sz[L] = to - from;
|
|
13286
|
-
|
|
13361
|
+
const weight = sz[0] * sz[1] * sz[2];
|
|
13362
|
+
if (fibrous) out.push({ center: c, size: [sz[L], sz[a], sz[b]], q: frame(L, a, b, breakAtEnd ? 0 : Math.PI), shape: "slab", weight });
|
|
13363
|
+
else out.push({ center: c, size: sz, q: quat.identity(), shape: "slab", weight });
|
|
13287
13364
|
};
|
|
13288
|
-
stub(-half, lo);
|
|
13289
|
-
stub(hi, half);
|
|
13365
|
+
stub(-half, lo, true);
|
|
13366
|
+
stub(hi, half, false);
|
|
13290
13367
|
const band = { c: [root.c[0], root.c[1], root.c[2]], s: [dims[0], dims[1], dims[2]] };
|
|
13291
13368
|
band.c[L] = (lo + hi) / 2;
|
|
13292
13369
|
band.s[L] = Math.max(hi - lo, 0.01);
|
|
13293
|
-
|
|
13294
|
-
|
|
13370
|
+
const room = inp.maxFragments - out.length;
|
|
13371
|
+
if (inp.style === "snap" && inp.form === "plies") for (const p of plyBreak(inp, band, Math.max(3, room))) out.push(p);
|
|
13372
|
+
else if (inp.style === "snap" && inp.form === "granules") for (const p of granules(inp, band, clamp(room, 3, 12))) out.push(p);
|
|
13373
|
+
else if (inp.style === "snap") {
|
|
13374
|
+
for (const b2 of bsp(band, Math.max(3, Math.min(6, room)), [0, 1, 2], inp.rnd)) out.push({ center: b2.c, size: b2.s, q: quat.identity(), shape: "chunk", weight: b2.s[0] * b2.s[1] * b2.s[2] });
|
|
13295
13375
|
} else for (const p of splinterBox(inp, band, Math.max(3, inp.maxFragments - out.length))) out.push(p);
|
|
13296
13376
|
return out;
|
|
13297
13377
|
};
|
|
@@ -13324,8 +13404,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
13324
13404
|
const [u, v] = [sorted[1], sorted[2]].sort((a, b) => a - b);
|
|
13325
13405
|
if (style === "snap") {
|
|
13326
13406
|
if (inp.cut) return severAt(inp, root, inp.cut.at, inp.cut.gap);
|
|
13407
|
+
if (inp.form === "plies") return plyBreak(inp, root, maxFragments);
|
|
13327
13408
|
const n2 = Math.min(maxFragments, 2 + Math.floor(rnd() * 3));
|
|
13328
13409
|
for (const b of bsp(root, n2, [0, 1, 2], rnd)) out.push({ center: b.c, size: b.s, q: idq, shape: "slab", weight: b.s[0] * b.s[1] * b.s[2] });
|
|
13410
|
+
if (inp.form !== "granules") return out;
|
|
13411
|
+
const crumbs = Math.min(CRUMBS, maxFragments - out.length);
|
|
13412
|
+
if (crumbs <= 0) return out;
|
|
13413
|
+
const band = { c: [0, 0, 0], s: [0, 0, 0] };
|
|
13414
|
+
for (let i = 0; i < 3; i++) {
|
|
13415
|
+
band.s[i] = Math.min(dims[i], Math.max(fmin, dims[i] * 0.2));
|
|
13416
|
+
band.c[i] = clamp(inp.hit[i], -dims[i] / 2 + band.s[i] / 2, dims[i] / 2 - band.s[i] / 2);
|
|
13417
|
+
}
|
|
13418
|
+
for (const p of granules(inp, band, crumbs)) out.push({ ...p, weight: p.weight * 0.5 });
|
|
13329
13419
|
return out;
|
|
13330
13420
|
}
|
|
13331
13421
|
if (style === "crumble" || style === "none") {
|
|
@@ -13432,6 +13522,88 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
13432
13522
|
}
|
|
13433
13523
|
return marks;
|
|
13434
13524
|
};
|
|
13525
|
+
var JOINT_GAP = 1e-4;
|
|
13526
|
+
var MIN_BEARING_SHARE = 0.25;
|
|
13527
|
+
var unsupportedCells = (cells, thin, dims, standing) => {
|
|
13528
|
+
if (thin === 1) return [];
|
|
13529
|
+
const [u, v] = planeAxes(thin);
|
|
13530
|
+
const bottom = -dims[v] / 2;
|
|
13531
|
+
const rowOf = (y) => Math.round((y - bottom) * 1e4);
|
|
13532
|
+
const rows = /* @__PURE__ */ new Map();
|
|
13533
|
+
for (let i = 0; i < cells.length; i++) {
|
|
13534
|
+
if (!standing(i)) continue;
|
|
13535
|
+
const cell = cells[i];
|
|
13536
|
+
const key2 = rowOf(cell.center[v] - cell.size[v] / 2);
|
|
13537
|
+
const row = rows.get(key2);
|
|
13538
|
+
if (row) row.push(i);
|
|
13539
|
+
else rows.set(key2, [i]);
|
|
13540
|
+
}
|
|
13541
|
+
const held = /* @__PURE__ */ new Set();
|
|
13542
|
+
const queue = [];
|
|
13543
|
+
for (const i of rows.get(0) ?? []) {
|
|
13544
|
+
held.add(i);
|
|
13545
|
+
queue.push(i);
|
|
13546
|
+
}
|
|
13547
|
+
const overlap = (a, b) => Math.min(a.center[u] + a.size[u] / 2, b.center[u] + b.size[u] / 2) - Math.max(a.center[u] - a.size[u] / 2, b.center[u] - b.size[u] / 2);
|
|
13548
|
+
const climb = () => {
|
|
13549
|
+
while (queue.length > 0) {
|
|
13550
|
+
const cell = cells[queue.pop()];
|
|
13551
|
+
for (const j of rows.get(rowOf(cell.center[v] + cell.size[v] / 2)) ?? []) {
|
|
13552
|
+
const other = cells[j];
|
|
13553
|
+
if (held.has(j) || overlap(cell, other) <= Math.max(JOINT_GAP, MIN_BEARING_SHARE * Math.min(cell.size[u], other.size[u]))) continue;
|
|
13554
|
+
held.add(j);
|
|
13555
|
+
queue.push(j);
|
|
13556
|
+
}
|
|
13557
|
+
}
|
|
13558
|
+
};
|
|
13559
|
+
for (const row of rows.values()) row.sort((a, b) => cells[a].center[u] - cells[b].center[u]);
|
|
13560
|
+
const touching = (a, b) => Math.abs(a.center[u] + a.size[u] / 2 - (b.center[u] - b.size[u] / 2)) <= 1e-3;
|
|
13561
|
+
for (let wedged = true; wedged; ) {
|
|
13562
|
+
climb();
|
|
13563
|
+
wedged = false;
|
|
13564
|
+
for (const row of rows.values()) {
|
|
13565
|
+
for (let k = 1; k < row.length - 1; k++) {
|
|
13566
|
+
const i = row[k];
|
|
13567
|
+
if (held.has(i) || !held.has(row[k - 1]) || !held.has(row[k + 1])) continue;
|
|
13568
|
+
if (!touching(cells[row[k - 1]], cells[i]) || !touching(cells[i], cells[row[k + 1]])) continue;
|
|
13569
|
+
held.add(i);
|
|
13570
|
+
queue.push(i);
|
|
13571
|
+
wedged = true;
|
|
13572
|
+
}
|
|
13573
|
+
}
|
|
13574
|
+
}
|
|
13575
|
+
const loose = [];
|
|
13576
|
+
for (const row of rows.values()) for (const i of row) if (!held.has(i)) loose.push(i);
|
|
13577
|
+
return loose;
|
|
13578
|
+
};
|
|
13579
|
+
var clumpCells = (cells, thin, cap) => {
|
|
13580
|
+
if (cells.length <= cap) return [...cells];
|
|
13581
|
+
const [u, v] = planeAxes(thin);
|
|
13582
|
+
let lo0 = Infinity, lo1 = Infinity, hi0 = -Infinity, hi1 = -Infinity;
|
|
13583
|
+
for (const cell of cells) {
|
|
13584
|
+
lo0 = Math.min(lo0, cell.center[u] - cell.size[u] / 2);
|
|
13585
|
+
hi0 = Math.max(hi0, cell.center[u] + cell.size[u] / 2);
|
|
13586
|
+
lo1 = Math.min(lo1, cell.center[v] - cell.size[v] / 2);
|
|
13587
|
+
hi1 = Math.max(hi1, cell.center[v] + cell.size[v] / 2);
|
|
13588
|
+
}
|
|
13589
|
+
let side = Math.sqrt((hi0 - lo0) * (hi1 - lo1) / cap);
|
|
13590
|
+
for (; ; ) {
|
|
13591
|
+
const bins = /* @__PURE__ */ new Map();
|
|
13592
|
+
for (const cell of cells) {
|
|
13593
|
+
const key2 = `${Math.floor((cell.center[u] - lo0) / side)}:${Math.floor((cell.center[v] - lo1) / side)}`;
|
|
13594
|
+
const bin = bins.get(key2) ?? { lo: [Infinity, Infinity, Infinity], hi: [-Infinity, -Infinity, -Infinity] };
|
|
13595
|
+
for (let k = 0; k < 3; k++) {
|
|
13596
|
+
bin.lo[k] = Math.min(bin.lo[k], cell.center[k] - cell.size[k] / 2);
|
|
13597
|
+
bin.hi[k] = Math.max(bin.hi[k], cell.center[k] + cell.size[k] / 2);
|
|
13598
|
+
}
|
|
13599
|
+
bins.set(key2, bin);
|
|
13600
|
+
}
|
|
13601
|
+
if (bins.size <= cap) {
|
|
13602
|
+
return [...bins.values()].map(({ lo, hi }) => ({ center: [(lo[0] + hi[0]) / 2, (lo[1] + hi[1]) / 2, (lo[2] + hi[2]) / 2], size: [hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]] }));
|
|
13603
|
+
}
|
|
13604
|
+
side *= 1.25;
|
|
13605
|
+
}
|
|
13606
|
+
};
|
|
13435
13607
|
var MAX_SPALLS = 64;
|
|
13436
13608
|
var thinAxisOf = (dims) => dims[0] <= dims[1] && dims[0] <= dims[2] ? 0 : dims[1] <= dims[2] ? 1 : 2;
|
|
13437
13609
|
var resolveLayer = (def, index, mat) => ({ index, def, mat, energy: mat.penetration * def.thickness * 1e3 });
|
|
@@ -14411,6 +14583,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14411
14583
|
},
|
|
14412
14584
|
{
|
|
14413
14585
|
id: "wood_soft",
|
|
14586
|
+
splitForm: "slivers",
|
|
14414
14587
|
density: 500,
|
|
14415
14588
|
hpPerKg: 90,
|
|
14416
14589
|
penetration: 9,
|
|
@@ -14456,6 +14629,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14456
14629
|
},
|
|
14457
14630
|
{
|
|
14458
14631
|
id: "wood_hard",
|
|
14632
|
+
splitForm: "slivers",
|
|
14459
14633
|
density: 750,
|
|
14460
14634
|
hpPerKg: 140,
|
|
14461
14635
|
penetration: 14,
|
|
@@ -14500,6 +14674,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14500
14674
|
},
|
|
14501
14675
|
{
|
|
14502
14676
|
id: "plywood",
|
|
14677
|
+
splitForm: "plies",
|
|
14503
14678
|
density: 600,
|
|
14504
14679
|
hpPerKg: 70,
|
|
14505
14680
|
penetration: 7,
|
|
@@ -14547,6 +14722,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14547
14722
|
},
|
|
14548
14723
|
{
|
|
14549
14724
|
id: "mdf",
|
|
14725
|
+
splitForm: "granules",
|
|
14550
14726
|
density: 750,
|
|
14551
14727
|
hpPerKg: 45,
|
|
14552
14728
|
penetration: 6,
|
|
@@ -14713,6 +14889,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14713
14889
|
floor: 60
|
|
14714
14890
|
}
|
|
14715
14891
|
},
|
|
14892
|
+
ricochetDeg: 12,
|
|
14716
14893
|
hitDebris: "chips",
|
|
14717
14894
|
breakDebris: "dust",
|
|
14718
14895
|
visual: { innerColor: 10197652 },
|
|
@@ -14744,6 +14921,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14744
14921
|
0.04,
|
|
14745
14922
|
0.12
|
|
14746
14923
|
],
|
|
14924
|
+
ricochetDeg: 10,
|
|
14747
14925
|
hitDebris: "chips",
|
|
14748
14926
|
breakDebris: "dust",
|
|
14749
14927
|
visual: { innerColor: 12085567 },
|
|
@@ -14801,6 +14979,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14801
14979
|
0.06,
|
|
14802
14980
|
0.3
|
|
14803
14981
|
],
|
|
14982
|
+
ricochetDeg: 15,
|
|
14804
14983
|
hitDebris: "chips",
|
|
14805
14984
|
breakDebris: "dust",
|
|
14806
14985
|
visual: { innerColor: 9407364 },
|
|
@@ -15058,6 +15237,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15058
15237
|
},
|
|
15059
15238
|
{
|
|
15060
15239
|
id: "green_wood",
|
|
15240
|
+
splitForm: "slivers",
|
|
15061
15241
|
density: 650,
|
|
15062
15242
|
hpPerKg: 5,
|
|
15063
15243
|
penetration: 10,
|
|
@@ -15228,6 +15408,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15228
15408
|
0.03,
|
|
15229
15409
|
0.15
|
|
15230
15410
|
],
|
|
15411
|
+
ricochetDeg: 8,
|
|
15231
15412
|
hitDebris: "chips",
|
|
15232
15413
|
breakDebris: "dust",
|
|
15233
15414
|
thermal: {
|
|
@@ -15327,6 +15508,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15327
15508
|
0.02,
|
|
15328
15509
|
0.08
|
|
15329
15510
|
],
|
|
15511
|
+
ricochetDeg: 8,
|
|
15330
15512
|
hitDebris: "chips",
|
|
15331
15513
|
breakDebris: "dust",
|
|
15332
15514
|
thermal: {
|
|
@@ -15338,6 +15520,127 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15338
15520
|
"brittle"
|
|
15339
15521
|
],
|
|
15340
15522
|
compressive: 1e5
|
|
15523
|
+
},
|
|
15524
|
+
{
|
|
15525
|
+
id: "mud",
|
|
15526
|
+
density: 1700,
|
|
15527
|
+
hpPerKg: 1,
|
|
15528
|
+
penetration: 5,
|
|
15529
|
+
ductility: 0.8,
|
|
15530
|
+
fracture: "crumble",
|
|
15531
|
+
fragmentSize: [
|
|
15532
|
+
0.02,
|
|
15533
|
+
0.08
|
|
15534
|
+
],
|
|
15535
|
+
hitDebris: "dust",
|
|
15536
|
+
breakDebris: "dust",
|
|
15537
|
+
thermal: {
|
|
15538
|
+
conductivity: 0.5,
|
|
15539
|
+
heatCapacity: 3.2
|
|
15540
|
+
},
|
|
15541
|
+
tags: [
|
|
15542
|
+
"soil",
|
|
15543
|
+
"wet"
|
|
15544
|
+
],
|
|
15545
|
+
compressive: 5e3
|
|
15546
|
+
},
|
|
15547
|
+
{
|
|
15548
|
+
id: "clay",
|
|
15549
|
+
density: 1800,
|
|
15550
|
+
hpPerKg: 5,
|
|
15551
|
+
penetration: 7,
|
|
15552
|
+
ductility: 0.05,
|
|
15553
|
+
fracture: "crumble",
|
|
15554
|
+
fragmentSize: [
|
|
15555
|
+
0.02,
|
|
15556
|
+
0.1
|
|
15557
|
+
],
|
|
15558
|
+
hitDebris: "chips",
|
|
15559
|
+
breakDebris: "dust",
|
|
15560
|
+
thermal: {
|
|
15561
|
+
conductivity: 0.15,
|
|
15562
|
+
heatCapacity: 2.2
|
|
15563
|
+
},
|
|
15564
|
+
tags: [
|
|
15565
|
+
"soil",
|
|
15566
|
+
"brittle"
|
|
15567
|
+
],
|
|
15568
|
+
compressive: 6e4
|
|
15569
|
+
},
|
|
15570
|
+
{
|
|
15571
|
+
id: "snow",
|
|
15572
|
+
density: 300,
|
|
15573
|
+
hpPerKg: 1,
|
|
15574
|
+
penetration: 3,
|
|
15575
|
+
ductility: 0.6,
|
|
15576
|
+
fracture: "crumble",
|
|
15577
|
+
fragmentSize: [
|
|
15578
|
+
0.01,
|
|
15579
|
+
0.05
|
|
15580
|
+
],
|
|
15581
|
+
hitDebris: "dust",
|
|
15582
|
+
breakDebris: "dust",
|
|
15583
|
+
thermal: {
|
|
15584
|
+
conductivity: 0.1,
|
|
15585
|
+
heatCapacity: 2.1
|
|
15586
|
+
},
|
|
15587
|
+
tags: [
|
|
15588
|
+
"soil",
|
|
15589
|
+
"frozen"
|
|
15590
|
+
],
|
|
15591
|
+
compressive: 1e3
|
|
15592
|
+
},
|
|
15593
|
+
{
|
|
15594
|
+
id: "cobble",
|
|
15595
|
+
density: 2650,
|
|
15596
|
+
hpPerKg: 25,
|
|
15597
|
+
penetration: 25,
|
|
15598
|
+
penetrationClass: "concrete",
|
|
15599
|
+
penetrationScale: 0.9,
|
|
15600
|
+
ductility: 0.03,
|
|
15601
|
+
fracture: "crumble",
|
|
15602
|
+
fragmentSize: [
|
|
15603
|
+
0.05,
|
|
15604
|
+
0.15
|
|
15605
|
+
],
|
|
15606
|
+
ricochetDeg: 15,
|
|
15607
|
+
hitDebris: "chips",
|
|
15608
|
+
breakDebris: "chips",
|
|
15609
|
+
thermal: {
|
|
15610
|
+
conductivity: 0.2,
|
|
15611
|
+
heatCapacity: 2.5
|
|
15612
|
+
},
|
|
15613
|
+
tags: [
|
|
15614
|
+
"masonry",
|
|
15615
|
+
"brittle"
|
|
15616
|
+
],
|
|
15617
|
+
compressive: 3e5
|
|
15618
|
+
},
|
|
15619
|
+
{
|
|
15620
|
+
id: "paver",
|
|
15621
|
+
density: 2300,
|
|
15622
|
+
hpPerKg: 14,
|
|
15623
|
+
penetration: 18,
|
|
15624
|
+
penetrationClass: "concrete",
|
|
15625
|
+
penetrationScale: 1,
|
|
15626
|
+
ductility: 0.03,
|
|
15627
|
+
fracture: "crumble",
|
|
15628
|
+
fragmentSize: [
|
|
15629
|
+
0.04,
|
|
15630
|
+
0.12
|
|
15631
|
+
],
|
|
15632
|
+
ricochetDeg: 12,
|
|
15633
|
+
hitDebris: "chips",
|
|
15634
|
+
breakDebris: "chips",
|
|
15635
|
+
thermal: {
|
|
15636
|
+
conductivity: 0.15,
|
|
15637
|
+
heatCapacity: 2.5
|
|
15638
|
+
},
|
|
15639
|
+
tags: [
|
|
15640
|
+
"masonry",
|
|
15641
|
+
"brittle"
|
|
15642
|
+
],
|
|
15643
|
+
compressive: 35e4
|
|
15341
15644
|
}
|
|
15342
15645
|
];
|
|
15343
15646
|
var material_hints_default = {
|
|
@@ -15550,6 +15853,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15550
15853
|
var BREACH_BLAST_FACTOR = 6;
|
|
15551
15854
|
var BREACH_AREA = 0.25;
|
|
15552
15855
|
var BREACH_BLAST_REACH = 0.12;
|
|
15856
|
+
var MEMBER_CUT_REACH = 0.5;
|
|
15857
|
+
var BLAST_REFERENCE_RESISTANCE = 200 * 1900 * 0.13;
|
|
15858
|
+
var BLAST_EDGE_RAGGED = 0.3;
|
|
15859
|
+
var BLAST_EDGE_LOOSE = 1.35;
|
|
15860
|
+
var BLAST_EDGE_WEAR = 0.6;
|
|
15553
15861
|
var RESIDUAL_CAPACITY = 0.15;
|
|
15554
15862
|
var SEVER_BAND = 0.1;
|
|
15555
15863
|
var SEVER_ASPECT = 3;
|
|
@@ -16802,7 +17110,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16802
17110
|
if (j.st.open) continue;
|
|
16803
17111
|
if (j.spec.kind === "rebar" && (isReinforced(o.parts[j.ia].spec) || isReinforced(o.parts[j.ib].spec))) continue;
|
|
16804
17112
|
if (near && jointReach(o, j, near) > Math.max(radius, jointReachLimit(o, j))) continue;
|
|
16805
|
-
j.st.hp -= span === void 0 ? amount : amount * Math.min(1, span / Math.max(jointLength(o, j), 1e-6));
|
|
17113
|
+
j.st.hp -= span === void 0 ? amount : Math.min(amount, j.st.maxHp) * Math.min(1, span / Math.max(jointLength(o, j), 1e-6));
|
|
16806
17114
|
if (j.st.hp <= 0) {
|
|
16807
17115
|
j.st.hp = 0;
|
|
16808
17116
|
j.st.open = true;
|
|
@@ -16930,6 +17238,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16930
17238
|
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
16931
17239
|
const cut = (_b = p.rt).craters ?? (_b.craters = {});
|
|
16932
17240
|
const out = [];
|
|
17241
|
+
const wholeBefore = Object.values(worn).filter((w) => w === -1).length;
|
|
16933
17242
|
const shot = kind === "ballistic";
|
|
16934
17243
|
for (let i = 0; i < grid.length; i++) {
|
|
16935
17244
|
const cell = grid[i];
|
|
@@ -16988,6 +17297,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16988
17297
|
emit({ ...base(o, src), type: "chip", part: p.spec.id, center, size: [cell.size[0], cell.size[1], cell.size[2]], rotation: q, fragments });
|
|
16989
17298
|
debris(o, p, p.mat.breakDebris, center, vec.scale(dir ?? [0, 1, 0], -1), 6, 2, src);
|
|
16990
17299
|
}
|
|
17300
|
+
if (Object.values(worn).filter((w) => w === -1).length > wholeBefore) dropUnsupported(o, p, src);
|
|
16991
17301
|
if (p.spec.reinforcement) exposeRebar(o, p, src);
|
|
16992
17302
|
for (const cell of out) addBreach(o, p, toWorld(c, q, cell.center), cell.size[u] * cell.size[v], energy, dir, src);
|
|
16993
17303
|
if (p.structural && !isLost(p)) {
|
|
@@ -17091,10 +17401,122 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17091
17401
|
setStage(o, p, 1, {}, src);
|
|
17092
17402
|
setStage(o, p, 2, { opening: { center: worldCenter, radius }, fragments }, src);
|
|
17093
17403
|
debris(o, p, p.mat.breakDebris, worldCenter, vec.scale(dir ?? [0, 1, 0], -1), 14, 3, src);
|
|
17404
|
+
dropUnsupported(o, p, src);
|
|
17094
17405
|
const reinforcement = p.spec.reinforcement;
|
|
17095
17406
|
if (reinforcement) exposeRebar(o, p, src);
|
|
17096
17407
|
if (p.structural) solveStructure(o);
|
|
17097
17408
|
};
|
|
17409
|
+
const blastReachOf = (p, energy) => {
|
|
17410
|
+
const perKg = p.mat.hits?.blunt?.unitJoules ?? chipEnergy;
|
|
17411
|
+
const resistance = Math.max(1, perKg * p.mat.density * p.thickness);
|
|
17412
|
+
return BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3) * clamp2(Math.cbrt(BLAST_REFERENCE_RESISTANCE / resistance), 0.3, 2);
|
|
17413
|
+
};
|
|
17414
|
+
const blastUnits = (o, p, wp, energy, dist, src) => {
|
|
17415
|
+
var _a, _b;
|
|
17416
|
+
if (!p.staged || p.st.stripped || isLost(p) || chipEnergy <= 0) return false;
|
|
17417
|
+
const reach = blastReachOf(p, energy);
|
|
17418
|
+
if (dist >= reach) return false;
|
|
17419
|
+
const radius = Math.sqrt(reach * reach - dist * dist);
|
|
17420
|
+
const [u, v] = planeAxes(p.thin);
|
|
17421
|
+
const lp = toLocal(p.pos, p.q, objLocal(o, wp));
|
|
17422
|
+
const op = p.st.opening ? toLocal(p.pos, p.q, p.st.opening.center) : null;
|
|
17423
|
+
const grid = gridOf(p);
|
|
17424
|
+
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
17425
|
+
const perKg = p.mat.hits?.blunt?.unitJoules ?? chipEnergy;
|
|
17426
|
+
const lobes = [rnd() * 2 * Math.PI, rnd() * 2 * Math.PI];
|
|
17427
|
+
const out = [];
|
|
17428
|
+
for (let i = 0; i < grid.length; i++) {
|
|
17429
|
+
const cell = grid[i];
|
|
17430
|
+
if (worn[i] === -1) continue;
|
|
17431
|
+
if (op && p.st.opening && Math.hypot(cell.center[u] - op[u], cell.center[v] - op[v]) <= p.st.opening.radius) continue;
|
|
17432
|
+
const du = cell.center[u] - lp[u], dv = cell.center[v] - lp[v];
|
|
17433
|
+
const angle = Math.atan2(dv, du);
|
|
17434
|
+
const edge = radius * (1 + BLAST_EDGE_RAGGED * (0.5 * Math.sin(3 * angle + lobes[0]) + 0.3 * Math.sin(5 * angle + lobes[1]) + 0.4 * (rnd() - 0.5)));
|
|
17435
|
+
const d = Math.hypot(du, dv);
|
|
17436
|
+
if (d <= edge) {
|
|
17437
|
+
worn[i] = -1;
|
|
17438
|
+
out.push(i);
|
|
17439
|
+
} else if (d <= edge * BLAST_EDGE_LOOSE) {
|
|
17440
|
+
const mass = p.mat.density * cell.size[0] * cell.size[1] * cell.size[2];
|
|
17441
|
+
worn[i] = Math.max(worn[i] ?? 0, perKg * mass * BLAST_EDGE_WEAR);
|
|
17442
|
+
}
|
|
17443
|
+
}
|
|
17444
|
+
if (out.length === 0) return false;
|
|
17445
|
+
const loose = unsupportedCells(grid, p.thin, p.dims, (i) => worn[i] !== -1 && !(op && p.st.opening && Math.hypot(grid[i].center[u] - op[u], grid[i].center[v] - op[v]) <= p.st.opening.radius));
|
|
17446
|
+
for (const i of loose) worn[i] = -1;
|
|
17447
|
+
const blown = out.map((i) => grid[i]), fallen = loose.map((i) => grid[i]);
|
|
17448
|
+
const volume = (cells2) => cells2.reduce((sum, cell) => sum + cell.size[0] * cell.size[1] * cell.size[2], 0);
|
|
17449
|
+
const blownMass = Math.min(p.st.mass, p.mat.density * volume(blown));
|
|
17450
|
+
const fallenMass = Math.min(p.st.mass - blownMass, p.mat.density * volume(fallen));
|
|
17451
|
+
const speed = clamp2(Math.sqrt(2 * energy * 0.02 / Math.max(blownMass, 0.05)), 1, 12);
|
|
17452
|
+
const { c, q } = partXf(o, p);
|
|
17453
|
+
const chipped = (_b = p.st).chipped ?? (_b.chipped = []);
|
|
17454
|
+
const tag = `x${chipped.length}_`;
|
|
17455
|
+
const fragments = [
|
|
17456
|
+
...cellFragments(o, p, clumpCells(blown, p.thin, maxFragments), wp, null, speed, blownMass, tag, true),
|
|
17457
|
+
...fallen.length > 0 ? cellFragments(o, p, clumpCells(fallen, p.thin, Math.max(2, Math.round(maxFragments / 4))), wp, null, 0.3, fallenMass, `${tag}f`, true) : []
|
|
17458
|
+
];
|
|
17459
|
+
const cells = [...blown, ...fallen];
|
|
17460
|
+
const holes = localHolesOf(p);
|
|
17461
|
+
p.st.holes = p.st.holes.filter((_, k) => !cells.some((cell) => marksInBox(cell.center, cell.size, void 0, [holes[k]]).length > 0));
|
|
17462
|
+
const lo = [Infinity, Infinity, Infinity], hi = [-Infinity, -Infinity, -Infinity];
|
|
17463
|
+
for (const cell of cells) {
|
|
17464
|
+
chipped.push({ center: [cell.center[0], cell.center[1], cell.center[2]], size: [cell.size[0], cell.size[1], cell.size[2]] });
|
|
17465
|
+
for (let k = 0; k < 3; k++) {
|
|
17466
|
+
lo[k] = Math.min(lo[k], cell.center[k] - cell.size[k] / 2);
|
|
17467
|
+
hi[k] = Math.max(hi[k], cell.center[k] + cell.size[k] / 2);
|
|
17468
|
+
}
|
|
17469
|
+
}
|
|
17470
|
+
p.st.mass = Math.max(0, p.st.mass - blownMass - fallenMass);
|
|
17471
|
+
p.rt.removed = (p.rt.removed ?? 0) + blownMass + fallenMass;
|
|
17472
|
+
markDamaged(p);
|
|
17473
|
+
setStage(o, p, 1, {}, src);
|
|
17474
|
+
const center = toWorld(c, q, [(lo[0] + hi[0]) / 2, (lo[1] + hi[1]) / 2, (lo[2] + hi[2]) / 2]);
|
|
17475
|
+
const units = cells.map((cell) => ({ center: toWorld(c, q, cell.center), size: [cell.size[0], cell.size[1], cell.size[2]] }));
|
|
17476
|
+
emit({ ...base(o, src), type: "chip", part: p.spec.id, center, size: [hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]], rotation: q, fragments, units });
|
|
17477
|
+
debris(o, p, p.mat.breakDebris, center, vec.normalize(vec.sub(center, wp), [0, 1, 0]), 14, 3, src);
|
|
17478
|
+
if (p.spec.reinforcement) exposeRebar(o, p, src);
|
|
17479
|
+
if (p.structural && !isLost(p)) {
|
|
17480
|
+
solveStructure(o);
|
|
17481
|
+
collapseCheck(o, src);
|
|
17482
|
+
}
|
|
17483
|
+
return true;
|
|
17484
|
+
};
|
|
17485
|
+
const dropUnsupported = (o, p, src) => {
|
|
17486
|
+
var _a, _b;
|
|
17487
|
+
if (!p.spec.units || p.spec.units.mortar === p.spec.material || p.st.stripped || isLost(p)) return 0;
|
|
17488
|
+
const [u, v] = planeAxes(p.thin);
|
|
17489
|
+
const grid = gridOf(p);
|
|
17490
|
+
const worn = (_a = p.rt).chips ?? (_a.chips = {});
|
|
17491
|
+
const op = p.st.opening ? toLocal(p.pos, p.q, p.st.opening.center) : null;
|
|
17492
|
+
const opened = (cell) => !!op && !!p.st.opening && Math.hypot(cell.center[u] - op[u], cell.center[v] - op[v]) <= p.st.opening.radius;
|
|
17493
|
+
const loose = unsupportedCells(grid, p.thin, p.dims, (i) => worn[i] !== -1 && !opened(grid[i]));
|
|
17494
|
+
if (loose.length === 0) return 0;
|
|
17495
|
+
for (const i of loose) worn[i] = -1;
|
|
17496
|
+
const fallen = loose.map((i) => grid[i]);
|
|
17497
|
+
const mass = Math.min(p.st.mass, p.mat.density * fallen.reduce((sum, cell) => sum + cell.size[0] * cell.size[1] * cell.size[2], 0));
|
|
17498
|
+
const { c, q } = partXf(o, p);
|
|
17499
|
+
const chipped = (_b = p.st).chipped ?? (_b.chipped = []);
|
|
17500
|
+
const lo = [Infinity, Infinity, Infinity], hi = [-Infinity, -Infinity, -Infinity];
|
|
17501
|
+
for (const cell of fallen) {
|
|
17502
|
+
for (let k = 0; k < 3; k++) {
|
|
17503
|
+
lo[k] = Math.min(lo[k], cell.center[k] - cell.size[k] / 2);
|
|
17504
|
+
hi[k] = Math.max(hi[k], cell.center[k] + cell.size[k] / 2);
|
|
17505
|
+
}
|
|
17506
|
+
}
|
|
17507
|
+
const center = toWorld(c, q, [(lo[0] + hi[0]) / 2, (lo[1] + hi[1]) / 2, (lo[2] + hi[2]) / 2]);
|
|
17508
|
+
const fragments = cellFragments(o, p, clumpCells(fallen, p.thin, Math.max(2, Math.round(maxFragments / 4))), vec.add(center, [0, 1, 0]), null, 0.3, mass, `u${chipped.length}_`, true);
|
|
17509
|
+
const holes = localHolesOf(p);
|
|
17510
|
+
p.st.holes = p.st.holes.filter((_, k) => !fallen.some((cell) => marksInBox(cell.center, cell.size, void 0, [holes[k]]).length > 0));
|
|
17511
|
+
for (const cell of fallen) chipped.push({ center: [cell.center[0], cell.center[1], cell.center[2]], size: [cell.size[0], cell.size[1], cell.size[2]] });
|
|
17512
|
+
p.st.mass = Math.max(0, p.st.mass - mass);
|
|
17513
|
+
p.rt.removed = (p.rt.removed ?? 0) + mass;
|
|
17514
|
+
markDamaged(p);
|
|
17515
|
+
const units = fallen.map((cell) => ({ center: toWorld(c, q, cell.center), size: [cell.size[0], cell.size[1], cell.size[2]] }));
|
|
17516
|
+
emit({ ...base(o, src), type: "chip", part: p.spec.id, center, size: [hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]], rotation: q, fragments, units });
|
|
17517
|
+
debris(o, p, p.mat.breakDebris, center, [0, -1, 0], 6, 1, src);
|
|
17518
|
+
return loose.length;
|
|
17519
|
+
};
|
|
17098
17520
|
const stripPart = (o, p, reinforcement, src) => {
|
|
17099
17521
|
const bars = rebarBars(p.dims, p.thin, reinforcement.spacing);
|
|
17100
17522
|
p.st.stripped = true;
|
|
@@ -17161,6 +17583,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17161
17583
|
const unitPlan = p.spec.units ? unitFragmentPlan(p, maxFragments * UNIT_FRAGMENT_FACTOR) : [];
|
|
17162
17584
|
const axis = style === "splinter" || style === "snap" ? severAxis(p) : -1;
|
|
17163
17585
|
const cutAt2 = axis < 0 ? void 0 : p.rt.cutAt ?? (origin ? hitLocal[axis] : void 0);
|
|
17586
|
+
const planRnd = p.mat.splitForm ? splitStream(o.id, p.spec.id, hitLocal) : rnd;
|
|
17164
17587
|
const plan = unitPlan.length > 0 ? unitPlan : planFragments({
|
|
17165
17588
|
style,
|
|
17166
17589
|
dims: p.dims,
|
|
@@ -17169,8 +17592,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17169
17592
|
hit: hitLocal,
|
|
17170
17593
|
fragmentSize: p.mat.fragmentSize ?? [0.04, 0.2],
|
|
17171
17594
|
maxFragments,
|
|
17172
|
-
rnd,
|
|
17595
|
+
rnd: planRnd,
|
|
17173
17596
|
sheet: p.mat.sheet,
|
|
17597
|
+
...p.mat.splitForm ? { form: p.mat.splitForm } : {},
|
|
17174
17598
|
...cutAt2 !== void 0 ? { cut: { at: cutAt2, gap: SEVER_BAND } } : {}
|
|
17175
17599
|
});
|
|
17176
17600
|
const holes = p.st.holes.length > 0 ? localHolesOf(p) : [];
|
|
@@ -17309,7 +17733,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17309
17733
|
const fragments = [];
|
|
17310
17734
|
for (let i = 0; i < n; i++) {
|
|
17311
17735
|
const back = !exit || i % 3 === 2;
|
|
17312
|
-
const
|
|
17736
|
+
const plies = p.mat.splitForm === "plies";
|
|
17737
|
+
const len = scale * (fibre ? 1.2 + 1.2 * rnd() : 3 + 4 * rnd()), w = scale * (0.8 + 0.8 * rnd()), t = scale * (fibre ? 0.7 + 0.6 * rnd() : plies ? 0.15 + 0.15 * rnd() : 0.4 + 0.4 * rnd());
|
|
17313
17738
|
const size = [w, w, w];
|
|
17314
17739
|
size[along] = len;
|
|
17315
17740
|
size[(along + 1) % 3] = w;
|
|
@@ -17470,7 +17895,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17470
17895
|
checkIgnite(o, p, src);
|
|
17471
17896
|
}
|
|
17472
17897
|
}
|
|
17473
|
-
wearJoints(o, p, Ein * 0.5, void 0, 0, src);
|
|
17898
|
+
wearJoints(o, p, Ein * 0.5, void 0, 0, src, false, 2 * BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3));
|
|
17474
17899
|
const amount = Ein * DMG_PER_J * (mat.damageScale?.explosive ?? 1);
|
|
17475
17900
|
if (blastFrontSpeed > 0 && dist > 0 && mat.tags?.includes("glass")) {
|
|
17476
17901
|
frontQueue.push({ o, p, due: time + dist / blastFrontSpeed, amount, fragEnergy: Ein * 0.3, point, ...src !== void 0 ? { src } : {} });
|
|
@@ -17480,7 +17905,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17480
17905
|
const dealt = applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
|
|
17481
17906
|
res.damage += dealt;
|
|
17482
17907
|
if (p.bend && flexure.enabled) bendByBlast(o, p, point, energy, radius, reach, src);
|
|
17483
|
-
|
|
17908
|
+
const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
|
|
17909
|
+
if (p.spec.units && p.spec.units.mortar !== p.spec.material) blastUnits(o, p, wp, energy, dist, src);
|
|
17910
|
+
else if (p.spec.reinforcement && p.spec.units && dist > MEMBER_CUT_REACH * breachReach) blastUnits(o, p, wp, energy, dist, src);
|
|
17911
|
+
else if (dist <= breachReach) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
|
|
17484
17912
|
return reach;
|
|
17485
17913
|
};
|
|
17486
17914
|
const blastProbe = { partsTested: 0, partsNear: 0 };
|
|
@@ -17726,6 +18154,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
17726
18154
|
}
|
|
17727
18155
|
return h | 0;
|
|
17728
18156
|
};
|
|
18157
|
+
const splitStream = (objectId, partId, hit) => {
|
|
18158
|
+
const codes = Array.from(`${objectId}|${partId}`, (char) => char.charCodeAt(0) / 1e3);
|
|
18159
|
+
const stream = createRng(seedOf2(rng3.state() / 1e3, ...codes, hit[0], hit[1], hit[2]));
|
|
18160
|
+
return () => stream.next();
|
|
18161
|
+
};
|
|
17729
18162
|
const throwFragment = (frag, objectId, from, g, centre, index, src, shields, results, reports, mult) => {
|
|
17730
18163
|
const v = frag.velocity;
|
|
17731
18164
|
const speed = Math.hypot(v[0], v[1], v[2]);
|
|
@@ -19021,7 +19454,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19021
19454
|
var DEFAULT_DENSITY = 500;
|
|
19022
19455
|
var densityOf = (material) => DENSITY[material] ?? DEFAULT_DENSITY;
|
|
19023
19456
|
var OPEN_ROOM_TYPES = ["balcony", "terrace", "porch"];
|
|
19457
|
+
var WALL_PILLAR_SIDE = 0.2;
|
|
19458
|
+
var HALF = WALL_PILLAR_SIDE / 2;
|
|
19024
19459
|
var CLOSED_ONLY = [...OPEN_ROOM_TYPES, "void"];
|
|
19460
|
+
var HALF_PILLAR = WALL_PILLAR_SIDE / 2;
|
|
19025
19461
|
var entry = (itemId, min, max, group, pickable, weight) => ({ itemId, min, max, group, pickable, weight });
|
|
19026
19462
|
var FRIDGE = [
|
|
19027
19463
|
entry("water_bottle", 1, 3, "water", true, 3),
|
|
@@ -19756,6 +20192,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19756
20192
|
}
|
|
19757
20193
|
var LINTEL_DEPTH2 = 0.2;
|
|
19758
20194
|
var LINTEL_BEARING2 = 0.2;
|
|
20195
|
+
var SILL_BEAM_DEPTH = 0.1;
|
|
20196
|
+
var LINTEL_SPAN_RATIO = 10;
|
|
19759
20197
|
var MIN_PIECE = 0.05;
|
|
19760
20198
|
var frameOf = (wall) => {
|
|
19761
20199
|
const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1];
|
|
@@ -19769,6 +20207,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19769
20207
|
const drafts = [];
|
|
19770
20208
|
const piers = [];
|
|
19771
20209
|
const lintels = [];
|
|
20210
|
+
const sillBeams = [];
|
|
19772
20211
|
const spandrels = [];
|
|
19773
20212
|
const height = wall.y1 - wall.y0;
|
|
19774
20213
|
let cursor = frame2.from;
|
|
@@ -19779,23 +20218,26 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19779
20218
|
};
|
|
19780
20219
|
own.forEach((opening2, k) => {
|
|
19781
20220
|
addPier(Math.max(cursor, opening2.from));
|
|
19782
|
-
const
|
|
20221
|
+
const span = opening2.to - opening2.from;
|
|
20222
|
+
const lintelTop = Math.min(wall.y1, opening2.y1 + Math.max(LINTEL_DEPTH2, style.lintelDepth?.(span) ?? 0, (span + LINTEL_BEARING2) / LINTEL_SPAN_RATIO));
|
|
19783
20223
|
const lintelFrom = Math.max(frame2.from, opening2.from - LINTEL_BEARING2);
|
|
19784
20224
|
const lintelTo = Math.min(frame2.to, opening2.to + LINTEL_BEARING2);
|
|
19785
20225
|
const lintelHeight = lintelTop - opening2.y1;
|
|
19786
|
-
|
|
20226
|
+
const sillTop = style.sillBeam && opening2.y0 - wall.y0 > SILL_BEAM_DEPTH + MIN_PIECE ? opening2.y0 - SILL_BEAM_DEPTH : opening2.y0;
|
|
20227
|
+
if (sillTop - wall.y0 > MIN_PIECE) drafts.push({ id: `${wall.id}_sill_${k}`, role: "partition", material: wall.material, from: opening2.from, to: opening2.to, y0: wall.y0, y1: sillTop, volume: (opening2.to - opening2.from) * (sillTop - wall.y0) });
|
|
20228
|
+
if (sillTop < opening2.y0) sillBeams.push({ id: `${wall.id}_sillbeam_${k}`, role: "beam", material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: sillTop, y1: opening2.y0, volume: (lintelTo - lintelFrom) * SILL_BEAM_DEPTH });
|
|
19787
20229
|
lintels.push({ id: `${wall.id}_lintel_${k}`, role: "beam", material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: opening2.y1, y1: lintelTop, volume: (lintelTo - lintelFrom) * lintelHeight });
|
|
19788
20230
|
spandrels.push(wall.y1 - lintelTop > MIN_PIECE ? { id: `${wall.id}_spandrel_${k}`, role: roleOf2, material: wall.material, from: opening2.from, to: opening2.to, y0: lintelTop, y1: wall.y1, volume: (opening2.to - opening2.from) * (wall.y1 - lintelTop) } : void 0);
|
|
19789
20231
|
cursor = opening2.to;
|
|
19790
20232
|
});
|
|
19791
20233
|
addPier(frame2.to);
|
|
19792
20234
|
for (const pier of piers) {
|
|
19793
|
-
for (const lintel of lintels) {
|
|
20235
|
+
for (const lintel of [...lintels, ...sillBeams]) {
|
|
19794
20236
|
const overlap = Math.max(0, Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from));
|
|
19795
20237
|
pier.volume -= overlap * (lintel.y1 - lintel.y0);
|
|
19796
20238
|
}
|
|
19797
20239
|
}
|
|
19798
|
-
const all = [...piers, ...drafts, ...lintels, ...spandrels.filter((d) => d !== void 0)];
|
|
20240
|
+
const all = [...piers, ...drafts, ...sillBeams, ...lintels, ...spandrels.filter((d) => d !== void 0)];
|
|
19799
20241
|
const total = all.reduce((sum, d) => sum + d.volume, 0);
|
|
19800
20242
|
const pieces = all.map((d) => ({
|
|
19801
20243
|
id: d.id,
|
|
@@ -19810,6 +20252,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19810
20252
|
...d.role === "beam" ? style.lintelAssembly ? { assembly: style.lintelAssembly } : {} : wall.assembly ? { assembly: wall.assembly } : {}
|
|
19811
20253
|
}));
|
|
19812
20254
|
const internal = [];
|
|
20255
|
+
for (const beam of sillBeams) {
|
|
20256
|
+
const sill = drafts.find((d) => d.id === beam.id.replace("_sillbeam_", "_sill_"));
|
|
20257
|
+
if (sill) internal.push({ part: beam.id, on: sill.id, joint: style.lintelJoint });
|
|
20258
|
+
for (const pier of piers) if (Math.min(pier.to, beam.to) - Math.max(pier.from, beam.from) > 0) internal.push({ part: beam.id, on: pier.id, joint: style.lintelJoint });
|
|
20259
|
+
}
|
|
19813
20260
|
lintels.forEach((lintel, k) => {
|
|
19814
20261
|
for (const pier of piers) if (Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from) > 0) internal.push({ part: lintel.id, on: pier.id, joint: style.lintelJoint });
|
|
19815
20262
|
const spandrel = spandrels[k];
|
|
@@ -19839,7 +20286,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19839
20286
|
...system.timber ? {} : { lintelAssembly: "reinforced_concrete" },
|
|
19840
20287
|
lintelJoint: system.joints.beam,
|
|
19841
20288
|
wallJoint: system.joints.wall,
|
|
19842
|
-
...lintelDepth && !system.timber ? { lintelDepth } : {}
|
|
20289
|
+
...lintelDepth && !system.timber ? { lintelDepth } : {},
|
|
20290
|
+
...construction.system === "masonry" ? { sillBeam: true } : {}
|
|
19843
20291
|
});
|
|
19844
20292
|
if (split.pieces.length > 1) splits.set(part.id, split);
|
|
19845
20293
|
}
|
|
@@ -19847,7 +20295,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19847
20295
|
}
|
|
19848
20296
|
function applyPanels(input, structure, detail, lintelDepth) {
|
|
19849
20297
|
if (detail === "coarse") return input;
|
|
19850
|
-
return applySplits(input, panelSplits(input, structure, lintelDepth));
|
|
20298
|
+
return onJambPillars(applySplits(input, panelSplits(input, structure, lintelDepth)));
|
|
20299
|
+
}
|
|
20300
|
+
var OPENING_BEAM = /_(lintel|sillbeam)_\d+$/;
|
|
20301
|
+
var overlaps2 = (a, b) => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1];
|
|
20302
|
+
function onJambPillars(split) {
|
|
20303
|
+
const pillars = split.parts.filter((part) => part.role === "column" && part.material === "concrete");
|
|
20304
|
+
const extra = [];
|
|
20305
|
+
for (const beam of split.parts) {
|
|
20306
|
+
if (beam.role !== "beam" || !OPENING_BEAM.test(beam.id)) continue;
|
|
20307
|
+
for (const pillar of pillars) if (pillar.floor === beam.floor && overlaps2(pillar.aabb, beam.aabb) && pillar.y0 <= beam.y0 && pillar.y1 >= beam.y1 - 0.01) extra.push({ part: beam.id, on: pillar.id, joint: "rebar" });
|
|
20308
|
+
}
|
|
20309
|
+
return extra.length ? { parts: split.parts, supports: [...split.supports, ...extra] } : split;
|
|
19851
20310
|
}
|
|
19852
20311
|
function applyUnits(input, structure) {
|
|
19853
20312
|
const splits = /* @__PURE__ */ new Map();
|
|
@@ -19909,21 +20368,35 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19909
20368
|
};
|
|
19910
20369
|
var MEMBER_CAGE = { spacing: 0.1, diameter: 8e-3, unit: 0.1 };
|
|
19911
20370
|
var CAGED_ROLES = /* @__PURE__ */ new Set(["beam", "column"]);
|
|
20371
|
+
var CAGE_COVER = 0.03;
|
|
20372
|
+
var CAGE_BUCKLING_SHARE = 0.5;
|
|
20373
|
+
var DEFAULT_RESIDUAL = 0.15;
|
|
20374
|
+
function cageResidualCapacity(size, reinforcement, capacity) {
|
|
20375
|
+
const [a = 0, b = 0] = [...size].sort((x, y) => x - y);
|
|
20376
|
+
const perSide = (w) => Math.max(2, Math.floor(Math.max(0, w - 2 * CAGE_COVER) / reinforcement.spacing) + 1);
|
|
20377
|
+
const bars = 2 * perSide(a) + 2 * perSide(b) - 4;
|
|
20378
|
+
const steel = MATERIALS2.find((m) => m.id === reinforcement.material)?.compressive ?? 0;
|
|
20379
|
+
const carries2 = bars * Math.PI * (reinforcement.diameter / 2) ** 2 * steel * CAGE_BUCKLING_SHARE;
|
|
20380
|
+
if (!capacity || capacity <= 0 || carries2 <= 0) return DEFAULT_RESIDUAL;
|
|
20381
|
+
return Math.min(1, Math.max(DEFAULT_RESIDUAL, carries2 / capacity));
|
|
20382
|
+
}
|
|
19912
20383
|
var caged = (spec, part, rebar2) => {
|
|
19913
20384
|
if (!rebar2 || part.material !== "concrete" || !CAGED_ROLES.has(part.role) || spec.reinforcement) return spec;
|
|
19914
20385
|
const size = spec.shape.kind === "box" ? spec.shape.size : null;
|
|
19915
20386
|
if (!size) return spec;
|
|
19916
20387
|
const thin = Math.min(...size);
|
|
20388
|
+
const reinforcement = { material: rebar2, spacing: MEMBER_CAGE.spacing, diameter: MEMBER_CAGE.diameter };
|
|
19917
20389
|
return {
|
|
19918
20390
|
...spec,
|
|
19919
|
-
reinforcement: {
|
|
20391
|
+
reinforcement: part.role === "column" ? { ...reinforcement, residualCapacity: cageResidualCapacity(size, reinforcement, spec.structure?.capacity) } : reinforcement,
|
|
19920
20392
|
units: { size: [MEMBER_CAGE.unit, MEMBER_CAGE.unit, thin], bond: "stack", mortar: "concrete" }
|
|
19921
20393
|
};
|
|
19922
20394
|
};
|
|
19923
20395
|
var partSpecOf = (part, capacity, detailed, rebar2) => {
|
|
19924
20396
|
if (detailed && part.assembly) return assemblySpec(part, capacity);
|
|
19925
20397
|
const spec = boxSpec(part, capacity);
|
|
19926
|
-
|
|
20398
|
+
const out = detailed ? caged(spec, part, rebar2) : spec;
|
|
20399
|
+
return part.beamKind === "ground_beam" ? { ...out, anchored: true, structure: { role: "foundation" } } : out;
|
|
19927
20400
|
};
|
|
19928
20401
|
function toDestructibleSpec(structure, options = {}) {
|
|
19929
20402
|
const { safety = 0.65, redundancy = 0.97, safetyOthers = 0.45 } = options;
|
|
@@ -19939,7 +20412,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19939
20412
|
const walled = applyPanels(slabbed, structure, detail, slabOptions && structure.construction.frame.rebar ? (span) => beamDepthFor(span, slabOptions) : void 0);
|
|
19940
20413
|
const panels = slabOptions && detail !== "coarse" ? deepenBondBeams(walled, structure, slabOptions) : walled;
|
|
19941
20414
|
const sizing = { safety, redundancy, safetyOthers };
|
|
19942
|
-
const
|
|
20415
|
+
const foundation = new Set(panels.parts.filter((part) => part.beamKind === "ground_beam").map((part) => part.id));
|
|
20416
|
+
const onFoundation = foundation.size ? panels.supports.filter((s) => !foundation.has(s.part)).map((s) => foundation.has(s.on) ? { ...s, on: GROUND } : s) : panels.supports;
|
|
20417
|
+
const sized = { ...panels, capacities: options.sized === false ? /* @__PURE__ */ new Map() : sizeCapacities(panels.parts.filter((part) => !foundation.has(part.id)), onFoundation, sizing) };
|
|
19943
20418
|
const { parts, supports, capacities } = detail === "units" ? applyUnits(sized, structure) : sized;
|
|
19944
20419
|
const specs = parts.map((part) => partSpecOf(part, capacities.get(part.id), detail !== "coarse", structure.construction.frame.rebar));
|
|
19945
20420
|
const margin = options.terrainMargin ?? TERRAIN_MARGIN;
|
|
@@ -20004,6 +20479,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20004
20479
|
out.parts = out.parts.map((p, i) => i === ground ? raft2 : p);
|
|
20005
20480
|
return out;
|
|
20006
20481
|
}
|
|
20482
|
+
var LOW_WINDOW = SILL_BEAM_DEPTH + 0.05;
|
|
20007
20483
|
var slabId = (g, f) => f === g.floors - 1 && g.roof ? "roof" : `slab_${f}`;
|
|
20008
20484
|
var storeyBase = (g, f) => f * (g.height + g.slab);
|
|
20009
20485
|
var slabHalf = (g) => [(g.spanX + g.columnSize + 0.2) / 2, (g.spanZ + g.columnSize + 0.2) / 2];
|
|
@@ -20162,7 +20638,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20162
20638
|
parts.push({ id, material: c.material, shape: box3(size), position, structure: { role: "partition" }, tags: ["infill"] });
|
|
20163
20639
|
for (const o of on) rests(joints, id, o, "mortar");
|
|
20164
20640
|
};
|
|
20165
|
-
const bay = (side, k, along,
|
|
20641
|
+
const bay = (side, k, along, centre2, fixed, length, c1, c2) => {
|
|
20166
20642
|
const clear = length - g.columnSize;
|
|
20167
20643
|
const win = clear * c.window;
|
|
20168
20644
|
const pier = (clear - win) / 2;
|
|
@@ -20173,11 +20649,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20173
20649
|
wall(`infill_${f}_${side}_${k}_${name}`, size(u, h), [p[0], y, p[2]], on);
|
|
20174
20650
|
};
|
|
20175
20651
|
const id = (name) => `infill_${f}_${side}_${k}_${name}`;
|
|
20176
|
-
put("sill", clear, sill, yb + sill / 2,
|
|
20177
|
-
put("pl", pier, head - sill, yb + sill + (head - sill) / 2,
|
|
20178
|
-
put("pr", pier, head - sill, yb + sill + (head - sill) / 2,
|
|
20179
|
-
put("head", clear, room - head, yb + head + (room - head) / 2,
|
|
20180
|
-
const gp = at2(
|
|
20652
|
+
put("sill", clear, sill, yb + sill / 2, centre2, [c1, c2]);
|
|
20653
|
+
put("pl", pier, head - sill, yb + sill + (head - sill) / 2, centre2 - clear / 2 + pier / 2, [c1, id("sill")]);
|
|
20654
|
+
put("pr", pier, head - sill, yb + sill + (head - sill) / 2, centre2 + clear / 2 - pier / 2, [c2, id("sill")]);
|
|
20655
|
+
put("head", clear, room - head, yb + head + (room - head) / 2, centre2, [c1, c2]);
|
|
20656
|
+
const gp = at2(centre2);
|
|
20181
20657
|
const gid = `glass_${f}_${side}_${k}`;
|
|
20182
20658
|
parts.push({
|
|
20183
20659
|
id: gid,
|
|
@@ -20644,7 +21120,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20644
21120
|
}
|
|
20645
21121
|
var towerLocales = { en: { labels: en_default.labels }, "pt-BR": { labels: pt_BR_default.labels } };
|
|
20646
21122
|
|
|
20647
|
-
// ../game-floorplan-three/dist/chunk-
|
|
21123
|
+
// ../game-floorplan-three/dist/chunk-Y3Y7NYOL.js
|
|
21124
|
+
var __defProp2 = Object.defineProperty;
|
|
21125
|
+
var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp2(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
|
|
21126
|
+
var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
|
|
20648
21127
|
var en2 = {
|
|
20649
21128
|
"prompt.open": "E: open {what}",
|
|
20650
21129
|
"prompt.close": "E: close {what}",
|
|
@@ -20728,6 +21207,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20728
21207
|
const WITH_MAP = { roughcast: 1, block: 1 };
|
|
20729
21208
|
class Accumulator {
|
|
20730
21209
|
constructor() {
|
|
21210
|
+
__publicField(this, "cv");
|
|
21211
|
+
__publicField(this, "ci");
|
|
21212
|
+
__publicField(this, "p");
|
|
21213
|
+
__publicField(this, "n");
|
|
21214
|
+
__publicField(this, "c");
|
|
21215
|
+
__publicField(this, "u");
|
|
21216
|
+
__publicField(this, "i");
|
|
21217
|
+
__publicField(this, "nv");
|
|
21218
|
+
__publicField(this, "ni");
|
|
21219
|
+
__publicField(this, "lim");
|
|
21220
|
+
__publicField(this, "cur");
|
|
21221
|
+
__publicField(this, "piece0");
|
|
21222
|
+
__publicField(this, "mat", "");
|
|
21223
|
+
__publicField(this, "group", "");
|
|
20731
21224
|
this.cv = 2048;
|
|
20732
21225
|
this.ci = 3072;
|
|
20733
21226
|
this.p = new Float32Array(this.cv * 3);
|
|
@@ -20790,7 +21283,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20790
21283
|
g.position.copy(u.pose0.p);
|
|
20791
21284
|
g.quaternion.copy(u.pose0.q);
|
|
20792
21285
|
g.scale.copy(u.pose0.s);
|
|
20793
|
-
const
|
|
21286
|
+
const [ax, ay, az] = a.axis || [0, 1, 0];
|
|
21287
|
+
const e = new THREE.Vector3(ax, ay, az);
|
|
20794
21288
|
if (a.type === "swing" || a.type === "toggle") g.rotateOnAxis(e, (a.angle || 0) * t);
|
|
20795
21289
|
else if (a.type === "slide") g.translateOnAxis(e, (a.dist || 0) * t);
|
|
20796
21290
|
else if (a.type === "scale") {
|
|
@@ -20885,7 +21379,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20885
21379
|
}
|
|
20886
21380
|
if (uvr) {
|
|
20887
21381
|
let gu = G.u[k * 2], gv = G.u[k * 2 + 1];
|
|
20888
|
-
for (let r = uvr.rot | 0; r > 0; r--) {
|
|
21382
|
+
for (let r = (uvr.rot ?? 0) | 0; r > 0; r--) {
|
|
20889
21383
|
const t = gu;
|
|
20890
21384
|
gu = gv;
|
|
20891
21385
|
gv = 1 - t;
|
|
@@ -20983,14 +21477,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20983
21477
|
A.nv += n;
|
|
20984
21478
|
}
|
|
20985
21479
|
let bxImpl = bxBase;
|
|
20986
|
-
|
|
20987
|
-
|
|
20988
|
-
|
|
20989
|
-
K.getBx = () => bxImpl;
|
|
20990
|
-
K.setBx = (f) => {
|
|
21480
|
+
const bx = (...a) => bxImpl(...a);
|
|
21481
|
+
const getBx = () => bxImpl;
|
|
21482
|
+
const setBx = (f) => {
|
|
20991
21483
|
bxImpl = f;
|
|
20992
21484
|
};
|
|
20993
|
-
|
|
21485
|
+
const defined = { GEO, UV_SCALE, WITH_MAP, Accumulator, cursor, PARTS, MIRRORS, part, applyPart, _Y, _qa, _qb, pieceRecord, structurePiece, accFor, _q, _e, _col, rgbOf, put, boxC, bx, getBx, setBx, cylBase, polyFace };
|
|
21486
|
+
Object.assign(K, defined);
|
|
20994
21487
|
}
|
|
20995
21488
|
function installKernelNoise(K, _shared) {
|
|
20996
21489
|
const _h2 = (x, z) => {
|
|
@@ -21006,15 +21499,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21006
21499
|
const n = 0.5 * vnoise(x / 5.5, z / 5.5) + 0.32 * vnoise(x / 1.9 + 31, z / 1.9) + 0.18 * vnoise(x / 0.8 + 7, z / 0.8), m = vnoise(x / 9 + 100, z / 9 + 50) - 0.5, f = 0.76 + 0.5 * n;
|
|
21007
21500
|
return type === "dirt" ? [f * (1 + 0.14 * m), f * (1 + 0.03 * m), f * (1 - 0.18 * m)] : [f * (1 + 0.1 * m), f * (1 + 0.05 * m), f * (1 - 0.1 * m)];
|
|
21008
21501
|
}
|
|
21009
|
-
|
|
21502
|
+
const defined = { _h2, vnoise, macroGround };
|
|
21503
|
+
Object.assign(K, defined);
|
|
21010
21504
|
}
|
|
21011
21505
|
function installMaterialsTextures(K, _shared) {
|
|
21012
21506
|
const { DOC, THREE, cfg } = K;
|
|
21013
21507
|
function texture(n, f, rep = true, rx = 1, ry = 1) {
|
|
21508
|
+
if (!DOC) throw new Error("game-floorplan-three: the procedural textures need a document (options.document)");
|
|
21014
21509
|
const c = DOC.createElement("canvas");
|
|
21015
21510
|
c.width = n;
|
|
21016
21511
|
c.height = n;
|
|
21017
21512
|
const g = c.getContext("2d");
|
|
21513
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
21018
21514
|
f(g, n);
|
|
21019
21515
|
const t = new THREE.CanvasTexture(c);
|
|
21020
21516
|
t.colorSpace = THREE.SRGBColorSpace;
|
|
@@ -21133,7 +21629,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21133
21629
|
const TEX = {};
|
|
21134
21630
|
for (const k of Object.keys(TEXGEN)) TEX[k] = cfg.textures && cfg.textures[k] || TEXGEN[k]();
|
|
21135
21631
|
const ATLAS = {};
|
|
21136
|
-
|
|
21632
|
+
const defined = { texture, rngTexture, TEXGEN, TEX, ATLAS };
|
|
21633
|
+
Object.assign(K, defined);
|
|
21634
|
+
}
|
|
21635
|
+
function context2d(c) {
|
|
21636
|
+
const g = c.getContext("2d");
|
|
21637
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
21638
|
+
return g;
|
|
21137
21639
|
}
|
|
21138
21640
|
function installMaterialsMaterials(K, _shared) {
|
|
21139
21641
|
const { THREE, cfg, ATLAS, TEX, rngTexture } = K;
|
|
@@ -21146,7 +21648,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21146
21648
|
return t;
|
|
21147
21649
|
};
|
|
21148
21650
|
if (!(cfg.atlas && cfg.atlas.floorKind)) {
|
|
21149
|
-
const pc = props.atlas("floor").canvas, g = pc
|
|
21651
|
+
const pc = props.atlas("floor").canvas, g = context2d(pc);
|
|
21150
21652
|
for (const c of [0, 1]) {
|
|
21151
21653
|
g.save();
|
|
21152
21654
|
g.globalCompositeOperation = "screen";
|
|
@@ -21161,7 +21663,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21161
21663
|
g.restore();
|
|
21162
21664
|
}
|
|
21163
21665
|
if (!(cfg.atlas && cfg.atlas.floorKind)) {
|
|
21164
|
-
const pc = props.atlas("floor").canvas, g = pc
|
|
21666
|
+
const pc = props.atlas("floor").canvas, g = context2d(pc);
|
|
21165
21667
|
g.save();
|
|
21166
21668
|
g.fillStyle = "rgba(128,92,62,0.52)";
|
|
21167
21669
|
g.fillRect(256, 256, 256, 256);
|
|
@@ -21258,7 +21760,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21258
21760
|
}
|
|
21259
21761
|
const ORDER = { glass: 3, water: 2, screen: 3, building: 4 };
|
|
21260
21762
|
const NO_SHADOW = /* @__PURE__ */ new Set(["dirt", "glass", "water", "screen", "building", "picture", "floor", "emissive"]);
|
|
21261
|
-
|
|
21763
|
+
const defined = { createMaterials, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER, NO_SHADOW };
|
|
21764
|
+
Object.assign(K, defined);
|
|
21262
21765
|
}
|
|
21263
21766
|
function installKernelCloseScene(K, shared2) {
|
|
21264
21767
|
const { THREE, NO_SHADOW, ORDER, PARTS, applyPart, cursor } = K;
|
|
@@ -21267,15 +21770,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21267
21770
|
const assembleVegetation = (...a) => K.assembleVegetation(...a);
|
|
21268
21771
|
function markMesh(m, A) {
|
|
21269
21772
|
const L = A.lim, fx = [];
|
|
21773
|
+
const pieces = shared2.ctx.pieces;
|
|
21270
21774
|
for (let k = 0; k < L.length; k++) {
|
|
21271
|
-
|
|
21272
|
-
|
|
21273
|
-
|
|
21775
|
+
const lim = L[k], pc = lim.pc;
|
|
21776
|
+
if (!pc) continue;
|
|
21777
|
+
const next = L[k + 1];
|
|
21778
|
+
const v1 = next ? next.v : A.nv, i1 = next ? next.i : A.ni;
|
|
21779
|
+
if (v1 > lim.v) fx.push({ id: pc.id, v0: lim.v, v1, i0: lim.i, i1 });
|
|
21274
21780
|
}
|
|
21275
21781
|
if (!fx.length) return;
|
|
21276
21782
|
const u = m.userData, ids = [...new Set(fx.map((f) => f.id))], weight = {};
|
|
21277
21783
|
for (const f of fx) {
|
|
21278
|
-
const mt =
|
|
21784
|
+
const mt = pieces.get(f.id).mat;
|
|
21279
21785
|
weight[mt] = (weight[mt] || 0) + f.v1 - f.v0;
|
|
21280
21786
|
}
|
|
21281
21787
|
u.ranges = fx;
|
|
@@ -21283,7 +21789,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21283
21789
|
u.destructionMaterial = Object.keys(weight).sort((a, b) => weight[b] - weight[a])[0];
|
|
21284
21790
|
if (ids.length === 1) {
|
|
21285
21791
|
u.destructionPart = ids[0];
|
|
21286
|
-
const pc =
|
|
21792
|
+
const pc = pieces.get(ids[0]);
|
|
21287
21793
|
if (pc.role) u.structuralRole = pc.role;
|
|
21288
21794
|
}
|
|
21289
21795
|
}
|
|
@@ -21334,7 +21840,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21334
21840
|
assembleVegetation(groups);
|
|
21335
21841
|
return groups;
|
|
21336
21842
|
}
|
|
21337
|
-
|
|
21843
|
+
const defined = { markMesh, closeScene };
|
|
21844
|
+
Object.assign(K, defined);
|
|
21338
21845
|
}
|
|
21339
21846
|
function installHouseHelpers(K, shared2) {
|
|
21340
21847
|
shared2.ctx = {};
|
|
@@ -21370,8 +21877,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21370
21877
|
for (const h of holes) L = L.flatMap((r) => subRect(r, h));
|
|
21371
21878
|
return L;
|
|
21372
21879
|
}
|
|
21373
|
-
const wallColor = (c) =>
|
|
21374
|
-
|
|
21880
|
+
const wallColor = (c) => {
|
|
21881
|
+
const k = c && c.color ? colorOf(c.color.wall) : null;
|
|
21882
|
+
return k != null ? k : 14999768;
|
|
21883
|
+
};
|
|
21884
|
+
const floorColor = (c) => {
|
|
21885
|
+
const k = c && c.color ? colorOf(c.color.floor) : null;
|
|
21886
|
+
return k != null ? k : 11577496;
|
|
21887
|
+
};
|
|
21375
21888
|
function stairFootprint(m) {
|
|
21376
21889
|
const c = Math.cos(m.ry), s = Math.sin(m.ry), pts = [[-m.w / 2, -m.d / 2], [m.w / 2, -m.d / 2], [m.w / 2, m.d / 2], [-m.w / 2, m.d / 2]].map(([a, b]) => [m.x + a * c + b * s, m.z - a * s + b * c]);
|
|
21377
21890
|
return [Math.min(...pts.map((p) => p[0])), Math.min(...pts.map((p) => p[1])), Math.max(...pts.map((p) => p[0])), Math.max(...pts.map((p) => p[1]))];
|
|
@@ -21382,10 +21895,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21382
21895
|
const pitch = A[f + 1].y0 - A[f].y0;
|
|
21383
21896
|
return h > pitch && h - pitch <= 0.45 ? pitch : h;
|
|
21384
21897
|
}
|
|
21385
|
-
|
|
21898
|
+
const defined = { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS3, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight };
|
|
21899
|
+
Object.assign(K, defined);
|
|
21386
21900
|
}
|
|
21387
21901
|
function installHouseWalls(K, shared2) {
|
|
21388
21902
|
const { EPS: EPS3, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
|
|
21903
|
+
const sh = (...a) => K.sh(...a);
|
|
21389
21904
|
function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
|
|
21390
21905
|
if (yb - ya < 1e-4 || b - a < 1e-4) return;
|
|
21391
21906
|
if (alongU) {
|
|
@@ -21429,8 +21944,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21429
21944
|
function walls() {
|
|
21430
21945
|
const R = shared2.ctx.r, cut = shared2.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
|
|
21431
21946
|
const corners = /* @__PURE__ */ new Map();
|
|
21947
|
+
const looks = /* @__PURE__ */ new Map();
|
|
21432
21948
|
for (const w of R.walls) {
|
|
21433
|
-
const f = w.floor;
|
|
21949
|
+
const f = w.floor, colliders = shared2.ctx.colliders;
|
|
21434
21950
|
cursor.group = "f" + f;
|
|
21435
21951
|
cursor.pc = pieceOf(w);
|
|
21436
21952
|
const y0 = Y0(f), pitch = f + 1 < nA ? Y0(f + 1) - y0 : Infinity, th = w.thickness || 0.15, alongU = w.axis === "u";
|
|
@@ -21438,7 +21954,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21438
21954
|
const hh = cut ? Math.min(h, 1.2) : h, L = alongU ? w.v0 : w.u0, s0 = Math.min(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1), s1 = Math.max(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1);
|
|
21439
21955
|
const front = alongU && Math.abs(L - vMin) < 0.05;
|
|
21440
21956
|
const sideL = sideOf(w.sides[0], front), sideH = sideOf(w.sides[1], front);
|
|
21441
|
-
|
|
21957
|
+
if (w.id) {
|
|
21958
|
+
const face = sideL.exterior ? sideL : sideH;
|
|
21959
|
+
looks.set(w.id, { mat: face.mat, color: face.color, top: y0 + hh });
|
|
21960
|
+
}
|
|
21961
|
+
colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
|
|
21442
21962
|
if (w.type === "railing") {
|
|
21443
21963
|
const c0 = shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9080466;
|
|
21444
21964
|
const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
|
|
@@ -21484,8 +22004,28 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21484
22004
|
cursor.group = "f" + e.f;
|
|
21485
22005
|
bx(e.color.mat, e.pu - e.th / 2, e.y0, e.pv - e.th / 2, e.pu + e.th / 2, e.y0 + e.hh, e.pv + e.th / 2, e.color.color);
|
|
21486
22006
|
}
|
|
22007
|
+
if (shared2.ctx.showPillars) wallPillars(looks);
|
|
21487
22008
|
}
|
|
21488
|
-
|
|
22009
|
+
const PILLAR_IN_WALL = /^(wall_column_|column_\d|jamb_column_)/;
|
|
22010
|
+
const wallOf = (pillar, parts) => {
|
|
22011
|
+
const u = (pillar.aabb[0] + pillar.aabb[2]) / 2, v = (pillar.aabb[1] + pillar.aabb[3]) / 2;
|
|
22012
|
+
return parts.find((q) => (q.role === "wall" || q.role === "partition") && q.assembly !== void 0 && q.floor === pillar.floor && u >= q.aabb[0] - 1e-3 && u <= q.aabb[2] + 1e-3 && v >= q.aabb[1] - 1e-3 && v <= q.aabb[3] + 1e-3);
|
|
22013
|
+
};
|
|
22014
|
+
function wallPillars(looks) {
|
|
22015
|
+
const parts = Object.values(shared2.ctx.structureIndex);
|
|
22016
|
+
for (const e of parts) {
|
|
22017
|
+
if (e.role !== "column" || !PILLAR_IN_WALL.test(e.id)) continue;
|
|
22018
|
+
const host = wallOf(e, parts);
|
|
22019
|
+
const look = host && looks.get(host.id);
|
|
22020
|
+
if (!host || !look) continue;
|
|
22021
|
+
cursor.group = "f" + e.floor;
|
|
22022
|
+
cursor.pc = structurePiece(host.id);
|
|
22023
|
+
bx(look.mat, e.aabb[0], e.y0, e.aabb[1], e.aabb[2], Math.min(e.y1, look.top), e.aabb[3], sh(look.color != null ? look.color : 15262420, 0.93));
|
|
22024
|
+
}
|
|
22025
|
+
cursor.pc = null;
|
|
22026
|
+
}
|
|
22027
|
+
const defined = { wallBox, sideOf, pieceOf, nearestWall, walls, wallPillars };
|
|
22028
|
+
Object.assign(K, defined);
|
|
21489
22029
|
}
|
|
21490
22030
|
function installHouseDoors(K, shared2) {
|
|
21491
22031
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -21502,7 +22042,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21502
22042
|
}
|
|
21503
22043
|
shared2.doorState = /* @__PURE__ */ new Map();
|
|
21504
22044
|
function doors() {
|
|
21505
|
-
shared2.ctx.leaves = [];
|
|
22045
|
+
const leaves = shared2.ctx.leaves = [], doorState = shared2.doorState, colliders = shared2.ctx.colliders;
|
|
21506
22046
|
const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
|
|
21507
22047
|
for (const p of R.doors) {
|
|
21508
22048
|
const f = p.floor;
|
|
@@ -21533,21 +22073,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21533
22073
|
}
|
|
21534
22074
|
const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
|
|
21535
22075
|
const extC = wood;
|
|
21536
|
-
const open0 = p.blocked ? false :
|
|
21537
|
-
|
|
22076
|
+
const open0 = p.blocked ? false : doorState.has(p.id) ? doorState.get(p.id) === true : !!p.open;
|
|
22077
|
+
doorState.set(p.id, open0);
|
|
21538
22078
|
const dc = alongU ? [p.at, L] : [L, p.at];
|
|
21539
|
-
const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], col: null };
|
|
22079
|
+
const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], gs: [], col: null };
|
|
21540
22080
|
const colR = { type: "door", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b, off: open0 };
|
|
21541
|
-
|
|
22081
|
+
colliders.push(colR);
|
|
21542
22082
|
fo.col = colR;
|
|
21543
22083
|
const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
|
|
21544
|
-
const
|
|
22084
|
+
const newGroup2 = (k, hu, topY) => {
|
|
21545
22085
|
cursor.group = "dyn:" + p.id + ":" + k;
|
|
21546
22086
|
fo.groups.push({ name: cursor.group, pos: alongU ? [hu, topY != null ? y0 + topY : y0, L] : [L, topY != null ? y0 + topY : y0, hu] });
|
|
21547
22087
|
};
|
|
21548
22088
|
if (p.model === "steel") {
|
|
21549
|
-
const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
|
|
21550
|
-
|
|
22089
|
+
const light = [14276044, 13223615, 14999766], pal = ((Number(R.seed) | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
|
|
22090
|
+
newGroup2(0, mid, visH);
|
|
21551
22091
|
const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color2, 0.55);
|
|
21552
22092
|
leafBox(0, la, lb, -visH, 0, 0.05, color2, "metal");
|
|
21553
22093
|
for (let k = 1; k < nSec; k++) leafBox(0, la, lb, -k * hs - 0.012, -k * hs + 0.012, 0.07, grv, "metal");
|
|
@@ -21562,7 +22102,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21562
22102
|
for (let k = 0; k < nf; k++) {
|
|
21563
22103
|
const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color2 = p.exterior ? extC : wood;
|
|
21564
22104
|
const hingeAt = nf === 2 ? k ? u1 : u0 : p.hinge === "end" ? u1 : u0, dir = hingeAt === u0 ? 1 : -1, len = u1 - u0;
|
|
21565
|
-
|
|
22105
|
+
newGroup2(k, hingeAt);
|
|
21566
22106
|
const d0 = dir > 0 ? 5e-3 : -len + 5e-3, d1 = dir > 0 ? len - 5e-3 : -5e-3;
|
|
21567
22107
|
leafBox(hingeAt, d0, d1, 0, visH, 0.04, color2, PMAT);
|
|
21568
22108
|
{
|
|
@@ -21598,7 +22138,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21598
22138
|
fo.rot = Math.atan2(n[0] * A[1] - n[1] * A[0], A[0] * n[0] + A[1] * n[1]);
|
|
21599
22139
|
}
|
|
21600
22140
|
}
|
|
21601
|
-
|
|
22141
|
+
leaves.push(fo);
|
|
21602
22142
|
cursor.group = "f" + f;
|
|
21603
22143
|
if (p.blocked) {
|
|
21604
22144
|
part("window_boards", [0, 0, 0], () => {
|
|
@@ -21626,11 +22166,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21626
22166
|
}
|
|
21627
22167
|
}
|
|
21628
22168
|
}, { id: "boards:" + p.id }, "f" + f);
|
|
21629
|
-
|
|
22169
|
+
colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
|
|
21630
22170
|
}
|
|
21631
22171
|
}
|
|
21632
22172
|
}
|
|
21633
|
-
|
|
22173
|
+
const defined = { doorLineSides, doors };
|
|
22174
|
+
Object.assign(K, defined);
|
|
21634
22175
|
}
|
|
21635
22176
|
function installHouseWindows(K, shared2) {
|
|
21636
22177
|
const { EPS: EPS3, Y0, boxC, bx, cursor, pieceRecord, roomAt } = K;
|
|
@@ -21688,7 +22229,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21688
22229
|
}
|
|
21689
22230
|
}
|
|
21690
22231
|
}
|
|
21691
|
-
|
|
22232
|
+
const defined = { FRAME_COLORS, SILL_COLORS, windows };
|
|
22233
|
+
Object.assign(K, defined);
|
|
21692
22234
|
}
|
|
21693
22235
|
function installHouseFloors(K, shared2) {
|
|
21694
22236
|
const { rectsOf: rectsOf2, EPS: EPS3, OPEN_AREA, Y0, bx, cursor, floorColor, stairFootprint, structurePiece, subRects } = K;
|
|
@@ -21696,7 +22238,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21696
22238
|
if (shared2.ctx._flights && shared2.ctx._flights.r === shared2.ctx.r) return shared2.ctx._flights.l;
|
|
21697
22239
|
const R = shared2.ctx.r, mp = /* @__PURE__ */ new Map();
|
|
21698
22240
|
for (const m of R.items) {
|
|
21699
|
-
if (m.type !== "stairs" || !m.link) continue;
|
|
22241
|
+
if (m.type !== "stairs" || !m.link || typeof m.link !== "object") continue;
|
|
21700
22242
|
const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
|
|
21701
22243
|
if (!mp.has(k)) mp.set(k, { m, from: m.link.from, to: m.link.to, rect: stairFootprint(m) });
|
|
21702
22244
|
}
|
|
@@ -21715,7 +22257,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21715
22257
|
}
|
|
21716
22258
|
const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
|
|
21717
22259
|
function tilesOf(parent, rc) {
|
|
21718
|
-
const ps = parent
|
|
22260
|
+
const ps = parent ? shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent) : void 0;
|
|
21719
22261
|
if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
|
|
21720
22262
|
const out = [], taken = [];
|
|
21721
22263
|
for (const p of ps) for (const q of panelRects(p)) {
|
|
@@ -21777,13 +22319,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21777
22319
|
const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
|
|
21778
22320
|
const sh = (...a) => K.sh(...a);
|
|
21779
22321
|
function buildStairs() {
|
|
21780
|
-
const R = shared2.ctx.r;
|
|
21781
|
-
shared2.ctx.stairs = [];
|
|
22322
|
+
const R = shared2.ctx.r, stairs = shared2.ctx.stairs = [];
|
|
21782
22323
|
for (const vo of flights()) {
|
|
21783
22324
|
const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
|
|
21784
22325
|
cursor.group = "f" + f;
|
|
21785
22326
|
cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
|
|
21786
|
-
const y0 = Y0(f), H = Y0(
|
|
22327
|
+
const y0 = Y0(f), H = Y0(vo.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
|
|
21787
22328
|
const wood = shared2.ctx.colors.wood != null ? shared2.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
|
|
21788
22329
|
const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
|
|
21789
22330
|
const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
|
|
@@ -21806,7 +22347,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21806
22347
|
}
|
|
21807
22348
|
}
|
|
21808
22349
|
cursor.pc = null;
|
|
21809
|
-
|
|
22350
|
+
stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
|
|
21810
22351
|
}
|
|
21811
22352
|
}
|
|
21812
22353
|
function elevator() {
|
|
@@ -21823,7 +22364,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21823
22364
|
}
|
|
21824
22365
|
}
|
|
21825
22366
|
}
|
|
21826
|
-
|
|
22367
|
+
const defined = { buildStairs, elevator };
|
|
22368
|
+
Object.assign(K, defined);
|
|
21827
22369
|
}
|
|
21828
22370
|
function installLightsFixtures(K, shared2) {
|
|
21829
22371
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -21861,14 +22403,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21861
22403
|
c: (mat, x, y, z, r, h, color2, seg2) => api.cylinder(M, mat, x, y0 + y, z, r, h, color2, 0, 0, seg2),
|
|
21862
22404
|
e: (mat, x, y, z, r, h, color2) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color2, 0, 0, "sphere"),
|
|
21863
22405
|
t(mat, p, q, r, color2, seg2) {
|
|
22406
|
+
const tc = color2 ?? NaN;
|
|
21864
22407
|
const dx = q[0] - p[0], dy = q[1] - p[1], dz = q[2] - p[2], L = Math.hypot(dx, dy, dz);
|
|
21865
22408
|
if (L < 1e-5) return;
|
|
21866
22409
|
const nx = dx / L, ny = dy / L, nz = dz / L;
|
|
21867
22410
|
if (Math.abs(nx) < 1e-4 && Math.abs(nz) < 1e-4) {
|
|
21868
|
-
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L,
|
|
22411
|
+
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, tc, 0, 0, seg2);
|
|
21869
22412
|
return;
|
|
21870
22413
|
}
|
|
21871
|
-
api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L,
|
|
22414
|
+
api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, tc, Math.atan2(nz, ny), -Math.asin(nx), seg2);
|
|
21872
22415
|
},
|
|
21873
22416
|
polyFace: (mat, pts, color2, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color2, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
|
|
21874
22417
|
part(type, lx, ly, lz, fn, meta) {
|
|
@@ -22047,7 +22590,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22047
22590
|
K2.part("light_switch", x, 0, 0.011, () => K2.b("plain", x, -0.018, 0.0125, two ? 0.03 : 0.036, 0.034, 8e-3, 16513782, 0, -0.12), { id: "sw_" + M.seed + "_" + i, room: M.room, target: M.target || M.room, opens: { type: "toggle", axis: [1, 0, 0], angle: 0.24 }, on: !!M.on, t0: M.on ? 1 : 0 });
|
|
22048
22591
|
}
|
|
22049
22592
|
}
|
|
22050
|
-
|
|
22593
|
+
const defined = { hashString: hashString2, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch };
|
|
22594
|
+
Object.assign(K, defined);
|
|
22051
22595
|
}
|
|
22052
22596
|
function installLightsDecor(K, shared2) {
|
|
22053
22597
|
const { EPS: EPS3, OPEN_AREA, SEED, Y0, cursor, rngString, roomAt, stairFootprint } = K;
|
|
@@ -22112,7 +22656,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22112
22656
|
void sd;
|
|
22113
22657
|
}
|
|
22114
22658
|
}
|
|
22115
|
-
|
|
22659
|
+
const defined = { decorLights };
|
|
22660
|
+
Object.assign(K, defined);
|
|
22116
22661
|
}
|
|
22117
22662
|
function installLotTerrain(K, shared2) {
|
|
22118
22663
|
const { rectsOf: rectsOf2, MIRRORS, PARTS, bx, cursor } = K;
|
|
@@ -22163,7 +22708,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22163
22708
|
if (x < b) out.push([x, b]);
|
|
22164
22709
|
return out.filter((q) => q[1] - q[0] > 0.3);
|
|
22165
22710
|
}
|
|
22166
|
-
|
|
22711
|
+
const defined = { terrain, freeSpans };
|
|
22712
|
+
Object.assign(K, defined);
|
|
22167
22713
|
}
|
|
22168
22714
|
function installLotPerimeter(K, shared2) {
|
|
22169
22715
|
const { EPS: EPS3, boxC, bx, colorOf, cursor, freeSpans, pieceRecord } = K;
|
|
@@ -22181,7 +22727,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22181
22727
|
for (const s of lt.perimeter) {
|
|
22182
22728
|
const alongU = Math.abs(s.v1 - s.v0) < EPS3, L = alongU ? s.v0 : s.u0, a = Math.min(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1), b = Math.max(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1);
|
|
22183
22729
|
cursor.pc = pieceRecord("lot_wall:" + s.id, s.type === "wall" ? "brick" : s.type === "fence" ? "wood_soft" : "steel", null, { tags: ["wall"] });
|
|
22184
|
-
const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color)
|
|
22730
|
+
const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) ?? (C.wall || 12104874), len = b - a;
|
|
22185
22731
|
const B = (mat, u0, y0, u1, y1, t, c, off = 0) => alongU ? bx(mat, u0, y0, L + off - t / 2, u1, y1, L + off + t / 2, c) : bx(mat, L + off - t / 2, y0, u0, L + off + t / 2, y1, u1, c);
|
|
22186
22732
|
const col = { type: "lot_wall", f: -1, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b };
|
|
22187
22733
|
shared2.ctx.colliders.push(col);
|
|
@@ -22255,7 +22801,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22255
22801
|
}
|
|
22256
22802
|
}
|
|
22257
22803
|
}
|
|
22258
|
-
|
|
22804
|
+
const defined = { perimeter, paths };
|
|
22805
|
+
Object.assign(K, defined);
|
|
22259
22806
|
}
|
|
22260
22807
|
function installLotGates(K, shared2) {
|
|
22261
22808
|
const { bx, colorOf, cursor, cylBase } = K;
|
|
@@ -22269,7 +22816,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22269
22816
|
cursor.group = "lot";
|
|
22270
22817
|
const structure = R.style, auto = structure !== "budget", wall = colorOf("wall") || 12104874, cu = (lt.rect[0] + lt.rect[2]) / 2, cz = (lt.rect[1] + lt.rect[3]) / 2;
|
|
22271
22818
|
for (const g of lt.gates) {
|
|
22272
|
-
const gc = colorOf(g.color)
|
|
22819
|
+
const gc = colorOf(g.color) ?? (C.gate != null ? C.gate : 2763310), a = g.u - g.width / 2, b = g.u + g.width / 2, v = g.v, h = g.height, t = 0.05, ped = g.model === "pedestrian", tilt = g.model === "tilting";
|
|
22273
22820
|
const sd = cz - v >= 0 ? 1 : -1;
|
|
22274
22821
|
const pil = (x0, x1, high) => {
|
|
22275
22822
|
bx("plaster", x0, 0, v - 0.13, x1, high, v + 0.13, wall);
|
|
@@ -22341,7 +22888,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22341
22888
|
if (!g.open || ped) shared2.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
|
|
22342
22889
|
}
|
|
22343
22890
|
}
|
|
22344
|
-
|
|
22891
|
+
const defined = { slideDirection, gates };
|
|
22892
|
+
Object.assign(K, defined);
|
|
22345
22893
|
}
|
|
22346
22894
|
function installRoofRoofs(K, shared2) {
|
|
22347
22895
|
const { rectsOf: rectsOf2, EPS: EPS3, OPEN_AREA, Y0, bx, cursor } = K;
|
|
@@ -22353,13 +22901,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22353
22901
|
function roofs() {
|
|
22354
22902
|
const R = shared2.ctx.r, F = R.facade, C = shared2.ctx.colors, nA = R.floors.length, type = F.roof;
|
|
22355
22903
|
cursor.group = "roof";
|
|
22356
|
-
shared2.ctx.roofRects = [];
|
|
22357
|
-
shared2.ctx.gutter = gutterConfig();
|
|
22358
|
-
|
|
22359
|
-
|
|
22360
|
-
|
|
22904
|
+
const roofRects = shared2.ctx.roofRects = [];
|
|
22905
|
+
const G = shared2.ctx.gutter = gutterConfig();
|
|
22906
|
+
G.ncond = 0;
|
|
22907
|
+
G.nbuz = 0;
|
|
22908
|
+
G.bz = /* @__PURE__ */ new Set();
|
|
22361
22909
|
shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
|
|
22362
|
-
const roofColor = C.roof != null ? C.roof : 11031610, gable = (R.seed | 0) % 2 === 0;
|
|
22910
|
+
const roofColor = C.roof != null ? C.roof : 11031610, gable = (Number(R.seed) | 0) % 2 === 0;
|
|
22363
22911
|
for (let f = 0; f < nA; f++) {
|
|
22364
22912
|
const rs = R.rooms.filter((c) => c.floor === f && c.type !== "void" && !c.outbuilding && !OPEN_AREA(c)).flatMap(rectsOf2), up = R.rooms.filter((c) => c.floor === f + 1 && c.type !== "void").flatMap(rectsOf2);
|
|
22365
22913
|
if (!rs.length) continue;
|
|
@@ -22381,7 +22929,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22381
22929
|
return Y0(f) + Math.max(...cs.map((c) => c.ceiling)) + 0.2;
|
|
22382
22930
|
};
|
|
22383
22931
|
if (type === "slab") {
|
|
22384
|
-
for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i))
|
|
22932
|
+
for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
|
|
22385
22933
|
slabs(f, xs, zs, O, U, nx, nz, full, pe, C);
|
|
22386
22934
|
cursor.pc = null;
|
|
22387
22935
|
continue;
|
|
@@ -22404,16 +22952,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22404
22952
|
if (U(q.j0 - 1, i)) touchesU[1] = 1;
|
|
22405
22953
|
if (U(q.j1 + 1, i)) touchesU[3] = 1;
|
|
22406
22954
|
}
|
|
22407
|
-
|
|
22955
|
+
roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
|
|
22408
22956
|
const ybq = pe(x0, z0, x1, z1);
|
|
22409
22957
|
roofRect(type, x0, z0, x1, z1, ybq, roofColor, gable && single, F, touchesU);
|
|
22410
22958
|
cursor.pc = null;
|
|
22411
|
-
if (
|
|
22959
|
+
if (G.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
|
|
22412
22960
|
}
|
|
22413
22961
|
}
|
|
22414
22962
|
for (const e of shared2.ctx.outbuildingList || []) {
|
|
22415
22963
|
const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
|
|
22416
|
-
|
|
22964
|
+
roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
|
|
22417
22965
|
if (type === "slab") {
|
|
22418
22966
|
const c = C.facade != null ? C.facade : 14209216;
|
|
22419
22967
|
bx("plaster", x0 - 0.08, yb, z0 - 0.08, x1 + 0.08, yb + 0.03, z1 + 0.08, sh(C.ceiling != null ? C.ceiling : 12104876, 0.85));
|
|
@@ -22424,11 +22972,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22424
22972
|
roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
|
|
22425
22973
|
cursor.pc = null;
|
|
22426
22974
|
shared2.ctx.noPiece = false;
|
|
22427
|
-
if (
|
|
22975
|
+
if (G.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
|
|
22428
22976
|
}
|
|
22429
22977
|
}
|
|
22430
|
-
|
|
22978
|
+
const defined = { roofs };
|
|
22979
|
+
Object.assign(K, defined);
|
|
22431
22980
|
}
|
|
22981
|
+
var paletteMeta = (colors) => colors.meta;
|
|
22432
22982
|
function installRoofGutters(K, shared2) {
|
|
22433
22983
|
const { boxC, bx, cursor, roomAt } = K;
|
|
22434
22984
|
const sh = (...a) => K.sh(...a);
|
|
@@ -22445,7 +22995,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22445
22995
|
const draw = rnd() < p, light = rnd() < 0.6;
|
|
22446
22996
|
void draw;
|
|
22447
22997
|
const on = true;
|
|
22448
|
-
return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared2.ctx.colors
|
|
22998
|
+
return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: paletteMeta(shared2.ctx.colors)?.state === "abandoned" || R.state === "abandoned", fallback: false };
|
|
22449
22999
|
}
|
|
22450
23000
|
function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
|
|
22451
23001
|
const G = shared2.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
|
|
@@ -22487,7 +23037,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22487
23037
|
const px = cx + sx * 0.06, pz = cz + sz * 0.06;
|
|
22488
23038
|
if (!freeAt(px, pz, sx, sz)) return false;
|
|
22489
23039
|
const floats = G.bad && G.ncond === 1, yt = yb - 0.1, ybx = floats ? 0.7 : 0.04;
|
|
22490
|
-
G.ncond
|
|
23040
|
+
G.ncond = (G.ncond ?? 0) + 1;
|
|
22491
23041
|
if (run2 >= 2) boxC("plain", (sides[run2][4] + px) / 2, yt, pz, Math.abs(sides[run2][4] - px), 0.07, 0.07, c);
|
|
22492
23042
|
else boxC("plain", px, yt, (sides[run2][4] + pz) / 2, 0.07, 0.07, Math.abs(sides[run2][4] - pz), c);
|
|
22493
23043
|
boxC("plain", px, (ybx + yt) / 2, pz, 0.08, yt - ybx, 0.08, c);
|
|
@@ -22521,7 +23071,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22521
23071
|
function drain(x, z, px, pz, c) {
|
|
22522
23072
|
const g0 = cursor.group;
|
|
22523
23073
|
cursor.group = "f0";
|
|
22524
|
-
if (px != null) boxC("plain", (px + x) / 2, 0.075, (pz + z) / 2, Math.abs(x - px) + 0.05, 0.05, Math.abs(z - pz) + 0.05, sh(c, 0.85));
|
|
23074
|
+
if (px != null && pz != null && c != null) boxC("plain", (px + x) / 2, 0.075, (pz + z) / 2, Math.abs(x - px) + 0.05, 0.05, Math.abs(z - pz) + 0.05, sh(c, 0.85));
|
|
22525
23075
|
const t = 0.045;
|
|
22526
23076
|
bx("plain", x - 0.12, 0, z - 0.12, x + 0.12, t - 6e-3, z + 0.12, 12170668);
|
|
22527
23077
|
bx("metal", x - 0.11, t, z - 0.11, x + 0.11, t + 0.012, z + 0.11, 5922145);
|
|
@@ -22532,7 +23082,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22532
23082
|
bx("metal", x - 0.085, t + 0.012, z - 6e-3, x + 0.085, t + 0.02, z + 6e-3, 9080466);
|
|
22533
23083
|
cursor.group = g0;
|
|
22534
23084
|
}
|
|
22535
|
-
|
|
23085
|
+
const defined = { gutterConfig, gutter, drain };
|
|
23086
|
+
Object.assign(K, defined);
|
|
22536
23087
|
}
|
|
22537
23088
|
function installRoofSlabs(K, shared2) {
|
|
22538
23089
|
const { boxC, bx, cursor, drain, roomAt, structurePiece } = K;
|
|
@@ -22564,15 +23115,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22564
23115
|
side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
|
|
22565
23116
|
side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
|
|
22566
23117
|
side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
|
|
22567
|
-
|
|
23118
|
+
const G = shared2.ctx.gutter;
|
|
23119
|
+
if (G && G.on && G.bz) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
|
|
22568
23120
|
const kd = f + ":" + dx + ":" + dz;
|
|
22569
|
-
if (!ok ||
|
|
22570
|
-
|
|
22571
|
-
|
|
22572
|
-
const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc =
|
|
23121
|
+
if (!ok || G.bz.has(kd)) continue;
|
|
23122
|
+
G.bz.add(kd);
|
|
23123
|
+
G.nbuz = (G.nbuz ?? 0) + 1;
|
|
23124
|
+
const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = G.color;
|
|
22573
23125
|
boxC("plain", ex + dx * 0.15, yb + 0.1, ez + dz * 0.15, dx ? 0.42 : 0.14, 0.1, dz ? 0.42 : 0.14, cc);
|
|
22574
23126
|
boxC("plain", ex + dx * 0.36, yb + 0.1, ez + dz * 0.36, dx ? 0.04 : 0.18, 0.14, dz ? 0.04 : 0.18, sh(cc, 0.8));
|
|
22575
|
-
if (
|
|
23127
|
+
if (G.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
|
|
22576
23128
|
{
|
|
22577
23129
|
const tx = ex + dx * 0.38, tz = ez + dz * 0.38;
|
|
22578
23130
|
let lv = true;
|
|
@@ -22592,7 +23144,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22592
23144
|
}
|
|
22593
23145
|
}
|
|
22594
23146
|
}
|
|
22595
|
-
|
|
23147
|
+
const defined = { slabs };
|
|
23148
|
+
Object.assign(K, defined);
|
|
22596
23149
|
}
|
|
22597
23150
|
function installRoofTiles(K, shared2) {
|
|
22598
23151
|
const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
|
|
@@ -22723,7 +23276,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22723
23276
|
}
|
|
22724
23277
|
return m ? structurePiece(m.id) : null;
|
|
22725
23278
|
}
|
|
22726
|
-
|
|
23279
|
+
const defined = { R_STYLE, tileRelief, ridge, pieceOfPane };
|
|
23280
|
+
Object.assign(K, defined);
|
|
22727
23281
|
}
|
|
22728
23282
|
function installRoofRect(K, shared2) {
|
|
22729
23283
|
const { R_STYLE, bx, cursor, pieceOfPane, polyFace, ridge, tileRelief } = K;
|
|
@@ -22767,7 +23321,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22767
23321
|
}
|
|
22768
23322
|
const rm = alongX ? dz / 2 : dx / 2;
|
|
22769
23323
|
{
|
|
22770
|
-
const
|
|
23324
|
+
const roofRects = shared2.ctx.roofRects, rr = roofRects[roofRects.length - 1];
|
|
22771
23325
|
if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
|
|
22772
23326
|
}
|
|
22773
23327
|
if (gable) {
|
|
@@ -22804,7 +23358,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22804
23358
|
}
|
|
22805
23359
|
}
|
|
22806
23360
|
}
|
|
22807
|
-
|
|
23361
|
+
const defined = { roofRect };
|
|
23362
|
+
Object.assign(K, defined);
|
|
22808
23363
|
}
|
|
22809
23364
|
function installMirrors(K, shared2) {
|
|
22810
23365
|
const { DOC, THREE, Reflector, MIRRORS, Y0, _Y, roomAt } = K;
|
|
@@ -22813,9 +23368,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22813
23368
|
function mirrorEnv() {
|
|
22814
23369
|
if (shared2.mirrorEnv) return shared2.mirrorEnv;
|
|
22815
23370
|
const mk = (f) => {
|
|
23371
|
+
if (!DOC) throw new Error("game-floorplan-three: the mirrors need a document (options.document)");
|
|
22816
23372
|
const c = DOC.createElement("canvas");
|
|
22817
23373
|
c.width = c.height = 64;
|
|
22818
23374
|
const g = c.getContext("2d");
|
|
23375
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
22819
23376
|
f(g);
|
|
22820
23377
|
return c;
|
|
22821
23378
|
};
|
|
@@ -22874,7 +23431,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22874
23431
|
B.N.push(v.x, v.y, v.z);
|
|
22875
23432
|
B.U.push(ua.getX(i), ua.getY(i));
|
|
22876
23433
|
}
|
|
22877
|
-
for (const k of geo.index
|
|
23434
|
+
for (const k of geo.index?.array ?? []) B.I.push(B.nv + k);
|
|
22878
23435
|
B.nv += pa.count;
|
|
22879
23436
|
geo.dispose();
|
|
22880
23437
|
}
|
|
@@ -22952,7 +23509,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22952
23509
|
m.fake.visible = !on;
|
|
22953
23510
|
}
|
|
22954
23511
|
}
|
|
22955
|
-
|
|
23512
|
+
const defined = { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror };
|
|
23513
|
+
Object.assign(K, defined);
|
|
22956
23514
|
}
|
|
22957
23515
|
function installCars(K, shared2) {
|
|
22958
23516
|
const { THREE, FLEET, _Y } = K;
|
|
@@ -22963,13 +23521,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22963
23521
|
high: ["electric_hatch", "hybrid_suv", "midsize_suv", "v8_coupe", "large_suv", "midsize_pickup", "crossover_pickup", "fastback_sedan"]
|
|
22964
23522
|
}, K.cfg.carKinds);
|
|
22965
23523
|
const CAR_CACHE = /* @__PURE__ */ new Map();
|
|
22966
|
-
function materialSignature(
|
|
23524
|
+
function materialSignature(material) {
|
|
23525
|
+
const m = material;
|
|
22967
23526
|
const f = (v) => v == null ? "" : typeof v === "number" ? v.toFixed(3) : v.isColor ? v.getHexString() : v.uuid || String(v);
|
|
22968
23527
|
return [m.type, f(m.color), f(m.roughness), f(m.metalness), f(m.opacity), m.transparent ? 1 : 0, m.side, f(m.map), f(m.emissive), f(m.emissiveIntensity), m.vertexColors ? 1 : 0, m.flatShading ? 1 : 0, f(m.envMapIntensity), f(m.alphaTest)].join("|");
|
|
22969
23528
|
}
|
|
22970
23529
|
const BUCKETS = /* @__PURE__ */ new Map();
|
|
22971
|
-
function bucketMaterial(
|
|
22972
|
-
if (
|
|
23530
|
+
function bucketMaterial(material) {
|
|
23531
|
+
if (material.type !== "MeshStandardMaterial") return null;
|
|
23532
|
+
const m = material;
|
|
23533
|
+
if (m.map || m.alphaTest || m.vertexColors || !m.color) return null;
|
|
22973
23534
|
const mt = m.metalness > 0.5 ? 2 : m.metalness > 0.2 ? 1 : 0, rg = m.roughness < 0.3 ? 0 : m.roughness < 0.6 ? 1 : 2, tr = m.transparent || m.opacity < 1, op = tr ? Math.max(0.2, Math.min(0.9, Math.round(m.opacity * 5) / 5)) : 1, sig = "bucket" + mt + rg + "s" + m.side + (tr ? "t" + op : "");
|
|
22974
23535
|
let b = BUCKETS.get(sig);
|
|
22975
23536
|
if (!b) {
|
|
@@ -22981,7 +23542,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22981
23542
|
}
|
|
22982
23543
|
function carModel(k, seed) {
|
|
22983
23544
|
const kc = k + "|" + shared2.quality + "|" + (seed || 0);
|
|
22984
|
-
if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc);
|
|
23545
|
+
if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc) ?? null;
|
|
22985
23546
|
if (!FLEET) return null;
|
|
22986
23547
|
let res = null;
|
|
22987
23548
|
try {
|
|
@@ -22989,8 +23550,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22989
23550
|
c.root.updateMatrixWorld(true);
|
|
22990
23551
|
const inv = new THREE.Matrix4();
|
|
22991
23552
|
const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
|
|
22992
|
-
c.g.traverse((
|
|
22993
|
-
if (!
|
|
23553
|
+
c.g.traverse((node) => {
|
|
23554
|
+
if (!isMesh(node)) return;
|
|
23555
|
+
const o = node;
|
|
23556
|
+
if (o.isInstancedMesh || o.isSkinnedMesh || !o.geometry || !o.geometry.attributes.position) return;
|
|
22994
23557
|
for (let p = o; p; p = p.parent) if (p.visible === false) return;
|
|
22995
23558
|
const mats = Array.isArray(o.material) ? o.material : [o.material];
|
|
22996
23559
|
let geo = o.geometry;
|
|
@@ -23004,7 +23567,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23004
23567
|
const pa = geo.attributes.position, na = geo.attributes.normal, ua = geo.attributes.uv, total = pa.count;
|
|
23005
23568
|
const grs = Array.isArray(o.material) && o.geometry.groups.length ? o.geometry.groups : [{ start: 0, count: total, materialIndex: 0 }];
|
|
23006
23569
|
for (const gr of grs) {
|
|
23007
|
-
const m = mats[gr.materialIndex] || mats[0];
|
|
23570
|
+
const m = (gr.materialIndex != null ? mats[gr.materialIndex] : void 0) || mats[0];
|
|
23008
23571
|
if (!m) continue;
|
|
23009
23572
|
const a0 = Math.min(gr.start, total), n0 = Math.min(gr.count, total - a0) - Math.min(gr.count, total - a0) % 3;
|
|
23010
23573
|
if (n0 < 3) continue;
|
|
@@ -23105,7 +23668,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23105
23668
|
return g;
|
|
23106
23669
|
}
|
|
23107
23670
|
function assembleCars(groups) {
|
|
23108
|
-
if (shared2.quality === "game")
|
|
23671
|
+
if (shared2.quality === "game") {
|
|
23672
|
+
assembleMergedCars(groups);
|
|
23673
|
+
return;
|
|
23674
|
+
}
|
|
23109
23675
|
for (const C of CARS) {
|
|
23110
23676
|
const g = carGroup(C.k, C.w, C.d, C.seed);
|
|
23111
23677
|
if (!g) continue;
|
|
@@ -23156,7 +23722,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23156
23722
|
(groups[B.parent] || (groups[B.parent] = new THREE.Group())).add(m);
|
|
23157
23723
|
}
|
|
23158
23724
|
}
|
|
23159
|
-
|
|
23725
|
+
const defined = { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars };
|
|
23726
|
+
Object.assign(K, defined);
|
|
23160
23727
|
}
|
|
23161
23728
|
function installHouseBuilding(K, shared2) {
|
|
23162
23729
|
const { bx, cursor } = K;
|
|
@@ -23210,12 +23777,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23210
23777
|
bx("plaster", Math.min(hall[0] - 3, color2[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color2[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
|
|
23211
23778
|
shared2.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
|
|
23212
23779
|
}
|
|
23213
|
-
|
|
23780
|
+
const defined = { building };
|
|
23781
|
+
Object.assign(K, defined);
|
|
23214
23782
|
}
|
|
23215
23783
|
function installUtilitiesWater(K, shared2) {
|
|
23216
23784
|
const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
|
|
23217
23785
|
function createWater(r, state) {
|
|
23218
|
-
const H = r.utilities
|
|
23786
|
+
const H = r.utilities?.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
|
|
23219
23787
|
if (H) for (const p of H.points) {
|
|
23220
23788
|
points[p.id] = p;
|
|
23221
23789
|
itemPoint[p.item] = p.id;
|
|
@@ -23304,14 +23872,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23304
23872
|
}
|
|
23305
23873
|
const _v3 = new THREE.Vector3();
|
|
23306
23874
|
function waterPipes() {
|
|
23307
|
-
const H = shared2.ctx.r.utilities
|
|
23875
|
+
const H = shared2.ctx.r.utilities?.plumbing;
|
|
23308
23876
|
if (!H || !H.visibleRuns) return;
|
|
23309
23877
|
const nA = shared2.ctx.r.floors.length;
|
|
23310
23878
|
const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
|
|
23311
23879
|
for (const tr of H.visibleRuns) {
|
|
23312
23880
|
const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
|
|
23313
23881
|
if (tr.exposed === "wall") {
|
|
23314
|
-
const pt = H.points.find((p) => p.run === tr.id), com = shared2.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
|
|
23882
|
+
const pt = H.points.find((p) => p.run === tr.id), com = tr.to != null ? shared2.ctx.roomById[tr.to] : void 0, g2 = groupOf(com || pt && { floor: pt.floor });
|
|
23315
23883
|
part("wall_pipe", [0, 0, 0], () => {
|
|
23316
23884
|
for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
|
|
23317
23885
|
for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
|
|
@@ -23333,16 +23901,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23333
23901
|
cursor.pc = null;
|
|
23334
23902
|
}
|
|
23335
23903
|
}
|
|
23336
|
-
|
|
23904
|
+
const defined = { createWater, PIPE_COLOR, pipe, _v3, waterPipes };
|
|
23905
|
+
Object.assign(K, defined);
|
|
23337
23906
|
}
|
|
23338
23907
|
function installUtilitiesElectrical(K, shared2) {
|
|
23339
23908
|
const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
|
|
23340
23909
|
const sh = (...a) => K.sh(...a);
|
|
23341
23910
|
function electricalStructure() {
|
|
23342
|
-
const
|
|
23911
|
+
const R = shared2.ctx.r, E = R.utilities?.electrical;
|
|
23343
23912
|
shared2.ctx.electricalInfo = null;
|
|
23344
23913
|
if (!E) return;
|
|
23345
|
-
const
|
|
23914
|
+
const nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
|
|
23346
23915
|
const en22 = E.serviceEntrance, KV = shared2.ctx.iv ? shared2.ctx.iv.plane : null;
|
|
23347
23916
|
const wireL = (a, b, r_ = 8e-3) => {
|
|
23348
23917
|
const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
@@ -23447,7 +24016,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23447
24016
|
_q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
|
|
23448
24017
|
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
|
|
23449
24018
|
}
|
|
23450
|
-
|
|
24019
|
+
const defined = { electricalStructure, pipe2 };
|
|
24020
|
+
Object.assign(K, defined);
|
|
23451
24021
|
}
|
|
23452
24022
|
function installHouseBaseboard(K, shared2) {
|
|
23453
24023
|
const { Y0, bx, cursor, sideOf } = K;
|
|
@@ -23483,7 +24053,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23483
24053
|
strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
|
|
23484
24054
|
}
|
|
23485
24055
|
}
|
|
23486
|
-
|
|
24056
|
+
const defined = { baseboardAndSidewalk };
|
|
24057
|
+
Object.assign(K, defined);
|
|
23487
24058
|
}
|
|
23488
24059
|
function installUtilitiesSolar(K, shared2) {
|
|
23489
24060
|
const { Y0, boxC, bx, cursor, cylBase } = K;
|
|
@@ -23496,6 +24067,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23496
24067
|
if (u >= a - 0.05 && u <= c + 0.05 && v >= b - 0.05 && v <= d + 0.05) y = Math.max(y == null ? -1e9 : y, rr.yb);
|
|
23497
24068
|
continue;
|
|
23498
24069
|
}
|
|
24070
|
+
if (!rr.exterior || rr.tp == null || rr.rm == null) continue;
|
|
23499
24071
|
const [x0, z0, x1, z1] = rr.exterior;
|
|
23500
24072
|
if (u < x0 || u > x1 || v < z0 || v > z1) continue;
|
|
23501
24073
|
const dz = Math.min(v - z0, z1 - v), dx = Math.min(u - x0, x1 - u), dd = rr.gable ? rr.alongX ? dz : dx : Math.min(dx, dz), h = rr.yb + rr.tp * Math.min(dd, rr.rm);
|
|
@@ -23504,7 +24076,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23504
24076
|
return y;
|
|
23505
24077
|
}
|
|
23506
24078
|
function solar() {
|
|
23507
|
-
const R = shared2.ctx.r, S = R.utilities
|
|
24079
|
+
const R = shared2.ctx.r, S = R.utilities?.solar;
|
|
23508
24080
|
shared2.ctx.solarInfo = null;
|
|
23509
24081
|
if (!S || !S.panels || !S.panels.length) return;
|
|
23510
24082
|
cursor.group = "roof";
|
|
@@ -23547,13 +24119,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23547
24119
|
bx("plain", iv.u - W * 0.6, y0 + 0.05, iv.v + fa0, iv.u + W * 0.6, y0 + 0.17, iv.v + fa1, 2106924);
|
|
23548
24120
|
bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
|
|
23549
24121
|
}
|
|
23550
|
-
const top = Math.max(...(shared2.ctx.roofRects || []).
|
|
24122
|
+
const top = Math.max(...(shared2.ctx.roofRects || []).flatMap((t2) => t2.yb != null ? [t2.yb] : []), Y0(fa) + 2.8);
|
|
23551
24123
|
cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
|
|
23552
24124
|
info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
|
|
23553
24125
|
}
|
|
23554
24126
|
shared2.ctx.solarInfo = info;
|
|
23555
24127
|
}
|
|
23556
|
-
|
|
24128
|
+
const defined = { roofHeightAt, solar };
|
|
24129
|
+
Object.assign(K, defined);
|
|
23557
24130
|
}
|
|
23558
24131
|
function installHouseOutbuildings(K, shared2) {
|
|
23559
24132
|
const { t, bx, cursor, floorColor } = K;
|
|
@@ -23566,7 +24139,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23566
24139
|
counts.set(w.floor, i + 1);
|
|
23567
24140
|
return w.id ? w : Object.assign({}, w, { id: `wall_${w.floor}_${i}` });
|
|
23568
24141
|
}) });
|
|
23569
|
-
const E = (r.outbuildings || []).filter((e) => e && e.walls && e.walls.length && e.interior && e.interior.length);
|
|
24142
|
+
const E = (r.outbuildings || []).filter((e) => !!(e && e.walls && e.walls.length && e.interior && e.interior.length));
|
|
23570
24143
|
if (!E.length) return r;
|
|
23571
24144
|
const rooms = r.rooms.slice(), walls = r.walls.slice(), doors = r.doors.slice(), windows = r.windows.slice(), items = r.items.filter((m) => m.type !== "outbuilding");
|
|
23572
24145
|
for (const e of E) {
|
|
@@ -23580,7 +24153,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23580
24153
|
const alongU = p.axis === "u", below = p.pos < (alongU ? cz : cx);
|
|
23581
24154
|
doors.push({ id: p.id, floor: 0, u: p.u, v: p.v, axis: p.axis, pos: p.pos, at: p.at, width: p.width, a: below ? "outside" : e.id, b: below ? e.id : "outside", opensTo: e.id, exterior: true, side: p.side, leaves: 1, model: "single", hinge: "start", zones: [], blocked: false, outbuilding: e.id });
|
|
23582
24155
|
}
|
|
23583
|
-
for (const j of e.windows || []) windows.push({
|
|
24156
|
+
for (const j of e.windows || []) windows.push({
|
|
24157
|
+
id: j.id,
|
|
24158
|
+
floor: 0,
|
|
24159
|
+
u: j.u,
|
|
24160
|
+
v: j.v,
|
|
24161
|
+
axis: j.axis,
|
|
24162
|
+
pos: j.pos,
|
|
24163
|
+
at: j.at,
|
|
24164
|
+
width: j.width,
|
|
24165
|
+
y0: j.y0 ?? 1,
|
|
24166
|
+
y1: j.y1 ?? 2,
|
|
24167
|
+
/* the structure always gives a window its sill and head (1.0, 2.0) */
|
|
24168
|
+
room: e.id,
|
|
24169
|
+
side: j.side,
|
|
24170
|
+
outbuilding: e.id
|
|
24171
|
+
});
|
|
23584
24172
|
(e.items || []).forEach((m, i) => items.push({ id: e.id + "." + m.type + i, type: m.type, category: m.category, x: m.u, z: m.v, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: 0.04, frontU: m.frontU, frontV: m.frontV, room: e.id, floor: 0, outdoor: false, aabb: m.aabb, color: "wood" }));
|
|
23585
24173
|
items.push({ id: e.id + ".ceiling_light", type: "ceiling_light", category: "ceiling_light", x: cx, z: cz, ry: 0, w: 0.35, d: 0.35, h: 0.1, y: pe - 0.1, room: e.id, floor: 0, outdoor: false, assembly: "ceiling", color: "metal", decor: true });
|
|
23586
24174
|
}
|
|
@@ -23601,7 +24189,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23601
24189
|
}
|
|
23602
24190
|
}
|
|
23603
24191
|
}
|
|
23604
|
-
|
|
24192
|
+
const defined = { OUTBUILDING_USE, applyOutbuildings, outbuildings };
|
|
24193
|
+
Object.assign(K, defined);
|
|
23605
24194
|
}
|
|
23606
24195
|
function installFurnitureApi(K, _shared) {
|
|
23607
24196
|
const { _e, _h2, _q, boxC, cursor, macroGround, polyFace, put } = K;
|
|
@@ -23664,7 +24253,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23664
24253
|
return { b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color2, rx, rz, seg2) => A.cylinder(M, mat, x, y0 + y, z, r, h, color2, rx || 0, rz || 0, seg2), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
|
|
23665
24254
|
}
|
|
23666
24255
|
const PE = Math.PI / 2;
|
|
23667
|
-
|
|
24256
|
+
const defined = { MATERIAL_MAP: MATERIAL_MAP2, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE };
|
|
24257
|
+
Object.assign(K, defined);
|
|
23668
24258
|
}
|
|
23669
24259
|
function installFurnitureBuilders(K, _shared) {
|
|
23670
24260
|
const { PE, _q, kit2, kk, paletteColor, put, rngOf, sh } = K;
|
|
@@ -23790,7 +24380,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23790
24380
|
for (let s = 0; s < np; s++) lb("fabric", np === 1 ? 0 : (s ? 1 : -1) * w * 0.23, 0.5, -d / 2 + 0.3, w * (np === 1 ? 0.6 : 0.4), 0.12, 0.34, 15789798, (s ? 1 : -1) * 0.08);
|
|
23791
24381
|
},
|
|
23792
24382
|
wardrobe(M, A) {
|
|
23793
|
-
const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, wood =
|
|
24383
|
+
const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, wood = paletteColor(M, "wood", 5980208), np = Math.max(2, Math.round(w / 0.7));
|
|
23794
24384
|
lb("wood", 0, 0.06, 0, w, h - 0.06, d, wood);
|
|
23795
24385
|
lb("wood", 0, h, 0, w + 0.04, 0.04, d + 0.04, sh(wood, 0.8));
|
|
23796
24386
|
lb("wood", 0, 0, 0, w - 0.04, 0.06, d - 0.04, sh(wood, 0.4));
|
|
@@ -24182,7 +24772,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24182
24772
|
lb("metal", 0, h - 0.04, d / 2, w, 0.03, 0.03, 3815994);
|
|
24183
24773
|
}
|
|
24184
24774
|
};
|
|
24185
|
-
|
|
24775
|
+
const defined = { FURNITURE };
|
|
24776
|
+
Object.assign(K, defined);
|
|
24186
24777
|
}
|
|
24187
24778
|
function installFurnitureTypeTable(K, _shared) {
|
|
24188
24779
|
const { FURNITURE, kk, paletteColor } = K;
|
|
@@ -24190,7 +24781,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24190
24781
|
function typeTable(props) {
|
|
24191
24782
|
const B = props.builders, T2 = {};
|
|
24192
24783
|
const mv = (type, id) => {
|
|
24193
|
-
|
|
24784
|
+
const f = B[id || type];
|
|
24785
|
+
if (f) T2[type] = { f, source: "props3d" };
|
|
24194
24786
|
};
|
|
24195
24787
|
const mine = (type, f, source = "game") => {
|
|
24196
24788
|
T2[type] = { f, source };
|
|
@@ -24329,7 +24921,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24329
24921
|
extraTypes(T2, props);
|
|
24330
24922
|
return T2;
|
|
24331
24923
|
}
|
|
24332
|
-
|
|
24924
|
+
const defined = { typeTable };
|
|
24925
|
+
Object.assign(K, defined);
|
|
24333
24926
|
}
|
|
24334
24927
|
function installFurnitureTaps(K, shared2) {
|
|
24335
24928
|
shared2.tapCount = 0;
|
|
@@ -24391,7 +24984,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24391
24984
|
}, { id: id + "_a", target: id, hidden: true, fluid: "water" });
|
|
24392
24985
|
return id;
|
|
24393
24986
|
}
|
|
24394
|
-
|
|
24987
|
+
const defined = { counterTap, wallTap };
|
|
24988
|
+
Object.assign(K, defined);
|
|
24395
24989
|
}
|
|
24396
24990
|
function installFurnitureFixtures(K, _shared) {
|
|
24397
24991
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -24500,7 +25094,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24500
25094
|
const a = rnd() * 6.283, u = Math.sqrt(rnd()), ph = (rnd() - 0.2) * 1.2, dx = Math.cos(a) * u * R * 0.75, dz = Math.sin(a) * u * R * 0.75, dy = (o.flatten ? 0.35 : 0.55) * R * (Math.sin(ph) * 0.5 + 0.5) * 1.5 - R * 0.15;
|
|
24501
25095
|
const r = R * (0.34 + rnd() * 0.22) * (1 - u * 0.25), alt = r * 2 * (o.flatten ? 0.75 : 0.95), f = 0.72 + Math.min(1, (dy + R * 0.2) / (R * 1.2)) * 0.32 + rnd() * 0.12;
|
|
24502
25096
|
K2.e("plant", cx + dx, cy + dy + r * 0.5, cz + dz, r, alt, sh(green2, f));
|
|
24503
|
-
if (o.flower && rnd() < o.flower) {
|
|
25097
|
+
if (o.flower && o.flowers && rnd() < o.flower) {
|
|
24504
25098
|
const fa = rnd() * 6.283;
|
|
24505
25099
|
K2.e("plain", cx + dx + Math.cos(fa) * r * 0.78, cy + dy + r * 0.5 + rnd() * r * 0.5, cz + dz + Math.sin(fa) * r * 0.78, 0.028 + rnd() * 0.012, 0.05, o.flowers[rnd() * o.flowers.length | 0]);
|
|
24506
25100
|
}
|
|
@@ -24613,7 +25207,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24613
25207
|
else blobs(K2, x, bh - 0.05, z, 0.24 + rnd() * 0.08, 6, green2, rnd, { flatten: true, flower: tp === "flower" ? 0.9 : 0.25, flowers: FLOWERS.slice(i % 3, i % 3 + 3) });
|
|
24614
25208
|
}
|
|
24615
25209
|
}
|
|
24616
|
-
|
|
25210
|
+
const defined = { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel };
|
|
25211
|
+
Object.assign(K, defined);
|
|
24617
25212
|
}
|
|
24618
25213
|
function installFurnitureYard(K, shared2) {
|
|
24619
25214
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -24767,7 +25362,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24767
25362
|
};
|
|
24768
25363
|
FURNITURE.mailbox = function(M, A) {
|
|
24769
25364
|
const K2 = kit2(M, A, 0), w = M.w || 0.3, d = M.d || 0.22, h = M.h || 0.3, y = M.y != null && M.y > 0 ? M.y : 1, structure = STYLE(), pc = structure === "high" ? 2763824 : structure === "mid" ? 13676640 : 13126202, rnd = rngString(SEED() + "|" + seedKey(M.seed) + "|correio");
|
|
24770
|
-
if (M.pole !== false && !(M.y > 0)) {
|
|
25365
|
+
if (M.pole !== false && !(M.y != null && M.y > 0)) {
|
|
24771
25366
|
K2.b("plain", 0, 0, -d / 2 - 0.1, 0.12, y, 0.12, 12104874);
|
|
24772
25367
|
}
|
|
24773
25368
|
K2.b("metal", 0, y, 0, w, h * 0.78, d, pc);
|
|
@@ -24787,7 +25382,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24787
25382
|
);
|
|
24788
25383
|
K2.b("plain", 0, y + h * 0.62, d / 2 + 4e-3, 0.08, 0.05, 4e-3, 15921386);
|
|
24789
25384
|
};
|
|
24790
|
-
|
|
25385
|
+
const defined = { CLOTHES_COLORS, strip, garment: garment2 };
|
|
25386
|
+
Object.assign(K, defined);
|
|
24791
25387
|
}
|
|
24792
25388
|
function installFurnitureExtraTypes(K, _shared) {
|
|
24793
25389
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -24845,7 +25441,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24845
25441
|
tuft(K2, 0, 0, 0, Math.max(0.2, (M.w || 0.4) / 2), 16, 5212738, rnd);
|
|
24846
25442
|
});
|
|
24847
25443
|
}
|
|
24848
|
-
|
|
25444
|
+
const defined = { extraTypes };
|
|
25445
|
+
Object.assign(K, defined);
|
|
24849
25446
|
}
|
|
24850
25447
|
function installFurniturePlaceItems(K, shared2) {
|
|
24851
25448
|
const { THREE, Y0, _col, boxC, colorOf, cursor, decorLights, makeApi, structurePiece } = K;
|
|
@@ -24865,8 +25462,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24865
25462
|
if (m.type === "stairs") continue;
|
|
24866
25463
|
const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
|
|
24867
25464
|
cursor.group = exterior ? "lot" : "f" + f;
|
|
24868
|
-
const com = shared2.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
|
|
24869
|
-
const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color)
|
|
25465
|
+
const com = m.room != null ? shared2.ctx.roomById[m.room] : void 0, base = exterior ? 0 : Y0(f);
|
|
25466
|
+
const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) ?? void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
|
|
24870
25467
|
if (m.category === "ground_cover" && m.polygon) {
|
|
24871
25468
|
const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
|
|
24872
25469
|
M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
|
|
@@ -24943,7 +25540,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24943
25540
|
boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
|
|
24944
25541
|
shared2.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
|
|
24945
25542
|
}
|
|
24946
|
-
|
|
25543
|
+
const defined = { houseItems, waterTankOfHouse, hashColor, labeledBox };
|
|
25544
|
+
Object.assign(K, defined);
|
|
24947
25545
|
}
|
|
24948
25546
|
function installVegetationBridge(K, shared2) {
|
|
24949
25547
|
const seedKey = (id) => K.seedKey(id);
|
|
@@ -24976,7 +25574,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
24976
25574
|
const ids = VEG_MAP[m.type], can2 = VEG_PLANTER[m.type];
|
|
24977
25575
|
if (!ids && !can2) return false;
|
|
24978
25576
|
const rnd = rngString(SEED() + "|" + seedKey(m.id) + "|veg"), pick2 = (l) => l[Math.min(l.length - 1, rnd() * l.length | 0)], ok = (id) => {
|
|
24979
|
-
if (V.ok.has(id)) return V.ok.get(id);
|
|
25577
|
+
if (V.ok.has(id)) return V.ok.get(id) === true;
|
|
24980
25578
|
let r = true;
|
|
24981
25579
|
try {
|
|
24982
25580
|
V.S.toSpec(id);
|
|
@@ -25022,7 +25620,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25022
25620
|
obj.position.y = G.y;
|
|
25023
25621
|
obj.name = "vegetation";
|
|
25024
25622
|
obj.traverse((o) => {
|
|
25025
|
-
if (o
|
|
25623
|
+
if (isMesh(o)) {
|
|
25026
25624
|
o.castShadow = true;
|
|
25027
25625
|
o.receiveShadow = true;
|
|
25028
25626
|
o.name = "veg/" + o.name;
|
|
@@ -25037,7 +25635,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25037
25635
|
}
|
|
25038
25636
|
shared2.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
|
|
25039
25637
|
}
|
|
25040
|
-
|
|
25638
|
+
const defined = { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation };
|
|
25639
|
+
Object.assign(K, defined);
|
|
25041
25640
|
}
|
|
25042
25641
|
function installInteractionState(K, shared2) {
|
|
25043
25642
|
const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
|
|
@@ -25103,12 +25702,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25103
25702
|
shared2.inter.msg = { text, until: performance.now() + MESSAGE_MS };
|
|
25104
25703
|
if (cfg.onMessage) cfg.onMessage(text);
|
|
25105
25704
|
};
|
|
25106
|
-
|
|
25705
|
+
const I = () => shared2.inter;
|
|
25706
|
+
function definePiece(name, definition) {
|
|
25707
|
+
const def = definition;
|
|
25107
25708
|
def.name = name;
|
|
25108
25709
|
def.meshes = [];
|
|
25109
25710
|
def.t = def.target = shared2.partState.has(name) ? shared2.partState.get(name) : def.t0 || 0;
|
|
25110
|
-
|
|
25111
|
-
|
|
25711
|
+
I().defs.set(name, def);
|
|
25712
|
+
I().pieces.push(def);
|
|
25112
25713
|
return def;
|
|
25113
25714
|
}
|
|
25114
25715
|
const localOf = (M, lx, lz) => {
|
|
@@ -25120,17 +25721,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25120
25721
|
return true;
|
|
25121
25722
|
}
|
|
25122
25723
|
function assembleInteractive(gs) {
|
|
25123
|
-
|
|
25724
|
+
const inter = I();
|
|
25725
|
+
for (const [name, def] of inter.defs) {
|
|
25124
25726
|
const g = gs[name];
|
|
25125
25727
|
if (!g) continue;
|
|
25126
25728
|
delete gs[name];
|
|
25127
25729
|
const outer = new THREE.Group();
|
|
25128
|
-
outer.position.
|
|
25730
|
+
outer.position.fromArray(def.pivot);
|
|
25129
25731
|
outer.rotation.y = def.ry || 0;
|
|
25130
25732
|
outer.updateMatrix();
|
|
25131
|
-
const inv = new THREE.Matrix4().compose(new THREE.Vector3(
|
|
25733
|
+
const inv = new THREE.Matrix4().compose(new THREE.Vector3().fromArray(def.pivot), new THREE.Quaternion().setFromAxisAngle(_EY, def.ry || 0), _UM3).invert();
|
|
25132
25734
|
g.traverse((o) => {
|
|
25133
|
-
if (o
|
|
25735
|
+
if (isMesh(o)) {
|
|
25134
25736
|
o.geometry.applyMatrix4(inv);
|
|
25135
25737
|
o.userData.piece = def;
|
|
25136
25738
|
def.meshes.push(o);
|
|
@@ -25142,13 +25744,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25142
25744
|
const parent = def.leaf ? def.leaf.gs[def.k] : gs[def.parent] || (gs[def.parent] = new THREE.Group());
|
|
25143
25745
|
if (parent) parent.add(outer);
|
|
25144
25746
|
if (def.roomId) {
|
|
25145
|
-
|
|
25146
|
-
|
|
25747
|
+
let lamps = inter.lights.get(def.roomId);
|
|
25748
|
+
if (!lamps) inter.lights.set(def.roomId, lamps = []);
|
|
25749
|
+
lamps.push(def);
|
|
25147
25750
|
}
|
|
25148
25751
|
applyPiece(def);
|
|
25149
25752
|
}
|
|
25150
|
-
for (const roomId of
|
|
25151
|
-
|
|
25753
|
+
for (const roomId of inter.litRooms) applyLight(roomId);
|
|
25754
|
+
inter.defs.forEach((d) => {
|
|
25152
25755
|
if (d.col) d.col.off = d.t > 0.5;
|
|
25153
25756
|
});
|
|
25154
25757
|
}
|
|
@@ -25156,6 +25759,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25156
25759
|
const n = p.inner;
|
|
25157
25760
|
if (!n) return;
|
|
25158
25761
|
switch (p.kind) {
|
|
25762
|
+
/* each kind always sets its dimensions (sgn, angle, travel, k, axis) */
|
|
25159
25763
|
case "swing":
|
|
25160
25764
|
n.rotation.y = p.sgn * p.t * p.angle;
|
|
25161
25765
|
break;
|
|
@@ -25188,8 +25792,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25188
25792
|
}
|
|
25189
25793
|
const DURATION = { swing: 0.55, drawer: 0.4, curtain: 0.9, gate_swing: 0.9, gate_tilt: 1.4, gate_slide: 1.6, lightSwitch: 0.12, part: 0.4 };
|
|
25190
25794
|
function animateInteractive(dt) {
|
|
25191
|
-
|
|
25192
|
-
|
|
25795
|
+
const inter = I();
|
|
25796
|
+
if (!inter.anim.size) return;
|
|
25797
|
+
for (const p of inter.anim) {
|
|
25193
25798
|
const step = dt / (DURATION[p.kind] || 0.5), d = p.target - p.t;
|
|
25194
25799
|
p.t = Math.abs(d) <= step ? p.target : p.t + Math.sign(d) * step;
|
|
25195
25800
|
applyPiece(p);
|
|
@@ -25197,7 +25802,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25197
25802
|
p.col.off = p.target > 0.5;
|
|
25198
25803
|
colliderChanged(p.col);
|
|
25199
25804
|
}
|
|
25200
|
-
if (p.t === p.target)
|
|
25805
|
+
if (p.t === p.target) inter.anim.delete(p);
|
|
25201
25806
|
}
|
|
25202
25807
|
invalidateShadow();
|
|
25203
25808
|
}
|
|
@@ -25208,7 +25813,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25208
25813
|
p.col.off = p.target > 0.5;
|
|
25209
25814
|
colliderChanged(p.col);
|
|
25210
25815
|
}
|
|
25211
|
-
|
|
25816
|
+
I().anim.add(p);
|
|
25212
25817
|
}
|
|
25213
25818
|
const lightBase = (roomId) => roomId == null ? true : shared2.partState.has("light:" + roomId) ? !!shared2.partState.get("light:" + roomId) : !!shared2.ctx.night;
|
|
25214
25819
|
const lightOn = (roomId) => {
|
|
@@ -25216,20 +25821,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25216
25821
|
return S ? S.ef : lightBase(roomId);
|
|
25217
25822
|
};
|
|
25218
25823
|
function applyLight(roomId) {
|
|
25219
|
-
const on = lightOn(roomId);
|
|
25220
|
-
for (const d of
|
|
25221
|
-
const sw =
|
|
25824
|
+
const on = lightOn(roomId), inter = I(), mats = shared2.mats;
|
|
25825
|
+
for (const d of inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? mats.emissive : mats.off;
|
|
25826
|
+
const sw = inter.defs.get("ix:int:" + roomId);
|
|
25222
25827
|
if (sw) {
|
|
25223
25828
|
sw.target = on ? 1 : 0;
|
|
25224
|
-
if (sw.t !== sw.target)
|
|
25829
|
+
if (sw.t !== sw.target) inter.anim.add(sw);
|
|
25225
25830
|
}
|
|
25226
25831
|
invalidate();
|
|
25227
25832
|
}
|
|
25228
25833
|
function toggleLight(roomId) {
|
|
25229
25834
|
const S = shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
|
|
25230
25835
|
if (S) {
|
|
25231
|
-
|
|
25232
|
-
|
|
25836
|
+
const IV = shared2.ctx.iv;
|
|
25837
|
+
ivRoomLight(IV, roomId, !S.ef);
|
|
25838
|
+
const ef = ivRoomEffective(IV, S);
|
|
25233
25839
|
if (ef !== S.ef) {
|
|
25234
25840
|
S.ef = ef;
|
|
25235
25841
|
applyLight(roomId);
|
|
@@ -25241,9 +25847,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25241
25847
|
applyLight(roomId);
|
|
25242
25848
|
if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
|
|
25243
25849
|
}
|
|
25244
|
-
|
|
25850
|
+
const defined = { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight };
|
|
25851
|
+
Object.assign(K, defined);
|
|
25245
25852
|
}
|
|
25246
25853
|
function installInteractionCollision(K, shared2) {
|
|
25854
|
+
const inter = () => shared2.inter;
|
|
25247
25855
|
const NO_COLLIDE = /(^|_)(rug|floor|concrete|dirt|lawn|deck|ceiling_light|pendant|chandelier|spot|picture|curtain|blinds|wall_shelving|plank_shelf|wall_ac|ac_condenser|pool|soaking_tub|pergola|stairs|mirror)/;
|
|
25248
25856
|
function registerCollision(m, M) {
|
|
25249
25857
|
const h = m.h || 0, y = M.y || 0;
|
|
@@ -25253,7 +25861,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25253
25861
|
w = Math.min(w, 0.5);
|
|
25254
25862
|
d = Math.min(d, 0.5);
|
|
25255
25863
|
}
|
|
25256
|
-
|
|
25864
|
+
inter().objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
|
|
25257
25865
|
}
|
|
25258
25866
|
function objectDistance(o, x, z) {
|
|
25259
25867
|
const dx = x - o.cx, dz = z - o.cz, lx = dx * o.c - dz * o.s, lz = dx * o.s + dz * o.c, ex = Math.abs(lx) - o.hw, ez = Math.abs(lz) - o.hd;
|
|
@@ -25261,7 +25869,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25261
25869
|
}
|
|
25262
25870
|
function collideObject(x, z, fx, fz, floor) {
|
|
25263
25871
|
const R = 0.2;
|
|
25264
|
-
for (const o of
|
|
25872
|
+
for (const o of inter().objs) {
|
|
25265
25873
|
if (o.f !== -1 ? o.f !== floor : floor !== 0) continue;
|
|
25266
25874
|
const d1 = objectDistance(o, x, z);
|
|
25267
25875
|
if (d1 < R && d1 < objectDistance(o, fx, fz) - 1e-6) return true;
|
|
@@ -25281,13 +25889,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25281
25889
|
const de = opt.from || [x + 1e4, z + 1e4];
|
|
25282
25890
|
return collideObject(x, z, de[0], de[1], floor);
|
|
25283
25891
|
}
|
|
25284
|
-
|
|
25892
|
+
const defined = { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt };
|
|
25893
|
+
Object.assign(K, defined);
|
|
25285
25894
|
}
|
|
25286
25895
|
function installInteractionItems(K, shared2) {
|
|
25287
25896
|
const { t, LIGHTS, cursor, definePiece, localOf, registerCollision, togglePiece } = K;
|
|
25288
25897
|
const DOOR_ITEM = /^(tv_unit|tv_unit_small|tv_unit_large|sideboard|china_cabinet|filing_cabinet|pantry|laundry_cabinet|wardrobe|wardrobe_small|wardrobe_large|closet_wardrobe|kitchen_cabinet|kitchen_cabinet_large|kitchen_cabinet_small|fridge|fridge_large|display_fridge_medium|display_fridge)$/;
|
|
25289
25898
|
const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
|
|
25290
25899
|
const LIGHT_TYPES = /* @__PURE__ */ new Set(["ceiling_light", "pendant", "chandelier", "track_spot", "hanging_plant"]);
|
|
25900
|
+
const I = () => shared2.inter;
|
|
25291
25901
|
function objectName(type, drawer) {
|
|
25292
25902
|
return drawer ? "drawer" : /^wardrobe/.test(type) ? "wardrobe" : /fridge|refrig|freezer/.test(type) ? "fridge" : /pantry/.test(type) ? "pantry" : "cabinet";
|
|
25293
25903
|
}
|
|
@@ -25316,8 +25926,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25316
25926
|
cursor.group = parent;
|
|
25317
25927
|
}
|
|
25318
25928
|
for (let i = n0; i < LIGHTS.length; i++) LIGHTS[i].roomId = m.room;
|
|
25319
|
-
if (!
|
|
25320
|
-
|
|
25929
|
+
if (!I().defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
|
|
25930
|
+
I().litRooms.add(m.room);
|
|
25321
25931
|
}
|
|
25322
25932
|
function curtainItem(m, M, ent, api, parent) {
|
|
25323
25933
|
M.open = false;
|
|
@@ -25345,12 +25955,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25345
25955
|
for (const c of body) api[c[0]](M, ...c[1]);
|
|
25346
25956
|
if (!parts.length) return;
|
|
25347
25957
|
const [ax, az] = localOf(M, 0, 0.2);
|
|
25348
|
-
|
|
25349
|
-
|
|
25958
|
+
const first = parts[0];
|
|
25959
|
+
I().items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(first.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
|
|
25960
|
+
const al = first.target > 0.5 ? 0 : 1;
|
|
25350
25961
|
for (const p of parts) {
|
|
25351
25962
|
p.target = al;
|
|
25352
25963
|
shared2.partState.set(p.name, al);
|
|
25353
|
-
|
|
25964
|
+
I().anim.add(p);
|
|
25354
25965
|
}
|
|
25355
25966
|
} });
|
|
25356
25967
|
}
|
|
@@ -25371,7 +25982,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25371
25982
|
calls.forEach((c, i) => {
|
|
25372
25983
|
if (owner.has(i)) return;
|
|
25373
25984
|
const a = c[1];
|
|
25374
|
-
let x0, x1, y0, y1, ok = false, grip = 0, wide = false;
|
|
25985
|
+
let x0 = 0, x1 = 0, y0 = 0, y1 = 0, ok = false, grip = 0, wide = false;
|
|
25375
25986
|
if (c[0] === "box") {
|
|
25376
25987
|
const [mat, x, y, z, w, h, d, , ry, rx, rz] = a;
|
|
25377
25988
|
if (ry || rx || rz || d > 0.05 || z + d / 2 < front - 5e-3 || w > M.w * 1.01) return;
|
|
@@ -25403,8 +26014,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25403
26014
|
return;
|
|
25404
26015
|
}
|
|
25405
26016
|
candidate.sort((p, q) => overlap(x0, x1, q.x0, q.x1) - overlap(x0, x1, p.x0, p.x1));
|
|
25406
|
-
|
|
25407
|
-
|
|
26017
|
+
const best = candidate[0];
|
|
26018
|
+
owner.set(i, best);
|
|
26019
|
+
if (grip) best.grip = grip;
|
|
25408
26020
|
});
|
|
25409
26021
|
const name = objectName(m.type, drawer), parts = [];
|
|
25410
26022
|
panels.forEach((p, k) => {
|
|
@@ -25420,8 +26032,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25420
26032
|
p.def = def;
|
|
25421
26033
|
parts.push(def);
|
|
25422
26034
|
const [ax, az] = localOf(M, cx, front + 0.08);
|
|
25423
|
-
|
|
25424
|
-
def.item =
|
|
26035
|
+
I().items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
|
|
26036
|
+
def.item = I().items[I().items.length - 1];
|
|
25425
26037
|
});
|
|
25426
26038
|
calls.forEach((c, i) => {
|
|
25427
26039
|
const p = owner.get(i);
|
|
@@ -25435,12 +26047,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25435
26047
|
}
|
|
25436
26048
|
cursor.group = parent;
|
|
25437
26049
|
}
|
|
25438
|
-
|
|
26050
|
+
const defined = { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem };
|
|
26051
|
+
Object.assign(K, defined);
|
|
25439
26052
|
}
|
|
25440
26053
|
function installInteractionFittings(K, shared2) {
|
|
25441
26054
|
const { t, EPS: EPS3, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
|
|
26055
|
+
const I = () => shared2.inter;
|
|
26056
|
+
const house = () => shared2.ctx.r;
|
|
25442
26057
|
function gatesInteractive() {
|
|
25443
|
-
const lt =
|
|
26058
|
+
const lt = house().lot;
|
|
25444
26059
|
if (!lt) return;
|
|
25445
26060
|
const cz0 = (lt.rect[1] + lt.rect[3]) / 2;
|
|
25446
26061
|
const orig = K.getBx(), gs = lt.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
|
|
@@ -25460,9 +26075,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25460
26075
|
return;
|
|
25461
26076
|
}
|
|
25462
26077
|
}
|
|
25463
|
-
|
|
26078
|
+
orig(mat, x0, y0, z0, x1, y1, z1, color2);
|
|
25464
26079
|
});
|
|
25465
|
-
const
|
|
26080
|
+
const colliders = shared2.ctx.colliders, n0 = colliders.length;
|
|
25466
26081
|
try {
|
|
25467
26082
|
gs.forEach((g) => {
|
|
25468
26083
|
g.open = false;
|
|
@@ -25474,7 +26089,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25474
26089
|
g.open = opening[i];
|
|
25475
26090
|
});
|
|
25476
26091
|
}
|
|
25477
|
-
const cols =
|
|
26092
|
+
const cols = colliders.slice(n0), cz = (lt.rect[1] + lt.rect[3]) / 2, cu = (lt.rect[0] + lt.rect[2]) / 2;
|
|
25478
26093
|
reg.forEach((r, i) => {
|
|
25479
26094
|
const g = r.g;
|
|
25480
26095
|
if (!isFinite(r.x0)) return;
|
|
@@ -25483,25 +26098,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25483
26098
|
const p = ped ? definePiece(name, Object.assign(base, { kind: "gate_swing", pivot: [r.x0, 0, g.v], angle: -sd * 1.65 })) : tilt ? definePiece(name, Object.assign(base, { kind: "gate_tilting", pivot: [(r.x0 + r.x1) / 2, r.y1, g.v], angle: -sd * 1.45 })) : definePiece(name, Object.assign(base, { kind: "gate_sliding", pivot: [r.x0, 0, r.zm], travel: r.dx * g.width }));
|
|
25484
26099
|
if (p.col) p.col.off = p.target > 0.5;
|
|
25485
26100
|
const text = () => t(p.target > 0.5 ? "prompt.close" : "prompt.open", { what: t(ped ? "what.pedestrianGate" : "what.garageGate") });
|
|
25486
|
-
|
|
26101
|
+
I().items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
|
|
25487
26102
|
});
|
|
25488
26103
|
}
|
|
25489
26104
|
function mailboxInteractive() {
|
|
25490
|
-
for (const m of
|
|
26105
|
+
for (const m of house().items) {
|
|
25491
26106
|
if (m.type !== "mailbox") continue;
|
|
25492
26107
|
const g = shared2.ctx.parts && shared2.ctx.parts["mailbox_" + m.id];
|
|
25493
26108
|
if (!g) continue;
|
|
25494
26109
|
const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
|
|
25495
26110
|
def.inner = g;
|
|
25496
26111
|
const fx = Math.sin(m.ry || 0), fz = Math.cos(m.ry || 0), ay = (m.y || 1) + (m.h || 0.3) * 0.4;
|
|
25497
|
-
|
|
26112
|
+
I().items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
|
|
25498
26113
|
applyPiece(def);
|
|
25499
26114
|
}
|
|
25500
26115
|
}
|
|
25501
26116
|
function placeSwitches() {
|
|
25502
|
-
const R =
|
|
26117
|
+
const R = house(), used = /* @__PURE__ */ new Set();
|
|
25503
26118
|
for (const c of R.rooms) {
|
|
25504
|
-
if (c.type === "void" || OPEN_AREA(c) || !
|
|
26119
|
+
if (c.type === "void" || OPEN_AREA(c) || !I().litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
|
|
25505
26120
|
const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
|
|
25506
26121
|
doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
|
|
25507
26122
|
for (const p of doors) if (putSwitch(c, p)) {
|
|
@@ -25511,11 +26126,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25511
26126
|
}
|
|
25512
26127
|
}
|
|
25513
26128
|
function putSwitch(c, p) {
|
|
25514
|
-
const R =
|
|
26129
|
+
const R = house(), f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
|
|
25515
26130
|
const wref = R.walls.find((w) => w.floor === f && w.axis === p.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS3), th = wref ? wref.thickness || 0.15 : 0.15;
|
|
25516
26131
|
const inside2 = (sd2) => {
|
|
25517
26132
|
const cc = roomAt(f, alongU ? p.at : L + sd2 * 0.4, alongU ? L + sd2 * 0.4 : p.at);
|
|
25518
|
-
return cc && cc.id === c.id;
|
|
26133
|
+
return !!cc && cc.id === c.id;
|
|
25519
26134
|
};
|
|
25520
26135
|
const sd = inside2(1) ? 1 : inside2(-1) ? -1 : 0;
|
|
25521
26136
|
if (!sd) return false;
|
|
@@ -25538,17 +26153,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25538
26153
|
const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
|
|
25539
26154
|
piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
|
|
25540
26155
|
const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
|
|
25541
|
-
|
|
26156
|
+
I().items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
|
|
25542
26157
|
return true;
|
|
25543
26158
|
}
|
|
25544
26159
|
return false;
|
|
25545
26160
|
}
|
|
25546
|
-
|
|
26161
|
+
const defined = { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch };
|
|
26162
|
+
Object.assign(K, defined);
|
|
25547
26163
|
}
|
|
25548
26164
|
function installInteractionDoors(K, shared2) {
|
|
25549
26165
|
const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
|
|
26166
|
+
const leaves = () => shared2.ctx.leaves;
|
|
25550
26167
|
function linkDoorLeaves() {
|
|
25551
|
-
|
|
26168
|
+
const I = shared2.inter;
|
|
26169
|
+
for (const fo of leaves()) fo.handles = (fo.handleNames || []).map((n) => I.defs.get(n)).filter((d) => !!d);
|
|
25552
26170
|
}
|
|
25553
26171
|
function handleApply(fo) {
|
|
25554
26172
|
for (const mc of fo.handles || []) {
|
|
@@ -25558,11 +26176,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25558
26176
|
}
|
|
25559
26177
|
function toggleDoor(fo) {
|
|
25560
26178
|
if (fo.phase === "rattle") return;
|
|
26179
|
+
const col = fo.col;
|
|
25561
26180
|
if (fo.phase === "handle" || fo.phase === "swing") {
|
|
25562
26181
|
fo.open = !fo.open;
|
|
25563
26182
|
shared2.doorState.set(fo.id, fo.open);
|
|
25564
|
-
|
|
25565
|
-
colliderChanged(
|
|
26183
|
+
col.off = fo.open;
|
|
26184
|
+
colliderChanged(col);
|
|
25566
26185
|
fo.anim = true;
|
|
25567
26186
|
fo.phase = "swing";
|
|
25568
26187
|
return;
|
|
@@ -25576,8 +26195,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25576
26195
|
}
|
|
25577
26196
|
fo.open = !fo.open;
|
|
25578
26197
|
shared2.doorState.set(fo.id, fo.open);
|
|
25579
|
-
|
|
25580
|
-
colliderChanged(
|
|
26198
|
+
col.off = fo.open;
|
|
26199
|
+
colliderChanged(col);
|
|
25581
26200
|
fo.anim = true;
|
|
25582
26201
|
shared2.ctx.animateDoorsOn = true;
|
|
25583
26202
|
if (fo.handles && fo.handles.length) {
|
|
@@ -25588,7 +26207,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25588
26207
|
function animateDoors(dt) {
|
|
25589
26208
|
if (!shared2.ctx.animateDoorsOn) return;
|
|
25590
26209
|
let active = false;
|
|
25591
|
-
for (const fo of
|
|
26210
|
+
for (const fo of leaves()) {
|
|
25592
26211
|
if (!fo.phase) continue;
|
|
25593
26212
|
active = true;
|
|
25594
26213
|
if (fo.phase === "handle") {
|
|
@@ -25608,7 +26227,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25608
26227
|
handleApply(fo);
|
|
25609
26228
|
if (fo.hT <= 0) fo.phase = null;
|
|
25610
26229
|
} else if (fo.phase === "rattle") {
|
|
25611
|
-
fo.jig
|
|
26230
|
+
fo.jig = (fo.jig ?? 0) - dt;
|
|
25612
26231
|
fo.hT = fo.jig > 0 ? 0.55 * Math.abs(Math.sin(fo.jig * 26)) : 0;
|
|
25613
26232
|
handleApply(fo);
|
|
25614
26233
|
if (fo.jig <= 0) {
|
|
@@ -25622,9 +26241,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25622
26241
|
invalidateShadow();
|
|
25623
26242
|
}
|
|
25624
26243
|
function wallBlocks(ex, ez, ax, az, floor) {
|
|
25625
|
-
const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0;
|
|
26244
|
+
const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0, colliders = shared2.ctx.colliders;
|
|
25626
26245
|
for (let i = 0; i < n; i++) {
|
|
25627
|
-
const c =
|
|
26246
|
+
const c = colliders[i];
|
|
25628
26247
|
if (c.f !== floor && !(c.f === -1 && floor === 0)) continue;
|
|
25629
26248
|
let t0 = 0, t1 = 1;
|
|
25630
26249
|
const dx = ax - ex, dz = az - ez;
|
|
@@ -25654,7 +26273,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25654
26273
|
g.updateMatrix();
|
|
25655
26274
|
}
|
|
25656
26275
|
}
|
|
25657
|
-
|
|
26276
|
+
const defined = { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf };
|
|
26277
|
+
Object.assign(K, defined);
|
|
25658
26278
|
}
|
|
25659
26279
|
function installInteractionTarget(K, shared2) {
|
|
25660
26280
|
const { doorText, toggleDoor, visibleChain, wallBlocks } = K;
|
|
@@ -25662,6 +26282,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25662
26282
|
function targetOf(o, opt) {
|
|
25663
26283
|
if (!o) return null;
|
|
25664
26284
|
opt = opt || {};
|
|
26285
|
+
const I = shared2.inter;
|
|
25665
26286
|
const ex = o.x, ey = o.y, ez = o.z, floor = o.floor, cp = Math.cos(o.pitch || 0), vx = Math.sin(o.yaw) * cp, vy = Math.sin(o.pitch || 0), vz = Math.cos(o.yaw) * cp;
|
|
25666
26287
|
let best = null;
|
|
25667
26288
|
const tries = (score, text, action, target) => {
|
|
@@ -25675,16 +26296,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25675
26296
|
if (angle > 1.35 && d > 0.9) continue;
|
|
25676
26297
|
tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
|
|
25677
26298
|
}
|
|
25678
|
-
const vis =
|
|
26299
|
+
const vis = I.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
|
|
25679
26300
|
const kitA = shared2.ctx.iv ? ivTarget(shared2.ctx.iv, o, opt && opt.interactives) : null;
|
|
25680
26301
|
const nearKit = kitA && hit && Math.hypot(kitA.target.pos[0] - ex, kitA.target.pos[1] - ey, kitA.target.pos[2] - ez) < hit.distance + 0.1;
|
|
25681
26302
|
const pieceHit = hit && !nearKit && hit.object.userData.piece;
|
|
25682
|
-
for (const it of
|
|
26303
|
+
for (const it of I.items) {
|
|
25683
26304
|
if (it.floor !== floor && !(it.floor === -1 && floor === 0)) continue;
|
|
25684
26305
|
const [ax, ay, az] = it.anchor, dx = ax - ex, dy = ay - ey, dz = az - ez, d = Math.hypot(dx, dy, dz), dh = Math.hypot(dx, dz);
|
|
25685
26306
|
if (dh > it.range + 0.4) continue;
|
|
25686
26307
|
const angle = Math.acos(Math.max(-1, Math.min(1, (dx * vx + dy * vy + dz * vz) / (d || 1))));
|
|
25687
|
-
const byRay = pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
|
|
26308
|
+
const byRay = !!hit && pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
|
|
25688
26309
|
if (!byRay && !(dh <= it.range && angle <= it.angle)) continue;
|
|
25689
26310
|
if (!it.noWall && wallBlocks(ex, ez, ax, az, it.floor < 0 ? 0 : it.floor)) continue;
|
|
25690
26311
|
tries((byRay ? 0 : angle * 2) + d * 0.3 - (byRay ? 1.5 : 0), it.text(), it.action, it);
|
|
@@ -25692,7 +26313,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25692
26313
|
if (kitA) tries(kitA.score - (nearKit ? 0.5 : 0), kitA.text, kitA.action, kitA.target);
|
|
25693
26314
|
return best;
|
|
25694
26315
|
}
|
|
25695
|
-
|
|
26316
|
+
const defined = { targetOf };
|
|
26317
|
+
Object.assign(K, defined);
|
|
25696
26318
|
}
|
|
25697
26319
|
function installInteractablesBridge(K, shared2) {
|
|
25698
26320
|
const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString: hashString2, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
|
|
@@ -25747,7 +26369,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25747
26369
|
function ivBuild(h, water) {
|
|
25748
26370
|
const ik = K.IVK, r = shared2.ctx.r, A = ik.A, world0 = null;
|
|
25749
26371
|
void world0;
|
|
25750
|
-
const
|
|
26372
|
+
const source = r;
|
|
26373
|
+
const plane2 = A.plan(source, { seed: r.seed });
|
|
25751
26374
|
const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
|
|
25752
26375
|
h.IV = IV;
|
|
25753
26376
|
const t0 = performance.now();
|
|
@@ -25766,9 +26389,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25766
26389
|
const wants = (roomId) => lightBase(roomId);
|
|
25767
26390
|
const entById = new Map(plane2.items.map((e) => [e.id, e]));
|
|
25768
26391
|
const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
|
|
25769
|
-
|
|
26392
|
+
const mats = shared2.mats;
|
|
26393
|
+
IV.mats = { plain: mats.plain, metal: shared2.mats.metal, wood: shared2.mats.wood, glass: shared2.mats.glass, fabric: shared2.mats.fabric, plant: shared2.mats.plant, water: shared2.mats.water, emissive: shared2.mats.emissive, atlas_picture: shared2.mats.picture, atlas_floor: shared2.mats.floor };
|
|
25770
26394
|
const ev = (e) => ivEvent(h, e);
|
|
25771
|
-
const world = IV.world = A.createWorld(
|
|
26395
|
+
const world = IV.world = A.createWorld(source, { water, seed: r.seed, onEvent: ev });
|
|
25772
26396
|
const add0 = world.add;
|
|
25773
26397
|
world.add = (id, spec, tr) => {
|
|
25774
26398
|
const e = entById.get(id);
|
|
@@ -25785,7 +26409,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25785
26409
|
}
|
|
25786
26410
|
return add0(id, spec, tr);
|
|
25787
26411
|
};
|
|
25788
|
-
const added = A.add(world, plane2, { isBlocked: A.blockedOf(
|
|
26412
|
+
const added = A.add(world, plane2, { isBlocked: A.blockedOf(source), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
|
|
25789
26413
|
world.add = add0;
|
|
25790
26414
|
IV.warnings = added.warnings;
|
|
25791
26415
|
IV.added = added;
|
|
@@ -25832,14 +26456,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25832
26456
|
}
|
|
25833
26457
|
function ivDraw(IV, ent, type, item) {
|
|
25834
26458
|
const ik = IV.k, loc = Object.assign({}, item, { x: 0, z: 0, ry: 0 });
|
|
26459
|
+
const ix = item.x, iz = item.z, iry = item.ry;
|
|
25835
26460
|
const mesh2 = ik.gfx.createMeshApi({ quality: "game", materials: IV.mats, shadows: true, mergeParts: true, swayAmplitude: 0.03 });
|
|
25836
26461
|
const spec = ik.A.household.build(type, loc, mesh2.api);
|
|
25837
26462
|
const out = mesh2.finish(spec);
|
|
25838
26463
|
for (const l of out.lights) l.removeFromParent();
|
|
25839
26464
|
const group = ivGroup(ent), g0 = cursor.group, root = new THREE.Group();
|
|
25840
26465
|
root.name = "iv:" + ent.id;
|
|
25841
|
-
root.position.set(
|
|
25842
|
-
root.rotation.y =
|
|
26466
|
+
root.position.set(ix, ent.floorY, iz);
|
|
26467
|
+
root.rotation.y = iry;
|
|
25843
26468
|
root.userData.iv = ent.id;
|
|
25844
26469
|
const screen = spec.devices && spec.devices.some((d) => d.kind === "screen");
|
|
25845
26470
|
let body = null;
|
|
@@ -25848,7 +26473,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25848
26473
|
if (type === "gas_bottle") {
|
|
25849
26474
|
cursor.pc = pieceRecord("gas_cylinder:" + ent.id, "steel", null, { floor: ent.floor, mass: 11, form: "cyl", thickness: 3e-3, fill: 0.03, contains: { fluid: "gas", liters: 13, pressurized: true }, explodes: { energy: 12e4, radius: 5, atC: 300 }, tags: ["gas_bottle"] });
|
|
25850
26475
|
for (const m of out.group.children) if (!m.name.startsWith("static:")) m.traverse((o) => {
|
|
25851
|
-
if (o
|
|
26476
|
+
if (isMesh(o)) {
|
|
25852
26477
|
o.userData.destructionPart = cursor.pc.id;
|
|
25853
26478
|
o.userData.destructionMaterial = "steel";
|
|
25854
26479
|
}
|
|
@@ -25856,13 +26481,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25856
26481
|
}
|
|
25857
26482
|
try {
|
|
25858
26483
|
for (const m of out.group.children.slice()) {
|
|
25859
|
-
if (m
|
|
26484
|
+
if (isMesh(m) && m.name.startsWith("static:")) {
|
|
25860
26485
|
if (screen && m.userData.material === "emissive") {
|
|
25861
26486
|
body = m;
|
|
25862
26487
|
root.add(m);
|
|
25863
26488
|
continue;
|
|
25864
26489
|
}
|
|
25865
|
-
ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry,
|
|
26490
|
+
ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, ix, ent.floorY, iz, iry, null);
|
|
25866
26491
|
m.geometry.dispose();
|
|
25867
26492
|
} else root.add(m);
|
|
25868
26493
|
}
|
|
@@ -25872,7 +26497,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25872
26497
|
}
|
|
25873
26498
|
const base = new Set(Object.values(IV.mats));
|
|
25874
26499
|
root.traverse((o) => {
|
|
25875
|
-
if (!o
|
|
26500
|
+
if (!isMesh(o)) return;
|
|
25876
26501
|
o.userData.iv = ent.id;
|
|
25877
26502
|
if (o.castShadow) {
|
|
25878
26503
|
if (!o.geometry.boundingSphere) o.geometry.computeBoundingSphere();
|
|
@@ -25883,7 +26508,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25883
26508
|
roomLightMask(m);
|
|
25884
26509
|
}
|
|
25885
26510
|
});
|
|
25886
|
-
const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [
|
|
26511
|
+
const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [ix, ent.floorY, iz], ry: iry, origin: ent.origin };
|
|
25887
26512
|
IV.entries.set(ent.id, E);
|
|
25888
26513
|
if (root.children.length) IV.roots.push(E);
|
|
25889
26514
|
return spec;
|
|
@@ -25911,7 +26536,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25911
26536
|
const wire = (spec.wires || []).find((x) => x.id === d.id + "_cord"), pts = (wire ? wire.points : [d.plug]).map((p) => wl(o, p));
|
|
25912
26537
|
const sid = w.power.pluggedInto(E.id, d.id);
|
|
25913
26538
|
if (sid) {
|
|
25914
|
-
const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && so.spec.sockets.find((s) => s.id === sid.slice(cut + 1));
|
|
26539
|
+
const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && (so.spec.sockets || []).find((s) => s.id === sid.slice(cut + 1));
|
|
25915
26540
|
if (so && sk) {
|
|
25916
26541
|
const sp = wl(so, sk.pos), dir = [Math.sin(so.transform.ry), Math.cos(so.transform.ry)], last = pts[pts.length - 1];
|
|
25917
26542
|
if (last[1] < 0.3 + E.pos[1]) {
|
|
@@ -25946,9 +26571,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25946
26571
|
roomLightMask(sc.material);
|
|
25947
26572
|
IV.screens.set(E.id, sc);
|
|
25948
26573
|
}
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
|
|
26574
|
+
const mesh2 = E.screen;
|
|
26575
|
+
mesh2.material = sc.material;
|
|
26576
|
+
mesh2.castShadow = false;
|
|
26577
|
+
mesh2.receiveShadow = false;
|
|
25952
26578
|
}
|
|
25953
26579
|
function ivEvent(h, e) {
|
|
25954
26580
|
const IV = h.IV;
|
|
@@ -25984,16 +26610,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
25984
26610
|
IV.itemsDirty = true;
|
|
25985
26611
|
break;
|
|
25986
26612
|
}
|
|
25987
|
-
|
|
26613
|
+
const ik = K.IVK;
|
|
26614
|
+
if (ik.onEvent) {
|
|
25988
26615
|
try {
|
|
25989
|
-
|
|
26616
|
+
ik.onEvent(e, IV.pub);
|
|
25990
26617
|
} catch (err) {
|
|
25991
26618
|
console.warn("interactables.onEvent", err);
|
|
25992
26619
|
}
|
|
25993
26620
|
}
|
|
25994
|
-
if (e.type === "seat" &&
|
|
26621
|
+
if (e.type === "seat" && ik.onSeat && e.actor === "player") {
|
|
25995
26622
|
try {
|
|
25996
|
-
|
|
26623
|
+
ik.onSeat(e.seated ? ivSeat(IV) : null, e);
|
|
25997
26624
|
} catch (err) {
|
|
25998
26625
|
console.warn("interactables.onSeat", err);
|
|
25999
26626
|
}
|
|
@@ -26002,7 +26629,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26002
26629
|
function ivSeat(IV) {
|
|
26003
26630
|
const w = IV.world, s = w.seatOf("player");
|
|
26004
26631
|
if (!s) return null;
|
|
26005
|
-
const o = w.get(s.object), seat = o.spec.seats.find((q) => q.id === s.seat), L = IV.k.GI.localToWorld, tr = o.transform, E = IV.entries.get(s.object);
|
|
26632
|
+
const o = w.get(s.object), seat = (o.spec.seats || []).find((q) => q.id === s.seat), L = IV.k.GI.localToWorld, tr = o.transform, E = IV.entries.get(s.object);
|
|
26006
26633
|
const eye = L(tr, [seat.pos[0], seat.pos[1] + (seat.eye === void 0 ? seat.pose === "lie" ? 0.18 : 0.62 : seat.eye), seat.pos[2]]);
|
|
26007
26634
|
return { object: s.object, seatInfo: s.seat, pose: seat.pose, eye, yaw: tr.ry + seat.ry, pitch: seat.pose === "lie" ? 0.55 : -0.08, exitPoint: L(tr, seat.exit), floor: E ? E.floor : 0, type: E ? E.type : null };
|
|
26008
26635
|
}
|
|
@@ -26044,18 +26671,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26044
26671
|
}
|
|
26045
26672
|
}
|
|
26046
26673
|
const em = w.emitters();
|
|
26047
|
-
|
|
26674
|
+
const ivk = K.IVK;
|
|
26675
|
+
if (em.length && !IV.efx && ivk.effects) {
|
|
26048
26676
|
const g = h.houseGroup;
|
|
26049
|
-
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...
|
|
26677
|
+
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...ivk.effectSink ? { effects: ivk.effectSink } : {} });
|
|
26050
26678
|
}
|
|
26051
26679
|
if (IV.efx) {
|
|
26052
26680
|
const alive = IV.efx.stats().alive;
|
|
26053
26681
|
if (em.length || alive) {
|
|
26054
|
-
IV.efx.update(dt, em,
|
|
26682
|
+
IV.efx.update(dt, em, ivk.camera ? typeof ivk.camera === "function" ? ivk.camera() : ivk.camera : void 0);
|
|
26055
26683
|
invalidate();
|
|
26056
26684
|
}
|
|
26057
26685
|
}
|
|
26058
|
-
if (
|
|
26686
|
+
if (ivk.items && IV.itemsDirty && IV.t - IV.itemsT > 0.1 && !IV.anim.size) ivItems(IV, h);
|
|
26059
26687
|
}
|
|
26060
26688
|
const IV_SHAPE = {
|
|
26061
26689
|
can: [["cyl", 1, 1, 1, 0, 1]],
|
|
@@ -26090,7 +26718,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26090
26718
|
if (c.access && w.partT(E.id, c.access) < 0.02) continue;
|
|
26091
26719
|
const st = w.contents(E.id, c.id);
|
|
26092
26720
|
for (let i = 0; i < st.length; i++) {
|
|
26093
|
-
|
|
26721
|
+
const stack = st[i];
|
|
26722
|
+
if (stack && items[stack.type]) list2.push([E, c.id, i, items[stack.type]]);
|
|
26094
26723
|
}
|
|
26095
26724
|
}
|
|
26096
26725
|
}
|
|
@@ -26119,12 +26748,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26119
26748
|
gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
|
|
26120
26749
|
gm.computeBoundingSphere();
|
|
26121
26750
|
if (!IV.items) {
|
|
26122
|
-
|
|
26123
|
-
IV.items
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26751
|
+
const mesh2 = new THREE.Mesh(gm, shared2.mats.plain);
|
|
26752
|
+
IV.items = mesh2;
|
|
26753
|
+
mesh2.name = "iv-items";
|
|
26754
|
+
mesh2.castShadow = false;
|
|
26755
|
+
mesh2.receiveShadow = true;
|
|
26756
|
+
mesh2.frustumCulled = false;
|
|
26757
|
+
h.houseGroup.add(mesh2);
|
|
26128
26758
|
} else {
|
|
26129
26759
|
IV.items.geometry.dispose();
|
|
26130
26760
|
IV.items.geometry = gm;
|
|
@@ -26258,7 +26888,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26258
26888
|
};
|
|
26259
26889
|
return IV.pub;
|
|
26260
26890
|
}
|
|
26261
|
-
|
|
26891
|
+
const defined = { IV_MATERIAL, IV_WIRE, IV_DOOR, ivGroup, ivAccumulate, ivBuild, ivRoomEffective, ivDraw, ivCords, ivAssemble, ivScreen, ivEvent, ivSeat, ivUpdate, IV_SHAPE, ivItems, ivTarget, ivRoomLight, ivParts, ivDispose, ivPublish };
|
|
26892
|
+
Object.assign(K, defined);
|
|
26262
26893
|
}
|
|
26263
26894
|
function installAnimationClotheslines(K, shared2) {
|
|
26264
26895
|
const { invalidate, CLOTHES_UNIFORMS } = K;
|
|
@@ -26281,7 +26912,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26281
26912
|
}
|
|
26282
26913
|
invalidate();
|
|
26283
26914
|
}
|
|
26284
|
-
|
|
26915
|
+
const defined = { WIND, animateClotheslines };
|
|
26916
|
+
Object.assign(K, defined);
|
|
26285
26917
|
}
|
|
26286
26918
|
function installBuildInstance(K, shared2) {
|
|
26287
26919
|
const { PROPS, THREE, DOC, cfg, HP, createInteractiveMaterials, createMaterials, typeTable } = K;
|
|
@@ -26304,7 +26936,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26304
26936
|
shared2.quality = h.quality;
|
|
26305
26937
|
}
|
|
26306
26938
|
const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
|
|
26307
|
-
|
|
26939
|
+
const defined = { props, TYPES, newState, enter, tagDamage };
|
|
26940
|
+
Object.assign(K, defined);
|
|
26308
26941
|
}
|
|
26309
26942
|
function installInteractablesKit(K, shared2) {
|
|
26310
26943
|
const { t, THREE, DOC, cfg, Reflector } = K;
|
|
@@ -26330,15 +26963,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26330
26963
|
for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
|
|
26331
26964
|
return m;
|
|
26332
26965
|
})());
|
|
26333
|
-
|
|
26966
|
+
const defined = { IVK, VEG, vegMaterials };
|
|
26967
|
+
Object.assign(K, defined);
|
|
26334
26968
|
}
|
|
26969
|
+
var newGroup = (k, house, exterior) => ({ k, house, ls: [], exterior, pos: [0, 0, 0], color: 0, n: 0, range: 0, rects: [], y: [0, 0], exclusion: null, lumens: 0, dist: 0, decay: 0, floor: 0, roomId: null, dm: 0, d: 0 });
|
|
26335
26970
|
function installLightsRoomLight(K, shared2) {
|
|
26336
26971
|
const { THREE, rectsOf: rectsOf2, cfg } = K;
|
|
26337
26972
|
const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
|
|
26338
26973
|
const LZU = { uRB0: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB1: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB2: { value: new Float32Array(MAX_LIGHTS * 4) }, uRBY: { value: new Float32Array(MAX_LIGHTS * 2) }, uREx: { value: new Float32Array(MAX_LIGHTS * 4) }, uIndK: { value: 0.06 } };
|
|
26339
26974
|
for (let i = 0; i < MAX_LIGHTS; i++) for (const k of ["uRB0", "uRB1", "uRB2", "uREx"]) LZU[k].value.set(EMPTY, i * 4);
|
|
26340
|
-
function roomLightMask(
|
|
26341
|
-
|
|
26975
|
+
function roomLightMask(material) {
|
|
26976
|
+
const m = material;
|
|
26977
|
+
if (!m || m.userData && m.userData.roomLightMask || !(m.isMeshLambertMaterial || m.isMeshPhongMaterial || m.isMeshStandardMaterial || m.isMeshPhysicalMaterial)) return material;
|
|
26342
26978
|
m.userData = m.userData || {};
|
|
26343
26979
|
m.userData.roomLightMask = true;
|
|
26344
26980
|
const prev = m.onBeforeCompile, pk = m.customProgramCacheKey;
|
|
@@ -26366,12 +27002,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26366
27002
|
return (pk ? pk.call(this) : "") + "|rm1";
|
|
26367
27003
|
};
|
|
26368
27004
|
m.needsUpdate = true;
|
|
26369
|
-
return
|
|
27005
|
+
return material;
|
|
26370
27006
|
}
|
|
26371
|
-
function lighting(
|
|
26372
|
-
o =
|
|
27007
|
+
function lighting(options) {
|
|
27008
|
+
const o = options || {};
|
|
26373
27009
|
const scene = o.scene, N = Math.max(1, Math.min(MAX_LIGHTS, o.n || 6)), NS = Math.max(0, Math.min(N, o.shadows != null ? o.shadows : 2)), size = o.shadowSize || 512, MAX_EXTERNAL = o.external != null ? o.external : 2;
|
|
26374
|
-
|
|
27010
|
+
const mats = shared2.mats;
|
|
27011
|
+
for (const k of Object.keys(mats)) roomLightMask(mats[k]);
|
|
26375
27012
|
const budget = o.budget, lease = budget ? budget.lease({ owner: "floorplan.rooms", point: N, shadows: NS }) : null;
|
|
26376
27013
|
if (budget && !lease) throw new Error("lighting: the LightBudget has no " + N + " free point slots (" + NS + " with shadow) for the rooms");
|
|
26377
27014
|
if (budget) for (const [key2, width] of [["uRB0", 4], ["uRB1", 4], ["uRB2", 4], ["uRBY", 2], ["uREx", 4]]) {
|
|
@@ -26422,9 +27059,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26422
27059
|
}
|
|
26423
27060
|
for (let i = 0; i < NS; i++) PL[i].shadow.needsUpdate = true;
|
|
26424
27061
|
};
|
|
26425
|
-
A.update = function(
|
|
26426
|
-
op =
|
|
26427
|
-
houses = (Array.isArray(houses) ? houses : [houses]).filter(Boolean);
|
|
27062
|
+
A.update = function(houseOrList, focus, options2) {
|
|
27063
|
+
const op = options2 || {}, houses = (Array.isArray(houseOrList) ? houseOrList : [houseOrList]).filter((h) => !!h);
|
|
26428
27064
|
_f.set(focus.x, focus.y, focus.z);
|
|
26429
27065
|
const rooms = [], exterior = [];
|
|
26430
27066
|
for (const house of houses) {
|
|
@@ -26436,7 +27072,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26436
27072
|
if (!house.lightOn(l.roomId)) continue;
|
|
26437
27073
|
const k = l.type === "outdoor" ? "ext:" + (l.id || exterior.length) : l.roomId != null ? l.roomId : l.room;
|
|
26438
27074
|
let g = by.get(k);
|
|
26439
|
-
if (!g) by.set(k, g =
|
|
27075
|
+
if (!g) by.set(k, g = newGroup(k, house, l.type === "outdoor"));
|
|
26440
27076
|
g.ls.push(l);
|
|
26441
27077
|
}
|
|
26442
27078
|
for (const g of by.values()) {
|
|
@@ -26471,9 +27107,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26471
27107
|
}
|
|
26472
27108
|
}
|
|
26473
27109
|
g.exclusion = [x0 + 0.03, z0 + 0.03, x1 - 0.03, z1 - 0.03];
|
|
26474
|
-
|
|
26475
|
-
g.
|
|
26476
|
-
g.
|
|
27110
|
+
const l0 = ls[0];
|
|
27111
|
+
g.lumens = l0.lumens != null ? l0.lumens : 3.2;
|
|
27112
|
+
g.dist = l0.dist != null ? l0.dist : 5.5;
|
|
27113
|
+
g.decay = l0.decay != null ? l0.decay : 2;
|
|
26477
27114
|
} else {
|
|
26478
27115
|
const c = house.r.rooms.find((q) => q.id === g.k);
|
|
26479
27116
|
if (!c) continue;
|
|
@@ -26574,8 +27211,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26574
27211
|
}
|
|
26575
27212
|
const effectsByBudget = /* @__PURE__ */ new WeakMap();
|
|
26576
27213
|
const OPENING_REACH = 2.5, OPENING_SIDE = 0.6;
|
|
26577
|
-
function effectLights(
|
|
26578
|
-
o =
|
|
27214
|
+
function effectLights(options) {
|
|
27215
|
+
const o = options || {};
|
|
26579
27216
|
const budget = o.budget;
|
|
26580
27217
|
if (!budget) throw new Error("effectLights: a LightBudget is required");
|
|
26581
27218
|
const known = effectsByBudget.get(budget);
|
|
@@ -26653,7 +27290,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26653
27290
|
const A = {
|
|
26654
27291
|
/** Once per frame, after the budget's `present`: points the mask of every lit slot that is not the house's at the rooms its light reaches. */
|
|
26655
27292
|
update(houses) {
|
|
26656
|
-
const indoors = cfg.effectLightsIndoors !== false, list2 = (Array.isArray(houses) ? houses : [houses]).filter(
|
|
27293
|
+
const indoors = cfg.effectLightsIndoors !== false, list2 = (Array.isArray(houses) ? houses : [houses]).filter((h) => !!h), cache2 = /* @__PURE__ */ new Map();
|
|
26657
27294
|
for (let at2 = 0; at2 < size; at2++) {
|
|
26658
27295
|
if (ours.has(at2)) continue;
|
|
26659
27296
|
const light = budget.group.children[at2];
|
|
@@ -26681,7 +27318,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26681
27318
|
if (!o.ours) effectsByBudget.set(budget, A);
|
|
26682
27319
|
return A;
|
|
26683
27320
|
}
|
|
26684
|
-
|
|
27321
|
+
const defined = { MAX_LIGHTS, EMPTY, LZU, roomLightMask, lighting, effectLights };
|
|
27322
|
+
Object.assign(K, defined);
|
|
26685
27323
|
}
|
|
26686
27324
|
var NONE = { panels: [], replaced: [], supports: [] };
|
|
26687
27325
|
var MEMO = /* @__PURE__ */ new WeakMap();
|
|
@@ -26857,7 +27495,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26857
27495
|
if (!pc || pc.unit) return sp;
|
|
26858
27496
|
if (pc.role !== "wall" && pc.role !== "partition") {
|
|
26859
27497
|
const def = getAssembly(pc.assembly || (pc.material === "concrete" && ["slab", "beam", "column", "stair"].includes(pc.role) ? "reinforced_concrete" : ""));
|
|
26860
|
-
const
|
|
27498
|
+
const cage = def && def.reinforcement ? pc.role === "column" && sp.shape.kind === "box" ? { ...def.reinforcement, residualCapacity: cageResidualCapacity(sp.shape.size, def.reinforcement, sp.structure?.capacity) } : { ...def.reinforcement } : null;
|
|
27499
|
+
const out = cage && !sp.reinforcement ? { ...sp, reinforcement: cage } : sp;
|
|
26861
27500
|
if (out.reinforcement && !out.units && pc.material === "concrete" && (pc.role === "beam" || pc.role === "column") && sp.shape.kind === "box") {
|
|
26862
27501
|
return { ...out, units: { size: [MEMBER_CAGE.unit, MEMBER_CAGE.unit, Math.min(...sp.shape.size)], bond: "stack", mortar: "concrete" } };
|
|
26863
27502
|
}
|
|
@@ -26883,6 +27522,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26883
27522
|
const a = pos.array;
|
|
26884
27523
|
const u = mesh2.userData;
|
|
26885
27524
|
if (!u._p0) u._p0 = a.slice();
|
|
27525
|
+
if (!u.plainPositions) Object.defineProperty(u, "plainPositions", { value: u._p0, enumerable: false, configurable: true, writable: true });
|
|
26886
27526
|
const list2 = u.collapsedRanges ?? (u.collapsedRanges = []);
|
|
26887
27527
|
if (!list2.some((r) => r[0] === v0 && r[1] === v1)) list2.push([v0, v1]);
|
|
26888
27528
|
const saved = a.slice(v0 * 3, v1 * 3);
|
|
@@ -26966,10 +27606,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26966
27606
|
const v = house.worldToLocal(tmp.p.set(p[0], p[1], p[2]));
|
|
26967
27607
|
return [v.x, v.y, v.z];
|
|
26968
27608
|
};
|
|
26969
|
-
function cells(part, units) {
|
|
27609
|
+
function cells(part, units, mask) {
|
|
26970
27610
|
const [u0, v0, u1, v1] = part.aabb;
|
|
26971
|
-
const alongU =
|
|
27611
|
+
const alongU = mask.alongU;
|
|
26972
27612
|
const len = alongU ? u1 - u0 : v1 - v0;
|
|
27613
|
+
const offset = (alongU ? u0 : v0) - mask.start;
|
|
26973
27614
|
const [ul, uh] = units.size;
|
|
26974
27615
|
const rows = Math.max(1, Math.round((part.y1 - part.y0) / uh));
|
|
26975
27616
|
const rowH = (part.y1 - part.y0) / rows;
|
|
@@ -26980,7 +27621,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26980
27621
|
const shift = units.bond === "running" && r & 1 ? w / 2 : 0;
|
|
26981
27622
|
for (let i = 0; i < per + (shift ? 1 : 0); i++) {
|
|
26982
27623
|
const a = Math.max(0, i * w - shift), b = Math.min(len, i * w - shift + w);
|
|
26983
|
-
if (b - a > 1e-3) out.push({ a, b, y0: part.y0 + r * rowH, y1: part.y0 + (r + 1) * rowH, r, i });
|
|
27624
|
+
if (b - a > 1e-3) out.push({ a: offset + a, b: offset + b, y0: part.y0 + r * rowH, y1: part.y0 + (r + 1) * rowH, r, i });
|
|
26984
27625
|
}
|
|
26985
27626
|
}
|
|
26986
27627
|
return out;
|
|
@@ -26994,8 +27635,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
26994
27635
|
for (const q of structure.parts) {
|
|
26995
27636
|
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;
|
|
26996
27637
|
}
|
|
27638
|
+
return part.role === "column" ? wallAround(part) : null;
|
|
27639
|
+
}
|
|
27640
|
+
function wallAround(part) {
|
|
27641
|
+
const cu = (part.aabb[0] + part.aabb[2]) / 2, cv = (part.aabb[1] + part.aabb[3]) / 2;
|
|
27642
|
+
for (const q of structure.parts) {
|
|
27643
|
+
if (q.id === part.id || q.role !== "wall" && q.role !== "partition" || !structure.meshesOf(q.id).some((it) => it.mesh)) continue;
|
|
27644
|
+
const inside2 = cu >= q.aabb[0] - 1e-3 && cu <= q.aabb[2] + 1e-3 && cv >= q.aabb[1] - 1e-3 && cv <= q.aabb[3] + 1e-3;
|
|
27645
|
+
if (inside2 && Math.min(q.y1, part.y1) - Math.max(q.y0, part.y0) > 0.5) return q.id;
|
|
27646
|
+
}
|
|
26997
27647
|
return null;
|
|
26998
27648
|
}
|
|
27649
|
+
const pillarSpans = (view) => structure.parts.filter((q) => q.role === "column" && wallAround(q) === view.host).map((q) => {
|
|
27650
|
+
const a = (view.mask.alongU ? q.aabb[0] : q.aabb[1]) - view.mask.start, b = (view.mask.alongU ? q.aabb[2] : q.aabb[3]) - view.mask.start;
|
|
27651
|
+
return { a, b, y0: q.y0, y1: q.y1 };
|
|
27652
|
+
});
|
|
26999
27653
|
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);
|
|
27000
27654
|
function shell(it, mask) {
|
|
27001
27655
|
const g0 = it.mesh.geometry, g = new THREE.BufferGeometry();
|
|
@@ -27084,6 +27738,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27084
27738
|
texture.needsUpdate = true;
|
|
27085
27739
|
return { data, texture, w, h, alongU, start: alongU ? u0 : v0, len, y0, height: y1 - y0, rect: new THREE.Vector4(alongU ? u0 : v0, y0, len, y1 - y0) };
|
|
27086
27740
|
}
|
|
27741
|
+
function besidePillars(c, pillars) {
|
|
27742
|
+
let { a, b } = c;
|
|
27743
|
+
for (const k of pillars) {
|
|
27744
|
+
if (c.y1 <= k.y0 || c.y0 >= k.y1 || b <= k.a || a >= k.b) continue;
|
|
27745
|
+
const centre = (a + b) / 2;
|
|
27746
|
+
if (centre > k.a && centre < k.b) return [];
|
|
27747
|
+
if (centre <= k.a) b = Math.min(b, k.a);
|
|
27748
|
+
else a = Math.max(a, k.b);
|
|
27749
|
+
}
|
|
27750
|
+
return b - a > 1e-3 ? [{ ...c, a, b }] : [];
|
|
27751
|
+
}
|
|
27087
27752
|
const boxDistance = (s, y, a, b, c, d) => Math.hypot(Math.max(a - s, 0, s - b), Math.max(c - y, 0, y - d));
|
|
27088
27753
|
const ellipseDistance = (s, y, cs, cy, rs, ry) => (Math.hypot((s - cs) / Math.max(rs, 1e-4), (y - cy) / Math.max(ry, 1e-4)) - 1) * Math.min(rs, ry);
|
|
27089
27754
|
function covered(c, boxes) {
|
|
@@ -27106,9 +27771,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27106
27771
|
const discs = [];
|
|
27107
27772
|
const flakes = [];
|
|
27108
27773
|
const shown = [];
|
|
27774
|
+
const pillars = pillarSpans(view);
|
|
27109
27775
|
for (const id of view.parts) {
|
|
27110
27776
|
const part = structure.byId.get(id), units2 = specOf(id).units, chips = view.chips.get(id), opening = view.openings.get(id), spalls = view.spalls.get(id);
|
|
27111
|
-
const
|
|
27777
|
+
const own = cells(part, units2, mask);
|
|
27778
|
+
const all = id === view.host ? own.flatMap((c) => besidePillars(c, pillars)) : own;
|
|
27779
|
+
if (view.fallen.has(id)) {
|
|
27780
|
+
holes.push(...all);
|
|
27781
|
+
continue;
|
|
27782
|
+
}
|
|
27112
27783
|
const thick = mask.alongU ? part.aabb[3] - part.aabb[1] : part.aabb[2] - part.aabb[0];
|
|
27113
27784
|
const mid = mask.alongU ? (part.aabb[1] + part.aabb[3]) / 2 : (part.aabb[0] + part.aabb[2]) / 2;
|
|
27114
27785
|
if (opening) discs.push({ s: along(opening.center), y: opening.center[1], r: opening.radius });
|
|
@@ -27204,52 +27875,55 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27204
27875
|
}
|
|
27205
27876
|
return { center: local(chip.center), along: a, up: u };
|
|
27206
27877
|
}
|
|
27878
|
+
function newView(hostId) {
|
|
27879
|
+
const items = structure.meshesOf(hostId).filter((it) => it.mesh);
|
|
27880
|
+
if (!items.length) return null;
|
|
27881
|
+
const parts = [hostId, ...riders(hostId)].filter((id) => structure.byId.get(id) && specOf(id)?.units);
|
|
27882
|
+
const mask = maskOf(hostId, parts), core = maskOf(hostId, parts);
|
|
27883
|
+
return {
|
|
27884
|
+
host: hostId,
|
|
27885
|
+
parts,
|
|
27886
|
+
items,
|
|
27887
|
+
mask,
|
|
27888
|
+
core,
|
|
27889
|
+
unitMaterial: unitsMaterial(core),
|
|
27890
|
+
shells: [],
|
|
27891
|
+
saved: null,
|
|
27892
|
+
units: null,
|
|
27893
|
+
gone: 0,
|
|
27894
|
+
pits: 0,
|
|
27895
|
+
bounds: drawnBounds(items),
|
|
27896
|
+
chips: new Map(parts.map((id) => [id, []])),
|
|
27897
|
+
spalls: new Map(parts.map((id) => [id, []])),
|
|
27898
|
+
openings: /* @__PURE__ */ new Map(),
|
|
27899
|
+
flakes: 0,
|
|
27900
|
+
fallen: /* @__PURE__ */ new Set()
|
|
27901
|
+
};
|
|
27902
|
+
}
|
|
27903
|
+
function cut(view) {
|
|
27904
|
+
if (view.saved) return;
|
|
27905
|
+
view.shells = view.items.map((it) => shell(it, view.mask));
|
|
27906
|
+
for (const m of view.shells) m.userData.behind = () => view.units;
|
|
27907
|
+
view.saved = view.items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
|
|
27908
|
+
}
|
|
27207
27909
|
function draw(partId, change) {
|
|
27208
27910
|
if (lod !== 0) return false;
|
|
27209
27911
|
const hostId = hostOf(partId);
|
|
27210
27912
|
if (!hostId || !specOf(partId)?.units) return false;
|
|
27211
|
-
|
|
27212
|
-
if (!view)
|
|
27213
|
-
const items = structure.meshesOf(hostId).filter((it) => it.mesh);
|
|
27214
|
-
if (!items.length) return false;
|
|
27215
|
-
const parts = [hostId, ...riders(hostId)].filter((id) => structure.byId.get(id) && specOf(id)?.units);
|
|
27216
|
-
if (!parts.includes(partId)) return false;
|
|
27217
|
-
const mask = maskOf(hostId, parts), core = maskOf(hostId, parts);
|
|
27218
|
-
view = {
|
|
27219
|
-
host: hostId,
|
|
27220
|
-
parts,
|
|
27221
|
-
items,
|
|
27222
|
-
mask,
|
|
27223
|
-
core,
|
|
27224
|
-
unitMaterial: unitsMaterial(core),
|
|
27225
|
-
shells: [],
|
|
27226
|
-
saved: null,
|
|
27227
|
-
units: null,
|
|
27228
|
-
gone: 0,
|
|
27229
|
-
pits: 0,
|
|
27230
|
-
bounds: drawnBounds(items),
|
|
27231
|
-
chips: new Map(parts.map((id) => [id, []])),
|
|
27232
|
-
spalls: new Map(parts.map((id) => [id, []])),
|
|
27233
|
-
openings: /* @__PURE__ */ new Map(),
|
|
27234
|
-
flakes: 0
|
|
27235
|
-
};
|
|
27236
|
-
}
|
|
27237
|
-
if (!view.chips.has(partId)) return false;
|
|
27913
|
+
const view = views.get(hostId) ?? newView(hostId);
|
|
27914
|
+
if (!view || !view.chips.has(partId)) return false;
|
|
27238
27915
|
if (change.opening) {
|
|
27239
27916
|
if (view.openings.has(partId)) return false;
|
|
27240
27917
|
view.openings.set(partId, { center: local(change.opening.center), radius: change.opening.radius });
|
|
27241
27918
|
}
|
|
27242
27919
|
if (change.chip) view.chips.get(partId).push(chipBox(change.chip, view.mask.alongU));
|
|
27920
|
+
for (const chip of change.chips ?? []) view.chips.get(partId).push(chipBox(chip, view.mask.alongU));
|
|
27243
27921
|
if (change.spall) {
|
|
27244
27922
|
const list2 = view.spalls.get(partId);
|
|
27245
27923
|
list2.push({ center: local(change.spall.center), radius: change.spall.radius });
|
|
27246
27924
|
if (list2.length > MAX_FLAKES) list2.shift();
|
|
27247
27925
|
}
|
|
27248
|
-
|
|
27249
|
-
view.shells = view.items.map((it) => shell(it, view.mask));
|
|
27250
|
-
for (const m of view.shells) m.userData.behind = () => view.units;
|
|
27251
|
-
view.saved = view.items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
|
|
27252
|
-
}
|
|
27926
|
+
cut(view);
|
|
27253
27927
|
views.set(hostId, view);
|
|
27254
27928
|
if (opts.deferPaint && change.spall) dirty.add(view);
|
|
27255
27929
|
else {
|
|
@@ -27360,14 +28034,32 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27360
28034
|
*/
|
|
27361
28035
|
chip(event) {
|
|
27362
28036
|
if (event.torn) return false;
|
|
27363
|
-
|
|
28037
|
+
const rotation = event.rotation ?? [0, 0, 0, 1];
|
|
28038
|
+
if (event.units?.length) return draw(event.part, { chips: event.units.map((unit) => ({ center: unit.center, size: unit.size, rotation })) });
|
|
28039
|
+
return draw(event.part, { chip: { center: event.center, size: event.size ?? [0, 0, 0], rotation } });
|
|
27364
28040
|
},
|
|
27365
28041
|
/** The part broke or fell: its damage goes (the plain range stays collapsed, the renderer hides the part). */
|
|
27366
28042
|
drop(partId) {
|
|
27367
|
-
|
|
27368
|
-
if (!
|
|
28043
|
+
let host = views.get(partId) ?? [...views.values()].find((view) => view.parts.includes(partId));
|
|
28044
|
+
if (!host && lod === 0 && riders(partId).length > 0) {
|
|
28045
|
+
host = newView(partId);
|
|
28046
|
+
if (host) {
|
|
28047
|
+
cut(host);
|
|
28048
|
+
views.set(partId, host);
|
|
28049
|
+
}
|
|
28050
|
+
}
|
|
28051
|
+
if (!host) return;
|
|
28052
|
+
host.fallen.add(partId);
|
|
28053
|
+
if (host.parts.some((id) => !host.fallen.has(id))) {
|
|
28054
|
+
dirty.delete(host);
|
|
28055
|
+
paint(host);
|
|
28056
|
+
invalidate();
|
|
28057
|
+
invalidateShadow();
|
|
28058
|
+
return;
|
|
28059
|
+
}
|
|
28060
|
+
const v = host;
|
|
27369
28061
|
dispose(v);
|
|
27370
|
-
views.delete(
|
|
28062
|
+
views.delete(v.host);
|
|
27371
28063
|
if (v.saved) dropped.push(v);
|
|
27372
28064
|
},
|
|
27373
28065
|
/** LOD 0 draws the cut wall; LOD 1 and 2 give the wall its box back. */
|
|
@@ -27804,8 +28496,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27804
28496
|
}
|
|
27805
28497
|
function installBuildBuild(K, shared2) {
|
|
27806
28498
|
const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS: EPS3, LIGHTS, MIRRORS, Y0, animateClotheslines, animateDoors, animateInteractive, applyLeaf, applyOutbuildings, applyPart, applyPiece, assembleInteractive, baseboardAndSidewalk, buildStairs, building, carModel, chooseMirror, closeScene, collideAt, createWater, cursor, doorText, doors, electricalStructure, elevator, floorsAndSlabs, gatesInteractive, houseItems, ivAssemble, ivBuild, ivDispose, ivParts, ivPublish, ivUpdate, lightOn, linkDoorLeaves, mailboxInteractive, newInteractiveState, newMirrorState, outbuildings, paths, perimeter, placeSwitches, roofs, roomAt, solar, targetOf, terrain, toggleDoor, toggleLight, walls, waterPipes, windows, props, TYPES, IVK, VEG, vegMaterials, markGroups, assembleStructure, createHouseDestruction, newState, enter, tagDamage } = K;
|
|
27807
|
-
function build(r0,
|
|
27808
|
-
opts =
|
|
28499
|
+
function build(r0, options) {
|
|
28500
|
+
const opts = options || {};
|
|
27809
28501
|
const r = applyOutbuildings(r0);
|
|
27810
28502
|
const t0 = performance.now();
|
|
27811
28503
|
const h = { ctx: { mv: props, types: TYPES }, inter: newInteractiveState(), state: opts.state || newState(), mirrors: newMirrorState(), quality: opts.quality === "game" || opts.quality === "high" ? opts.quality : cfg.quality === "game" ? "game" : "high", lodCurrent: 0, lodMin: 0 };
|
|
@@ -27826,7 +28518,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27826
28518
|
shared2.ctx.pieces = /* @__PURE__ */ new Map();
|
|
27827
28519
|
shared2.ctx.pieceObjects = /* @__PURE__ */ new Map();
|
|
27828
28520
|
shared2.ctx.structureIndex = {};
|
|
27829
|
-
for (const e of r0.structure
|
|
28521
|
+
for (const e of r0.structure?.parts || []) shared2.ctx.structureIndex[e.id] = e;
|
|
27830
28522
|
{
|
|
27831
28523
|
const view = shared2.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
|
|
27832
28524
|
shared2.ctx.panelsOf = /* @__PURE__ */ new Map();
|
|
@@ -27838,17 +28530,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27838
28530
|
else shared2.ctx.panelsOf.set(e.slab, [e]);
|
|
27839
28531
|
}
|
|
27840
28532
|
}
|
|
27841
|
-
shared2.ctx.panes = r0.roof
|
|
28533
|
+
shared2.ctx.panes = r0.roof?.panes || [];
|
|
27842
28534
|
shared2.ctx.noPiece = false;
|
|
27843
28535
|
cursor.separate = opts.pieces === "meshes";
|
|
27844
28536
|
cursor.pc = null;
|
|
28537
|
+
shared2.ctx.showPillars = opts.pillars !== "hidden";
|
|
27845
28538
|
shared2.ctx.apartment = r.template === "apartment_modern";
|
|
27846
28539
|
shared2.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
|
|
27847
28540
|
shared2.ctx.pf = Math.max(1, Math.min(shared2.ctx.pa, pr.floor != null ? pr.floor : 3));
|
|
27848
28541
|
shared2.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
|
|
27849
28542
|
shared2.ctx.showBuilding = shared2.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
|
|
27850
28543
|
shared2.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
|
|
27851
|
-
shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
|
|
28544
|
+
shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { quality: "high", lod: 0, triangleBudget: 6e4 } } : null;
|
|
27852
28545
|
shared2.ctx.vegInfo = null;
|
|
27853
28546
|
terrain();
|
|
27854
28547
|
if (r.lot) {
|
|
@@ -27898,7 +28591,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27898
28591
|
const g = gs[gd.name];
|
|
27899
28592
|
if (!g) continue;
|
|
27900
28593
|
delete gs[gd.name];
|
|
27901
|
-
g.position.
|
|
28594
|
+
g.position.fromArray(gd.pos);
|
|
27902
28595
|
parent.add(g);
|
|
27903
28596
|
fo.gs.push(g);
|
|
27904
28597
|
}
|
|
@@ -27913,7 +28606,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
27913
28606
|
root.add(house);
|
|
27914
28607
|
shared2.mirrors.house = house;
|
|
27915
28608
|
if (shared2.ctx.apartment) {
|
|
27916
|
-
const
|
|
28609
|
+
const units = r.building.units, u = units[Math.min(shared2.ctx.pu, units.length - 1)];
|
|
27917
28610
|
house.position.set(u.u, shared2.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
|
|
27918
28611
|
house.rotation.y = u.ry;
|
|
27919
28612
|
shared2.ctx.unitRy = u.ry;
|
|
@@ -28029,7 +28722,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28029
28722
|
const wallAt = (f, axis, L) => r.walls.find((w) => w.floor === f && w.axis === axis && Math.abs((axis === "u" ? w.v0 : w.u0) - L) < EPS3);
|
|
28030
28723
|
for (const j of r.windows) {
|
|
28031
28724
|
const alongU = j.axis === "u", y0 = Y0(j.floor), a = j.at - j.width / 2, b = j.at + j.width / 2, w = wallAt(j.floor, j.axis, j.pos), th = w ? w.thickness || 0.15 : 0.15, L = j.pos, id = "window:" + j.id;
|
|
28032
|
-
|
|
28725
|
+
const jy0 = j.y0, jy1 = j.y1;
|
|
28726
|
+
parts[id] = { id, type: "window", group: null, virtual: true, floor: j.floor, aabb: alongU ? [a, y0 + jy0, L - th / 2, b, y0 + jy1, L + th / 2] : [L - th / 2, y0 + jy0, a, L + th / 2, y0 + jy1, b], damageable: tagDamage("glass"), opens: () => {
|
|
28033
28727
|
}, t: 0 };
|
|
28034
28728
|
}
|
|
28035
28729
|
for (const E of mirrorsCopy) {
|
|
@@ -28072,7 +28766,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28072
28766
|
const countDraw = () => {
|
|
28073
28767
|
let n = 0, t = 0;
|
|
28074
28768
|
root.traverseVisible((o) => {
|
|
28075
|
-
if (o
|
|
28769
|
+
if (isMesh(o)) {
|
|
28076
28770
|
n++;
|
|
28077
28771
|
t += (o.geometry.index ? o.geometry.index.count : o.geometry.attributes.position.count) / 3;
|
|
28078
28772
|
}
|
|
@@ -28086,8 +28780,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28086
28780
|
const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
|
|
28087
28781
|
const stats2 = { quality: h.quality, drawCalls: s0.n, drawCallsLOD1: s1.n, triangles: s0.t, trianglesLod1: s1.t, budget: budget || null, overBudget: !!budget && s0.n > budget, tBuild: performance.now() - t0 };
|
|
28088
28782
|
shared2.ctx.tBuild = stats2.tBuild;
|
|
28089
|
-
const applyLod = (
|
|
28090
|
-
n = Math.max(0, Math.min(2,
|
|
28783
|
+
const applyLod = (level) => {
|
|
28784
|
+
const n = Math.max(0, Math.min(2, level | 0));
|
|
28091
28785
|
if (n === h.lodCurrent) return;
|
|
28092
28786
|
h.lodCurrent = n;
|
|
28093
28787
|
for (const o of lodObjects) o.visible = n < 1;
|
|
@@ -28164,7 +28858,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28164
28858
|
lights: (() => {
|
|
28165
28859
|
const by = {};
|
|
28166
28860
|
for (const l of shared2.ctx.lights) {
|
|
28167
|
-
const k = l.roomId != null ? l.roomId : l.room;
|
|
28861
|
+
const k = String(l.roomId != null ? l.roomId : l.room);
|
|
28168
28862
|
(by[k] || (by[k] = [])).push(l);
|
|
28169
28863
|
}
|
|
28170
28864
|
return { list: shared2.ctx.lights, byRoom: by };
|
|
@@ -28204,9 +28898,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28204
28898
|
applyLod(Math.max(n, h.lodMin));
|
|
28205
28899
|
}
|
|
28206
28900
|
},
|
|
28207
|
-
show(
|
|
28901
|
+
show(options2) {
|
|
28208
28902
|
enter(h);
|
|
28209
|
-
o =
|
|
28903
|
+
const o = options2 || {};
|
|
28210
28904
|
const rr = shared2.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
|
|
28211
28905
|
for (const [k, g] of Object.entries(gs)) {
|
|
28212
28906
|
let v = true;
|
|
@@ -28226,7 +28920,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28226
28920
|
enter(h);
|
|
28227
28921
|
const a = targetOf(o, opt);
|
|
28228
28922
|
if (!a) return false;
|
|
28229
|
-
return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action }, a);
|
|
28923
|
+
return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action, floor: 0, pos: [], radius: 0 }, a);
|
|
28230
28924
|
},
|
|
28231
28925
|
message() {
|
|
28232
28926
|
return shared2.inter.msg && performance.now() < shared2.inter.msg.until ? shared2.inter.msg.text : null;
|
|
@@ -28283,13 +28977,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28283
28977
|
}
|
|
28284
28978
|
return null;
|
|
28285
28979
|
},
|
|
28286
|
-
partAt(p,
|
|
28287
|
-
tol =
|
|
28980
|
+
partAt(p, tolerance) {
|
|
28981
|
+
const tol = tolerance || 0.05;
|
|
28288
28982
|
let m = null;
|
|
28289
28983
|
for (const k in parts) {
|
|
28290
|
-
const
|
|
28984
|
+
const part = parts[k], a = part.aabb;
|
|
28291
28985
|
if (a && p.x >= a[0] - tol && p.x <= a[3] + tol && p.y >= a[1] - tol && p.y <= a[4] + tol && p.z >= a[2] - tol && p.z <= a[5] + tol) {
|
|
28292
|
-
m =
|
|
28986
|
+
m = part;
|
|
28293
28987
|
break;
|
|
28294
28988
|
}
|
|
28295
28989
|
}
|
|
@@ -28300,8 +28994,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28300
28994
|
destruction.deactivate();
|
|
28301
28995
|
if (h.IV) ivDispose(h);
|
|
28302
28996
|
root.traverse((o) => {
|
|
28303
|
-
if (o
|
|
28304
|
-
if (o.type === "Reflector" && o.dispose) o.dispose();
|
|
28997
|
+
if (isMesh(o) && o.geometry && !o.geometry.userData.shared) o.geometry.dispose();
|
|
28998
|
+
if (o.type === "Reflector" && "dispose" in o && typeof o.dispose === "function") o.dispose();
|
|
28305
28999
|
});
|
|
28306
29000
|
root.removeFromParent();
|
|
28307
29001
|
},
|
|
@@ -28309,7 +29003,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28309
29003
|
};
|
|
28310
29004
|
return res;
|
|
28311
29005
|
}
|
|
28312
|
-
|
|
29006
|
+
const defined = { build };
|
|
29007
|
+
Object.assign(K, defined);
|
|
28313
29008
|
}
|
|
28314
29009
|
function buildApi(K, shared2) {
|
|
28315
29010
|
const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, effectLights, newState, build } = K;
|
|
@@ -28329,11 +29024,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28329
29024
|
lighting,
|
|
28330
29025
|
effectLights,
|
|
28331
29026
|
setNight(n) {
|
|
28332
|
-
shared2.mats.glass
|
|
28333
|
-
|
|
29027
|
+
const glass = shared2.mats.glass;
|
|
29028
|
+
glass.emissive.set(n ? 9067040 : 0);
|
|
29029
|
+
glass.opacity = n ? 0.4 : 0.24;
|
|
28334
29030
|
},
|
|
28335
29031
|
/** The chipped-plaster painting of every house of this renderer as a `DeferredQueue` for a frame budget (id `floorplan.breach-paint`); asking for it changes nothing. */
|
|
28336
29032
|
deferredQueue: () => K.breachPaintQueue,
|
|
29033
|
+
/* the destruction side is typed with the breach */
|
|
28337
29034
|
cars: { model: carModel, group: carGroup, info: (k, seed) => {
|
|
28338
29035
|
const m = carModel(k, seed);
|
|
28339
29036
|
return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
|
|
@@ -28435,10 +29132,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
28435
29132
|
}
|
|
28436
29133
|
|
|
28437
29134
|
// ../game-floorplan-residential/dist/index.js
|
|
28438
|
-
var
|
|
29135
|
+
var __defProp3 = Object.defineProperty;
|
|
28439
29136
|
var __export2 = (target, all) => {
|
|
28440
29137
|
for (var name in all)
|
|
28441
|
-
|
|
29138
|
+
__defProp3(target, name, { get: all[name], enumerable: true });
|
|
28442
29139
|
};
|
|
28443
29140
|
var residentialItems = [
|
|
28444
29141
|
{ type: "sofa_3seat", category: "sofa", w: 2.1, d: 0.9, h: 0.85, color: { role: "fabric_main" } },
|