@adatechnology/game-floorplan-three 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7XVCZF6H.js → chunk-Y3Y7NYOL.js} +422 -272
- package/dist/chunk-Y3Y7NYOL.js.map +1 -0
- package/dist/index.d.ts +92 -34
- package/dist/index.global.js +447 -292
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/testing-BK7QmoUq.d.ts +1611 -0
- package/dist/testing.d.ts +12 -1
- package/dist/testing.js +1 -1
- package/package.json +24 -10
- package/dist/chunk-7XVCZF6H.js.map +0 -1
- package/dist/testing-CcAh3Eg1.d.ts +0 -386
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
1
5
|
// src/test-area/module.ts
|
|
2
6
|
import { DEFERRED_PRIORITY, DEFERRED_QUEUE_ID as DEFERRED_QUEUE_ID2 } from "@adatechnology/game-contracts";
|
|
3
7
|
import { isLightBudget } from "@adatechnology/game-render-three";
|
|
@@ -108,6 +112,20 @@ function installKernelGeometry(K, shared) {
|
|
|
108
112
|
const WITH_MAP = { roughcast: 1, block: 1 };
|
|
109
113
|
class Accumulator {
|
|
110
114
|
constructor() {
|
|
115
|
+
__publicField(this, "cv");
|
|
116
|
+
__publicField(this, "ci");
|
|
117
|
+
__publicField(this, "p");
|
|
118
|
+
__publicField(this, "n");
|
|
119
|
+
__publicField(this, "c");
|
|
120
|
+
__publicField(this, "u");
|
|
121
|
+
__publicField(this, "i");
|
|
122
|
+
__publicField(this, "nv");
|
|
123
|
+
__publicField(this, "ni");
|
|
124
|
+
__publicField(this, "lim");
|
|
125
|
+
__publicField(this, "cur");
|
|
126
|
+
__publicField(this, "piece0");
|
|
127
|
+
__publicField(this, "mat", "");
|
|
128
|
+
__publicField(this, "group", "");
|
|
111
129
|
this.cv = 2048;
|
|
112
130
|
this.ci = 3072;
|
|
113
131
|
this.p = new Float32Array(this.cv * 3);
|
|
@@ -170,7 +188,8 @@ function installKernelGeometry(K, shared) {
|
|
|
170
188
|
g.position.copy(u.pose0.p);
|
|
171
189
|
g.quaternion.copy(u.pose0.q);
|
|
172
190
|
g.scale.copy(u.pose0.s);
|
|
173
|
-
const
|
|
191
|
+
const [ax, ay, az] = a.axis || [0, 1, 0];
|
|
192
|
+
const e = new THREE.Vector3(ax, ay, az);
|
|
174
193
|
if (a.type === "swing" || a.type === "toggle") g.rotateOnAxis(e, (a.angle || 0) * t);
|
|
175
194
|
else if (a.type === "slide") g.translateOnAxis(e, (a.dist || 0) * t);
|
|
176
195
|
else if (a.type === "scale") {
|
|
@@ -265,7 +284,7 @@ function installKernelGeometry(K, shared) {
|
|
|
265
284
|
}
|
|
266
285
|
if (uvr) {
|
|
267
286
|
let gu = G.u[k * 2], gv = G.u[k * 2 + 1];
|
|
268
|
-
for (let r = uvr.rot | 0; r > 0; r--) {
|
|
287
|
+
for (let r = (uvr.rot ?? 0) | 0; r > 0; r--) {
|
|
269
288
|
const t = gu;
|
|
270
289
|
gu = gv;
|
|
271
290
|
gv = 1 - t;
|
|
@@ -363,14 +382,13 @@ function installKernelGeometry(K, shared) {
|
|
|
363
382
|
A.nv += n;
|
|
364
383
|
}
|
|
365
384
|
let bxImpl = bxBase;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
K.getBx = () => bxImpl;
|
|
370
|
-
K.setBx = (f) => {
|
|
385
|
+
const bx = (...a) => bxImpl(...a);
|
|
386
|
+
const getBx = () => bxImpl;
|
|
387
|
+
const setBx = (f) => {
|
|
371
388
|
bxImpl = f;
|
|
372
389
|
};
|
|
373
|
-
|
|
390
|
+
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 };
|
|
391
|
+
Object.assign(K, defined);
|
|
374
392
|
}
|
|
375
393
|
|
|
376
394
|
// src/kernel/noise.ts
|
|
@@ -388,17 +406,20 @@ function installKernelNoise(K, _shared) {
|
|
|
388
406
|
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;
|
|
389
407
|
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)];
|
|
390
408
|
}
|
|
391
|
-
|
|
409
|
+
const defined = { _h2, vnoise, macroGround };
|
|
410
|
+
Object.assign(K, defined);
|
|
392
411
|
}
|
|
393
412
|
|
|
394
413
|
// src/materials/textures.ts
|
|
395
414
|
function installMaterialsTextures(K, _shared) {
|
|
396
415
|
const { DOC, THREE, cfg } = K;
|
|
397
416
|
function texture(n, f, rep = true, rx = 1, ry = 1) {
|
|
417
|
+
if (!DOC) throw new Error("game-floorplan-three: the procedural textures need a document (options.document)");
|
|
398
418
|
const c = DOC.createElement("canvas");
|
|
399
419
|
c.width = n;
|
|
400
420
|
c.height = n;
|
|
401
421
|
const g = c.getContext("2d");
|
|
422
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
402
423
|
f(g, n);
|
|
403
424
|
const t = new THREE.CanvasTexture(c);
|
|
404
425
|
t.colorSpace = THREE.SRGBColorSpace;
|
|
@@ -517,10 +538,16 @@ function installMaterialsTextures(K, _shared) {
|
|
|
517
538
|
const TEX = {};
|
|
518
539
|
for (const k of Object.keys(TEXGEN)) TEX[k] = cfg.textures && cfg.textures[k] || TEXGEN[k]();
|
|
519
540
|
const ATLAS = {};
|
|
520
|
-
|
|
541
|
+
const defined = { texture, rngTexture, TEXGEN, TEX, ATLAS };
|
|
542
|
+
Object.assign(K, defined);
|
|
521
543
|
}
|
|
522
544
|
|
|
523
545
|
// src/materials/materials.ts
|
|
546
|
+
function context2d(c) {
|
|
547
|
+
const g = c.getContext("2d");
|
|
548
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
549
|
+
return g;
|
|
550
|
+
}
|
|
524
551
|
function installMaterialsMaterials(K, _shared) {
|
|
525
552
|
const { THREE, cfg, ATLAS, TEX, rngTexture } = K;
|
|
526
553
|
function createMaterials(props) {
|
|
@@ -532,7 +559,7 @@ function installMaterialsMaterials(K, _shared) {
|
|
|
532
559
|
return t;
|
|
533
560
|
};
|
|
534
561
|
if (!(cfg.atlas && cfg.atlas.floorKind)) {
|
|
535
|
-
const pc = props.atlas("floor").canvas, g = pc
|
|
562
|
+
const pc = props.atlas("floor").canvas, g = context2d(pc);
|
|
536
563
|
for (const c of [0, 1]) {
|
|
537
564
|
g.save();
|
|
538
565
|
g.globalCompositeOperation = "screen";
|
|
@@ -547,7 +574,7 @@ function installMaterialsMaterials(K, _shared) {
|
|
|
547
574
|
g.restore();
|
|
548
575
|
}
|
|
549
576
|
if (!(cfg.atlas && cfg.atlas.floorKind)) {
|
|
550
|
-
const pc = props.atlas("floor").canvas, g = pc
|
|
577
|
+
const pc = props.atlas("floor").canvas, g = context2d(pc);
|
|
551
578
|
g.save();
|
|
552
579
|
g.fillStyle = "rgba(128,92,62,0.52)";
|
|
553
580
|
g.fillRect(256, 256, 256, 256);
|
|
@@ -644,7 +671,8 @@ function installMaterialsMaterials(K, _shared) {
|
|
|
644
671
|
}
|
|
645
672
|
const ORDER = { glass: 3, water: 2, screen: 3, building: 4 };
|
|
646
673
|
const NO_SHADOW = /* @__PURE__ */ new Set(["dirt", "glass", "water", "screen", "building", "picture", "floor", "emissive"]);
|
|
647
|
-
|
|
674
|
+
const defined = { createMaterials, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER, NO_SHADOW };
|
|
675
|
+
Object.assign(K, defined);
|
|
648
676
|
}
|
|
649
677
|
|
|
650
678
|
// src/kernel/close-scene.ts
|
|
@@ -655,15 +683,18 @@ function installKernelCloseScene(K, shared) {
|
|
|
655
683
|
const assembleVegetation = (...a) => K.assembleVegetation(...a);
|
|
656
684
|
function markMesh(m, A) {
|
|
657
685
|
const L = A.lim, fx = [];
|
|
686
|
+
const pieces = shared.ctx.pieces;
|
|
658
687
|
for (let k = 0; k < L.length; k++) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
688
|
+
const lim = L[k], pc = lim.pc;
|
|
689
|
+
if (!pc) continue;
|
|
690
|
+
const next = L[k + 1];
|
|
691
|
+
const v1 = next ? next.v : A.nv, i1 = next ? next.i : A.ni;
|
|
692
|
+
if (v1 > lim.v) fx.push({ id: pc.id, v0: lim.v, v1, i0: lim.i, i1 });
|
|
662
693
|
}
|
|
663
694
|
if (!fx.length) return;
|
|
664
695
|
const u = m.userData, ids = [...new Set(fx.map((f) => f.id))], weight = {};
|
|
665
696
|
for (const f of fx) {
|
|
666
|
-
const mt =
|
|
697
|
+
const mt = pieces.get(f.id).mat;
|
|
667
698
|
weight[mt] = (weight[mt] || 0) + f.v1 - f.v0;
|
|
668
699
|
}
|
|
669
700
|
u.ranges = fx;
|
|
@@ -671,7 +702,7 @@ function installKernelCloseScene(K, shared) {
|
|
|
671
702
|
u.destructionMaterial = Object.keys(weight).sort((a, b) => weight[b] - weight[a])[0];
|
|
672
703
|
if (ids.length === 1) {
|
|
673
704
|
u.destructionPart = ids[0];
|
|
674
|
-
const pc =
|
|
705
|
+
const pc = pieces.get(ids[0]);
|
|
675
706
|
if (pc.role) u.structuralRole = pc.role;
|
|
676
707
|
}
|
|
677
708
|
}
|
|
@@ -722,7 +753,8 @@ function installKernelCloseScene(K, shared) {
|
|
|
722
753
|
assembleVegetation(groups);
|
|
723
754
|
return groups;
|
|
724
755
|
}
|
|
725
|
-
|
|
756
|
+
const defined = { markMesh, closeScene };
|
|
757
|
+
Object.assign(K, defined);
|
|
726
758
|
}
|
|
727
759
|
|
|
728
760
|
// src/house/helpers.ts
|
|
@@ -760,8 +792,14 @@ function installHouseHelpers(K, shared) {
|
|
|
760
792
|
for (const h of holes) L = L.flatMap((r) => subRect(r, h));
|
|
761
793
|
return L;
|
|
762
794
|
}
|
|
763
|
-
const wallColor = (c) =>
|
|
764
|
-
|
|
795
|
+
const wallColor = (c) => {
|
|
796
|
+
const k = c && c.color ? colorOf(c.color.wall) : null;
|
|
797
|
+
return k != null ? k : 14999768;
|
|
798
|
+
};
|
|
799
|
+
const floorColor = (c) => {
|
|
800
|
+
const k = c && c.color ? colorOf(c.color.floor) : null;
|
|
801
|
+
return k != null ? k : 11577496;
|
|
802
|
+
};
|
|
765
803
|
function stairFootprint(m) {
|
|
766
804
|
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]);
|
|
767
805
|
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]))];
|
|
@@ -772,13 +810,14 @@ function installHouseHelpers(K, shared) {
|
|
|
772
810
|
const pitch = A[f + 1].y0 - A[f].y0;
|
|
773
811
|
return h > pitch && h - pitch <= 0.45 ? pitch : h;
|
|
774
812
|
}
|
|
775
|
-
|
|
813
|
+
const defined = { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES2, NO_CEILING, OPEN_AREA, EPS, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight };
|
|
814
|
+
Object.assign(K, defined);
|
|
776
815
|
}
|
|
777
816
|
|
|
778
817
|
// src/house/walls.ts
|
|
779
818
|
function installHouseWalls(K, shared) {
|
|
780
819
|
const { EPS, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
|
|
781
|
-
const sh = (
|
|
820
|
+
const sh = (...a) => K.sh(...a);
|
|
782
821
|
function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
|
|
783
822
|
if (yb - ya < 1e-4 || b - a < 1e-4) return;
|
|
784
823
|
if (alongU) {
|
|
@@ -824,7 +863,7 @@ function installHouseWalls(K, shared) {
|
|
|
824
863
|
const corners = /* @__PURE__ */ new Map();
|
|
825
864
|
const looks = /* @__PURE__ */ new Map();
|
|
826
865
|
for (const w of R.walls) {
|
|
827
|
-
const f = w.floor;
|
|
866
|
+
const f = w.floor, colliders = shared.ctx.colliders;
|
|
828
867
|
cursor.group = "f" + f;
|
|
829
868
|
cursor.pc = pieceOf(w);
|
|
830
869
|
const y0 = Y0(f), pitch = f + 1 < nA ? Y0(f + 1) - y0 : Infinity, th = w.thickness || 0.15, alongU = w.axis === "u";
|
|
@@ -836,7 +875,7 @@ function installHouseWalls(K, shared) {
|
|
|
836
875
|
const face = sideL.exterior ? sideL : sideH;
|
|
837
876
|
looks.set(w.id, { mat: face.mat, color: face.color, top: y0 + hh });
|
|
838
877
|
}
|
|
839
|
-
|
|
878
|
+
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 });
|
|
840
879
|
if (w.type === "railing") {
|
|
841
880
|
const c0 = shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9080466;
|
|
842
881
|
const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
|
|
@@ -902,7 +941,8 @@ function installHouseWalls(K, shared) {
|
|
|
902
941
|
}
|
|
903
942
|
cursor.pc = null;
|
|
904
943
|
}
|
|
905
|
-
|
|
944
|
+
const defined = { wallBox, sideOf, pieceOf, nearestWall, walls, wallPillars };
|
|
945
|
+
Object.assign(K, defined);
|
|
906
946
|
}
|
|
907
947
|
|
|
908
948
|
// src/house/doors.ts
|
|
@@ -921,7 +961,7 @@ function installHouseDoors(K, shared) {
|
|
|
921
961
|
}
|
|
922
962
|
shared.doorState = /* @__PURE__ */ new Map();
|
|
923
963
|
function doors() {
|
|
924
|
-
shared.ctx.leaves = [];
|
|
964
|
+
const leaves = shared.ctx.leaves = [], doorState = shared.doorState, colliders = shared.ctx.colliders;
|
|
925
965
|
const R = shared.ctx.r, cut = shared.ctx.cut, C = shared.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame = sh(wood, 0.55);
|
|
926
966
|
for (const p of R.doors) {
|
|
927
967
|
const f = p.floor;
|
|
@@ -952,21 +992,21 @@ function installHouseDoors(K, shared) {
|
|
|
952
992
|
}
|
|
953
993
|
const leaf = (u0, u1, y_0, y_1, tt, color, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color);
|
|
954
994
|
const extC = wood;
|
|
955
|
-
const open0 = p.blocked ? false :
|
|
956
|
-
|
|
995
|
+
const open0 = p.blocked ? false : doorState.has(p.id) ? doorState.get(p.id) === true : !!p.open;
|
|
996
|
+
doorState.set(p.id, open0);
|
|
957
997
|
const dc = alongU ? [p.at, L] : [L, p.at];
|
|
958
|
-
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 };
|
|
998
|
+
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 };
|
|
959
999
|
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 };
|
|
960
|
-
|
|
1000
|
+
colliders.push(colR);
|
|
961
1001
|
fo.col = colR;
|
|
962
1002
|
const leafBox = (hu, d0, d1, y_0, y_1, tt, color, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color);
|
|
963
|
-
const
|
|
1003
|
+
const newGroup2 = (k, hu, topY) => {
|
|
964
1004
|
cursor.group = "dyn:" + p.id + ":" + k;
|
|
965
1005
|
fo.groups.push({ name: cursor.group, pos: alongU ? [hu, topY != null ? y0 + topY : y0, L] : [L, topY != null ? y0 + topY : y0, hu] });
|
|
966
1006
|
};
|
|
967
1007
|
if (p.model === "steel") {
|
|
968
|
-
const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
|
|
969
|
-
|
|
1008
|
+
const light = [14276044, 13223615, 14999766], pal = ((Number(R.seed) | 0) + p.id.length * 7) % 4, color = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
|
|
1009
|
+
newGroup2(0, mid, visH);
|
|
970
1010
|
const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color, 0.55);
|
|
971
1011
|
leafBox(0, la, lb, -visH, 0, 0.05, color, "metal");
|
|
972
1012
|
for (let k = 1; k < nSec; k++) leafBox(0, la, lb, -k * hs - 0.012, -k * hs + 0.012, 0.07, grv, "metal");
|
|
@@ -981,7 +1021,7 @@ function installHouseDoors(K, shared) {
|
|
|
981
1021
|
for (let k = 0; k < nf; k++) {
|
|
982
1022
|
const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color = p.exterior ? extC : wood;
|
|
983
1023
|
const hingeAt = nf === 2 ? k ? u1 : u0 : p.hinge === "end" ? u1 : u0, dir = hingeAt === u0 ? 1 : -1, len = u1 - u0;
|
|
984
|
-
|
|
1024
|
+
newGroup2(k, hingeAt);
|
|
985
1025
|
const d0 = dir > 0 ? 5e-3 : -len + 5e-3, d1 = dir > 0 ? len - 5e-3 : -5e-3;
|
|
986
1026
|
leafBox(hingeAt, d0, d1, 0, visH, 0.04, color, PMAT);
|
|
987
1027
|
{
|
|
@@ -1017,7 +1057,7 @@ function installHouseDoors(K, shared) {
|
|
|
1017
1057
|
fo.rot = Math.atan2(n[0] * A[1] - n[1] * A[0], A[0] * n[0] + A[1] * n[1]);
|
|
1018
1058
|
}
|
|
1019
1059
|
}
|
|
1020
|
-
|
|
1060
|
+
leaves.push(fo);
|
|
1021
1061
|
cursor.group = "f" + f;
|
|
1022
1062
|
if (p.blocked) {
|
|
1023
1063
|
part("window_boards", [0, 0, 0], () => {
|
|
@@ -1045,11 +1085,12 @@ function installHouseDoors(K, shared) {
|
|
|
1045
1085
|
}
|
|
1046
1086
|
}
|
|
1047
1087
|
}, { id: "boards:" + p.id }, "f" + f);
|
|
1048
|
-
|
|
1088
|
+
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 });
|
|
1049
1089
|
}
|
|
1050
1090
|
}
|
|
1051
1091
|
}
|
|
1052
|
-
|
|
1092
|
+
const defined = { doorLineSides, doors };
|
|
1093
|
+
Object.assign(K, defined);
|
|
1053
1094
|
}
|
|
1054
1095
|
|
|
1055
1096
|
// src/house/windows.ts
|
|
@@ -1109,7 +1150,8 @@ function installHouseWindows(K, shared) {
|
|
|
1109
1150
|
}
|
|
1110
1151
|
}
|
|
1111
1152
|
}
|
|
1112
|
-
|
|
1153
|
+
const defined = { FRAME_COLORS, SILL_COLORS, windows };
|
|
1154
|
+
Object.assign(K, defined);
|
|
1113
1155
|
}
|
|
1114
1156
|
|
|
1115
1157
|
// src/house/floors.ts
|
|
@@ -1119,7 +1161,7 @@ function installHouseFloors(K, shared) {
|
|
|
1119
1161
|
if (shared.ctx._flights && shared.ctx._flights.r === shared.ctx.r) return shared.ctx._flights.l;
|
|
1120
1162
|
const R = shared.ctx.r, mp = /* @__PURE__ */ new Map();
|
|
1121
1163
|
for (const m of R.items) {
|
|
1122
|
-
if (m.type !== "stairs" || !m.link) continue;
|
|
1164
|
+
if (m.type !== "stairs" || !m.link || typeof m.link !== "object") continue;
|
|
1123
1165
|
const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
|
|
1124
1166
|
if (!mp.has(k)) mp.set(k, { m, from: m.link.from, to: m.link.to, rect: stairFootprint(m) });
|
|
1125
1167
|
}
|
|
@@ -1138,7 +1180,7 @@ function installHouseFloors(K, shared) {
|
|
|
1138
1180
|
}
|
|
1139
1181
|
const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
|
|
1140
1182
|
function tilesOf(parent, rc) {
|
|
1141
|
-
const ps = parent
|
|
1183
|
+
const ps = parent ? shared.ctx.panelsOf && shared.ctx.panelsOf.get(parent) : void 0;
|
|
1142
1184
|
if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
|
|
1143
1185
|
const out = [], taken = [];
|
|
1144
1186
|
for (const p of ps) for (const q of panelRects(p)) {
|
|
@@ -1202,13 +1244,12 @@ function installHouseStairs(K, shared) {
|
|
|
1202
1244
|
const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
|
|
1203
1245
|
const sh = (...a) => K.sh(...a);
|
|
1204
1246
|
function buildStairs() {
|
|
1205
|
-
const R = shared.ctx.r;
|
|
1206
|
-
shared.ctx.stairs = [];
|
|
1247
|
+
const R = shared.ctx.r, stairs = shared.ctx.stairs = [];
|
|
1207
1248
|
for (const vo of flights()) {
|
|
1208
1249
|
const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
|
|
1209
1250
|
cursor.group = "f" + f;
|
|
1210
1251
|
cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
|
|
1211
|
-
const y0 = Y0(f), H = Y0(
|
|
1252
|
+
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);
|
|
1212
1253
|
const wood = shared.ctx.colors.wood != null ? shared.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
|
|
1213
1254
|
const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
|
|
1214
1255
|
const boxL = (mat, lx, y, lz, w, h, d, color, rx = 0) => {
|
|
@@ -1231,7 +1272,7 @@ function installHouseStairs(K, shared) {
|
|
|
1231
1272
|
}
|
|
1232
1273
|
}
|
|
1233
1274
|
cursor.pc = null;
|
|
1234
|
-
|
|
1275
|
+
stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
|
|
1235
1276
|
}
|
|
1236
1277
|
}
|
|
1237
1278
|
function elevator() {
|
|
@@ -1248,7 +1289,8 @@ function installHouseStairs(K, shared) {
|
|
|
1248
1289
|
}
|
|
1249
1290
|
}
|
|
1250
1291
|
}
|
|
1251
|
-
|
|
1292
|
+
const defined = { buildStairs, elevator };
|
|
1293
|
+
Object.assign(K, defined);
|
|
1252
1294
|
}
|
|
1253
1295
|
|
|
1254
1296
|
// src/lights/fixtures.ts
|
|
@@ -1288,14 +1330,15 @@ function installLightsFixtures(K, shared) {
|
|
|
1288
1330
|
c: (mat, x, y, z, r, h, color, seg) => api.cylinder(M, mat, x, y0 + y, z, r, h, color, 0, 0, seg),
|
|
1289
1331
|
e: (mat, x, y, z, r, h, color) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color, 0, 0, "sphere"),
|
|
1290
1332
|
t(mat, p, q, r, color, seg) {
|
|
1333
|
+
const tc = color ?? NaN;
|
|
1291
1334
|
const dx = q[0] - p[0], dy = q[1] - p[1], dz = q[2] - p[2], L = Math.hypot(dx, dy, dz);
|
|
1292
1335
|
if (L < 1e-5) return;
|
|
1293
1336
|
const nx = dx / L, ny = dy / L, nz = dz / L;
|
|
1294
1337
|
if (Math.abs(nx) < 1e-4 && Math.abs(nz) < 1e-4) {
|
|
1295
|
-
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L,
|
|
1338
|
+
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, tc, 0, 0, seg);
|
|
1296
1339
|
return;
|
|
1297
1340
|
}
|
|
1298
|
-
api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L,
|
|
1341
|
+
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), seg);
|
|
1299
1342
|
},
|
|
1300
1343
|
polyFace: (mat, pts, color, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
|
|
1301
1344
|
part(type, lx, ly, lz, fn, meta) {
|
|
@@ -1474,7 +1517,8 @@ function installLightsFixtures(K, shared) {
|
|
|
1474
1517
|
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 });
|
|
1475
1518
|
}
|
|
1476
1519
|
}
|
|
1477
|
-
|
|
1520
|
+
const defined = { hashString, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch };
|
|
1521
|
+
Object.assign(K, defined);
|
|
1478
1522
|
}
|
|
1479
1523
|
|
|
1480
1524
|
// src/lights/decor.ts
|
|
@@ -1541,7 +1585,8 @@ function installLightsDecor(K, shared) {
|
|
|
1541
1585
|
void sd;
|
|
1542
1586
|
}
|
|
1543
1587
|
}
|
|
1544
|
-
|
|
1588
|
+
const defined = { decorLights };
|
|
1589
|
+
Object.assign(K, defined);
|
|
1545
1590
|
}
|
|
1546
1591
|
|
|
1547
1592
|
// src/lot/terrain.ts
|
|
@@ -1594,7 +1639,8 @@ function installLotTerrain(K, shared) {
|
|
|
1594
1639
|
if (x < b) out.push([x, b]);
|
|
1595
1640
|
return out.filter((q) => q[1] - q[0] > 0.3);
|
|
1596
1641
|
}
|
|
1597
|
-
|
|
1642
|
+
const defined = { terrain, freeSpans };
|
|
1643
|
+
Object.assign(K, defined);
|
|
1598
1644
|
}
|
|
1599
1645
|
|
|
1600
1646
|
// src/lot/perimeter.ts
|
|
@@ -1614,7 +1660,7 @@ function installLotPerimeter(K, shared) {
|
|
|
1614
1660
|
for (const s of lt.perimeter) {
|
|
1615
1661
|
const alongU = Math.abs(s.v1 - s.v0) < EPS, 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);
|
|
1616
1662
|
cursor.pc = pieceRecord("lot_wall:" + s.id, s.type === "wall" ? "brick" : s.type === "fence" ? "wood_soft" : "steel", null, { tags: ["wall"] });
|
|
1617
|
-
const th = s.thickness || 0.15, h = s.height, color = colorOf(s.color)
|
|
1663
|
+
const th = s.thickness || 0.15, h = s.height, color = colorOf(s.color) ?? (C.wall || 12104874), len = b - a;
|
|
1618
1664
|
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);
|
|
1619
1665
|
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 };
|
|
1620
1666
|
shared.ctx.colliders.push(col);
|
|
@@ -1688,7 +1734,8 @@ function installLotPerimeter(K, shared) {
|
|
|
1688
1734
|
}
|
|
1689
1735
|
}
|
|
1690
1736
|
}
|
|
1691
|
-
|
|
1737
|
+
const defined = { perimeter, paths };
|
|
1738
|
+
Object.assign(K, defined);
|
|
1692
1739
|
}
|
|
1693
1740
|
|
|
1694
1741
|
// src/lot/gates.ts
|
|
@@ -1704,7 +1751,7 @@ function installLotGates(K, shared) {
|
|
|
1704
1751
|
cursor.group = "lot";
|
|
1705
1752
|
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;
|
|
1706
1753
|
for (const g of lt.gates) {
|
|
1707
|
-
const gc = colorOf(g.color)
|
|
1754
|
+
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";
|
|
1708
1755
|
const sd = cz - v >= 0 ? 1 : -1;
|
|
1709
1756
|
const pil = (x0, x1, high) => {
|
|
1710
1757
|
bx("plaster", x0, 0, v - 0.13, x1, high, v + 0.13, wall);
|
|
@@ -1776,7 +1823,8 @@ function installLotGates(K, shared) {
|
|
|
1776
1823
|
if (!g.open || ped) shared.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
|
|
1777
1824
|
}
|
|
1778
1825
|
}
|
|
1779
|
-
|
|
1826
|
+
const defined = { slideDirection, gates };
|
|
1827
|
+
Object.assign(K, defined);
|
|
1780
1828
|
}
|
|
1781
1829
|
|
|
1782
1830
|
// src/roof/roofs.ts
|
|
@@ -1790,13 +1838,13 @@ function installRoofRoofs(K, shared) {
|
|
|
1790
1838
|
function roofs() {
|
|
1791
1839
|
const R = shared.ctx.r, F = R.facade, C = shared.ctx.colors, nA = R.floors.length, type = F.roof;
|
|
1792
1840
|
cursor.group = "roof";
|
|
1793
|
-
shared.ctx.roofRects = [];
|
|
1794
|
-
shared.ctx.gutter = gutterConfig();
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1841
|
+
const roofRects = shared.ctx.roofRects = [];
|
|
1842
|
+
const G = shared.ctx.gutter = gutterConfig();
|
|
1843
|
+
G.ncond = 0;
|
|
1844
|
+
G.nbuz = 0;
|
|
1845
|
+
G.bz = /* @__PURE__ */ new Set();
|
|
1798
1846
|
shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
|
|
1799
|
-
const roofColor = C.roof != null ? C.roof : 11031610, gable = (R.seed | 0) % 2 === 0;
|
|
1847
|
+
const roofColor = C.roof != null ? C.roof : 11031610, gable = (Number(R.seed) | 0) % 2 === 0;
|
|
1800
1848
|
for (let f = 0; f < nA; f++) {
|
|
1801
1849
|
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);
|
|
1802
1850
|
if (!rs.length) continue;
|
|
@@ -1818,7 +1866,7 @@ function installRoofRoofs(K, shared) {
|
|
|
1818
1866
|
return Y0(f) + Math.max(...cs.map((c) => c.ceiling)) + 0.2;
|
|
1819
1867
|
};
|
|
1820
1868
|
if (type === "slab") {
|
|
1821
|
-
for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i))
|
|
1869
|
+
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 });
|
|
1822
1870
|
slabs(f, xs, zs, O, U, nx, nz, full, pe, C);
|
|
1823
1871
|
cursor.pc = null;
|
|
1824
1872
|
continue;
|
|
@@ -1841,16 +1889,16 @@ function installRoofRoofs(K, shared) {
|
|
|
1841
1889
|
if (U(q.j0 - 1, i)) touchesU[1] = 1;
|
|
1842
1890
|
if (U(q.j1 + 1, i)) touchesU[3] = 1;
|
|
1843
1891
|
}
|
|
1844
|
-
|
|
1892
|
+
roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
|
|
1845
1893
|
const ybq = pe(x0, z0, x1, z1);
|
|
1846
1894
|
roofRect(type, x0, z0, x1, z1, ybq, roofColor, gable && single, F, touchesU);
|
|
1847
1895
|
cursor.pc = null;
|
|
1848
|
-
if (
|
|
1896
|
+
if (G.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
|
|
1849
1897
|
}
|
|
1850
1898
|
}
|
|
1851
1899
|
for (const e of shared.ctx.outbuildingList || []) {
|
|
1852
1900
|
const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
|
|
1853
|
-
|
|
1901
|
+
roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
|
|
1854
1902
|
if (type === "slab") {
|
|
1855
1903
|
const c = C.facade != null ? C.facade : 14209216;
|
|
1856
1904
|
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));
|
|
@@ -1861,13 +1909,15 @@ function installRoofRoofs(K, shared) {
|
|
|
1861
1909
|
roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
|
|
1862
1910
|
cursor.pc = null;
|
|
1863
1911
|
shared.ctx.noPiece = false;
|
|
1864
|
-
if (
|
|
1912
|
+
if (G.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
|
|
1865
1913
|
}
|
|
1866
1914
|
}
|
|
1867
|
-
|
|
1915
|
+
const defined = { roofs };
|
|
1916
|
+
Object.assign(K, defined);
|
|
1868
1917
|
}
|
|
1869
1918
|
|
|
1870
1919
|
// src/roof/gutters.ts
|
|
1920
|
+
var paletteMeta = (colors) => colors.meta;
|
|
1871
1921
|
function installRoofGutters(K, shared) {
|
|
1872
1922
|
const { boxC, bx, cursor, roomAt } = K;
|
|
1873
1923
|
const sh = (...a) => K.sh(...a);
|
|
@@ -1884,7 +1934,7 @@ function installRoofGutters(K, shared) {
|
|
|
1884
1934
|
const draw = rnd() < p, light = rnd() < 0.6;
|
|
1885
1935
|
void draw;
|
|
1886
1936
|
const on = true;
|
|
1887
|
-
return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared.ctx.colors
|
|
1937
|
+
return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: paletteMeta(shared.ctx.colors)?.state === "abandoned" || R.state === "abandoned", fallback: false };
|
|
1888
1938
|
}
|
|
1889
1939
|
function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
|
|
1890
1940
|
const G = shared.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;
|
|
@@ -1926,7 +1976,7 @@ function installRoofGutters(K, shared) {
|
|
|
1926
1976
|
const px = cx + sx * 0.06, pz = cz + sz * 0.06;
|
|
1927
1977
|
if (!freeAt(px, pz, sx, sz)) return false;
|
|
1928
1978
|
const floats = G.bad && G.ncond === 1, yt = yb - 0.1, ybx = floats ? 0.7 : 0.04;
|
|
1929
|
-
G.ncond
|
|
1979
|
+
G.ncond = (G.ncond ?? 0) + 1;
|
|
1930
1980
|
if (run2 >= 2) boxC("plain", (sides[run2][4] + px) / 2, yt, pz, Math.abs(sides[run2][4] - px), 0.07, 0.07, c);
|
|
1931
1981
|
else boxC("plain", px, yt, (sides[run2][4] + pz) / 2, 0.07, 0.07, Math.abs(sides[run2][4] - pz), c);
|
|
1932
1982
|
boxC("plain", px, (ybx + yt) / 2, pz, 0.08, yt - ybx, 0.08, c);
|
|
@@ -1960,7 +2010,7 @@ function installRoofGutters(K, shared) {
|
|
|
1960
2010
|
function drain(x, z, px, pz, c) {
|
|
1961
2011
|
const g0 = cursor.group;
|
|
1962
2012
|
cursor.group = "f0";
|
|
1963
|
-
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));
|
|
2013
|
+
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));
|
|
1964
2014
|
const t = 0.045;
|
|
1965
2015
|
bx("plain", x - 0.12, 0, z - 0.12, x + 0.12, t - 6e-3, z + 0.12, 12170668);
|
|
1966
2016
|
bx("metal", x - 0.11, t, z - 0.11, x + 0.11, t + 0.012, z + 0.11, 5922145);
|
|
@@ -1971,7 +2021,8 @@ function installRoofGutters(K, shared) {
|
|
|
1971
2021
|
bx("metal", x - 0.085, t + 0.012, z - 6e-3, x + 0.085, t + 0.02, z + 6e-3, 9080466);
|
|
1972
2022
|
cursor.group = g0;
|
|
1973
2023
|
}
|
|
1974
|
-
|
|
2024
|
+
const defined = { gutterConfig, gutter, drain };
|
|
2025
|
+
Object.assign(K, defined);
|
|
1975
2026
|
}
|
|
1976
2027
|
|
|
1977
2028
|
// src/roof/slabs.ts
|
|
@@ -2005,15 +2056,16 @@ function installRoofSlabs(K, shared) {
|
|
|
2005
2056
|
side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
|
|
2006
2057
|
side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
|
|
2007
2058
|
side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
|
|
2008
|
-
|
|
2059
|
+
const G = shared.ctx.gutter;
|
|
2060
|
+
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]]) {
|
|
2009
2061
|
const kd = f + ":" + dx + ":" + dz;
|
|
2010
|
-
if (!ok ||
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
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 =
|
|
2062
|
+
if (!ok || G.bz.has(kd)) continue;
|
|
2063
|
+
G.bz.add(kd);
|
|
2064
|
+
G.nbuz = (G.nbuz ?? 0) + 1;
|
|
2065
|
+
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;
|
|
2014
2066
|
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);
|
|
2015
2067
|
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));
|
|
2016
|
-
if (
|
|
2068
|
+
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);
|
|
2017
2069
|
{
|
|
2018
2070
|
const tx = ex + dx * 0.38, tz = ez + dz * 0.38;
|
|
2019
2071
|
let lv = true;
|
|
@@ -2033,7 +2085,8 @@ function installRoofSlabs(K, shared) {
|
|
|
2033
2085
|
}
|
|
2034
2086
|
}
|
|
2035
2087
|
}
|
|
2036
|
-
|
|
2088
|
+
const defined = { slabs };
|
|
2089
|
+
Object.assign(K, defined);
|
|
2037
2090
|
}
|
|
2038
2091
|
|
|
2039
2092
|
// src/roof/tiles.ts
|
|
@@ -2166,7 +2219,8 @@ function installRoofTiles(K, shared) {
|
|
|
2166
2219
|
}
|
|
2167
2220
|
return m ? structurePiece(m.id) : null;
|
|
2168
2221
|
}
|
|
2169
|
-
|
|
2222
|
+
const defined = { R_STYLE, tileRelief, ridge, pieceOfPane };
|
|
2223
|
+
Object.assign(K, defined);
|
|
2170
2224
|
}
|
|
2171
2225
|
|
|
2172
2226
|
// src/roof/rect.ts
|
|
@@ -2212,7 +2266,7 @@ function installRoofRect(K, shared) {
|
|
|
2212
2266
|
}
|
|
2213
2267
|
const rm = alongX ? dz / 2 : dx / 2;
|
|
2214
2268
|
{
|
|
2215
|
-
const
|
|
2269
|
+
const roofRects = shared.ctx.roofRects, rr = roofRects[roofRects.length - 1];
|
|
2216
2270
|
if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
|
|
2217
2271
|
}
|
|
2218
2272
|
if (gable) {
|
|
@@ -2249,7 +2303,8 @@ function installRoofRect(K, shared) {
|
|
|
2249
2303
|
}
|
|
2250
2304
|
}
|
|
2251
2305
|
}
|
|
2252
|
-
|
|
2306
|
+
const defined = { roofRect };
|
|
2307
|
+
Object.assign(K, defined);
|
|
2253
2308
|
}
|
|
2254
2309
|
|
|
2255
2310
|
// src/mirrors.ts
|
|
@@ -2260,9 +2315,11 @@ function installMirrors(K, shared) {
|
|
|
2260
2315
|
function mirrorEnv() {
|
|
2261
2316
|
if (shared.mirrorEnv) return shared.mirrorEnv;
|
|
2262
2317
|
const mk = (f) => {
|
|
2318
|
+
if (!DOC) throw new Error("game-floorplan-three: the mirrors need a document (options.document)");
|
|
2263
2319
|
const c = DOC.createElement("canvas");
|
|
2264
2320
|
c.width = c.height = 64;
|
|
2265
2321
|
const g = c.getContext("2d");
|
|
2322
|
+
if (!g) throw new Error("game-floorplan-three: no 2d canvas context");
|
|
2266
2323
|
f(g);
|
|
2267
2324
|
return c;
|
|
2268
2325
|
};
|
|
@@ -2321,7 +2378,7 @@ function installMirrors(K, shared) {
|
|
|
2321
2378
|
B.N.push(v.x, v.y, v.z);
|
|
2322
2379
|
B.U.push(ua.getX(i), ua.getY(i));
|
|
2323
2380
|
}
|
|
2324
|
-
for (const k of geo.index
|
|
2381
|
+
for (const k of geo.index?.array ?? []) B.I.push(B.nv + k);
|
|
2325
2382
|
B.nv += pa.count;
|
|
2326
2383
|
geo.dispose();
|
|
2327
2384
|
}
|
|
@@ -2399,10 +2456,12 @@ function installMirrors(K, shared) {
|
|
|
2399
2456
|
m.fake.visible = !on;
|
|
2400
2457
|
}
|
|
2401
2458
|
}
|
|
2402
|
-
|
|
2459
|
+
const defined = { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror };
|
|
2460
|
+
Object.assign(K, defined);
|
|
2403
2461
|
}
|
|
2404
2462
|
|
|
2405
2463
|
// src/cars.ts
|
|
2464
|
+
import { isMesh } from "@adatechnology/game-shapes-three";
|
|
2406
2465
|
function installCars(K, shared) {
|
|
2407
2466
|
const { THREE, FLEET, _Y } = K;
|
|
2408
2467
|
const CARS = [];
|
|
@@ -2412,13 +2471,16 @@ function installCars(K, shared) {
|
|
|
2412
2471
|
high: ["electric_hatch", "hybrid_suv", "midsize_suv", "v8_coupe", "large_suv", "midsize_pickup", "crossover_pickup", "fastback_sedan"]
|
|
2413
2472
|
}, K.cfg.carKinds);
|
|
2414
2473
|
const CAR_CACHE = /* @__PURE__ */ new Map();
|
|
2415
|
-
function materialSignature(
|
|
2474
|
+
function materialSignature(material) {
|
|
2475
|
+
const m = material;
|
|
2416
2476
|
const f = (v) => v == null ? "" : typeof v === "number" ? v.toFixed(3) : v.isColor ? v.getHexString() : v.uuid || String(v);
|
|
2417
2477
|
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("|");
|
|
2418
2478
|
}
|
|
2419
2479
|
const BUCKETS = /* @__PURE__ */ new Map();
|
|
2420
|
-
function bucketMaterial(
|
|
2421
|
-
if (
|
|
2480
|
+
function bucketMaterial(material) {
|
|
2481
|
+
if (material.type !== "MeshStandardMaterial") return null;
|
|
2482
|
+
const m = material;
|
|
2483
|
+
if (m.map || m.alphaTest || m.vertexColors || !m.color) return null;
|
|
2422
2484
|
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 : "");
|
|
2423
2485
|
let b = BUCKETS.get(sig);
|
|
2424
2486
|
if (!b) {
|
|
@@ -2430,7 +2492,7 @@ function installCars(K, shared) {
|
|
|
2430
2492
|
}
|
|
2431
2493
|
function carModel(k, seed) {
|
|
2432
2494
|
const kc = k + "|" + shared.quality + "|" + (seed || 0);
|
|
2433
|
-
if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc);
|
|
2495
|
+
if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc) ?? null;
|
|
2434
2496
|
if (!FLEET) return null;
|
|
2435
2497
|
let res = null;
|
|
2436
2498
|
try {
|
|
@@ -2438,8 +2500,10 @@ function installCars(K, shared) {
|
|
|
2438
2500
|
c.root.updateMatrixWorld(true);
|
|
2439
2501
|
const inv = new THREE.Matrix4();
|
|
2440
2502
|
const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
|
|
2441
|
-
c.g.traverse((
|
|
2442
|
-
if (!
|
|
2503
|
+
c.g.traverse((node) => {
|
|
2504
|
+
if (!isMesh(node)) return;
|
|
2505
|
+
const o = node;
|
|
2506
|
+
if (o.isInstancedMesh || o.isSkinnedMesh || !o.geometry || !o.geometry.attributes.position) return;
|
|
2443
2507
|
for (let p = o; p; p = p.parent) if (p.visible === false) return;
|
|
2444
2508
|
const mats = Array.isArray(o.material) ? o.material : [o.material];
|
|
2445
2509
|
let geo = o.geometry;
|
|
@@ -2453,7 +2517,7 @@ function installCars(K, shared) {
|
|
|
2453
2517
|
const pa = geo.attributes.position, na = geo.attributes.normal, ua = geo.attributes.uv, total = pa.count;
|
|
2454
2518
|
const grs = Array.isArray(o.material) && o.geometry.groups.length ? o.geometry.groups : [{ start: 0, count: total, materialIndex: 0 }];
|
|
2455
2519
|
for (const gr of grs) {
|
|
2456
|
-
const m = mats[gr.materialIndex] || mats[0];
|
|
2520
|
+
const m = (gr.materialIndex != null ? mats[gr.materialIndex] : void 0) || mats[0];
|
|
2457
2521
|
if (!m) continue;
|
|
2458
2522
|
const a0 = Math.min(gr.start, total), n0 = Math.min(gr.count, total - a0) - Math.min(gr.count, total - a0) % 3;
|
|
2459
2523
|
if (n0 < 3) continue;
|
|
@@ -2554,7 +2618,10 @@ function installCars(K, shared) {
|
|
|
2554
2618
|
return g;
|
|
2555
2619
|
}
|
|
2556
2620
|
function assembleCars(groups) {
|
|
2557
|
-
if (shared.quality === "game")
|
|
2621
|
+
if (shared.quality === "game") {
|
|
2622
|
+
assembleMergedCars(groups);
|
|
2623
|
+
return;
|
|
2624
|
+
}
|
|
2558
2625
|
for (const C of CARS) {
|
|
2559
2626
|
const g = carGroup(C.k, C.w, C.d, C.seed);
|
|
2560
2627
|
if (!g) continue;
|
|
@@ -2605,7 +2672,8 @@ function installCars(K, shared) {
|
|
|
2605
2672
|
(groups[B.parent] || (groups[B.parent] = new THREE.Group())).add(m);
|
|
2606
2673
|
}
|
|
2607
2674
|
}
|
|
2608
|
-
|
|
2675
|
+
const defined = { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars };
|
|
2676
|
+
Object.assign(K, defined);
|
|
2609
2677
|
}
|
|
2610
2678
|
|
|
2611
2679
|
// src/house/building.ts
|
|
@@ -2661,14 +2729,15 @@ function installHouseBuilding(K, shared) {
|
|
|
2661
2729
|
bx("plaster", Math.min(hall[0] - 3, color[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
|
|
2662
2730
|
shared.ctx.limits = { x0: Math.min(hall[0] - 3, color[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
|
|
2663
2731
|
}
|
|
2664
|
-
|
|
2732
|
+
const defined = { building };
|
|
2733
|
+
Object.assign(K, defined);
|
|
2665
2734
|
}
|
|
2666
2735
|
|
|
2667
2736
|
// src/utilities/water.ts
|
|
2668
2737
|
function installUtilitiesWater(K, shared) {
|
|
2669
2738
|
const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
|
|
2670
2739
|
function createWater(r, state) {
|
|
2671
|
-
const H = r.utilities
|
|
2740
|
+
const H = r.utilities?.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
|
|
2672
2741
|
if (H) for (const p of H.points) {
|
|
2673
2742
|
points[p.id] = p;
|
|
2674
2743
|
itemPoint[p.item] = p.id;
|
|
@@ -2757,14 +2826,14 @@ function installUtilitiesWater(K, shared) {
|
|
|
2757
2826
|
}
|
|
2758
2827
|
const _v3 = new THREE.Vector3();
|
|
2759
2828
|
function waterPipes() {
|
|
2760
|
-
const H = shared.ctx.r.utilities
|
|
2829
|
+
const H = shared.ctx.r.utilities?.plumbing;
|
|
2761
2830
|
if (!H || !H.visibleRuns) return;
|
|
2762
2831
|
const nA = shared.ctx.r.floors.length;
|
|
2763
2832
|
const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
|
|
2764
2833
|
for (const tr of H.visibleRuns) {
|
|
2765
2834
|
const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
|
|
2766
2835
|
if (tr.exposed === "wall") {
|
|
2767
|
-
const pt = H.points.find((p) => p.run === tr.id), com = shared.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
|
|
2836
|
+
const pt = H.points.find((p) => p.run === tr.id), com = tr.to != null ? shared.ctx.roomById[tr.to] : void 0, g2 = groupOf(com || pt && { floor: pt.floor });
|
|
2768
2837
|
part("wall_pipe", [0, 0, 0], () => {
|
|
2769
2838
|
for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
|
|
2770
2839
|
for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
|
|
@@ -2786,7 +2855,8 @@ function installUtilitiesWater(K, shared) {
|
|
|
2786
2855
|
cursor.pc = null;
|
|
2787
2856
|
}
|
|
2788
2857
|
}
|
|
2789
|
-
|
|
2858
|
+
const defined = { createWater, PIPE_COLOR, pipe, _v3, waterPipes };
|
|
2859
|
+
Object.assign(K, defined);
|
|
2790
2860
|
}
|
|
2791
2861
|
|
|
2792
2862
|
// src/utilities/electrical.ts
|
|
@@ -2794,10 +2864,10 @@ function installUtilitiesElectrical(K, shared) {
|
|
|
2794
2864
|
const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
|
|
2795
2865
|
const sh = (...a) => K.sh(...a);
|
|
2796
2866
|
function electricalStructure() {
|
|
2797
|
-
const
|
|
2867
|
+
const R = shared.ctx.r, E = R.utilities?.electrical;
|
|
2798
2868
|
shared.ctx.electricalInfo = null;
|
|
2799
2869
|
if (!E) return;
|
|
2800
|
-
const
|
|
2870
|
+
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 };
|
|
2801
2871
|
const en2 = E.serviceEntrance, KV = shared.ctx.iv ? shared.ctx.iv.plane : null;
|
|
2802
2872
|
const wireL = (a, b, r_ = 8e-3) => {
|
|
2803
2873
|
const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
@@ -2902,7 +2972,8 @@ function installUtilitiesElectrical(K, shared) {
|
|
|
2902
2972
|
_q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
|
|
2903
2973
|
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color);
|
|
2904
2974
|
}
|
|
2905
|
-
|
|
2975
|
+
const defined = { electricalStructure, pipe2 };
|
|
2976
|
+
Object.assign(K, defined);
|
|
2906
2977
|
}
|
|
2907
2978
|
|
|
2908
2979
|
// src/house/baseboard.ts
|
|
@@ -2940,7 +3011,8 @@ function installHouseBaseboard(K, shared) {
|
|
|
2940
3011
|
strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
|
|
2941
3012
|
}
|
|
2942
3013
|
}
|
|
2943
|
-
|
|
3014
|
+
const defined = { baseboardAndSidewalk };
|
|
3015
|
+
Object.assign(K, defined);
|
|
2944
3016
|
}
|
|
2945
3017
|
|
|
2946
3018
|
// src/utilities/solar.ts
|
|
@@ -2955,6 +3027,7 @@ function installUtilitiesSolar(K, shared) {
|
|
|
2955
3027
|
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);
|
|
2956
3028
|
continue;
|
|
2957
3029
|
}
|
|
3030
|
+
if (!rr.exterior || rr.tp == null || rr.rm == null) continue;
|
|
2958
3031
|
const [x0, z0, x1, z1] = rr.exterior;
|
|
2959
3032
|
if (u < x0 || u > x1 || v < z0 || v > z1) continue;
|
|
2960
3033
|
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);
|
|
@@ -2963,7 +3036,7 @@ function installUtilitiesSolar(K, shared) {
|
|
|
2963
3036
|
return y;
|
|
2964
3037
|
}
|
|
2965
3038
|
function solar() {
|
|
2966
|
-
const R = shared.ctx.r, S = R.utilities
|
|
3039
|
+
const R = shared.ctx.r, S = R.utilities?.solar;
|
|
2967
3040
|
shared.ctx.solarInfo = null;
|
|
2968
3041
|
if (!S || !S.panels || !S.panels.length) return;
|
|
2969
3042
|
cursor.group = "roof";
|
|
@@ -3006,13 +3079,14 @@ function installUtilitiesSolar(K, shared) {
|
|
|
3006
3079
|
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);
|
|
3007
3080
|
bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
|
|
3008
3081
|
}
|
|
3009
|
-
const top = Math.max(...(shared.ctx.roofRects || []).
|
|
3082
|
+
const top = Math.max(...(shared.ctx.roofRects || []).flatMap((t2) => t2.yb != null ? [t2.yb] : []), Y0(fa) + 2.8);
|
|
3010
3083
|
cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
|
|
3011
3084
|
info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
|
|
3012
3085
|
}
|
|
3013
3086
|
shared.ctx.solarInfo = info;
|
|
3014
3087
|
}
|
|
3015
|
-
|
|
3088
|
+
const defined = { roofHeightAt, solar };
|
|
3089
|
+
Object.assign(K, defined);
|
|
3016
3090
|
}
|
|
3017
3091
|
|
|
3018
3092
|
// src/house/outbuildings.ts
|
|
@@ -3027,7 +3101,7 @@ function installHouseOutbuildings(K, shared) {
|
|
|
3027
3101
|
counts.set(w.floor, i + 1);
|
|
3028
3102
|
return w.id ? w : Object.assign({}, w, { id: `wall_${w.floor}_${i}` });
|
|
3029
3103
|
}) });
|
|
3030
|
-
const E = (r.outbuildings || []).filter((e) => e && e.walls && e.walls.length && e.interior && e.interior.length);
|
|
3104
|
+
const E = (r.outbuildings || []).filter((e) => !!(e && e.walls && e.walls.length && e.interior && e.interior.length));
|
|
3031
3105
|
if (!E.length) return r;
|
|
3032
3106
|
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");
|
|
3033
3107
|
for (const e of E) {
|
|
@@ -3041,7 +3115,22 @@ function installHouseOutbuildings(K, shared) {
|
|
|
3041
3115
|
const alongU = p.axis === "u", below = p.pos < (alongU ? cz : cx);
|
|
3042
3116
|
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 });
|
|
3043
3117
|
}
|
|
3044
|
-
for (const j of e.windows || []) windows.push({
|
|
3118
|
+
for (const j of e.windows || []) windows.push({
|
|
3119
|
+
id: j.id,
|
|
3120
|
+
floor: 0,
|
|
3121
|
+
u: j.u,
|
|
3122
|
+
v: j.v,
|
|
3123
|
+
axis: j.axis,
|
|
3124
|
+
pos: j.pos,
|
|
3125
|
+
at: j.at,
|
|
3126
|
+
width: j.width,
|
|
3127
|
+
y0: j.y0 ?? 1,
|
|
3128
|
+
y1: j.y1 ?? 2,
|
|
3129
|
+
/* the structure always gives a window its sill and head (1.0, 2.0) */
|
|
3130
|
+
room: e.id,
|
|
3131
|
+
side: j.side,
|
|
3132
|
+
outbuilding: e.id
|
|
3133
|
+
});
|
|
3045
3134
|
(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" }));
|
|
3046
3135
|
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 });
|
|
3047
3136
|
}
|
|
@@ -3062,7 +3151,8 @@ function installHouseOutbuildings(K, shared) {
|
|
|
3062
3151
|
}
|
|
3063
3152
|
}
|
|
3064
3153
|
}
|
|
3065
|
-
|
|
3154
|
+
const defined = { OUTBUILDING_USE, applyOutbuildings, outbuildings };
|
|
3155
|
+
Object.assign(K, defined);
|
|
3066
3156
|
}
|
|
3067
3157
|
|
|
3068
3158
|
// src/furniture/api.ts
|
|
@@ -3127,7 +3217,8 @@ function installFurnitureApi(K, _shared) {
|
|
|
3127
3217
|
return { b: (mat, x, y, z, w, h, d, color, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color, rx, rz, seg) => A.cylinder(M, mat, x, y0 + y, z, r, h, color, rx || 0, rz || 0, seg), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
|
|
3128
3218
|
}
|
|
3129
3219
|
const PE = Math.PI / 2;
|
|
3130
|
-
|
|
3220
|
+
const defined = { MATERIAL_MAP, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE };
|
|
3221
|
+
Object.assign(K, defined);
|
|
3131
3222
|
}
|
|
3132
3223
|
|
|
3133
3224
|
// src/furniture/builders.ts
|
|
@@ -3255,7 +3346,7 @@ function installFurnitureBuilders(K, _shared) {
|
|
|
3255
3346
|
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);
|
|
3256
3347
|
},
|
|
3257
3348
|
wardrobe(M, A) {
|
|
3258
|
-
const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, wood =
|
|
3349
|
+
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));
|
|
3259
3350
|
lb("wood", 0, 0.06, 0, w, h - 0.06, d, wood);
|
|
3260
3351
|
lb("wood", 0, h, 0, w + 0.04, 0.04, d + 0.04, sh(wood, 0.8));
|
|
3261
3352
|
lb("wood", 0, 0, 0, w - 0.04, 0.06, d - 0.04, sh(wood, 0.4));
|
|
@@ -3647,7 +3738,8 @@ function installFurnitureBuilders(K, _shared) {
|
|
|
3647
3738
|
lb("metal", 0, h - 0.04, d / 2, w, 0.03, 0.03, 3815994);
|
|
3648
3739
|
}
|
|
3649
3740
|
};
|
|
3650
|
-
|
|
3741
|
+
const defined = { FURNITURE };
|
|
3742
|
+
Object.assign(K, defined);
|
|
3651
3743
|
}
|
|
3652
3744
|
|
|
3653
3745
|
// src/furniture/type-table.ts
|
|
@@ -3657,7 +3749,8 @@ function installFurnitureTypeTable(K, _shared) {
|
|
|
3657
3749
|
function typeTable(props) {
|
|
3658
3750
|
const B = props.builders, T = {};
|
|
3659
3751
|
const mv = (type, id) => {
|
|
3660
|
-
|
|
3752
|
+
const f = B[id || type];
|
|
3753
|
+
if (f) T[type] = { f, source: "props3d" };
|
|
3661
3754
|
};
|
|
3662
3755
|
const mine = (type, f, source = "game") => {
|
|
3663
3756
|
T[type] = { f, source };
|
|
@@ -3796,7 +3889,8 @@ function installFurnitureTypeTable(K, _shared) {
|
|
|
3796
3889
|
extraTypes(T, props);
|
|
3797
3890
|
return T;
|
|
3798
3891
|
}
|
|
3799
|
-
|
|
3892
|
+
const defined = { typeTable };
|
|
3893
|
+
Object.assign(K, defined);
|
|
3800
3894
|
}
|
|
3801
3895
|
|
|
3802
3896
|
// src/furniture/taps.ts
|
|
@@ -3860,7 +3954,8 @@ function installFurnitureTaps(K, shared) {
|
|
|
3860
3954
|
}, { id: id + "_a", target: id, hidden: true, fluid: "water" });
|
|
3861
3955
|
return id;
|
|
3862
3956
|
}
|
|
3863
|
-
|
|
3957
|
+
const defined = { counterTap, wallTap };
|
|
3958
|
+
Object.assign(K, defined);
|
|
3864
3959
|
}
|
|
3865
3960
|
|
|
3866
3961
|
// src/furniture/fixtures.ts
|
|
@@ -3973,7 +4068,7 @@ function installFurniturePlants(K, _shared) {
|
|
|
3973
4068
|
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;
|
|
3974
4069
|
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;
|
|
3975
4070
|
K2.e("plant", cx + dx, cy + dy + r * 0.5, cz + dz, r, alt, sh(green, f));
|
|
3976
|
-
if (o.flower && rnd() < o.flower) {
|
|
4071
|
+
if (o.flower && o.flowers && rnd() < o.flower) {
|
|
3977
4072
|
const fa = rnd() * 6.283;
|
|
3978
4073
|
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]);
|
|
3979
4074
|
}
|
|
@@ -4086,7 +4181,8 @@ function installFurniturePlants(K, _shared) {
|
|
|
4086
4181
|
else blobs(K2, x, bh - 0.05, z, 0.24 + rnd() * 0.08, 6, green, rnd, { flatten: true, flower: tp === "flower" ? 0.9 : 0.25, flowers: FLOWERS.slice(i % 3, i % 3 + 3) });
|
|
4087
4182
|
}
|
|
4088
4183
|
}
|
|
4089
|
-
|
|
4184
|
+
const defined = { GREENS, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel };
|
|
4185
|
+
Object.assign(K, defined);
|
|
4090
4186
|
}
|
|
4091
4187
|
|
|
4092
4188
|
// src/furniture/yard.ts
|
|
@@ -4242,7 +4338,7 @@ function installFurnitureYard(K, shared) {
|
|
|
4242
4338
|
};
|
|
4243
4339
|
FURNITURE.mailbox = function(M, A) {
|
|
4244
4340
|
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");
|
|
4245
|
-
if (M.pole !== false && !(M.y > 0)) {
|
|
4341
|
+
if (M.pole !== false && !(M.y != null && M.y > 0)) {
|
|
4246
4342
|
K2.b("plain", 0, 0, -d / 2 - 0.1, 0.12, y, 0.12, 12104874);
|
|
4247
4343
|
}
|
|
4248
4344
|
K2.b("metal", 0, y, 0, w, h * 0.78, d, pc);
|
|
@@ -4262,7 +4358,8 @@ function installFurnitureYard(K, shared) {
|
|
|
4262
4358
|
);
|
|
4263
4359
|
K2.b("plain", 0, y + h * 0.62, d / 2 + 4e-3, 0.08, 0.05, 4e-3, 15921386);
|
|
4264
4360
|
};
|
|
4265
|
-
|
|
4361
|
+
const defined = { CLOTHES_COLORS, strip, garment };
|
|
4362
|
+
Object.assign(K, defined);
|
|
4266
4363
|
}
|
|
4267
4364
|
|
|
4268
4365
|
// src/furniture/extra-types.ts
|
|
@@ -4322,7 +4419,8 @@ function installFurnitureExtraTypes(K, _shared) {
|
|
|
4322
4419
|
tuft(K2, 0, 0, 0, Math.max(0.2, (M.w || 0.4) / 2), 16, 5212738, rnd);
|
|
4323
4420
|
});
|
|
4324
4421
|
}
|
|
4325
|
-
|
|
4422
|
+
const defined = { extraTypes };
|
|
4423
|
+
Object.assign(K, defined);
|
|
4326
4424
|
}
|
|
4327
4425
|
|
|
4328
4426
|
// src/furniture/place-items.ts
|
|
@@ -4344,8 +4442,8 @@ function installFurniturePlaceItems(K, shared) {
|
|
|
4344
4442
|
if (m.type === "stairs") continue;
|
|
4345
4443
|
const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
|
|
4346
4444
|
cursor.group = exterior ? "lot" : "f" + f;
|
|
4347
|
-
const com = shared.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
|
|
4348
|
-
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: shared.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color)
|
|
4445
|
+
const com = m.room != null ? shared.ctx.roomById[m.room] : void 0, base = exterior ? 0 : Y0(f);
|
|
4446
|
+
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: shared.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: shared.ctx.night, light: shared.ctx.night, lit: shared.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
|
|
4349
4447
|
if (m.category === "ground_cover" && m.polygon) {
|
|
4350
4448
|
const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
|
|
4351
4449
|
M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
|
|
@@ -4422,10 +4520,12 @@ function installFurniturePlaceItems(K, shared) {
|
|
|
4422
4520
|
boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color, 0, m.ry || 0, 0);
|
|
4423
4521
|
shared.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" });
|
|
4424
4522
|
}
|
|
4425
|
-
|
|
4523
|
+
const defined = { houseItems, waterTankOfHouse, hashColor, labeledBox };
|
|
4524
|
+
Object.assign(K, defined);
|
|
4426
4525
|
}
|
|
4427
4526
|
|
|
4428
4527
|
// src/vegetation/bridge.ts
|
|
4528
|
+
import { isMesh as isMesh2 } from "@adatechnology/game-shapes-three";
|
|
4429
4529
|
function installVegetationBridge(K, shared) {
|
|
4430
4530
|
const seedKey = (id) => K.seedKey(id);
|
|
4431
4531
|
const { THREE, SEED, rngString } = K;
|
|
@@ -4457,7 +4557,7 @@ function installVegetationBridge(K, shared) {
|
|
|
4457
4557
|
const ids = VEG_MAP[m.type], can = VEG_PLANTER[m.type];
|
|
4458
4558
|
if (!ids && !can) return false;
|
|
4459
4559
|
const rnd = rngString(SEED() + "|" + seedKey(m.id) + "|veg"), pick = (l) => l[Math.min(l.length - 1, rnd() * l.length | 0)], ok = (id) => {
|
|
4460
|
-
if (V.ok.has(id)) return V.ok.get(id);
|
|
4560
|
+
if (V.ok.has(id)) return V.ok.get(id) === true;
|
|
4461
4561
|
let r = true;
|
|
4462
4562
|
try {
|
|
4463
4563
|
V.S.toSpec(id);
|
|
@@ -4503,7 +4603,7 @@ function installVegetationBridge(K, shared) {
|
|
|
4503
4603
|
obj.position.y = G.y;
|
|
4504
4604
|
obj.name = "vegetation";
|
|
4505
4605
|
obj.traverse((o) => {
|
|
4506
|
-
if (o
|
|
4606
|
+
if (isMesh2(o)) {
|
|
4507
4607
|
o.castShadow = true;
|
|
4508
4608
|
o.receiveShadow = true;
|
|
4509
4609
|
o.name = "veg/" + o.name;
|
|
@@ -4518,10 +4618,12 @@ function installVegetationBridge(K, shared) {
|
|
|
4518
4618
|
}
|
|
4519
4619
|
shared.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
|
|
4520
4620
|
}
|
|
4521
|
-
|
|
4621
|
+
const defined = { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation };
|
|
4622
|
+
Object.assign(K, defined);
|
|
4522
4623
|
}
|
|
4523
4624
|
|
|
4524
4625
|
// src/interaction/state.ts
|
|
4626
|
+
import { isMesh as isMesh3 } from "@adatechnology/game-shapes-three";
|
|
4525
4627
|
function installInteractionState(K, shared) {
|
|
4526
4628
|
const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
|
|
4527
4629
|
const ivRoomEffective = (...a) => K.ivRoomEffective(...a);
|
|
@@ -4586,12 +4688,14 @@ function installInteractionState(K, shared) {
|
|
|
4586
4688
|
shared.inter.msg = { text, until: performance.now() + MESSAGE_MS };
|
|
4587
4689
|
if (cfg.onMessage) cfg.onMessage(text);
|
|
4588
4690
|
};
|
|
4589
|
-
|
|
4691
|
+
const I = () => shared.inter;
|
|
4692
|
+
function definePiece(name, definition) {
|
|
4693
|
+
const def = definition;
|
|
4590
4694
|
def.name = name;
|
|
4591
4695
|
def.meshes = [];
|
|
4592
4696
|
def.t = def.target = shared.partState.has(name) ? shared.partState.get(name) : def.t0 || 0;
|
|
4593
|
-
|
|
4594
|
-
|
|
4697
|
+
I().defs.set(name, def);
|
|
4698
|
+
I().pieces.push(def);
|
|
4595
4699
|
return def;
|
|
4596
4700
|
}
|
|
4597
4701
|
const localOf = (M, lx, lz) => {
|
|
@@ -4603,17 +4707,18 @@ function installInteractionState(K, shared) {
|
|
|
4603
4707
|
return true;
|
|
4604
4708
|
}
|
|
4605
4709
|
function assembleInteractive(gs) {
|
|
4606
|
-
|
|
4710
|
+
const inter = I();
|
|
4711
|
+
for (const [name, def] of inter.defs) {
|
|
4607
4712
|
const g = gs[name];
|
|
4608
4713
|
if (!g) continue;
|
|
4609
4714
|
delete gs[name];
|
|
4610
4715
|
const outer = new THREE.Group();
|
|
4611
|
-
outer.position.
|
|
4716
|
+
outer.position.fromArray(def.pivot);
|
|
4612
4717
|
outer.rotation.y = def.ry || 0;
|
|
4613
4718
|
outer.updateMatrix();
|
|
4614
|
-
const inv = new THREE.Matrix4().compose(new THREE.Vector3(
|
|
4719
|
+
const inv = new THREE.Matrix4().compose(new THREE.Vector3().fromArray(def.pivot), new THREE.Quaternion().setFromAxisAngle(_EY, def.ry || 0), _UM3).invert();
|
|
4615
4720
|
g.traverse((o) => {
|
|
4616
|
-
if (o
|
|
4721
|
+
if (isMesh3(o)) {
|
|
4617
4722
|
o.geometry.applyMatrix4(inv);
|
|
4618
4723
|
o.userData.piece = def;
|
|
4619
4724
|
def.meshes.push(o);
|
|
@@ -4625,13 +4730,14 @@ function installInteractionState(K, shared) {
|
|
|
4625
4730
|
const parent = def.leaf ? def.leaf.gs[def.k] : gs[def.parent] || (gs[def.parent] = new THREE.Group());
|
|
4626
4731
|
if (parent) parent.add(outer);
|
|
4627
4732
|
if (def.roomId) {
|
|
4628
|
-
|
|
4629
|
-
|
|
4733
|
+
let lamps = inter.lights.get(def.roomId);
|
|
4734
|
+
if (!lamps) inter.lights.set(def.roomId, lamps = []);
|
|
4735
|
+
lamps.push(def);
|
|
4630
4736
|
}
|
|
4631
4737
|
applyPiece(def);
|
|
4632
4738
|
}
|
|
4633
|
-
for (const roomId of
|
|
4634
|
-
|
|
4739
|
+
for (const roomId of inter.litRooms) applyLight(roomId);
|
|
4740
|
+
inter.defs.forEach((d) => {
|
|
4635
4741
|
if (d.col) d.col.off = d.t > 0.5;
|
|
4636
4742
|
});
|
|
4637
4743
|
}
|
|
@@ -4639,6 +4745,7 @@ function installInteractionState(K, shared) {
|
|
|
4639
4745
|
const n = p.inner;
|
|
4640
4746
|
if (!n) return;
|
|
4641
4747
|
switch (p.kind) {
|
|
4748
|
+
/* each kind always sets its dimensions (sgn, angle, travel, k, axis) */
|
|
4642
4749
|
case "swing":
|
|
4643
4750
|
n.rotation.y = p.sgn * p.t * p.angle;
|
|
4644
4751
|
break;
|
|
@@ -4671,8 +4778,9 @@ function installInteractionState(K, shared) {
|
|
|
4671
4778
|
}
|
|
4672
4779
|
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 };
|
|
4673
4780
|
function animateInteractive(dt) {
|
|
4674
|
-
|
|
4675
|
-
|
|
4781
|
+
const inter = I();
|
|
4782
|
+
if (!inter.anim.size) return;
|
|
4783
|
+
for (const p of inter.anim) {
|
|
4676
4784
|
const step = dt / (DURATION[p.kind] || 0.5), d = p.target - p.t;
|
|
4677
4785
|
p.t = Math.abs(d) <= step ? p.target : p.t + Math.sign(d) * step;
|
|
4678
4786
|
applyPiece(p);
|
|
@@ -4680,7 +4788,7 @@ function installInteractionState(K, shared) {
|
|
|
4680
4788
|
p.col.off = p.target > 0.5;
|
|
4681
4789
|
colliderChanged(p.col);
|
|
4682
4790
|
}
|
|
4683
|
-
if (p.t === p.target)
|
|
4791
|
+
if (p.t === p.target) inter.anim.delete(p);
|
|
4684
4792
|
}
|
|
4685
4793
|
invalidateShadow();
|
|
4686
4794
|
}
|
|
@@ -4691,7 +4799,7 @@ function installInteractionState(K, shared) {
|
|
|
4691
4799
|
p.col.off = p.target > 0.5;
|
|
4692
4800
|
colliderChanged(p.col);
|
|
4693
4801
|
}
|
|
4694
|
-
|
|
4802
|
+
I().anim.add(p);
|
|
4695
4803
|
}
|
|
4696
4804
|
const lightBase = (roomId) => roomId == null ? true : shared.partState.has("light:" + roomId) ? !!shared.partState.get("light:" + roomId) : !!shared.ctx.night;
|
|
4697
4805
|
const lightOn = (roomId) => {
|
|
@@ -4699,20 +4807,21 @@ function installInteractionState(K, shared) {
|
|
|
4699
4807
|
return S ? S.ef : lightBase(roomId);
|
|
4700
4808
|
};
|
|
4701
4809
|
function applyLight(roomId) {
|
|
4702
|
-
const on = lightOn(roomId);
|
|
4703
|
-
for (const d of
|
|
4704
|
-
const sw =
|
|
4810
|
+
const on = lightOn(roomId), inter = I(), mats = shared.mats;
|
|
4811
|
+
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;
|
|
4812
|
+
const sw = inter.defs.get("ix:int:" + roomId);
|
|
4705
4813
|
if (sw) {
|
|
4706
4814
|
sw.target = on ? 1 : 0;
|
|
4707
|
-
if (sw.t !== sw.target)
|
|
4815
|
+
if (sw.t !== sw.target) inter.anim.add(sw);
|
|
4708
4816
|
}
|
|
4709
4817
|
invalidate();
|
|
4710
4818
|
}
|
|
4711
4819
|
function toggleLight(roomId) {
|
|
4712
4820
|
const S = shared.ctx.iv && shared.ctx.iv.roomStates.get(roomId);
|
|
4713
4821
|
if (S) {
|
|
4714
|
-
|
|
4715
|
-
|
|
4822
|
+
const IV = shared.ctx.iv;
|
|
4823
|
+
ivRoomLight(IV, roomId, !S.ef);
|
|
4824
|
+
const ef = ivRoomEffective(IV, S);
|
|
4716
4825
|
if (ef !== S.ef) {
|
|
4717
4826
|
S.ef = ef;
|
|
4718
4827
|
applyLight(roomId);
|
|
@@ -4724,11 +4833,13 @@ function installInteractionState(K, shared) {
|
|
|
4724
4833
|
applyLight(roomId);
|
|
4725
4834
|
if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
|
|
4726
4835
|
}
|
|
4727
|
-
|
|
4836
|
+
const defined = { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight };
|
|
4837
|
+
Object.assign(K, defined);
|
|
4728
4838
|
}
|
|
4729
4839
|
|
|
4730
4840
|
// src/interaction/collision.ts
|
|
4731
4841
|
function installInteractionCollision(K, shared) {
|
|
4842
|
+
const inter = () => shared.inter;
|
|
4732
4843
|
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)/;
|
|
4733
4844
|
function registerCollision(m, M) {
|
|
4734
4845
|
const h = m.h || 0, y = M.y || 0;
|
|
@@ -4738,7 +4849,7 @@ function installInteractionCollision(K, shared) {
|
|
|
4738
4849
|
w = Math.min(w, 0.5);
|
|
4739
4850
|
d = Math.min(d, 0.5);
|
|
4740
4851
|
}
|
|
4741
|
-
|
|
4852
|
+
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 });
|
|
4742
4853
|
}
|
|
4743
4854
|
function objectDistance(o, x, z) {
|
|
4744
4855
|
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;
|
|
@@ -4746,7 +4857,7 @@ function installInteractionCollision(K, shared) {
|
|
|
4746
4857
|
}
|
|
4747
4858
|
function collideObject(x, z, fx, fz, floor) {
|
|
4748
4859
|
const R = 0.2;
|
|
4749
|
-
for (const o of
|
|
4860
|
+
for (const o of inter().objs) {
|
|
4750
4861
|
if (o.f !== -1 ? o.f !== floor : floor !== 0) continue;
|
|
4751
4862
|
const d1 = objectDistance(o, x, z);
|
|
4752
4863
|
if (d1 < R && d1 < objectDistance(o, fx, fz) - 1e-6) return true;
|
|
@@ -4766,7 +4877,8 @@ function installInteractionCollision(K, shared) {
|
|
|
4766
4877
|
const de = opt.from || [x + 1e4, z + 1e4];
|
|
4767
4878
|
return collideObject(x, z, de[0], de[1], floor);
|
|
4768
4879
|
}
|
|
4769
|
-
|
|
4880
|
+
const defined = { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt };
|
|
4881
|
+
Object.assign(K, defined);
|
|
4770
4882
|
}
|
|
4771
4883
|
|
|
4772
4884
|
// src/interaction/items.ts
|
|
@@ -4775,6 +4887,7 @@ function installInteractionItems(K, shared) {
|
|
|
4775
4887
|
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)$/;
|
|
4776
4888
|
const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
|
|
4777
4889
|
const LIGHT_TYPES = /* @__PURE__ */ new Set(["ceiling_light", "pendant", "chandelier", "track_spot", "hanging_plant"]);
|
|
4890
|
+
const I = () => shared.inter;
|
|
4778
4891
|
function objectName(type, drawer) {
|
|
4779
4892
|
return drawer ? "drawer" : /^wardrobe/.test(type) ? "wardrobe" : /fridge|refrig|freezer/.test(type) ? "fridge" : /pantry/.test(type) ? "pantry" : "cabinet";
|
|
4780
4893
|
}
|
|
@@ -4803,8 +4916,8 @@ function installInteractionItems(K, shared) {
|
|
|
4803
4916
|
cursor.group = parent;
|
|
4804
4917
|
}
|
|
4805
4918
|
for (let i = n0; i < LIGHTS.length; i++) LIGHTS[i].roomId = m.room;
|
|
4806
|
-
if (!
|
|
4807
|
-
|
|
4919
|
+
if (!I().defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
|
|
4920
|
+
I().litRooms.add(m.room);
|
|
4808
4921
|
}
|
|
4809
4922
|
function curtainItem(m, M, ent, api, parent) {
|
|
4810
4923
|
M.open = false;
|
|
@@ -4832,12 +4945,13 @@ function installInteractionItems(K, shared) {
|
|
|
4832
4945
|
for (const c of body) api[c[0]](M, ...c[1]);
|
|
4833
4946
|
if (!parts.length) return;
|
|
4834
4947
|
const [ax, az] = localOf(M, 0, 0.2);
|
|
4835
|
-
|
|
4836
|
-
|
|
4948
|
+
const first = parts[0];
|
|
4949
|
+
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: () => {
|
|
4950
|
+
const al = first.target > 0.5 ? 0 : 1;
|
|
4837
4951
|
for (const p of parts) {
|
|
4838
4952
|
p.target = al;
|
|
4839
4953
|
shared.partState.set(p.name, al);
|
|
4840
|
-
|
|
4954
|
+
I().anim.add(p);
|
|
4841
4955
|
}
|
|
4842
4956
|
} });
|
|
4843
4957
|
}
|
|
@@ -4858,7 +4972,7 @@ function installInteractionItems(K, shared) {
|
|
|
4858
4972
|
calls.forEach((c, i) => {
|
|
4859
4973
|
if (owner.has(i)) return;
|
|
4860
4974
|
const a = c[1];
|
|
4861
|
-
let x0, x1, y0, y1, ok = false, grip = 0, wide = false;
|
|
4975
|
+
let x0 = 0, x1 = 0, y0 = 0, y1 = 0, ok = false, grip = 0, wide = false;
|
|
4862
4976
|
if (c[0] === "box") {
|
|
4863
4977
|
const [mat, x, y, z, w, h, d, , ry, rx, rz] = a;
|
|
4864
4978
|
if (ry || rx || rz || d > 0.05 || z + d / 2 < front - 5e-3 || w > M.w * 1.01) return;
|
|
@@ -4890,8 +5004,9 @@ function installInteractionItems(K, shared) {
|
|
|
4890
5004
|
return;
|
|
4891
5005
|
}
|
|
4892
5006
|
candidate.sort((p, q) => overlap(x0, x1, q.x0, q.x1) - overlap(x0, x1, p.x0, p.x1));
|
|
4893
|
-
|
|
4894
|
-
|
|
5007
|
+
const best = candidate[0];
|
|
5008
|
+
owner.set(i, best);
|
|
5009
|
+
if (grip) best.grip = grip;
|
|
4895
5010
|
});
|
|
4896
5011
|
const name = objectName(m.type, drawer), parts = [];
|
|
4897
5012
|
panels.forEach((p, k) => {
|
|
@@ -4907,8 +5022,8 @@ function installInteractionItems(K, shared) {
|
|
|
4907
5022
|
p.def = def;
|
|
4908
5023
|
parts.push(def);
|
|
4909
5024
|
const [ax, az] = localOf(M, cx, front + 0.08);
|
|
4910
|
-
|
|
4911
|
-
def.item =
|
|
5025
|
+
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) });
|
|
5026
|
+
def.item = I().items[I().items.length - 1];
|
|
4912
5027
|
});
|
|
4913
5028
|
calls.forEach((c, i) => {
|
|
4914
5029
|
const p = owner.get(i);
|
|
@@ -4922,14 +5037,17 @@ function installInteractionItems(K, shared) {
|
|
|
4922
5037
|
}
|
|
4923
5038
|
cursor.group = parent;
|
|
4924
5039
|
}
|
|
4925
|
-
|
|
5040
|
+
const defined = { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem, lightItem, curtainItem, furnitureItem };
|
|
5041
|
+
Object.assign(K, defined);
|
|
4926
5042
|
}
|
|
4927
5043
|
|
|
4928
5044
|
// src/interaction/fittings.ts
|
|
4929
5045
|
function installInteractionFittings(K, shared) {
|
|
4930
5046
|
const { t, EPS, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
|
|
5047
|
+
const I = () => shared.inter;
|
|
5048
|
+
const house = () => shared.ctx.r;
|
|
4931
5049
|
function gatesInteractive() {
|
|
4932
|
-
const lt =
|
|
5050
|
+
const lt = house().lot;
|
|
4933
5051
|
if (!lt) return;
|
|
4934
5052
|
const cz0 = (lt.rect[1] + lt.rect[3]) / 2;
|
|
4935
5053
|
const orig = K.getBx(), gs = lt.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
|
|
@@ -4949,9 +5067,9 @@ function installInteractionFittings(K, shared) {
|
|
|
4949
5067
|
return;
|
|
4950
5068
|
}
|
|
4951
5069
|
}
|
|
4952
|
-
|
|
5070
|
+
orig(mat, x0, y0, z0, x1, y1, z1, color);
|
|
4953
5071
|
});
|
|
4954
|
-
const
|
|
5072
|
+
const colliders = shared.ctx.colliders, n0 = colliders.length;
|
|
4955
5073
|
try {
|
|
4956
5074
|
gs.forEach((g) => {
|
|
4957
5075
|
g.open = false;
|
|
@@ -4963,7 +5081,7 @@ function installInteractionFittings(K, shared) {
|
|
|
4963
5081
|
g.open = opening[i];
|
|
4964
5082
|
});
|
|
4965
5083
|
}
|
|
4966
|
-
const cols =
|
|
5084
|
+
const cols = colliders.slice(n0), cz = (lt.rect[1] + lt.rect[3]) / 2, cu = (lt.rect[0] + lt.rect[2]) / 2;
|
|
4967
5085
|
reg.forEach((r, i) => {
|
|
4968
5086
|
const g = r.g;
|
|
4969
5087
|
if (!isFinite(r.x0)) return;
|
|
@@ -4972,25 +5090,25 @@ function installInteractionFittings(K, shared) {
|
|
|
4972
5090
|
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 }));
|
|
4973
5091
|
if (p.col) p.col.off = p.target > 0.5;
|
|
4974
5092
|
const text = () => t(p.target > 0.5 ? "prompt.close" : "prompt.open", { what: t(ped ? "what.pedestrianGate" : "what.garageGate") });
|
|
4975
|
-
|
|
5093
|
+
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 });
|
|
4976
5094
|
});
|
|
4977
5095
|
}
|
|
4978
5096
|
function mailboxInteractive() {
|
|
4979
|
-
for (const m of
|
|
5097
|
+
for (const m of house().items) {
|
|
4980
5098
|
if (m.type !== "mailbox") continue;
|
|
4981
5099
|
const g = shared.ctx.parts && shared.ctx.parts["mailbox_" + m.id];
|
|
4982
5100
|
if (!g) continue;
|
|
4983
5101
|
const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
|
|
4984
5102
|
def.inner = g;
|
|
4985
5103
|
const fx = Math.sin(m.ry || 0), fz = Math.cos(m.ry || 0), ay = (m.y || 1) + (m.h || 0.3) * 0.4;
|
|
4986
|
-
|
|
5104
|
+
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 });
|
|
4987
5105
|
applyPiece(def);
|
|
4988
5106
|
}
|
|
4989
5107
|
}
|
|
4990
5108
|
function placeSwitches() {
|
|
4991
|
-
const R =
|
|
5109
|
+
const R = house(), used = /* @__PURE__ */ new Set();
|
|
4992
5110
|
for (const c of R.rooms) {
|
|
4993
|
-
if (c.type === "void" || OPEN_AREA(c) || !
|
|
5111
|
+
if (c.type === "void" || OPEN_AREA(c) || !I().litRooms.has(c.id) || used.has(c.id) || shared.ctx.iv && shared.ctx.iv.switchRooms.has(c.id)) continue;
|
|
4994
5112
|
const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
|
|
4995
5113
|
doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
|
|
4996
5114
|
for (const p of doors) if (putSwitch(c, p)) {
|
|
@@ -5000,11 +5118,11 @@ function installInteractionFittings(K, shared) {
|
|
|
5000
5118
|
}
|
|
5001
5119
|
}
|
|
5002
5120
|
function putSwitch(c, p) {
|
|
5003
|
-
const R =
|
|
5121
|
+
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;
|
|
5004
5122
|
const wref = R.walls.find((w) => w.floor === f && w.axis === p.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS), th = wref ? wref.thickness || 0.15 : 0.15;
|
|
5005
5123
|
const inside = (sd2) => {
|
|
5006
5124
|
const cc = roomAt(f, alongU ? p.at : L + sd2 * 0.4, alongU ? L + sd2 * 0.4 : p.at);
|
|
5007
|
-
return cc && cc.id === c.id;
|
|
5125
|
+
return !!cc && cc.id === c.id;
|
|
5008
5126
|
};
|
|
5009
5127
|
const sd = inside(1) ? 1 : inside(-1) ? -1 : 0;
|
|
5010
5128
|
if (!sd) return false;
|
|
@@ -5027,19 +5145,22 @@ function installInteractionFittings(K, shared) {
|
|
|
5027
5145
|
const piece = 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 });
|
|
5028
5146
|
piece.t = piece.target = lightOn(roomId) ? 1 : 0;
|
|
5029
5147
|
const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
|
|
5030
|
-
|
|
5148
|
+
I().items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
|
|
5031
5149
|
return true;
|
|
5032
5150
|
}
|
|
5033
5151
|
return false;
|
|
5034
5152
|
}
|
|
5035
|
-
|
|
5153
|
+
const defined = { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch };
|
|
5154
|
+
Object.assign(K, defined);
|
|
5036
5155
|
}
|
|
5037
5156
|
|
|
5038
5157
|
// src/interaction/doors.ts
|
|
5039
5158
|
function installInteractionDoors(K, shared) {
|
|
5040
5159
|
const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
|
|
5160
|
+
const leaves = () => shared.ctx.leaves;
|
|
5041
5161
|
function linkDoorLeaves() {
|
|
5042
|
-
|
|
5162
|
+
const I = shared.inter;
|
|
5163
|
+
for (const fo of leaves()) fo.handles = (fo.handleNames || []).map((n) => I.defs.get(n)).filter((d) => !!d);
|
|
5043
5164
|
}
|
|
5044
5165
|
function handleApply(fo) {
|
|
5045
5166
|
for (const mc of fo.handles || []) {
|
|
@@ -5049,11 +5170,12 @@ function installInteractionDoors(K, shared) {
|
|
|
5049
5170
|
}
|
|
5050
5171
|
function toggleDoor(fo) {
|
|
5051
5172
|
if (fo.phase === "rattle") return;
|
|
5173
|
+
const col = fo.col;
|
|
5052
5174
|
if (fo.phase === "handle" || fo.phase === "swing") {
|
|
5053
5175
|
fo.open = !fo.open;
|
|
5054
5176
|
shared.doorState.set(fo.id, fo.open);
|
|
5055
|
-
|
|
5056
|
-
colliderChanged(
|
|
5177
|
+
col.off = fo.open;
|
|
5178
|
+
colliderChanged(col);
|
|
5057
5179
|
fo.anim = true;
|
|
5058
5180
|
fo.phase = "swing";
|
|
5059
5181
|
return;
|
|
@@ -5067,8 +5189,8 @@ function installInteractionDoors(K, shared) {
|
|
|
5067
5189
|
}
|
|
5068
5190
|
fo.open = !fo.open;
|
|
5069
5191
|
shared.doorState.set(fo.id, fo.open);
|
|
5070
|
-
|
|
5071
|
-
colliderChanged(
|
|
5192
|
+
col.off = fo.open;
|
|
5193
|
+
colliderChanged(col);
|
|
5072
5194
|
fo.anim = true;
|
|
5073
5195
|
shared.ctx.animateDoorsOn = true;
|
|
5074
5196
|
if (fo.handles && fo.handles.length) {
|
|
@@ -5079,7 +5201,7 @@ function installInteractionDoors(K, shared) {
|
|
|
5079
5201
|
function animateDoors(dt) {
|
|
5080
5202
|
if (!shared.ctx.animateDoorsOn) return;
|
|
5081
5203
|
let active = false;
|
|
5082
|
-
for (const fo of
|
|
5204
|
+
for (const fo of leaves()) {
|
|
5083
5205
|
if (!fo.phase) continue;
|
|
5084
5206
|
active = true;
|
|
5085
5207
|
if (fo.phase === "handle") {
|
|
@@ -5099,7 +5221,7 @@ function installInteractionDoors(K, shared) {
|
|
|
5099
5221
|
handleApply(fo);
|
|
5100
5222
|
if (fo.hT <= 0) fo.phase = null;
|
|
5101
5223
|
} else if (fo.phase === "rattle") {
|
|
5102
|
-
fo.jig
|
|
5224
|
+
fo.jig = (fo.jig ?? 0) - dt;
|
|
5103
5225
|
fo.hT = fo.jig > 0 ? 0.55 * Math.abs(Math.sin(fo.jig * 26)) : 0;
|
|
5104
5226
|
handleApply(fo);
|
|
5105
5227
|
if (fo.jig <= 0) {
|
|
@@ -5113,9 +5235,9 @@ function installInteractionDoors(K, shared) {
|
|
|
5113
5235
|
invalidateShadow();
|
|
5114
5236
|
}
|
|
5115
5237
|
function wallBlocks(ex, ez, ax, az, floor) {
|
|
5116
|
-
const n = shared.ctx.wallColliders != null ? shared.ctx.wallColliders : 0;
|
|
5238
|
+
const n = shared.ctx.wallColliders != null ? shared.ctx.wallColliders : 0, colliders = shared.ctx.colliders;
|
|
5117
5239
|
for (let i = 0; i < n; i++) {
|
|
5118
|
-
const c =
|
|
5240
|
+
const c = colliders[i];
|
|
5119
5241
|
if (c.f !== floor && !(c.f === -1 && floor === 0)) continue;
|
|
5120
5242
|
let t0 = 0, t1 = 1;
|
|
5121
5243
|
const dx = ax - ex, dz = az - ez;
|
|
@@ -5145,7 +5267,8 @@ function installInteractionDoors(K, shared) {
|
|
|
5145
5267
|
g.updateMatrix();
|
|
5146
5268
|
}
|
|
5147
5269
|
}
|
|
5148
|
-
|
|
5270
|
+
const defined = { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf };
|
|
5271
|
+
Object.assign(K, defined);
|
|
5149
5272
|
}
|
|
5150
5273
|
|
|
5151
5274
|
// src/interaction/target.ts
|
|
@@ -5155,6 +5278,7 @@ function installInteractionTarget(K, shared) {
|
|
|
5155
5278
|
function targetOf(o, opt) {
|
|
5156
5279
|
if (!o) return null;
|
|
5157
5280
|
opt = opt || {};
|
|
5281
|
+
const I = shared.inter;
|
|
5158
5282
|
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;
|
|
5159
5283
|
let best = null;
|
|
5160
5284
|
const tries = (score, text, action, target) => {
|
|
@@ -5168,16 +5292,16 @@ function installInteractionTarget(K, shared) {
|
|
|
5168
5292
|
if (angle > 1.35 && d > 0.9) continue;
|
|
5169
5293
|
tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
|
|
5170
5294
|
}
|
|
5171
|
-
const vis =
|
|
5295
|
+
const vis = I.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
|
|
5172
5296
|
const kitA = shared.ctx.iv ? ivTarget(shared.ctx.iv, o, opt && opt.interactives) : null;
|
|
5173
5297
|
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;
|
|
5174
5298
|
const pieceHit = hit && !nearKit && hit.object.userData.piece;
|
|
5175
|
-
for (const it of
|
|
5299
|
+
for (const it of I.items) {
|
|
5176
5300
|
if (it.floor !== floor && !(it.floor === -1 && floor === 0)) continue;
|
|
5177
5301
|
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);
|
|
5178
5302
|
if (dh > it.range + 0.4) continue;
|
|
5179
5303
|
const angle = Math.acos(Math.max(-1, Math.min(1, (dx * vx + dy * vy + dz * vz) / (d || 1))));
|
|
5180
|
-
const byRay = pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
|
|
5304
|
+
const byRay = !!hit && pieceHit && it.pieces.includes(pieceHit) && hit.distance <= it.range + 0.5;
|
|
5181
5305
|
if (!byRay && !(dh <= it.range && angle <= it.angle)) continue;
|
|
5182
5306
|
if (!it.noWall && wallBlocks(ex, ez, ax, az, it.floor < 0 ? 0 : it.floor)) continue;
|
|
5183
5307
|
tries((byRay ? 0 : angle * 2) + d * 0.3 - (byRay ? 1.5 : 0), it.text(), it.action, it);
|
|
@@ -5185,10 +5309,12 @@ function installInteractionTarget(K, shared) {
|
|
|
5185
5309
|
if (kitA) tries(kitA.score - (nearKit ? 0.5 : 0), kitA.text, kitA.action, kitA.target);
|
|
5186
5310
|
return best;
|
|
5187
5311
|
}
|
|
5188
|
-
|
|
5312
|
+
const defined = { targetOf };
|
|
5313
|
+
Object.assign(K, defined);
|
|
5189
5314
|
}
|
|
5190
5315
|
|
|
5191
5316
|
// src/interactables/bridge.ts
|
|
5317
|
+
import { isMesh as isMesh4 } from "@adatechnology/game-shapes-three";
|
|
5192
5318
|
function installInteractablesBridge(K, shared) {
|
|
5193
5319
|
const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
|
|
5194
5320
|
const enter = (...a) => K.enter(...a);
|
|
@@ -5242,7 +5368,8 @@ function installInteractablesBridge(K, shared) {
|
|
|
5242
5368
|
function ivBuild(h, water) {
|
|
5243
5369
|
const ik = K.IVK, r = shared.ctx.r, A = ik.A, world0 = null;
|
|
5244
5370
|
void world0;
|
|
5245
|
-
const
|
|
5371
|
+
const source = r;
|
|
5372
|
+
const plane = A.plan(source, { seed: r.seed });
|
|
5246
5373
|
const IV = { k: ik, plane, 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 };
|
|
5247
5374
|
h.IV = IV;
|
|
5248
5375
|
const t0 = performance.now();
|
|
@@ -5261,9 +5388,10 @@ function installInteractablesBridge(K, shared) {
|
|
|
5261
5388
|
const wants = (roomId) => lightBase(roomId);
|
|
5262
5389
|
const entById = new Map(plane.items.map((e) => [e.id, e]));
|
|
5263
5390
|
const entByItem = new Map(plane.items.map((e) => [e.item, e]));
|
|
5264
|
-
|
|
5391
|
+
const mats = shared.mats;
|
|
5392
|
+
IV.mats = { plain: mats.plain, metal: shared.mats.metal, wood: shared.mats.wood, glass: shared.mats.glass, fabric: shared.mats.fabric, plant: shared.mats.plant, water: shared.mats.water, emissive: shared.mats.emissive, atlas_picture: shared.mats.picture, atlas_floor: shared.mats.floor };
|
|
5265
5393
|
const ev = (e) => ivEvent(h, e);
|
|
5266
|
-
const world = IV.world = A.createWorld(
|
|
5394
|
+
const world = IV.world = A.createWorld(source, { water, seed: r.seed, onEvent: ev });
|
|
5267
5395
|
const add0 = world.add;
|
|
5268
5396
|
world.add = (id, spec, tr) => {
|
|
5269
5397
|
const e = entById.get(id);
|
|
@@ -5280,7 +5408,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5280
5408
|
}
|
|
5281
5409
|
return add0(id, spec, tr);
|
|
5282
5410
|
};
|
|
5283
|
-
const added = A.add(world, plane, { isBlocked: A.blockedOf(
|
|
5411
|
+
const added = A.add(world, plane, { isBlocked: A.blockedOf(source), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
|
|
5284
5412
|
world.add = add0;
|
|
5285
5413
|
IV.warnings = added.warnings;
|
|
5286
5414
|
IV.added = added;
|
|
@@ -5327,14 +5455,15 @@ function installInteractablesBridge(K, shared) {
|
|
|
5327
5455
|
}
|
|
5328
5456
|
function ivDraw(IV, ent, type, item) {
|
|
5329
5457
|
const ik = IV.k, loc = Object.assign({}, item, { x: 0, z: 0, ry: 0 });
|
|
5458
|
+
const ix = item.x, iz = item.z, iry = item.ry;
|
|
5330
5459
|
const mesh = ik.gfx.createMeshApi({ quality: "game", materials: IV.mats, shadows: true, mergeParts: true, swayAmplitude: 0.03 });
|
|
5331
5460
|
const spec = ik.A.household.build(type, loc, mesh.api);
|
|
5332
5461
|
const out = mesh.finish(spec);
|
|
5333
5462
|
for (const l of out.lights) l.removeFromParent();
|
|
5334
5463
|
const group = ivGroup(ent), g0 = cursor.group, root = new THREE.Group();
|
|
5335
5464
|
root.name = "iv:" + ent.id;
|
|
5336
|
-
root.position.set(
|
|
5337
|
-
root.rotation.y =
|
|
5465
|
+
root.position.set(ix, ent.floorY, iz);
|
|
5466
|
+
root.rotation.y = iry;
|
|
5338
5467
|
root.userData.iv = ent.id;
|
|
5339
5468
|
const screen = spec.devices && spec.devices.some((d) => d.kind === "screen");
|
|
5340
5469
|
let body = null;
|
|
@@ -5343,7 +5472,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5343
5472
|
if (type === "gas_bottle") {
|
|
5344
5473
|
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"] });
|
|
5345
5474
|
for (const m of out.group.children) if (!m.name.startsWith("static:")) m.traverse((o) => {
|
|
5346
|
-
if (o
|
|
5475
|
+
if (isMesh4(o)) {
|
|
5347
5476
|
o.userData.destructionPart = cursor.pc.id;
|
|
5348
5477
|
o.userData.destructionMaterial = "steel";
|
|
5349
5478
|
}
|
|
@@ -5351,13 +5480,13 @@ function installInteractablesBridge(K, shared) {
|
|
|
5351
5480
|
}
|
|
5352
5481
|
try {
|
|
5353
5482
|
for (const m of out.group.children.slice()) {
|
|
5354
|
-
if (m
|
|
5483
|
+
if (isMesh4(m) && m.name.startsWith("static:")) {
|
|
5355
5484
|
if (screen && m.userData.material === "emissive") {
|
|
5356
5485
|
body = m;
|
|
5357
5486
|
root.add(m);
|
|
5358
5487
|
continue;
|
|
5359
5488
|
}
|
|
5360
|
-
ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry,
|
|
5489
|
+
ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, ix, ent.floorY, iz, iry, null);
|
|
5361
5490
|
m.geometry.dispose();
|
|
5362
5491
|
} else root.add(m);
|
|
5363
5492
|
}
|
|
@@ -5367,7 +5496,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5367
5496
|
}
|
|
5368
5497
|
const base = new Set(Object.values(IV.mats));
|
|
5369
5498
|
root.traverse((o) => {
|
|
5370
|
-
if (!o
|
|
5499
|
+
if (!isMesh4(o)) return;
|
|
5371
5500
|
o.userData.iv = ent.id;
|
|
5372
5501
|
if (o.castShadow) {
|
|
5373
5502
|
if (!o.geometry.boundingSphere) o.geometry.computeBoundingSphere();
|
|
@@ -5378,7 +5507,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5378
5507
|
roomLightMask(m);
|
|
5379
5508
|
}
|
|
5380
5509
|
});
|
|
5381
|
-
const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [
|
|
5510
|
+
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 };
|
|
5382
5511
|
IV.entries.set(ent.id, E);
|
|
5383
5512
|
if (root.children.length) IV.roots.push(E);
|
|
5384
5513
|
return spec;
|
|
@@ -5406,7 +5535,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5406
5535
|
const wire = (spec.wires || []).find((x) => x.id === d.id + "_cord"), pts = (wire ? wire.points : [d.plug]).map((p) => wl(o, p));
|
|
5407
5536
|
const sid = w.power.pluggedInto(E.id, d.id);
|
|
5408
5537
|
if (sid) {
|
|
5409
|
-
const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && so.spec.sockets.find((s) => s.id === sid.slice(cut + 1));
|
|
5538
|
+
const cut = sid.indexOf(":"), so = w.get(sid.slice(0, cut)), sk = so && (so.spec.sockets || []).find((s) => s.id === sid.slice(cut + 1));
|
|
5410
5539
|
if (so && sk) {
|
|
5411
5540
|
const sp = wl(so, sk.pos), dir = [Math.sin(so.transform.ry), Math.cos(so.transform.ry)], last = pts[pts.length - 1];
|
|
5412
5541
|
if (last[1] < 0.3 + E.pos[1]) {
|
|
@@ -5441,9 +5570,10 @@ function installInteractablesBridge(K, shared) {
|
|
|
5441
5570
|
roomLightMask(sc.material);
|
|
5442
5571
|
IV.screens.set(E.id, sc);
|
|
5443
5572
|
}
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5573
|
+
const mesh = E.screen;
|
|
5574
|
+
mesh.material = sc.material;
|
|
5575
|
+
mesh.castShadow = false;
|
|
5576
|
+
mesh.receiveShadow = false;
|
|
5447
5577
|
}
|
|
5448
5578
|
function ivEvent(h, e) {
|
|
5449
5579
|
const IV = h.IV;
|
|
@@ -5479,16 +5609,17 @@ function installInteractablesBridge(K, shared) {
|
|
|
5479
5609
|
IV.itemsDirty = true;
|
|
5480
5610
|
break;
|
|
5481
5611
|
}
|
|
5482
|
-
|
|
5612
|
+
const ik = K.IVK;
|
|
5613
|
+
if (ik.onEvent) {
|
|
5483
5614
|
try {
|
|
5484
|
-
|
|
5615
|
+
ik.onEvent(e, IV.pub);
|
|
5485
5616
|
} catch (err) {
|
|
5486
5617
|
console.warn("interactables.onEvent", err);
|
|
5487
5618
|
}
|
|
5488
5619
|
}
|
|
5489
|
-
if (e.type === "seat" &&
|
|
5620
|
+
if (e.type === "seat" && ik.onSeat && e.actor === "player") {
|
|
5490
5621
|
try {
|
|
5491
|
-
|
|
5622
|
+
ik.onSeat(e.seated ? ivSeat(IV) : null, e);
|
|
5492
5623
|
} catch (err) {
|
|
5493
5624
|
console.warn("interactables.onSeat", err);
|
|
5494
5625
|
}
|
|
@@ -5497,7 +5628,7 @@ function installInteractablesBridge(K, shared) {
|
|
|
5497
5628
|
function ivSeat(IV) {
|
|
5498
5629
|
const w = IV.world, s = w.seatOf("player");
|
|
5499
5630
|
if (!s) return null;
|
|
5500
|
-
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);
|
|
5631
|
+
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);
|
|
5501
5632
|
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]]);
|
|
5502
5633
|
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 };
|
|
5503
5634
|
}
|
|
@@ -5539,18 +5670,19 @@ function installInteractablesBridge(K, shared) {
|
|
|
5539
5670
|
}
|
|
5540
5671
|
}
|
|
5541
5672
|
const em = w.emitters();
|
|
5542
|
-
|
|
5673
|
+
const ivk = K.IVK;
|
|
5674
|
+
if (em.length && !IV.efx && ivk.effects) {
|
|
5543
5675
|
const g = h.houseGroup;
|
|
5544
|
-
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...
|
|
5676
|
+
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...ivk.effectSink ? { effects: ivk.effectSink } : {} });
|
|
5545
5677
|
}
|
|
5546
5678
|
if (IV.efx) {
|
|
5547
5679
|
const alive = IV.efx.stats().alive;
|
|
5548
5680
|
if (em.length || alive) {
|
|
5549
|
-
IV.efx.update(dt, em,
|
|
5681
|
+
IV.efx.update(dt, em, ivk.camera ? typeof ivk.camera === "function" ? ivk.camera() : ivk.camera : void 0);
|
|
5550
5682
|
invalidate();
|
|
5551
5683
|
}
|
|
5552
5684
|
}
|
|
5553
|
-
if (
|
|
5685
|
+
if (ivk.items && IV.itemsDirty && IV.t - IV.itemsT > 0.1 && !IV.anim.size) ivItems(IV, h);
|
|
5554
5686
|
}
|
|
5555
5687
|
const IV_SHAPE = {
|
|
5556
5688
|
can: [["cyl", 1, 1, 1, 0, 1]],
|
|
@@ -5585,7 +5717,8 @@ function installInteractablesBridge(K, shared) {
|
|
|
5585
5717
|
if (c.access && w.partT(E.id, c.access) < 0.02) continue;
|
|
5586
5718
|
const st = w.contents(E.id, c.id);
|
|
5587
5719
|
for (let i = 0; i < st.length; i++) {
|
|
5588
|
-
|
|
5720
|
+
const stack = st[i];
|
|
5721
|
+
if (stack && items[stack.type]) list.push([E, c.id, i, items[stack.type]]);
|
|
5589
5722
|
}
|
|
5590
5723
|
}
|
|
5591
5724
|
}
|
|
@@ -5614,12 +5747,13 @@ function installInteractablesBridge(K, shared) {
|
|
|
5614
5747
|
gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
|
|
5615
5748
|
gm.computeBoundingSphere();
|
|
5616
5749
|
if (!IV.items) {
|
|
5617
|
-
|
|
5618
|
-
IV.items
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5750
|
+
const mesh = new THREE.Mesh(gm, shared.mats.plain);
|
|
5751
|
+
IV.items = mesh;
|
|
5752
|
+
mesh.name = "iv-items";
|
|
5753
|
+
mesh.castShadow = false;
|
|
5754
|
+
mesh.receiveShadow = true;
|
|
5755
|
+
mesh.frustumCulled = false;
|
|
5756
|
+
h.houseGroup.add(mesh);
|
|
5623
5757
|
} else {
|
|
5624
5758
|
IV.items.geometry.dispose();
|
|
5625
5759
|
IV.items.geometry = gm;
|
|
@@ -5753,7 +5887,8 @@ function installInteractablesBridge(K, shared) {
|
|
|
5753
5887
|
};
|
|
5754
5888
|
return IV.pub;
|
|
5755
5889
|
}
|
|
5756
|
-
|
|
5890
|
+
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 };
|
|
5891
|
+
Object.assign(K, defined);
|
|
5757
5892
|
}
|
|
5758
5893
|
|
|
5759
5894
|
// src/animation/clotheslines.ts
|
|
@@ -5778,7 +5913,8 @@ function installAnimationClotheslines(K, shared) {
|
|
|
5778
5913
|
}
|
|
5779
5914
|
invalidate();
|
|
5780
5915
|
}
|
|
5781
|
-
|
|
5916
|
+
const defined = { WIND, animateClotheslines };
|
|
5917
|
+
Object.assign(K, defined);
|
|
5782
5918
|
}
|
|
5783
5919
|
|
|
5784
5920
|
// src/build/instance.ts
|
|
@@ -5803,7 +5939,8 @@ function installBuildInstance(K, shared) {
|
|
|
5803
5939
|
shared.quality = h.quality;
|
|
5804
5940
|
}
|
|
5805
5941
|
const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
|
|
5806
|
-
|
|
5942
|
+
const defined = { props, TYPES, newState, enter, tagDamage };
|
|
5943
|
+
Object.assign(K, defined);
|
|
5807
5944
|
}
|
|
5808
5945
|
|
|
5809
5946
|
// src/interactables/kit.ts
|
|
@@ -5832,17 +5969,20 @@ function installInteractablesKit(K, shared) {
|
|
|
5832
5969
|
for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
|
|
5833
5970
|
return m;
|
|
5834
5971
|
})());
|
|
5835
|
-
|
|
5972
|
+
const defined = { IVK, VEG, vegMaterials };
|
|
5973
|
+
Object.assign(K, defined);
|
|
5836
5974
|
}
|
|
5837
5975
|
|
|
5838
5976
|
// src/lights/room-light.ts
|
|
5977
|
+
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 });
|
|
5839
5978
|
function installLightsRoomLight(K, shared) {
|
|
5840
5979
|
const { THREE, rectsOf: rectsOf2, cfg } = K;
|
|
5841
5980
|
const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
|
|
5842
5981
|
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 } };
|
|
5843
5982
|
for (let i = 0; i < MAX_LIGHTS; i++) for (const k of ["uRB0", "uRB1", "uRB2", "uREx"]) LZU[k].value.set(EMPTY, i * 4);
|
|
5844
|
-
function roomLightMask(
|
|
5845
|
-
|
|
5983
|
+
function roomLightMask(material) {
|
|
5984
|
+
const m = material;
|
|
5985
|
+
if (!m || m.userData && m.userData.roomLightMask || !(m.isMeshLambertMaterial || m.isMeshPhongMaterial || m.isMeshStandardMaterial || m.isMeshPhysicalMaterial)) return material;
|
|
5846
5986
|
m.userData = m.userData || {};
|
|
5847
5987
|
m.userData.roomLightMask = true;
|
|
5848
5988
|
const prev = m.onBeforeCompile, pk = m.customProgramCacheKey;
|
|
@@ -5870,12 +6010,13 @@ function installLightsRoomLight(K, shared) {
|
|
|
5870
6010
|
return (pk ? pk.call(this) : "") + "|rm1";
|
|
5871
6011
|
};
|
|
5872
6012
|
m.needsUpdate = true;
|
|
5873
|
-
return
|
|
6013
|
+
return material;
|
|
5874
6014
|
}
|
|
5875
|
-
function lighting(
|
|
5876
|
-
o =
|
|
6015
|
+
function lighting(options) {
|
|
6016
|
+
const o = options || {};
|
|
5877
6017
|
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;
|
|
5878
|
-
|
|
6018
|
+
const mats = shared.mats;
|
|
6019
|
+
for (const k of Object.keys(mats)) roomLightMask(mats[k]);
|
|
5879
6020
|
const budget = o.budget, lease = budget ? budget.lease({ owner: "floorplan.rooms", point: N, shadows: NS }) : null;
|
|
5880
6021
|
if (budget && !lease) throw new Error("lighting: the LightBudget has no " + N + " free point slots (" + NS + " with shadow) for the rooms");
|
|
5881
6022
|
if (budget) for (const [key, width] of [["uRB0", 4], ["uRB1", 4], ["uRB2", 4], ["uRBY", 2], ["uREx", 4]]) {
|
|
@@ -5926,9 +6067,8 @@ function installLightsRoomLight(K, shared) {
|
|
|
5926
6067
|
}
|
|
5927
6068
|
for (let i = 0; i < NS; i++) PL[i].shadow.needsUpdate = true;
|
|
5928
6069
|
};
|
|
5929
|
-
A.update = function(
|
|
5930
|
-
op =
|
|
5931
|
-
houses = (Array.isArray(houses) ? houses : [houses]).filter(Boolean);
|
|
6070
|
+
A.update = function(houseOrList, focus, options2) {
|
|
6071
|
+
const op = options2 || {}, houses = (Array.isArray(houseOrList) ? houseOrList : [houseOrList]).filter((h) => !!h);
|
|
5932
6072
|
_f.set(focus.x, focus.y, focus.z);
|
|
5933
6073
|
const rooms = [], exterior = [];
|
|
5934
6074
|
for (const house of houses) {
|
|
@@ -5940,7 +6080,7 @@ function installLightsRoomLight(K, shared) {
|
|
|
5940
6080
|
if (!house.lightOn(l.roomId)) continue;
|
|
5941
6081
|
const k = l.type === "outdoor" ? "ext:" + (l.id || exterior.length) : l.roomId != null ? l.roomId : l.room;
|
|
5942
6082
|
let g = by.get(k);
|
|
5943
|
-
if (!g) by.set(k, g =
|
|
6083
|
+
if (!g) by.set(k, g = newGroup(k, house, l.type === "outdoor"));
|
|
5944
6084
|
g.ls.push(l);
|
|
5945
6085
|
}
|
|
5946
6086
|
for (const g of by.values()) {
|
|
@@ -5975,9 +6115,10 @@ function installLightsRoomLight(K, shared) {
|
|
|
5975
6115
|
}
|
|
5976
6116
|
}
|
|
5977
6117
|
g.exclusion = [x0 + 0.03, z0 + 0.03, x1 - 0.03, z1 - 0.03];
|
|
5978
|
-
|
|
5979
|
-
g.
|
|
5980
|
-
g.
|
|
6118
|
+
const l0 = ls[0];
|
|
6119
|
+
g.lumens = l0.lumens != null ? l0.lumens : 3.2;
|
|
6120
|
+
g.dist = l0.dist != null ? l0.dist : 5.5;
|
|
6121
|
+
g.decay = l0.decay != null ? l0.decay : 2;
|
|
5981
6122
|
} else {
|
|
5982
6123
|
const c = house.r.rooms.find((q) => q.id === g.k);
|
|
5983
6124
|
if (!c) continue;
|
|
@@ -6078,8 +6219,8 @@ function installLightsRoomLight(K, shared) {
|
|
|
6078
6219
|
}
|
|
6079
6220
|
const effectsByBudget = /* @__PURE__ */ new WeakMap();
|
|
6080
6221
|
const OPENING_REACH = 2.5, OPENING_SIDE = 0.6;
|
|
6081
|
-
function effectLights(
|
|
6082
|
-
o =
|
|
6222
|
+
function effectLights(options) {
|
|
6223
|
+
const o = options || {};
|
|
6083
6224
|
const budget = o.budget;
|
|
6084
6225
|
if (!budget) throw new Error("effectLights: a LightBudget is required");
|
|
6085
6226
|
const known = effectsByBudget.get(budget);
|
|
@@ -6157,7 +6298,7 @@ function installLightsRoomLight(K, shared) {
|
|
|
6157
6298
|
const A = {
|
|
6158
6299
|
/** 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. */
|
|
6159
6300
|
update(houses) {
|
|
6160
|
-
const indoors = cfg.effectLightsIndoors !== false, list = (Array.isArray(houses) ? houses : [houses]).filter(
|
|
6301
|
+
const indoors = cfg.effectLightsIndoors !== false, list = (Array.isArray(houses) ? houses : [houses]).filter((h) => !!h), cache2 = /* @__PURE__ */ new Map();
|
|
6161
6302
|
for (let at = 0; at < size; at++) {
|
|
6162
6303
|
if (ours.has(at)) continue;
|
|
6163
6304
|
const light = budget.group.children[at];
|
|
@@ -6185,7 +6326,8 @@ function installLightsRoomLight(K, shared) {
|
|
|
6185
6326
|
if (!o.ours) effectsByBudget.set(budget, A);
|
|
6186
6327
|
return A;
|
|
6187
6328
|
}
|
|
6188
|
-
|
|
6329
|
+
const defined = { MAX_LIGHTS, EMPTY, LZU, roomLightMask, lighting, effectLights };
|
|
6330
|
+
Object.assign(K, defined);
|
|
6189
6331
|
}
|
|
6190
6332
|
|
|
6191
6333
|
// src/destruction/pieces.ts
|
|
@@ -7377,10 +7519,11 @@ function installDestructionWorld(K, shared) {
|
|
|
7377
7519
|
|
|
7378
7520
|
// src/build/build.ts
|
|
7379
7521
|
import { markKitOrigin } from "@adatechnology/game-contracts";
|
|
7522
|
+
import { isMesh as isMesh5 } from "@adatechnology/game-shapes-three";
|
|
7380
7523
|
function installBuildBuild(K, shared) {
|
|
7381
7524
|
const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS, 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;
|
|
7382
|
-
function build(r0,
|
|
7383
|
-
opts =
|
|
7525
|
+
function build(r0, options) {
|
|
7526
|
+
const opts = options || {};
|
|
7384
7527
|
const r = applyOutbuildings(r0);
|
|
7385
7528
|
const t0 = performance.now();
|
|
7386
7529
|
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 };
|
|
@@ -7401,7 +7544,7 @@ function installBuildBuild(K, shared) {
|
|
|
7401
7544
|
shared.ctx.pieces = /* @__PURE__ */ new Map();
|
|
7402
7545
|
shared.ctx.pieceObjects = /* @__PURE__ */ new Map();
|
|
7403
7546
|
shared.ctx.structureIndex = {};
|
|
7404
|
-
for (const e of r0.structure
|
|
7547
|
+
for (const e of r0.structure?.parts || []) shared.ctx.structureIndex[e.id] = e;
|
|
7405
7548
|
{
|
|
7406
7549
|
const view = shared.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
|
|
7407
7550
|
shared.ctx.panelsOf = /* @__PURE__ */ new Map();
|
|
@@ -7413,7 +7556,7 @@ function installBuildBuild(K, shared) {
|
|
|
7413
7556
|
else shared.ctx.panelsOf.set(e.slab, [e]);
|
|
7414
7557
|
}
|
|
7415
7558
|
}
|
|
7416
|
-
shared.ctx.panes = r0.roof
|
|
7559
|
+
shared.ctx.panes = r0.roof?.panes || [];
|
|
7417
7560
|
shared.ctx.noPiece = false;
|
|
7418
7561
|
cursor.separate = opts.pieces === "meshes";
|
|
7419
7562
|
cursor.pc = null;
|
|
@@ -7424,7 +7567,7 @@ function installBuildBuild(K, shared) {
|
|
|
7424
7567
|
shared.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
|
|
7425
7568
|
shared.ctx.showBuilding = shared.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
|
|
7426
7569
|
shared.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
|
|
7427
|
-
shared.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
|
|
7570
|
+
shared.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared.quality === "game" ? { quality: "game" } : { quality: "high", lod: 0, triangleBudget: 6e4 } } : null;
|
|
7428
7571
|
shared.ctx.vegInfo = null;
|
|
7429
7572
|
terrain();
|
|
7430
7573
|
if (r.lot) {
|
|
@@ -7474,7 +7617,7 @@ function installBuildBuild(K, shared) {
|
|
|
7474
7617
|
const g = gs[gd.name];
|
|
7475
7618
|
if (!g) continue;
|
|
7476
7619
|
delete gs[gd.name];
|
|
7477
|
-
g.position.
|
|
7620
|
+
g.position.fromArray(gd.pos);
|
|
7478
7621
|
parent.add(g);
|
|
7479
7622
|
fo.gs.push(g);
|
|
7480
7623
|
}
|
|
@@ -7489,7 +7632,7 @@ function installBuildBuild(K, shared) {
|
|
|
7489
7632
|
root.add(house);
|
|
7490
7633
|
shared.mirrors.house = house;
|
|
7491
7634
|
if (shared.ctx.apartment) {
|
|
7492
|
-
const
|
|
7635
|
+
const units = r.building.units, u = units[Math.min(shared.ctx.pu, units.length - 1)];
|
|
7493
7636
|
house.position.set(u.u, shared.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
|
|
7494
7637
|
house.rotation.y = u.ry;
|
|
7495
7638
|
shared.ctx.unitRy = u.ry;
|
|
@@ -7605,7 +7748,8 @@ function installBuildBuild(K, shared) {
|
|
|
7605
7748
|
const wallAt = (f, axis, L) => r.walls.find((w) => w.floor === f && w.axis === axis && Math.abs((axis === "u" ? w.v0 : w.u0) - L) < EPS);
|
|
7606
7749
|
for (const j of r.windows) {
|
|
7607
7750
|
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;
|
|
7608
|
-
|
|
7751
|
+
const jy0 = j.y0, jy1 = j.y1;
|
|
7752
|
+
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: () => {
|
|
7609
7753
|
}, t: 0 };
|
|
7610
7754
|
}
|
|
7611
7755
|
for (const E of mirrorsCopy) {
|
|
@@ -7648,7 +7792,7 @@ function installBuildBuild(K, shared) {
|
|
|
7648
7792
|
const countDraw = () => {
|
|
7649
7793
|
let n = 0, t = 0;
|
|
7650
7794
|
root.traverseVisible((o) => {
|
|
7651
|
-
if (o
|
|
7795
|
+
if (isMesh5(o)) {
|
|
7652
7796
|
n++;
|
|
7653
7797
|
t += (o.geometry.index ? o.geometry.index.count : o.geometry.attributes.position.count) / 3;
|
|
7654
7798
|
}
|
|
@@ -7662,8 +7806,8 @@ function installBuildBuild(K, shared) {
|
|
|
7662
7806
|
const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
|
|
7663
7807
|
const stats = { 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 };
|
|
7664
7808
|
shared.ctx.tBuild = stats.tBuild;
|
|
7665
|
-
const applyLod = (
|
|
7666
|
-
n = Math.max(0, Math.min(2,
|
|
7809
|
+
const applyLod = (level) => {
|
|
7810
|
+
const n = Math.max(0, Math.min(2, level | 0));
|
|
7667
7811
|
if (n === h.lodCurrent) return;
|
|
7668
7812
|
h.lodCurrent = n;
|
|
7669
7813
|
for (const o of lodObjects) o.visible = n < 1;
|
|
@@ -7740,7 +7884,7 @@ function installBuildBuild(K, shared) {
|
|
|
7740
7884
|
lights: (() => {
|
|
7741
7885
|
const by = {};
|
|
7742
7886
|
for (const l of shared.ctx.lights) {
|
|
7743
|
-
const k = l.roomId != null ? l.roomId : l.room;
|
|
7887
|
+
const k = String(l.roomId != null ? l.roomId : l.room);
|
|
7744
7888
|
(by[k] || (by[k] = [])).push(l);
|
|
7745
7889
|
}
|
|
7746
7890
|
return { list: shared.ctx.lights, byRoom: by };
|
|
@@ -7780,9 +7924,9 @@ function installBuildBuild(K, shared) {
|
|
|
7780
7924
|
applyLod(Math.max(n, h.lodMin));
|
|
7781
7925
|
}
|
|
7782
7926
|
},
|
|
7783
|
-
show(
|
|
7927
|
+
show(options2) {
|
|
7784
7928
|
enter(h);
|
|
7785
|
-
o =
|
|
7929
|
+
const o = options2 || {};
|
|
7786
7930
|
const rr = shared.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
|
|
7787
7931
|
for (const [k, g] of Object.entries(gs)) {
|
|
7788
7932
|
let v = true;
|
|
@@ -7802,7 +7946,7 @@ function installBuildBuild(K, shared) {
|
|
|
7802
7946
|
enter(h);
|
|
7803
7947
|
const a = targetOf(o, opt);
|
|
7804
7948
|
if (!a) return false;
|
|
7805
|
-
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);
|
|
7949
|
+
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);
|
|
7806
7950
|
},
|
|
7807
7951
|
message() {
|
|
7808
7952
|
return shared.inter.msg && performance.now() < shared.inter.msg.until ? shared.inter.msg.text : null;
|
|
@@ -7859,13 +8003,13 @@ function installBuildBuild(K, shared) {
|
|
|
7859
8003
|
}
|
|
7860
8004
|
return null;
|
|
7861
8005
|
},
|
|
7862
|
-
partAt(p,
|
|
7863
|
-
tol =
|
|
8006
|
+
partAt(p, tolerance) {
|
|
8007
|
+
const tol = tolerance || 0.05;
|
|
7864
8008
|
let m = null;
|
|
7865
8009
|
for (const k in parts) {
|
|
7866
|
-
const
|
|
8010
|
+
const part = parts[k], a = part.aabb;
|
|
7867
8011
|
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) {
|
|
7868
|
-
m =
|
|
8012
|
+
m = part;
|
|
7869
8013
|
break;
|
|
7870
8014
|
}
|
|
7871
8015
|
}
|
|
@@ -7876,8 +8020,8 @@ function installBuildBuild(K, shared) {
|
|
|
7876
8020
|
destruction.deactivate();
|
|
7877
8021
|
if (h.IV) ivDispose(h);
|
|
7878
8022
|
root.traverse((o) => {
|
|
7879
|
-
if (o
|
|
7880
|
-
if (o.type === "Reflector" && o.dispose) o.dispose();
|
|
8023
|
+
if (isMesh5(o) && o.geometry && !o.geometry.userData.shared) o.geometry.dispose();
|
|
8024
|
+
if (o.type === "Reflector" && "dispose" in o && typeof o.dispose === "function") o.dispose();
|
|
7881
8025
|
});
|
|
7882
8026
|
root.removeFromParent();
|
|
7883
8027
|
},
|
|
@@ -7885,7 +8029,8 @@ function installBuildBuild(K, shared) {
|
|
|
7885
8029
|
};
|
|
7886
8030
|
return res;
|
|
7887
8031
|
}
|
|
7888
|
-
|
|
8032
|
+
const defined = { build };
|
|
8033
|
+
Object.assign(K, defined);
|
|
7889
8034
|
}
|
|
7890
8035
|
|
|
7891
8036
|
// src/build/api.ts
|
|
@@ -7907,11 +8052,13 @@ function buildApi(K, shared) {
|
|
|
7907
8052
|
lighting,
|
|
7908
8053
|
effectLights,
|
|
7909
8054
|
setNight(n) {
|
|
7910
|
-
shared.mats.glass
|
|
7911
|
-
|
|
8055
|
+
const glass = shared.mats.glass;
|
|
8056
|
+
glass.emissive.set(n ? 9067040 : 0);
|
|
8057
|
+
glass.opacity = n ? 0.4 : 0.24;
|
|
7912
8058
|
},
|
|
7913
8059
|
/** 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. */
|
|
7914
8060
|
deferredQueue: () => K.breachPaintQueue,
|
|
8061
|
+
/* the destruction side is typed with the breach */
|
|
7915
8062
|
cars: { model: carModel, group: carGroup, info: (k, seed) => {
|
|
7916
8063
|
const m = carModel(k, seed);
|
|
7917
8064
|
return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
|
|
@@ -8176,7 +8323,7 @@ function createHouseScenarios(text, at = SPECIMEN_AT) {
|
|
|
8176
8323
|
const stopListening = () => {
|
|
8177
8324
|
for (const off of listening.splice(0)) off?.();
|
|
8178
8325
|
};
|
|
8179
|
-
const collapsed = (list) => list.
|
|
8326
|
+
const collapsed = (list) => list.flatMap((e) => e.type === "collapse" ? e.parts.map((p) => p.id || p) : []);
|
|
8180
8327
|
const whole = (room, oid, pid) => {
|
|
8181
8328
|
const p = room.world.part(oid, pid);
|
|
8182
8329
|
return !!p && p.status !== "broken" && !p.stripped;
|
|
@@ -8537,9 +8684,10 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8537
8684
|
return best;
|
|
8538
8685
|
};
|
|
8539
8686
|
const eyeOf = (p) => {
|
|
8687
|
+
const T = THREE;
|
|
8540
8688
|
const camera = host?.camera;
|
|
8541
8689
|
const at = toLocal(p, camera.position.x, camera.position.y, camera.position.z);
|
|
8542
|
-
const forward = new
|
|
8690
|
+
const forward = new T.Vector3(0, 0, -1).applyQuaternion(camera.quaternion).transformDirection(new T.Matrix4().copy(p.house.group.matrixWorld).invert());
|
|
8543
8691
|
return { x: at.x, y: at.y, z: at.z, floor: floorOf(p, camera.position.y), yaw: Math.atan2(forward.x, forward.z), pitch: Math.asin(Math.max(-1, Math.min(1, forward.y))) };
|
|
8544
8692
|
};
|
|
8545
8693
|
const blocked = (x, z, radius) => {
|
|
@@ -8555,8 +8703,9 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8555
8703
|
const standAt = (p, u, v, floor, lookU, lookV) => {
|
|
8556
8704
|
if (!host?.bench) return;
|
|
8557
8705
|
const y = p.house.y0(floor) + EYE;
|
|
8558
|
-
const
|
|
8559
|
-
const
|
|
8706
|
+
const T = THREE;
|
|
8707
|
+
const eye = p.house.group.localToWorld(new T.Vector3(u, y, v));
|
|
8708
|
+
const target = p.house.group.localToWorld(new T.Vector3(lookU, y - 0.1, lookV));
|
|
8560
8709
|
host.bench.look([eye.x, eye.y, eye.z], [target.x, target.y, target.z]);
|
|
8561
8710
|
floorNow = floor;
|
|
8562
8711
|
};
|
|
@@ -8606,16 +8755,17 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8606
8755
|
host?.log(fill(text.steps.door, { text: String(target.text) }));
|
|
8607
8756
|
};
|
|
8608
8757
|
const doorReach = (p, fo) => {
|
|
8758
|
+
const T = THREE;
|
|
8609
8759
|
const g = fo.gs[0];
|
|
8610
8760
|
const pivot = fo.handles[0].pivot;
|
|
8611
8761
|
const at = (angle) => {
|
|
8612
8762
|
const c = Math.cos(angle);
|
|
8613
8763
|
const s = Math.sin(angle);
|
|
8614
|
-
const v = new
|
|
8764
|
+
const v = new T.Vector3(pivot[0] * c + pivot[2] * s, pivot[1], -pivot[0] * s + pivot[2] * c).add(g.position);
|
|
8615
8765
|
return g.parent ? g.parent.localToWorld(v) : v;
|
|
8616
8766
|
};
|
|
8617
8767
|
const camera = host?.camera;
|
|
8618
|
-
const eye = new
|
|
8768
|
+
const eye = new T.Vector3(camera.position.x, 0, camera.position.z);
|
|
8619
8769
|
const flat = (v) => Math.hypot(v.x - eye.x, v.z - eye.z);
|
|
8620
8770
|
const closed = at(0);
|
|
8621
8771
|
const open = at(fo.rot);
|
|
@@ -8623,9 +8773,9 @@ function createFloorplanTestModule(options = {}) {
|
|
|
8623
8773
|
return {
|
|
8624
8774
|
handle: () => {
|
|
8625
8775
|
g.updateMatrixWorld(true);
|
|
8626
|
-
return g.localToWorld(new
|
|
8776
|
+
return g.localToWorld(new T.Vector3(pivot[0], pivot[1], pivot[2])).toArray();
|
|
8627
8777
|
},
|
|
8628
|
-
hinge: () => g.getWorldPosition(new
|
|
8778
|
+
hinge: () => g.getWorldPosition(new T.Vector3()).toArray(),
|
|
8629
8779
|
seconds: fo.locked || fo.blockedFlag ? 0.6 : 0.55,
|
|
8630
8780
|
pull: opening ? flat(open) <= flat(closed) : flat(closed) <= flat(open),
|
|
8631
8781
|
locked: !!(fo.locked || fo.blockedFlag)
|
|
@@ -8959,4 +9109,4 @@ export {
|
|
|
8959
9109
|
FLOORPLAN_AREA_ID,
|
|
8960
9110
|
createFloorplanTestModule
|
|
8961
9111
|
};
|
|
8962
|
-
//# sourceMappingURL=chunk-
|
|
9112
|
+
//# sourceMappingURL=chunk-Y3Y7NYOL.js.map
|