@adatechnology/game-floorplan-three 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.global.js +646 -367
- package/dist/index.global.js.map +1 -1
- package/package.json +8 -8
package/dist/index.global.js
CHANGED
|
@@ -54,6 +54,7 @@ var GameFloorplanThree = (() => {
|
|
|
54
54
|
create: () => create,
|
|
55
55
|
createNodeSkin: () => createNodeSkin,
|
|
56
56
|
createRecorder: () => createRecorder,
|
|
57
|
+
createShapeRecorder: () => createShapeRecorder,
|
|
57
58
|
hex: () => hex,
|
|
58
59
|
listTypes: () => listTypes,
|
|
59
60
|
locales: () => locales,
|
|
@@ -64,6 +65,228 @@ var GameFloorplanThree = (() => {
|
|
|
64
65
|
seedOf: () => seedOf,
|
|
65
66
|
shade: () => shade
|
|
66
67
|
});
|
|
68
|
+
|
|
69
|
+
// ../game-shapes/dist/chunk-R4RY23RH.js
|
|
70
|
+
function normalMatrix(me) {
|
|
71
|
+
const n11 = me[0], n21 = me[1], n31 = me[2];
|
|
72
|
+
const n12 = me[4], n22 = me[5], n32 = me[6];
|
|
73
|
+
const n13 = me[8], n23 = me[9], n33 = me[10];
|
|
74
|
+
const t11 = n33 * n22 - n32 * n23;
|
|
75
|
+
const t12 = n32 * n13 - n33 * n12;
|
|
76
|
+
const t13 = n23 * n12 - n22 * n13;
|
|
77
|
+
const det = n11 * t11 + n21 * t12 + n31 * t13;
|
|
78
|
+
if (det === 0) return [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
79
|
+
const detInv = 1 / det;
|
|
80
|
+
const te = [
|
|
81
|
+
t11 * detInv,
|
|
82
|
+
(n31 * n23 - n33 * n21) * detInv,
|
|
83
|
+
(n32 * n21 - n31 * n22) * detInv,
|
|
84
|
+
t12 * detInv,
|
|
85
|
+
(n33 * n11 - n31 * n13) * detInv,
|
|
86
|
+
(n31 * n12 - n32 * n11) * detInv,
|
|
87
|
+
t13 * detInv,
|
|
88
|
+
(n21 * n13 - n23 * n11) * detInv,
|
|
89
|
+
(n22 * n11 - n21 * n12) * detInv
|
|
90
|
+
];
|
|
91
|
+
let tmp = te[1];
|
|
92
|
+
te[1] = te[3];
|
|
93
|
+
te[3] = tmp;
|
|
94
|
+
tmp = te[2];
|
|
95
|
+
te[2] = te[6];
|
|
96
|
+
te[6] = tmp;
|
|
97
|
+
tmp = te[5];
|
|
98
|
+
te[5] = te[7];
|
|
99
|
+
te[7] = tmp;
|
|
100
|
+
return te;
|
|
101
|
+
}
|
|
102
|
+
function transformPoint(e, x, y, z) {
|
|
103
|
+
const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
|
|
104
|
+
return [(e[0] * x + e[4] * y + e[8] * z + e[12]) * w, (e[1] * x + e[5] * y + e[9] * z + e[13]) * w, (e[2] * x + e[6] * y + e[10] * z + e[14]) * w];
|
|
105
|
+
}
|
|
106
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? null : "expected a finite number";
|
|
107
|
+
var bool = (v) => typeof v === "boolean" ? null : "expected a boolean";
|
|
108
|
+
var str = (v) => typeof v === "string" ? null : "expected a string";
|
|
109
|
+
var int = (min) => (v) => typeof v === "number" && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`;
|
|
110
|
+
var range = (lo, hi, loOpen = false) => (v) => typeof v === "number" && (loOpen ? v > lo : v >= lo) && v <= hi ? null : `expected a number in ${loOpen ? "(" : "["}${lo}, ${hi}]`;
|
|
111
|
+
var tuple = (n, item = num) => (v) => {
|
|
112
|
+
if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`;
|
|
113
|
+
for (const x of v) if (item(x)) return `expected an array of ${n} numbers`;
|
|
114
|
+
return null;
|
|
115
|
+
};
|
|
116
|
+
var list = (item, min = 0) => (v) => {
|
|
117
|
+
if (!Array.isArray(v)) return "expected an array";
|
|
118
|
+
if (v.length < min) return `expected at least ${min} items`;
|
|
119
|
+
for (let i = 0; i < v.length; i++) {
|
|
120
|
+
const e = item(v[i]);
|
|
121
|
+
if (e) return `[${i}]: ${e}`;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
};
|
|
125
|
+
var color = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0 && v <= 16777215 || typeof v === "string" && /^#[0-9a-fA-F]{6}$/.test(v) ? null : 'expected 0xRRGGBB or "#rrggbb"';
|
|
126
|
+
var oneOf = (values) => (v) => values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(", ")}`;
|
|
127
|
+
var object = (fields, required = []) => (v) => {
|
|
128
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return "expected an object";
|
|
129
|
+
const record = v;
|
|
130
|
+
for (const key of required) if (record[key] === void 0) return `${key}: required`;
|
|
131
|
+
for (const key of Object.keys(record)) {
|
|
132
|
+
if (record[key] === void 0) continue;
|
|
133
|
+
const check = fields[key];
|
|
134
|
+
if (!check) return `${key}: unknown field`;
|
|
135
|
+
const e = check(record[key]);
|
|
136
|
+
if (e) return `${key}: ${e}`;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
};
|
|
140
|
+
var ORDERS = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"];
|
|
141
|
+
var TRANSFORM = {
|
|
142
|
+
position: tuple(3),
|
|
143
|
+
rotation: tuple(3),
|
|
144
|
+
rotationOrder: oneOf(ORDERS),
|
|
145
|
+
scale: (v) => typeof v === "number" ? num(v) : tuple(3)(v),
|
|
146
|
+
heading: num,
|
|
147
|
+
matrix: tuple(16)
|
|
148
|
+
};
|
|
149
|
+
var UV = object({ u0: num, v0: num, u1: num, v1: num }, ["u0", "v0", "u1", "v1"]);
|
|
150
|
+
var INSTANCE = object({ ...TRANSFORM, color });
|
|
151
|
+
var COMMON = {
|
|
152
|
+
...TRANSFORM,
|
|
153
|
+
kind: str,
|
|
154
|
+
name: str,
|
|
155
|
+
part: str,
|
|
156
|
+
material: str,
|
|
157
|
+
color,
|
|
158
|
+
uv: UV,
|
|
159
|
+
instances: list(INSTANCE),
|
|
160
|
+
minDetail: range(0, 1, true),
|
|
161
|
+
tags: list(str)
|
|
162
|
+
};
|
|
163
|
+
var vec2 = tuple(2);
|
|
164
|
+
var BEVEL = (v) => v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v);
|
|
165
|
+
var KINDS = {
|
|
166
|
+
group: { fields: {} },
|
|
167
|
+
box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },
|
|
168
|
+
cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
|
|
169
|
+
cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
|
|
170
|
+
sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },
|
|
171
|
+
plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },
|
|
172
|
+
circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },
|
|
173
|
+
ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },
|
|
174
|
+
lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ["points"] },
|
|
175
|
+
torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },
|
|
176
|
+
extrude: {
|
|
177
|
+
fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ["outer"]), depth: num, steps: int(1), bevel: BEVEL },
|
|
178
|
+
required: ["shape"]
|
|
179
|
+
},
|
|
180
|
+
difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ["min", "max"])) }, required: ["size", "subtract"] },
|
|
181
|
+
mesh: {
|
|
182
|
+
fields: {
|
|
183
|
+
positions: (v) => list(num)(v) ?? (v.length % 3 === 0 ? null : "expected a multiple of 3 numbers"),
|
|
184
|
+
normals: list(num),
|
|
185
|
+
uvs: list(num),
|
|
186
|
+
indices: list(int(0))
|
|
187
|
+
},
|
|
188
|
+
required: ["positions"]
|
|
189
|
+
},
|
|
190
|
+
point: { fields: { data: () => null } },
|
|
191
|
+
custom: { fields: { generator: str, params: () => null }, required: ["generator"] }
|
|
192
|
+
};
|
|
193
|
+
function mergeTransformed(pieces) {
|
|
194
|
+
let total = 0;
|
|
195
|
+
for (const piece2 of pieces) total += piece2.indices ? piece2.indices.length : piece2.positions.length / 3;
|
|
196
|
+
const positions = new Float32Array(total * 3);
|
|
197
|
+
const normals = new Float32Array(total * 3);
|
|
198
|
+
const uvs = new Float32Array(total * 2);
|
|
199
|
+
let at = 0;
|
|
200
|
+
for (const piece2 of pieces) {
|
|
201
|
+
const e = piece2.matrix;
|
|
202
|
+
const nm = normalMatrix(e);
|
|
203
|
+
const count = piece2.indices ? piece2.indices.length : piece2.positions.length / 3;
|
|
204
|
+
const p = new Float32Array(count * 3);
|
|
205
|
+
const n = new Float32Array(count * 3);
|
|
206
|
+
for (let k = 0; k < count; k++) {
|
|
207
|
+
const i = piece2.indices ? piece2.indices[k] : k;
|
|
208
|
+
for (let c = 0; c < 3; c++) {
|
|
209
|
+
p[k * 3 + c] = piece2.positions[i * 3 + c];
|
|
210
|
+
if (piece2.normals) n[k * 3 + c] = piece2.normals[i * 3 + c];
|
|
211
|
+
}
|
|
212
|
+
if (piece2.uvs) {
|
|
213
|
+
uvs[(at + k) * 2] = piece2.uvs[i * 2];
|
|
214
|
+
uvs[(at + k) * 2 + 1] = piece2.uvs[i * 2 + 1];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
for (let k = 0; k < count; k++) {
|
|
218
|
+
const q = transformPoint(e, p[k * 3], p[k * 3 + 1], p[k * 3 + 2]);
|
|
219
|
+
positions[(at + k) * 3] = q[0];
|
|
220
|
+
positions[(at + k) * 3 + 1] = q[1];
|
|
221
|
+
positions[(at + k) * 3 + 2] = q[2];
|
|
222
|
+
const x = n[k * 3];
|
|
223
|
+
const y = n[k * 3 + 1];
|
|
224
|
+
const z = n[k * 3 + 2];
|
|
225
|
+
const vx = nm[0] * x + nm[3] * y + nm[6] * z;
|
|
226
|
+
const vy = nm[1] * x + nm[4] * y + nm[7] * z;
|
|
227
|
+
const vz = nm[2] * x + nm[5] * y + nm[8] * z;
|
|
228
|
+
const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1);
|
|
229
|
+
normals[(at + k) * 3] = vx * s;
|
|
230
|
+
normals[(at + k) * 3 + 1] = vy * s;
|
|
231
|
+
normals[(at + k) * 3 + 2] = vz * s;
|
|
232
|
+
}
|
|
233
|
+
at += count;
|
|
234
|
+
}
|
|
235
|
+
return { positions, normals, uvs };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ../game-shapes-three/dist/index.js
|
|
239
|
+
var isVisible = (object2) => {
|
|
240
|
+
for (let node = object2; node; node = node.parent) if (!node.visible) return false;
|
|
241
|
+
return true;
|
|
242
|
+
};
|
|
243
|
+
var plain = (attribute) => attribute !== void 0 && !attribute.isInterleavedBufferAttribute && attribute.array instanceof Float32Array && !attribute.normalized;
|
|
244
|
+
function piece(geometry, matrix) {
|
|
245
|
+
const position = geometry.getAttribute("position");
|
|
246
|
+
const normal = geometry.getAttribute("normal");
|
|
247
|
+
const uv = geometry.getAttribute("uv");
|
|
248
|
+
const ok = plain(position) && (normal === void 0 || plain(normal)) && (uv === void 0 || plain(uv)) && position.itemSize === 3 && (uv === void 0 || uv.itemSize === 2);
|
|
249
|
+
if (ok) {
|
|
250
|
+
return { positions: position.array, ...normal ? { normals: normal.array } : {}, ...uv ? { uvs: uv.array } : {}, indices: geometry.index ? geometry.index.array : null, matrix: matrix.elements };
|
|
251
|
+
}
|
|
252
|
+
const flat = geometry.index ? geometry.toNonIndexed() : geometry;
|
|
253
|
+
const read = (name, size) => {
|
|
254
|
+
const attribute = flat.getAttribute(name);
|
|
255
|
+
if (!attribute) return void 0;
|
|
256
|
+
const out = new Float32Array(attribute.count * size);
|
|
257
|
+
for (let i = 0; i < attribute.count; i++) for (let c = 0; c < size; c++) out[i * size + c] = c === 0 ? attribute.getX(i) : c === 1 ? attribute.getY(i) : attribute.getZ(i);
|
|
258
|
+
return out;
|
|
259
|
+
};
|
|
260
|
+
const positions = read("position", 3);
|
|
261
|
+
const normals = read("normal", 3);
|
|
262
|
+
const uvs = read("uv", 2);
|
|
263
|
+
if (flat !== geometry) flat.dispose();
|
|
264
|
+
return { positions, ...normals ? { normals } : {}, ...uvs ? { uvs } : {}, indices: null, matrix: matrix.elements };
|
|
265
|
+
}
|
|
266
|
+
function mergeByMaterial(THREE, root, space) {
|
|
267
|
+
const toSpace = space.matrixWorld.clone().invert();
|
|
268
|
+
const byMaterial = /* @__PURE__ */ new Map();
|
|
269
|
+
root.traverse((object2) => {
|
|
270
|
+
const mesh = object2;
|
|
271
|
+
if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return;
|
|
272
|
+
const list2 = byMaterial.get(mesh.material) ?? [];
|
|
273
|
+
list2.push(piece(mesh.geometry, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)));
|
|
274
|
+
byMaterial.set(mesh.material, list2);
|
|
275
|
+
});
|
|
276
|
+
return [...byMaterial].map(([material, pieces]) => {
|
|
277
|
+
const merged = mergeTransformed(pieces);
|
|
278
|
+
const geometry = new THREE.BufferGeometry();
|
|
279
|
+
geometry.setAttribute("position", new THREE.BufferAttribute(merged.positions, 3));
|
|
280
|
+
geometry.setAttribute("normal", new THREE.BufferAttribute(merged.normals, 3));
|
|
281
|
+
geometry.setAttribute("uv", new THREE.BufferAttribute(merged.uvs, 2));
|
|
282
|
+
const mesh = new THREE.Mesh(geometry, material);
|
|
283
|
+
mesh.castShadow = false;
|
|
284
|
+
mesh.receiveShadow = true;
|
|
285
|
+
return mesh;
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ../game-props3d/dist/index.js
|
|
67
290
|
function rng(seed) {
|
|
68
291
|
let s = seed >>> 0;
|
|
69
292
|
return () => {
|
|
@@ -567,10 +790,10 @@ var GameFloorplanThree = (() => {
|
|
|
567
790
|
if (on) K.light(0, t - 0.15, 0, 16771256, 6, "ceiling_light");
|
|
568
791
|
};
|
|
569
792
|
B.pendant = (M, a) => {
|
|
570
|
-
const K = kit(M, a), t = K.ceiling(), { h } = K.dim("pendant"), ys = t - h,
|
|
793
|
+
const K = kit(M, a), t = K.ceiling(), { h } = K.dim("pendant"), ys = t - h, color2 = K.main(2763306);
|
|
571
794
|
K.box("plain", 0, ys + 0.1, 0, 0.012, h - 0.1, 0.012, 1710618);
|
|
572
795
|
K.cyl("plain", 0, t - 0.03, 0, 0.05, 0.03, 15262940);
|
|
573
|
-
K.cyl("plain", 0, ys, 0, 0.17, 0.14,
|
|
796
|
+
K.cyl("plain", 0, ys, 0, 0.17, 0.14, color2, 0, 0, "sphere");
|
|
574
797
|
K.cyl("emissive", 0, ys - 0.035, 0, 0.045, 0.09, 16769184, 0, 0, "sphere");
|
|
575
798
|
if (M.light) K.light(0, ys - 0.1, 0, 16763008, 6, "pendant");
|
|
576
799
|
};
|
|
@@ -939,9 +1162,9 @@ var GameFloorplanThree = (() => {
|
|
|
939
1162
|
K.box("plain", sx + 0.15, 0.012, sz + 0.05, 0.09, 0.07, 0.27, 2763306, 0.9);
|
|
940
1163
|
};
|
|
941
1164
|
B.fallen_chair = (M, a) => {
|
|
942
|
-
const g = Math.PI / 2, dy = 0.23, api = { box: (Mm, mat, x, y, z, w, h, d,
|
|
1165
|
+
const g = Math.PI / 2, dy = 0.23, api = { box: (Mm, mat, x, y, z, w, h, d, color2, ry, rx, rz) => {
|
|
943
1166
|
const cy = y + h / 2;
|
|
944
|
-
a.box(Mm, mat, -cy + 0, dy + x - h / 2 + 0 - 0, z, w, h, d,
|
|
1167
|
+
a.box(Mm, mat, -cy + 0, dy + x - h / 2 + 0 - 0, z, w, h, d, color2, ry, rx, g + (rz || 0));
|
|
945
1168
|
} };
|
|
946
1169
|
const K = kit(M, api), c = K.main(6965808);
|
|
947
1170
|
K.box("wood", 0, 0.44, 0, 0.42, 0.04, 0.42, c);
|
|
@@ -1031,20 +1254,20 @@ var GameFloorplanThree = (() => {
|
|
|
1031
1254
|
K.plane("atlas_picture", 0, y + h / 2, d / 2 + 3e-3, w - 0.05, h - 0.05, 16777215, 0, 0, 0, A.mirror());
|
|
1032
1255
|
};
|
|
1033
1256
|
B.curtain = (M, a) => {
|
|
1034
|
-
const K = kit(M, a), { w, h } = K.dim("curtain"), y = M.y != null && M.y > 0 ? M.y : 0.1,
|
|
1257
|
+
const K = kit(M, a), { w, h } = K.dim("curtain"), y = M.y != null && M.y > 0 ? M.y : 0.1, color2 = K.fabric(pick(K, [14208436, 10465470, 12953740, 14736592])), isOpen = M.open !== false, top = y + h;
|
|
1035
1258
|
K.box("metal", 0, top, 0, w + 0.1, 0.025, 0.025, K.metal(5918792));
|
|
1036
1259
|
for (const s of [-1, 1]) K.cyl("metal", s * (w / 2 + 0.07), top - 0.02, 0, 0.03, 0.07, 5918792, 0, 0, "sphere");
|
|
1037
1260
|
const pw = isOpen ? Math.min(0.5, w * 0.3) : w / 2 + 0.03, n = Math.max(4, Math.round(pw / 0.08));
|
|
1038
1261
|
for (const s of [-1, 1]) for (let i = 0; i < n; i++) {
|
|
1039
1262
|
const ux = isOpen ? s * (w / 2 + 0.03 - pw + (i + 0.5) * pw / n) : s * ((i + 0.5) * pw / n);
|
|
1040
|
-
K.box("fabric", ux, y, i % 2 ? 0.025 : -0.01, pw / n * 1.15, h - 0.02, 0.02, i % 2 ? shade(
|
|
1263
|
+
K.box("fabric", ux, y, i % 2 ? 0.025 : -0.01, pw / n * 1.15, h - 0.02, 0.02, i % 2 ? shade(color2, 0.9) : color2);
|
|
1041
1264
|
}
|
|
1042
|
-
if (isOpen) for (const s of [-1, 1]) K.box("fabric", s * (w / 2 - pw * 0.25), y + h * 0.4, 0.04, pw * 0.5, 0.05, 0.02, shade(
|
|
1265
|
+
if (isOpen) for (const s of [-1, 1]) K.box("fabric", s * (w / 2 - pw * 0.25), y + h * 0.4, 0.04, pw * 0.5, 0.05, 0.02, shade(color2, 0.7));
|
|
1043
1266
|
};
|
|
1044
1267
|
B.blinds = (M, a) => {
|
|
1045
|
-
const K = kit(M, a), { w, h } = K.dim("blinds"), y = M.y || 1, retract = M.retracted != null ? M.retracted : 0.15, isWood = M.variant === "wood",
|
|
1268
|
+
const K = kit(M, a), { w, h } = K.dim("blinds"), y = M.y || 1, retract = M.retracted != null ? M.retracted : 0.15, isWood = M.variant === "wood", color2 = isWood ? K.wood(10123858) : K.color("wall_living", 15262420), mat = isWood ? "wood" : "plain", yb = y + h * retract, n = Math.floor((y + h - yb) / 0.055);
|
|
1046
1269
|
K.box("plain", 0, y + h - 0.05, 0, w, 0.05, 0.06, 14473424);
|
|
1047
|
-
for (let i = 0; i < n; i++) K.box(mat, 0, y + h - 0.06 - (i + 1) * 0.055, 0, w - 0.05, 0.01, 0.035,
|
|
1270
|
+
for (let i = 0; i < n; i++) K.box(mat, 0, y + h - 0.06 - (i + 1) * 0.055, 0, w - 0.05, 0.01, 0.035, color2, 0, 0.3);
|
|
1048
1271
|
for (const s of [-1, 1]) K.box("plain", s * (w / 2 - 0.05), yb, 0.02, 8e-3, y + h - 0.05 - yb, 8e-3, 12104876);
|
|
1049
1272
|
K.box("plain", 0, yb - 0.02, 0, w - 0.03, 0.025, 0.04, 14473424);
|
|
1050
1273
|
};
|
|
@@ -1337,13 +1560,13 @@ var GameFloorplanThree = (() => {
|
|
|
1337
1560
|
const size = o.size || A.size(kind);
|
|
1338
1561
|
const nv = A.variants(kind);
|
|
1339
1562
|
const y = o.y != null ? o.y : HEIGHTS[kind] || 0.03;
|
|
1340
|
-
const
|
|
1563
|
+
const color2 = o.color != null ? hex(o.color) : 16777215;
|
|
1341
1564
|
const poly = o.poly || M.poly;
|
|
1342
1565
|
const sd = seedOf(M);
|
|
1343
1566
|
const rnd = rng(sd);
|
|
1344
1567
|
const tint = () => {
|
|
1345
1568
|
const v = 0.93 + rnd() * 0.07;
|
|
1346
|
-
return mix(0,
|
|
1569
|
+
return mix(0, color2, v);
|
|
1347
1570
|
};
|
|
1348
1571
|
const quad = (cx, cz, qw, qd, uv) => api.plane(M, "atlas_floor", cx, y, cz, qw, qd, tint(), 0, -Math.PI / 2, 0, uv);
|
|
1349
1572
|
if (!poly) {
|
|
@@ -1393,13 +1616,13 @@ var GameFloorplanThree = (() => {
|
|
|
1393
1616
|
M,
|
|
1394
1617
|
api,
|
|
1395
1618
|
rnd: rng(seedOf(M)),
|
|
1396
|
-
box: (material, x, y, z, w, h, d,
|
|
1397
|
-
cyl: (material, x, y, z, r, h,
|
|
1398
|
-
leaf: (x, y, z, w, h,
|
|
1399
|
-
plane: (material, x, y, z, w, h,
|
|
1400
|
-
light: (x, y, z,
|
|
1401
|
-
if (api.light) api.light(M, x, y, z, hex(
|
|
1402
|
-
else emit("light", { M, x, y, z, color: hex(
|
|
1619
|
+
box: (material, x, y, z, w, h, d, color2, ry, rx, rz) => api.box(M, material, x, y, z, w, h, d, hex(color2), ry || 0, rx || 0, rz || 0),
|
|
1620
|
+
cyl: (material, x, y, z, r, h, color2, rx, rz, shape) => api.cylinder(M, material, x, y, z, r, h, hex(color2), rx || 0, rz || 0, shape),
|
|
1621
|
+
leaf: (x, y, z, w, h, color2, ry, rx) => api.leaf(M, x, y, z, w, h, hex(color2), ry || 0, rx || 0),
|
|
1622
|
+
plane: (material, x, y, z, w, h, color2, ry, rx, rz, uv) => api.plane(M, material, x, y, z, w, h, hex(color2), ry || 0, rx || 0, rz || 0, uv),
|
|
1623
|
+
light: (x, y, z, color2, range2, kind) => {
|
|
1624
|
+
if (api.light) api.light(M, x, y, z, hex(color2), range2, kind);
|
|
1625
|
+
else emit("light", { M, x, y, z, color: hex(color2), range: range2, kind });
|
|
1403
1626
|
},
|
|
1404
1627
|
// colours: role in the house palette (M.palette) or the default; main = M.color
|
|
1405
1628
|
color: (name, fallback) => role(name) ?? hex(fallback),
|
|
@@ -1414,10 +1637,10 @@ var GameFloorplanThree = (() => {
|
|
|
1414
1637
|
},
|
|
1415
1638
|
ceiling: () => M.ceiling || 2.9,
|
|
1416
1639
|
// long tilted box: starts at (x, y, z) and follows u = (0, sin a, -cos a) for L meters
|
|
1417
|
-
ramp(material, x, y, z, w, t, L,
|
|
1640
|
+
ramp(material, x, y, z, w, t, L, color2, alpha) {
|
|
1418
1641
|
const cy = y + Math.sin(alpha) * L / 2;
|
|
1419
1642
|
const cz = z - Math.cos(alpha) * L / 2;
|
|
1420
|
-
K.box(material, x, cy - t / 2, cz, w, t, L,
|
|
1643
|
+
K.box(material, x, cy - t / 2, cz, w, t, L, color2, 0, alpha + Math.PI, 0);
|
|
1421
1644
|
}
|
|
1422
1645
|
};
|
|
1423
1646
|
return K;
|
|
@@ -1598,19 +1821,19 @@ var GameFloorplanThree = (() => {
|
|
|
1598
1821
|
for (const key in owner) if (!skip.includes(key)) walk(owner[key], 0);
|
|
1599
1822
|
return found;
|
|
1600
1823
|
};
|
|
1601
|
-
var isVisibleInTree = (
|
|
1602
|
-
for (let node =
|
|
1824
|
+
var isVisibleInTree = (object2) => {
|
|
1825
|
+
for (let node = object2; node; node = node.parent) if (!node.visible) return false;
|
|
1603
1826
|
return true;
|
|
1604
1827
|
};
|
|
1605
1828
|
var createNodeSkin = (THREE, root, options = {}) => {
|
|
1606
1829
|
const referenced = new Set(options.nodes ?? []);
|
|
1607
1830
|
const nodes = [];
|
|
1608
1831
|
const indexOf = /* @__PURE__ */ new Map();
|
|
1609
|
-
root.traverse((
|
|
1610
|
-
const mesh2 =
|
|
1611
|
-
if (!mesh2.isMesh ||
|
|
1612
|
-
indexOf.set(
|
|
1613
|
-
nodes.push(
|
|
1832
|
+
root.traverse((object2) => {
|
|
1833
|
+
const mesh2 = object2;
|
|
1834
|
+
if (!mesh2.isMesh || object2.children.length > 0 || referenced.has(object2)) {
|
|
1835
|
+
indexOf.set(object2, nodes.length);
|
|
1836
|
+
nodes.push(object2);
|
|
1614
1837
|
}
|
|
1615
1838
|
});
|
|
1616
1839
|
const positions = [];
|
|
@@ -1619,7 +1842,7 @@ var GameFloorplanThree = (() => {
|
|
|
1619
1842
|
const surfaces = [];
|
|
1620
1843
|
const nodeIndices = [];
|
|
1621
1844
|
const samples = /* @__PURE__ */ new Map();
|
|
1622
|
-
const
|
|
1845
|
+
const color2 = new THREE.Color();
|
|
1623
1846
|
const vertex = new THREE.Vector3();
|
|
1624
1847
|
const normal = new THREE.Vector3();
|
|
1625
1848
|
const sampleOf = (texture) => {
|
|
@@ -1633,22 +1856,22 @@ var GameFloorplanThree = (() => {
|
|
|
1633
1856
|
samples.set(texture, sample);
|
|
1634
1857
|
return sample;
|
|
1635
1858
|
};
|
|
1636
|
-
root.traverse((
|
|
1637
|
-
const mesh2 =
|
|
1638
|
-
if (!mesh2.isMesh || !isVisibleInTree(
|
|
1859
|
+
root.traverse((object2) => {
|
|
1860
|
+
const mesh2 = object2;
|
|
1861
|
+
if (!mesh2.isMesh || !isVisibleInTree(object2)) return;
|
|
1639
1862
|
const material2 = Array.isArray(mesh2.material) ? mesh2.material[0] : mesh2.material;
|
|
1640
1863
|
const geometry2 = mesh2.geometry;
|
|
1641
1864
|
const position = geometry2.attributes.position;
|
|
1642
1865
|
const normalAttribute = geometry2.attributes.normal;
|
|
1643
1866
|
const uv = geometry2.attributes.uv;
|
|
1644
1867
|
const matrix = new THREE.Matrix4();
|
|
1645
|
-
let nodeIndex = indexOf.get(
|
|
1868
|
+
let nodeIndex = indexOf.get(object2);
|
|
1646
1869
|
if (nodeIndex === void 0) {
|
|
1647
|
-
nodeIndex = indexOf.get(
|
|
1648
|
-
|
|
1649
|
-
matrix.copy(
|
|
1870
|
+
nodeIndex = indexOf.get(object2.parent) ?? 0;
|
|
1871
|
+
object2.updateMatrix();
|
|
1872
|
+
matrix.copy(object2.matrix);
|
|
1650
1873
|
}
|
|
1651
|
-
const
|
|
1874
|
+
const normalMatrix2 = new THREE.Matrix3().getNormalMatrix(matrix);
|
|
1652
1875
|
const sample = material2.map ? sampleOf(material2.map) : void 0;
|
|
1653
1876
|
const emissive = material2.emissive ? (material2.emissive.r + material2.emissive.g + material2.emissive.b) * (material2.emissiveIntensity ?? 1) : 0;
|
|
1654
1877
|
const index = geometry2.index ? geometry2.index.array : null;
|
|
@@ -1657,10 +1880,10 @@ var GameFloorplanThree = (() => {
|
|
|
1657
1880
|
const at = index ? index[item] : item;
|
|
1658
1881
|
vertex.fromBufferAttribute(position, at).applyMatrix4(matrix);
|
|
1659
1882
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
1660
|
-
if (normalAttribute) normal.fromBufferAttribute(normalAttribute, at).applyMatrix3(
|
|
1883
|
+
if (normalAttribute) normal.fromBufferAttribute(normalAttribute, at).applyMatrix3(normalMatrix2).normalize();
|
|
1661
1884
|
else normal.set(0, 1, 0);
|
|
1662
1885
|
normals.push(normal.x, normal.y, normal.z);
|
|
1663
|
-
|
|
1886
|
+
color2.copy(material2.color || color2.set(1, 1, 1)).convertLinearToSRGB();
|
|
1664
1887
|
if (sample && uv && material2.map) {
|
|
1665
1888
|
const repeat = material2.map.repeat;
|
|
1666
1889
|
const u = (uv.getX(at) * repeat.x % 1 + 1) % 1;
|
|
@@ -1668,10 +1891,10 @@ var GameFloorplanThree = (() => {
|
|
|
1668
1891
|
const pixelX = Math.min(sample.width - 1, u * sample.width | 0);
|
|
1669
1892
|
const pixelY = Math.min(sample.height - 1, (1 - v) * sample.height | 0);
|
|
1670
1893
|
const offset = (pixelY * sample.width + pixelX) * 4;
|
|
1671
|
-
|
|
1894
|
+
color2.multiply(new THREE.Color().setRGB(sample.data[offset] / 255, sample.data[offset + 1] / 255, sample.data[offset + 2] / 255, THREE.SRGBColorSpace));
|
|
1672
1895
|
}
|
|
1673
|
-
if (emissive > 0.3)
|
|
1674
|
-
tints.push(
|
|
1896
|
+
if (emissive > 0.3) color2.lerp(material2.emissive, 0.7);
|
|
1897
|
+
tints.push(color2.r, color2.g, color2.b);
|
|
1675
1898
|
surfaces.push(material2.roughness ?? 0.8, material2.metalness ?? 0, emissive > 0.3 ? 1 : 0);
|
|
1676
1899
|
nodeIndices.push(nodeIndex);
|
|
1677
1900
|
}
|
|
@@ -1718,64 +1941,120 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
1718
1941
|
function createRecorder(options = {}) {
|
|
1719
1942
|
const primitives = [];
|
|
1720
1943
|
const api = {
|
|
1721
|
-
box: (M, material, x, y, z, w, h, d,
|
|
1722
|
-
cylinder: (M, material, x, y, z, r, h,
|
|
1723
|
-
leaf: (M, x, y, z, w, h,
|
|
1724
|
-
plane: (M, material, x, y, z, w, h,
|
|
1944
|
+
box: (M, material, x, y, z, w, h, d, color2, ry, rx, rz) => void primitives.push({ kind: "box", M, material, x, y, z, w, h, d, color: color2, ry, rx, rz }),
|
|
1945
|
+
cylinder: (M, material, x, y, z, r, h, color2, rx, rz, shape) => void primitives.push({ kind: "cylinder", M, material, x, y, z, r, h, color: color2, rx, rz, shape }),
|
|
1946
|
+
leaf: (M, x, y, z, w, h, color2, ry, rx) => void primitives.push({ kind: "leaf", M, x, y, z, w, h, color: color2, ry, rx }),
|
|
1947
|
+
plane: (M, material, x, y, z, w, h, color2, ry, rx, rz, uv) => void primitives.push({ kind: "plane", M, material, x, y, z, w, h, color: color2, ry, rx, rz, uv })
|
|
1725
1948
|
};
|
|
1726
1949
|
if (options.light !== false) {
|
|
1727
|
-
api.light = (M, x, y, z,
|
|
1950
|
+
api.light = (M, x, y, z, color2, range2, lightKind) => void primitives.push({ kind: "light", M, x, y, z, color: color2, range: range2, lightKind });
|
|
1728
1951
|
}
|
|
1729
1952
|
return { api, primitives };
|
|
1730
1953
|
}
|
|
1731
|
-
var
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
const
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1954
|
+
var LEAF = (() => {
|
|
1955
|
+
const f = [0, 0, 0, -0.5, 0.4, 0, 0.5, 0.4, 0, 0, 1, 0];
|
|
1956
|
+
const positions = [];
|
|
1957
|
+
const normals = [];
|
|
1958
|
+
const uvs = [];
|
|
1959
|
+
const indices = [];
|
|
1960
|
+
for (const side of [1, -1]) {
|
|
1961
|
+
const base = positions.length / 3;
|
|
1962
|
+
for (let i = 0; i < 4; i++) {
|
|
1963
|
+
positions.push(f[i * 3], f[i * 3 + 1], f[i * 3 + 2]);
|
|
1964
|
+
normals.push(0, 0, side);
|
|
1965
|
+
uvs.push(f[i * 3] + 0.5, f[i * 3 + 1]);
|
|
1966
|
+
}
|
|
1967
|
+
if (side === 1) indices.push(base, base + 2, base + 1, base + 1, base + 2, base + 3);
|
|
1968
|
+
else indices.push(base, base + 1, base + 2, base + 1, base + 3, base + 2);
|
|
1969
|
+
}
|
|
1970
|
+
return { positions, normals, uvs, indices };
|
|
1971
|
+
})();
|
|
1972
|
+
function createShapeRecorder(options = {}) {
|
|
1973
|
+
const cyl = options.cylinderSegments ?? 12;
|
|
1974
|
+
const hex2 = options.hexSegments ?? 6;
|
|
1975
|
+
const [sphereW, sphereH] = options.sphereSegments ?? [12, 8];
|
|
1976
|
+
const root = [];
|
|
1977
|
+
const parts = [];
|
|
1978
|
+
const partChildren = /* @__PURE__ */ new Map();
|
|
1979
|
+
let current = root;
|
|
1980
|
+
let lastFrame = null;
|
|
1981
|
+
const into = (M) => {
|
|
1982
|
+
const x = M?.x ?? 0;
|
|
1983
|
+
const z = M?.z ?? 0;
|
|
1984
|
+
const ry = M?.ry ?? 0;
|
|
1985
|
+
const last = lastFrame;
|
|
1986
|
+
if (last && last.list === current && current[current.length - 1] === last.group && Object.is(last.x, x) && Object.is(last.z, z) && Object.is(last.ry, ry)) return last.group.children;
|
|
1987
|
+
const group = { kind: "group", position: [x, 0, z], heading: ry, children: [] };
|
|
1988
|
+
current.push(group);
|
|
1989
|
+
lastFrame = { list: current, group, x, z, ry };
|
|
1990
|
+
return group.children;
|
|
1991
|
+
};
|
|
1992
|
+
const api = {
|
|
1993
|
+
box(M, material, x, y, z, w, h, d, color2, ry, rx, rz) {
|
|
1994
|
+
into(M).push({ kind: "box", material, color: color2, position: [x, y + h / 2, z], rotation: [rx, ry, rz], rotationOrder: "YXZ", scale: [w, h, d] });
|
|
1995
|
+
},
|
|
1996
|
+
cylinder(M, material, x, y, z, r, h, color2, rx, rz, shape) {
|
|
1997
|
+
const tilted = rx !== 0 || rz !== 0;
|
|
1998
|
+
const cy = shape === "sphere" ? y + h / 2 : tilted ? y : y + h / 2;
|
|
1999
|
+
const sy = shape === "sphere" ? h / 2 : h;
|
|
2000
|
+
const place = { material, color: color2, position: [x, cy, z], rotation: [rx, 0, rz], rotationOrder: "YXZ", scale: [r, sy, r] };
|
|
2001
|
+
const list2 = into(M);
|
|
2002
|
+
switch (shape) {
|
|
2003
|
+
case "cyl6":
|
|
2004
|
+
list2.push({ kind: "cylinder", radiusTop: 1, radiusBottom: 1, height: 1, radialSegments: hex2, ...place });
|
|
2005
|
+
break;
|
|
2006
|
+
case "cone":
|
|
2007
|
+
list2.push({ kind: "cylinder", radiusTop: 0, radiusBottom: 1, height: 1, radialSegments: cyl, ...place });
|
|
2008
|
+
break;
|
|
2009
|
+
case "sphere":
|
|
2010
|
+
list2.push({ kind: "sphere", radius: 1, widthSegments: sphereW, heightSegments: sphereH, ...place });
|
|
2011
|
+
break;
|
|
2012
|
+
default:
|
|
2013
|
+
list2.push({ kind: "cylinder", radiusTop: 1, radiusBottom: 1, height: 1, radialSegments: cyl, ...place });
|
|
2014
|
+
}
|
|
2015
|
+
},
|
|
2016
|
+
leaf(M, x, y, z, w, h, color2, ry, rx) {
|
|
2017
|
+
into(M).push({ kind: "mesh", ...LEAF, material: "plant", color: color2, position: [x, y, z], rotation: [rx, ry, 0], rotationOrder: "YXZ", scale: [w, h, 1] });
|
|
2018
|
+
},
|
|
2019
|
+
plane(M, material, x, y, z, w, h, color2, ry, rx, rz, uv) {
|
|
2020
|
+
into(M).push({
|
|
2021
|
+
kind: "plane",
|
|
2022
|
+
width: 1,
|
|
2023
|
+
height: 1,
|
|
2024
|
+
material,
|
|
2025
|
+
color: color2,
|
|
2026
|
+
position: [x, y, z],
|
|
2027
|
+
rotation: [rx, ry, rz],
|
|
2028
|
+
rotationOrder: "YXZ",
|
|
2029
|
+
scale: [w, h, 1],
|
|
2030
|
+
...uv ? { uv: { u0: uv.u0, v0: uv.v0, u1: uv.u1, v1: uv.v1 } } : {}
|
|
2031
|
+
});
|
|
2032
|
+
},
|
|
2033
|
+
light(M, x, y, z, color2, range2, kind) {
|
|
2034
|
+
into(M).push({ kind: "point", position: [x, y, z], data: { light: true, color: color2, range: range2, kind } });
|
|
2035
|
+
},
|
|
2036
|
+
part(id, pivot, ry, draw) {
|
|
2037
|
+
let children = partChildren.get(id);
|
|
2038
|
+
if (!children) {
|
|
2039
|
+
children = [];
|
|
2040
|
+
partChildren.set(id, children);
|
|
2041
|
+
parts.push({ id, pivot: [pivot[0], pivot[1], pivot[2]], ry });
|
|
2042
|
+
current.push({ kind: "group", part: id, position: [pivot[0], pivot[1], pivot[2]], rotation: [0, ry, 0], children });
|
|
2043
|
+
}
|
|
2044
|
+
const outer = current;
|
|
2045
|
+
current = children;
|
|
2046
|
+
try {
|
|
2047
|
+
draw();
|
|
2048
|
+
} finally {
|
|
2049
|
+
current = outer;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
};
|
|
2053
|
+
return {
|
|
2054
|
+
api,
|
|
2055
|
+
parts,
|
|
2056
|
+
schema: () => ({ version: 1, ...options.name !== void 0 ? { name: options.name } : {}, root: { kind: "group", children: root } })
|
|
2057
|
+
};
|
|
1779
2058
|
}
|
|
1780
2059
|
|
|
1781
2060
|
// src/locale.ts
|
|
@@ -1987,7 +2266,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
1987
2266
|
_col.setHex(h);
|
|
1988
2267
|
return [_col.r, _col.g, _col.b];
|
|
1989
2268
|
};
|
|
1990
|
-
function put(mat, geo, px, py, pz, q, sx, sy, sz,
|
|
2269
|
+
function put(mat, geo, px, py, pz, q, sx, sy, sz, color2, uvr) {
|
|
1991
2270
|
{
|
|
1992
2271
|
const O = cursor.org, RY = cursor.ry;
|
|
1993
2272
|
if (RY) {
|
|
@@ -2009,7 +2288,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2009
2288
|
const x = q.x, y = q.y, z = q.z, w = q.w, x2 = x + x, y2 = y + y, z2 = z + z;
|
|
2010
2289
|
const xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2;
|
|
2011
2290
|
const m00 = 1 - (yy + zz), m01 = xy - wz, m02 = xz + wy, m10 = xy + wz, m11 = 1 - (xx + zz), m12 = yz - wx, m20 = xz - wy, m21 = yz + wx, m22 = 1 - (xx + yy);
|
|
2012
|
-
const [cr, cg, cb] = rgbOf(
|
|
2291
|
+
const [cr, cg, cb] = rgbOf(color2), scale = UV_SCALE[mat], b = A.nv;
|
|
2013
2292
|
for (let k = 0; k < G.nv; k++) {
|
|
2014
2293
|
const lx = G.p[k * 3] * sx, ly = G.p[k * 3 + 1] * sy, lz = G.p[k * 3 + 2] * sz;
|
|
2015
2294
|
const wx_ = m00 * lx + m01 * ly + m02 * lz + px, wy_ = m10 * lx + m11 * ly + m12 * lz + py, wz_ = m20 * lx + m21 * ly + m22 * lz + pz;
|
|
@@ -2064,21 +2343,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2064
2343
|
A.nv += G.nv;
|
|
2065
2344
|
A.ni += G.i ? G.i.length : G.nv;
|
|
2066
2345
|
}
|
|
2067
|
-
function boxC(mat, cx, cy, cz, sx, sy, sz,
|
|
2346
|
+
function boxC(mat, cx, cy, cz, sx, sy, sz, color2, rx = 0, ry = 0, rz = 0, uvr) {
|
|
2068
2347
|
if (rx || ry || rz) _q.setFromEuler(_e.set(rx, ry, rz, "YXZ"));
|
|
2069
2348
|
else _q.identity();
|
|
2070
|
-
put(mat, "box", cx, cy, cz, _q, sx, sy, sz,
|
|
2349
|
+
put(mat, "box", cx, cy, cz, _q, sx, sy, sz, color2, uvr);
|
|
2071
2350
|
}
|
|
2072
|
-
function bxBase(mat, x0, y0, z0, x1, y1, z1,
|
|
2351
|
+
function bxBase(mat, x0, y0, z0, x1, y1, z1, color2) {
|
|
2073
2352
|
if (x1 - x0 < 1e-4 || y1 - y0 < 1e-4 || z1 - z0 < 1e-4) return;
|
|
2074
2353
|
_q.identity();
|
|
2075
|
-
put(mat, "box", (x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2, _q, x1 - x0, y1 - y0, z1 - z0,
|
|
2354
|
+
put(mat, "box", (x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2, _q, x1 - x0, y1 - y0, z1 - z0, color2);
|
|
2076
2355
|
}
|
|
2077
|
-
function cylBase(mat, x, y, z, r, h,
|
|
2356
|
+
function cylBase(mat, x, y, z, r, h, color2, seg = "cyl") {
|
|
2078
2357
|
_q.identity();
|
|
2079
|
-
put(mat, seg, x, y + h / 2, z, _q, r * 2, h, r * 2,
|
|
2358
|
+
put(mat, seg, x, y + h / 2, z, _q, r * 2, h, r * 2, color2);
|
|
2080
2359
|
}
|
|
2081
|
-
function polyFace(mat, pts,
|
|
2360
|
+
function polyFace(mat, pts, color2, hint) {
|
|
2082
2361
|
const A = accFor(mat), n = pts.length, O = cursor.org, RY = cursor.ry;
|
|
2083
2362
|
A.ensure(n, (n - 2) * 3);
|
|
2084
2363
|
if (RY) {
|
|
@@ -2105,7 +2384,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2105
2384
|
nz = -nz;
|
|
2106
2385
|
[a, b] = [pts[0], pts[1]];
|
|
2107
2386
|
}
|
|
2108
|
-
const [cr, cg, cb] = rgbOf(
|
|
2387
|
+
const [cr, cg, cb] = rgbOf(color2), scale = UV_SCALE[mat] || 1, base = A.nv;
|
|
2109
2388
|
let e1x = b[0] - a[0], e1y = b[1] - a[1], e1z = b[2] - a[2];
|
|
2110
2389
|
const l1 = Math.hypot(e1x, e1y, e1z) || 1;
|
|
2111
2390
|
e1x /= l1;
|
|
@@ -2564,16 +2843,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2564
2843
|
const R = shared.ctx.r, F = R.facade;
|
|
2565
2844
|
if (id === "outside" || !shared.ctx.roomById[id]) {
|
|
2566
2845
|
const ac = F.finish;
|
|
2567
|
-
let mat = "plaster",
|
|
2846
|
+
let mat = "plaster", color2 = shared.ctx.colors.facade;
|
|
2568
2847
|
if (ac === "roughcast") mat = "roughcast";
|
|
2569
2848
|
else if (ac === "exposed_block") {
|
|
2570
2849
|
mat = "block";
|
|
2571
|
-
|
|
2850
|
+
color2 = 12894392;
|
|
2572
2851
|
} else if (ac === "partial_plaster" && !frontLine) {
|
|
2573
2852
|
mat = "block";
|
|
2574
|
-
|
|
2853
|
+
color2 = 12894392;
|
|
2575
2854
|
}
|
|
2576
|
-
return { color, mat, exterior: true };
|
|
2855
|
+
return { color: color2, mat, exterior: true };
|
|
2577
2856
|
}
|
|
2578
2857
|
return { color: wallColor(shared.ctx.roomById[id]), mat: "plaster", exterior: false };
|
|
2579
2858
|
}
|
|
@@ -2683,7 +2962,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2683
2962
|
wallBox(alongU, L, a, b, y0 + dH, y0 + effectiveHeight(f, wallHeight), th, lL.color, lH.color, lL.mat, lH.mat);
|
|
2684
2963
|
cursor.pc = null;
|
|
2685
2964
|
}
|
|
2686
|
-
const fb = (u0, y_0, u1, y_1, tt = th + 0.02,
|
|
2965
|
+
const fb = (u0, y_0, u1, y_1, tt = th + 0.02, color2 = frame) => alongU ? bx("wood", u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx("wood", L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
|
|
2687
2966
|
const jw = 0.05;
|
|
2688
2967
|
cursor.pc = pieceRecord("jamb:" + p.id, "wood_hard", null, { floor: f });
|
|
2689
2968
|
fb(a, 0, a + jw, visH);
|
|
@@ -2697,7 +2976,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2697
2976
|
if (cL && cL.id === p.opensTo) sw = -1;
|
|
2698
2977
|
else if (cH && cH.id === p.opensTo) sw = 1;
|
|
2699
2978
|
}
|
|
2700
|
-
const leaf = (u0, u1, y_0, y_1, tt,
|
|
2979
|
+
const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
|
|
2701
2980
|
const extC = wood;
|
|
2702
2981
|
const open0 = p.blocked ? false : shared.doorState.has(p.id) ? shared.doorState.get(p.id) : !!p.open;
|
|
2703
2982
|
shared.doorState.set(p.id, open0);
|
|
@@ -2706,19 +2985,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2706
2985
|
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 };
|
|
2707
2986
|
shared.ctx.colliders.push(colR);
|
|
2708
2987
|
fo.col = colR;
|
|
2709
|
-
const leafBox = (hu, d0, d1, y_0, y_1, tt,
|
|
2988
|
+
const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
|
|
2710
2989
|
const newGroup = (k, hu, topY) => {
|
|
2711
2990
|
cursor.group = "dyn:" + p.id + ":" + k;
|
|
2712
2991
|
fo.groups.push({ name: cursor.group, pos: alongU ? [hu, topY != null ? y0 + topY : y0, L] : [L, topY != null ? y0 + topY : y0, hu] });
|
|
2713
2992
|
};
|
|
2714
2993
|
if (p.model === "steel") {
|
|
2715
|
-
const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4,
|
|
2994
|
+
const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
|
|
2716
2995
|
newGroup(0, mid, visH);
|
|
2717
|
-
const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(
|
|
2718
|
-
leafBox(0, la, lb, -visH, 0, 0.05,
|
|
2996
|
+
const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color2, 0.55);
|
|
2997
|
+
leafBox(0, la, lb, -visH, 0, 0.05, color2, "metal");
|
|
2719
2998
|
for (let k = 1; k < nSec; k++) leafBox(0, la, lb, -k * hs - 0.012, -k * hs + 0.012, 0.07, grv, "metal");
|
|
2720
2999
|
const np = Math.max(2, Math.round((lb - la) / 0.8)), pw = (lb - la) / np;
|
|
2721
|
-
for (let k = 0; k < nSec; k++) for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.07, la + (i + 1) * pw - 0.07, -(k + 1) * hs + 0.07, -k * hs - 0.07, 0.062, sh(
|
|
3000
|
+
for (let k = 0; k < nSec; k++) for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.07, la + (i + 1) * pw - 0.07, -(k + 1) * hs + 0.07, -k * hs - 0.07, 0.062, sh(color2, k % 2 ? 0.93 : 1.06), "metal");
|
|
2722
3001
|
for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.14, la + (i + 1) * pw - 0.14, -hs + 0.12, -0.12, 0.072, 5924464, "glass");
|
|
2723
3002
|
leafBox(0, -0.1, 0.1, -visH + 0.5, -visH + 0.55, 0.085, 3815998, "metal");
|
|
2724
3003
|
fo.minScale = Math.min(1, 0.28 / visH);
|
|
@@ -2726,13 +3005,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2726
3005
|
} else {
|
|
2727
3006
|
const nf = p.model === "double" ? 2 : 1, aa = a + jw, bb = b - jw;
|
|
2728
3007
|
for (let k = 0; k < nf; k++) {
|
|
2729
|
-
const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb,
|
|
3008
|
+
const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color2 = p.exterior ? extC : wood;
|
|
2730
3009
|
const hingeAt = nf === 2 ? k ? u1 : u0 : p.hinge === "end" ? u1 : u0, dir = hingeAt === u0 ? 1 : -1, len = u1 - u0;
|
|
2731
3010
|
newGroup(k, hingeAt);
|
|
2732
3011
|
const d0 = dir > 0 ? 5e-3 : -len + 5e-3, d1 = dir > 0 ? len - 5e-3 : -5e-3;
|
|
2733
|
-
leafBox(hingeAt, d0, d1, 0, visH, 0.04,
|
|
3012
|
+
leafBox(hingeAt, d0, d1, 0, visH, 0.04, color2, PMAT);
|
|
2734
3013
|
{
|
|
2735
|
-
const e0 = Math.min(d0, d1) + 0.1, e1 = Math.max(d0, d1) - 0.1, pc = sh(
|
|
3014
|
+
const e0 = Math.min(d0, d1) + 0.1, e1 = Math.max(d0, d1) - 0.1, pc = sh(color2, 0.82);
|
|
2736
3015
|
if (e1 - e0 > 0.2 && visH > 1.2) {
|
|
2737
3016
|
leafBox(hingeAt, e0, e1, 0.15, visH * 0.45, 0.055, pc, PMAT);
|
|
2738
3017
|
leafBox(hingeAt, e0, e1, visH * 0.5, visH - 0.15, 0.055, pc, PMAT);
|
|
@@ -2769,9 +3048,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2769
3048
|
if (p.blocked) {
|
|
2770
3049
|
part("window_boards", [0, 0, 0], () => {
|
|
2771
3050
|
const rb = rngString(SEED() + "|" + seedKey(p.id) + "|tabua"), cx0 = alongU ? p.at : L, cz0 = alongU ? L : p.at, nT = Math.max(4, Math.round((visH - 0.3) / 0.3)), Lg = p.width + 0.34, WOODS = [8017460, 7031338, 9071172, 6177320, 7559746];
|
|
2772
|
-
const puts = (along, y, off, comp, alt, thickness,
|
|
3051
|
+
const puts = (along, y, off, comp, alt, thickness, color2, tilt) => {
|
|
2773
3052
|
const x = alongU ? along : L + off, z = alongU ? L + off : along;
|
|
2774
|
-
boxC("wood", x, y0 + y, z, comp, alt, thickness,
|
|
3053
|
+
boxC("wood", x, y0 + y, z, comp, alt, thickness, color2, 0, alongU ? 0 : K.PE, tilt);
|
|
2775
3054
|
};
|
|
2776
3055
|
const nailColor = (along, y, off) => {
|
|
2777
3056
|
const x = alongU ? along : L + off, z = alongU ? L + off : along;
|
|
@@ -2784,8 +3063,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2784
3063
|
puts(alongU ? cx0 : cz0, visH / 2, o1, Math.hypot(p.width + 0.2, visH - 0.4) + 0.1, 0.12, 0.028, sh(WOODS[rb() * 5 | 0], 0.85), a2);
|
|
2785
3064
|
}
|
|
2786
3065
|
for (let k = 0; k < nT; k++) {
|
|
2787
|
-
const y = 0.18 + k * (visH - 0.4) / (nT - 1) + (rb() - 0.5) * 0.04, comp = Lg + (rb() - 0.5) * 0.12, tilt = (rb() - 0.5) * 0.05, alt = 0.13 + rb() * 0.03, c0 = alongU ? cx0 : cz0,
|
|
2788
|
-
puts(c0 + (rb() - 0.5) * 0.06, y, o2, comp, alt, 0.03,
|
|
3066
|
+
const y = 0.18 + k * (visH - 0.4) / (nT - 1) + (rb() - 0.5) * 0.04, comp = Lg + (rb() - 0.5) * 0.12, tilt = (rb() - 0.5) * 0.05, alt = 0.13 + rb() * 0.03, c0 = alongU ? cx0 : cz0, color2 = WOODS[rb() * WOODS.length | 0];
|
|
3067
|
+
puts(c0 + (rb() - 0.5) * 0.06, y, o2, comp, alt, 0.03, color2, tilt);
|
|
2789
3068
|
for (const e of [-1, 1]) {
|
|
2790
3069
|
nailColor(c0 + e * (comp / 2 - 0.07), y + Math.sin(tilt) * e * comp / 2, o2 + sd * 0.019);
|
|
2791
3070
|
}
|
|
@@ -2817,7 +3096,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2817
3096
|
yb = Math.min(yb, 1.2);
|
|
2818
3097
|
}
|
|
2819
3098
|
const wref = R.walls.find((w) => w.floor === f && w.axis === j.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS), th = wref ? wref.thickness || 0.15 : 0.15, t = 0.05, tt = th + 0.02;
|
|
2820
|
-
const bar = (u0, y_0, u1, y_1, mat,
|
|
3099
|
+
const bar = (u0, y_0, u1, y_1, mat, color2, tw = tt) => alongU ? bx(mat, u0, y0 + y_0, L - tw / 2, u1, y0 + y_1, L + tw / 2, color2) : bx(mat, L - tw / 2, y0 + y_0, u0, L + tw / 2, y0 + y_1, u1, color2);
|
|
2821
3100
|
cursor.pc = pieceRecord("window_frame:" + j.id, "aluminium", null, { floor: f });
|
|
2822
3101
|
bar(a, ya, a + t, yb, "metal", fr);
|
|
2823
3102
|
bar(b - t, ya, b, yb, "metal", fr);
|
|
@@ -2929,9 +3208,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
2929
3208
|
const y0 = Y0(f), H = Y0(m.link.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
|
|
2930
3209
|
const wood = shared.ctx.colors.wood != null ? shared.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
|
|
2931
3210
|
const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
|
|
2932
|
-
const boxL = (mat, lx, y, lz, w, h, d,
|
|
3211
|
+
const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
|
|
2933
3212
|
const [px, pz] = P(lx, lz);
|
|
2934
|
-
boxC(mat, px, y, pz, w, h, d,
|
|
3213
|
+
boxC(mat, px, y, pz, w, h, d, color2, rx, m.ry, 0);
|
|
2935
3214
|
};
|
|
2936
3215
|
for (let i = 0; i < n; i++) {
|
|
2937
3216
|
const top = (i + 1) * H / n, lz = m.d / 2 - (i + 0.5) * Dr / n;
|
|
@@ -3002,20 +3281,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3002
3281
|
get A() {
|
|
3003
3282
|
return api;
|
|
3004
3283
|
},
|
|
3005
|
-
b: (mat, x, y, z, w, h, d,
|
|
3006
|
-
c: (mat, x, y, z, r, h,
|
|
3007
|
-
e: (mat, x, y, z, r, h,
|
|
3008
|
-
t(mat, p, q, r,
|
|
3284
|
+
b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => api.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0),
|
|
3285
|
+
c: (mat, x, y, z, r, h, color2, seg) => api.cylinder(M, mat, x, y0 + y, z, r, h, color2, 0, 0, seg),
|
|
3286
|
+
e: (mat, x, y, z, r, h, color2) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color2, 0, 0, "sphere"),
|
|
3287
|
+
t(mat, p, q, r, color2, seg) {
|
|
3009
3288
|
const dx = q[0] - p[0], dy = q[1] - p[1], dz = q[2] - p[2], L = Math.hypot(dx, dy, dz);
|
|
3010
3289
|
if (L < 1e-5) return;
|
|
3011
3290
|
const nx = dx / L, ny = dy / L, nz = dz / L;
|
|
3012
3291
|
if (Math.abs(nx) < 1e-4 && Math.abs(nz) < 1e-4) {
|
|
3013
|
-
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L,
|
|
3292
|
+
api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, color2, 0, 0, seg);
|
|
3014
3293
|
return;
|
|
3015
3294
|
}
|
|
3016
|
-
api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L,
|
|
3295
|
+
api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, color2, Math.atan2(nz, ny), -Math.asin(nx), seg);
|
|
3017
3296
|
},
|
|
3018
|
-
polyFace: (mat, pts,
|
|
3297
|
+
polyFace: (mat, pts, color2, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color2, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
|
|
3019
3298
|
part(type, lx, ly, lz, fn, meta) {
|
|
3020
3299
|
if (type === "lamp" && String(cursor.group).startsWith("ix:light:")) {
|
|
3021
3300
|
fn();
|
|
@@ -3056,28 +3335,28 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3056
3335
|
return v < 0.28 ? "recessed" : v < 0.5 ? "track" : v < 0.75 ? social ? "pendant" : "recessed" : /living|dining|hall/.test(tp) ? "chandelier" : "recessed";
|
|
3057
3336
|
}
|
|
3058
3337
|
function ceilingLamp(M, A, type) {
|
|
3059
|
-
const K2 = kit2(M, A, 0), t = M.ceiling || 2.8,
|
|
3060
|
-
const id = "lamp_" + (M.seed || hashString(M.x + "," + M.z)), meta = { id, room: M.room, on: !!M.on, color, lightType: type, hidden: !M.on };
|
|
3338
|
+
const K2 = kit2(M, A, 0), t = M.ceiling || 2.8, color2 = colorTemperature(M), r = rngString(SEED() + "|" + seedKey(M.seed) + "|lz");
|
|
3339
|
+
const id = "lamp_" + (M.seed || hashString(M.x + "," + M.z)), meta = { id, room: M.room, on: !!M.on, color: color2, lightType: type, hidden: !M.on };
|
|
3061
3340
|
const white = 16052972, offset = 15329247;
|
|
3062
|
-
let yLight = t - 0.18,
|
|
3341
|
+
let yLight = t - 0.18, range2 = 6;
|
|
3063
3342
|
const emitter = (fn) => K2.part("lamp", 0, t, 0, fn, meta);
|
|
3064
3343
|
if (type === "bare") {
|
|
3065
3344
|
K2.c("plain", 0, t - 0.03, 0, 0.05, 0.03, white);
|
|
3066
3345
|
K2.c("metal", 0, t - 0.085, 0, 0.022, 0.055, 6974054);
|
|
3067
3346
|
K2.c("plain", 0, t - 0.105, 0, 0.026, 0.02, 14209208);
|
|
3068
3347
|
K2.e("plain", 0, t - 0.165, 0, 0.036, 0.085, 15987178);
|
|
3069
|
-
emitter(() => K2.e("emissive", 0, t - 0.165, 0, 0.0385, 0.088,
|
|
3348
|
+
emitter(() => K2.e("emissive", 0, t - 0.165, 0, 0.0385, 0.088, color2));
|
|
3070
3349
|
yLight = t - 0.22;
|
|
3071
|
-
|
|
3350
|
+
range2 = 5.5;
|
|
3072
3351
|
} else if (type === "round") {
|
|
3073
3352
|
K2.c("plain", 0, t - 0.05, 0, 0.19, 0.05, white);
|
|
3074
3353
|
K2.c("plain", 0, t - 0.07, 0, 0.165, 0.02, offset);
|
|
3075
|
-
emitter(() => K2.c("emissive", 0, t - 0.073, 0, 0.1675, 0.023,
|
|
3354
|
+
emitter(() => K2.c("emissive", 0, t - 0.073, 0, 0.1675, 0.023, color2));
|
|
3076
3355
|
yLight = t - 0.2;
|
|
3077
3356
|
} else if (type === "square") {
|
|
3078
3357
|
K2.b("plain", 0, t - 0.05, 0, 0.36, 0.05, 0.36, white);
|
|
3079
3358
|
K2.b("plain", 0, t - 0.07, 0, 0.3, 0.02, 0.3, offset);
|
|
3080
|
-
emitter(() => K2.b("emissive", 0, t - 0.073, 0, 0.3025, 0.023, 0.3025,
|
|
3359
|
+
emitter(() => K2.b("emissive", 0, t - 0.073, 0, 0.3025, 0.023, 0.3025, color2));
|
|
3081
3360
|
yLight = t - 0.2;
|
|
3082
3361
|
} else if (type === "recessed") {
|
|
3083
3362
|
const o = 0.5;
|
|
@@ -3086,10 +3365,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3086
3365
|
K2.c("plain", x, t - 0.026, z, 0.05, 0.012, offset);
|
|
3087
3366
|
}
|
|
3088
3367
|
emitter(() => {
|
|
3089
|
-
for (const [x, z] of [[-o, -o], [o, -o], [-o, o], [o, o]]) K2.c("emissive", x, t - 0.028, z, 0.0505, 0.014,
|
|
3368
|
+
for (const [x, z] of [[-o, -o], [o, -o], [-o, o], [o, o]]) K2.c("emissive", x, t - 0.028, z, 0.0505, 0.014, color2);
|
|
3090
3369
|
});
|
|
3091
3370
|
yLight = t - 0.3;
|
|
3092
|
-
|
|
3371
|
+
range2 = 6.5;
|
|
3093
3372
|
} else if (type === "track") {
|
|
3094
3373
|
const len = 1.1, angle = r() < 0.5 ? 0 : Math.PI / 2, c = Math.cos(angle), s = Math.sin(angle);
|
|
3095
3374
|
K2.b("metal", 0, t - 0.03, 0, angle ? 0.035 : len, 0.03, angle ? len : 0.035, 2763308);
|
|
@@ -3105,16 +3384,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3105
3384
|
for (const [q, d] of cab) K2.t("emissive", [q[0] - d[0] * 3e-3, q[1] - d[1] * 3e-3, q[2] - d[2] * 3e-3], [q[0] + d[0] * 0.012, q[1] + d[1] * 0.012, q[2] + d[2] * 0.012], 0.029);
|
|
3106
3385
|
});
|
|
3107
3386
|
yLight = t - 0.3;
|
|
3108
|
-
|
|
3387
|
+
range2 = 6.5;
|
|
3109
3388
|
} else if (type === "pendant") {
|
|
3110
3389
|
const drop = Math.max(0.4, Math.min(1.1, t - 2.05)), yc = t - drop, cs = [2763308, 15262420, 12094036, 3495534][r() * 4 | 0];
|
|
3111
3390
|
K2.c("plain", 0, t - 0.025, 0, 0.05, 0.025, white);
|
|
3112
3391
|
K2.c("metal", 0, yc, 0, 6e-3, drop - 0.02, 1710618);
|
|
3113
3392
|
K2.e("plain", 0, yc - 0.09, 0, 0.19, 0.2, cs);
|
|
3114
3393
|
K2.e("plain", 0, yc - 0.2, 0, 0.065, 0.085, 15987178);
|
|
3115
|
-
emitter(() => K2.e("emissive", 0, yc - 0.2, 0, 0.069, 0.089,
|
|
3394
|
+
emitter(() => K2.e("emissive", 0, yc - 0.2, 0, 0.069, 0.089, color2));
|
|
3116
3395
|
yLight = yc - 0.3;
|
|
3117
|
-
|
|
3396
|
+
range2 = 6.5;
|
|
3118
3397
|
} else if (type === "chandelier") {
|
|
3119
3398
|
const yc = t - 0.5, gold = shared.ctx.colors && shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9075290, N = 6;
|
|
3120
3399
|
K2.c("metal", 0, yc, 0, 0.012, 0.5, gold);
|
|
@@ -3131,57 +3410,57 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3131
3410
|
emitter(() => {
|
|
3132
3411
|
for (let i = 0; i < N; i++) {
|
|
3133
3412
|
const an = i * Math.PI * 2 / N;
|
|
3134
|
-
K2.e("emissive", Math.cos(an) * 0.28, yc + 0.07, Math.sin(an) * 0.28, 0.0155, 0.036,
|
|
3413
|
+
K2.e("emissive", Math.cos(an) * 0.28, yc + 0.07, Math.sin(an) * 0.28, 0.0155, 0.036, color2);
|
|
3135
3414
|
}
|
|
3136
3415
|
});
|
|
3137
3416
|
yLight = yc - 0.05;
|
|
3138
|
-
|
|
3417
|
+
range2 = 7;
|
|
3139
3418
|
} else if (type === "trough") {
|
|
3140
3419
|
K2.b("metal", 0, t - 0.045, 0, 1.2, 0.045, 0.1, 14474456);
|
|
3141
3420
|
K2.b("plain", 0, t - 0.058, 0, 1.12, 0.013, 0.06, 15329764);
|
|
3142
|
-
emitter(() => K2.b("emissive", 0, t - 0.0605, 0, 1.125, 0.0155, 0.0625,
|
|
3421
|
+
emitter(() => K2.b("emissive", 0, t - 0.0605, 0, 1.125, 0.0155, 0.0625, color2));
|
|
3143
3422
|
yLight = t - 0.2;
|
|
3144
|
-
|
|
3423
|
+
range2 = 7;
|
|
3145
3424
|
}
|
|
3146
|
-
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, yLight, 0,
|
|
3425
|
+
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, yLight, 0, color2, range2, "ceiling_light");
|
|
3147
3426
|
}
|
|
3148
3427
|
function tableLamp(M, A, y) {
|
|
3149
|
-
const K2 = kit2(M, A, 0),
|
|
3428
|
+
const K2 = kit2(M, A, 0), color2 = colorTemperature(M), id = "lamp_ab_" + M.seed, cp = [15786688, 15262420, 13621470][hashString(seedKey(M.seed) + "cp") % 3], meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "table_lamp", hidden: !M.on };
|
|
3150
3429
|
K2.e("plain", 0, y + 0.045, 0, 0.065, 0.09, 3813928);
|
|
3151
3430
|
K2.c("metal", 0, y + 0.08, 0, 8e-3, 0.14, 9075290);
|
|
3152
3431
|
K2.c("plain", 0, y + 0.2, 0, 0.115, 0.15, cp);
|
|
3153
|
-
K2.part("lamp", 0, y + 0.2, 0, () => K2.c("emissive", 0, y + 0.2, 0, 0.118, 0.152,
|
|
3154
|
-
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, y + 0.3, 0,
|
|
3432
|
+
K2.part("lamp", 0, y + 0.2, 0, () => K2.c("emissive", 0, y + 0.2, 0, 0.118, 0.152, color2), meta);
|
|
3433
|
+
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, y + 0.3, 0, color2, 3.5, "table_lamp");
|
|
3155
3434
|
}
|
|
3156
3435
|
function floorLamp(M, A) {
|
|
3157
|
-
const K2 = kit2(M, A, M.y || 0),
|
|
3436
|
+
const K2 = kit2(M, A, M.y || 0), color2 = colorTemperature(M), id = "lamp_pe_" + M.seed, h = Math.min(1.6, M.h || 1.5), meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "floor", hidden: !M.on };
|
|
3158
3437
|
K2.c("metal", 0, 0, 0, 0.13, 0.025, 2763308);
|
|
3159
3438
|
K2.c("metal", 0, 0.025, 0, 0.011, h - 0.3, 2763308);
|
|
3160
3439
|
K2.c("plain", 0, h - 0.28, 0, 0.17, 0.26, 15656656);
|
|
3161
|
-
K2.part("lamp", 0, h - 0.28, 0, () => K2.c("emissive", 0, h - 0.28, 0, 0.173, 0.262,
|
|
3162
|
-
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, h - 0.15, 0,
|
|
3440
|
+
K2.part("lamp", 0, h - 0.28, 0, () => K2.c("emissive", 0, h - 0.28, 0, 0.173, 0.262, color2), meta);
|
|
3441
|
+
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, h - 0.15, 0, color2, 5, "floor");
|
|
3163
3442
|
}
|
|
3164
3443
|
function sconce(M, A) {
|
|
3165
|
-
const K2 = kit2(M, A, M.y || 1.7),
|
|
3444
|
+
const K2 = kit2(M, A, M.y || 1.7), color2 = colorTemperature(M), id = "lamp_ar_" + M.seed, meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "sconce", hidden: !M.on };
|
|
3166
3445
|
K2.b("metal", 0, -0.07, 8e-3, 0.07, 0.14, 0.016, 14210248);
|
|
3167
3446
|
K2.t("metal", [0, 0, 0.016], [0, 0, 0.075], 0.011, 11577480);
|
|
3168
3447
|
K2.e("plain", 0, 0, 0.1, 0.06, 0.15, 15920348);
|
|
3169
|
-
K2.part("lamp", 0, 0, 0.1, () => K2.e("emissive", 0, 0, 0.1, 0.0625, 0.153,
|
|
3170
|
-
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, 0.02, 0.2,
|
|
3448
|
+
K2.part("lamp", 0, 0, 0.1, () => K2.e("emissive", 0, 0, 0.1, 0.0625, 0.153, color2), meta);
|
|
3449
|
+
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, 0.02, 0.2, color2, 3, "sconce");
|
|
3171
3450
|
}
|
|
3172
3451
|
function outdoorLamp(M, A) {
|
|
3173
|
-
const K2 = kit2(M, A, M.y || 2.2),
|
|
3452
|
+
const K2 = kit2(M, A, M.y || 2.2), color2 = colorTemperature(M), id = "lamp_ext_" + M.seed, structure = STYLE(), meta = { id, room: "outside", on: !!M.on, color: color2, lightType: "outdoor", hidden: !M.on };
|
|
3174
3453
|
if (structure === "budget") {
|
|
3175
3454
|
K2.c("plain", 0, -0, 0.01, 0.05, 0.02, 15921386);
|
|
3176
3455
|
K2.t("metal", [0, 0, 0], [0, 0, 0.07], 0.022, 6974054);
|
|
3177
3456
|
K2.e("plain", 0, 0, 0.115, 0.036, 0.085, 15987178);
|
|
3178
|
-
K2.part("lamp", 0, 0, 0.115, () => K2.e("emissive", 0, 0, 0.115, 0.0385, 0.088,
|
|
3457
|
+
K2.part("lamp", 0, 0, 0.115, () => K2.e("emissive", 0, 0, 0.115, 0.0385, 0.088, color2), meta);
|
|
3179
3458
|
} else {
|
|
3180
3459
|
K2.b("metal", 0, -0.08, 0.01, 0.12, 0.16, 0.02, 2763308);
|
|
3181
3460
|
K2.b("plain", 0, -0.09, 0.07, 0.11, 0.18, 0.1, 15263454);
|
|
3182
|
-
K2.part("lamp", 0, -0.09, 0.07, () => K2.b("emissive", 0, -0.09, 0.07, 0.1125, 0.1825, 0.1025,
|
|
3461
|
+
K2.part("lamp", 0, -0.09, 0.07, () => K2.b("emissive", 0, -0.09, 0.07, 0.1125, 0.1825, 0.1025, color2), meta);
|
|
3183
3462
|
}
|
|
3184
|
-
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, (M.y != null ? M.y : 2.2) - (structure === "budget" ? 0 : 0.09), structure === "budget" ? 0.2 : 0.2,
|
|
3463
|
+
if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, (M.y != null ? M.y : 2.2) - (structure === "budget" ? 0 : 0.09), structure === "budget" ? 0.2 : 0.2, color2, 3.2, "outdoor", { lumens: 3.2, dist: 5.5, decay: 2 });
|
|
3185
3464
|
}
|
|
3186
3465
|
function lightSwitch(M, A) {
|
|
3187
3466
|
const K2 = kit2(M, A, M.y != null && M.y > 0 ? M.y : 1.1), two = !!M.double;
|
|
@@ -3332,13 +3611,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3332
3611
|
for (const s of lt.perimeter) {
|
|
3333
3612
|
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);
|
|
3334
3613
|
cursor.pc = pieceRecord("lot_wall:" + s.id, s.type === "wall" ? "brick" : s.type === "fence" ? "wood_soft" : "steel", null, { tags: ["wall"] });
|
|
3335
|
-
const th = s.thickness || 0.15, h = s.height,
|
|
3614
|
+
const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
|
|
3336
3615
|
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);
|
|
3337
3616
|
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 };
|
|
3338
3617
|
shared.ctx.colliders.push(col);
|
|
3339
3618
|
if (s.type === "wall") {
|
|
3340
|
-
B("plaster", a, 0, b, h, th,
|
|
3341
|
-
B("plaster", a, h, b, h + 0.05, th + 0.06, sh(
|
|
3619
|
+
B("plaster", a, 0, b, h, th, color2);
|
|
3620
|
+
B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color2, 1.15));
|
|
3342
3621
|
} else if (s.type === "fence") {
|
|
3343
3622
|
const np = Math.max(2, Math.round(len / 2.4) + 1);
|
|
3344
3623
|
for (let k = 0; k < np; k++) {
|
|
@@ -3350,8 +3629,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3350
3629
|
B("metal", a, 0.08, b, 0.12, 0.03, 9080466);
|
|
3351
3630
|
} else {
|
|
3352
3631
|
const gc = C.gate != null ? C.gate : 2763310, mh = 0.5;
|
|
3353
|
-
B("plaster", a, 0, b, mh, th,
|
|
3354
|
-
B("plaster", a, mh, b, mh + 0.04, th + 0.05, sh(
|
|
3632
|
+
B("plaster", a, 0, b, mh, th, color2);
|
|
3633
|
+
B("plaster", a, mh, b, mh + 0.04, th + 0.05, sh(color2, 1.15));
|
|
3355
3634
|
const n = Math.max(2, Math.round(len / 0.13));
|
|
3356
3635
|
for (let k = 0; k <= n; k++) {
|
|
3357
3636
|
const u = a + k * len / n;
|
|
@@ -3400,9 +3679,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3400
3679
|
cursor.group = "lot";
|
|
3401
3680
|
for (const c of lt.paths) {
|
|
3402
3681
|
if (c.type === "vehicle" && c.id !== "cargo_path") continue;
|
|
3403
|
-
const
|
|
3682
|
+
const color2 = c.type === "pedestrian" ? 13617856 : 11841704;
|
|
3404
3683
|
for (const [u0, v0, u1, v1] of c.rects) {
|
|
3405
|
-
bx("sidewalk", u0, 0, v0, u1, 0.05, v1,
|
|
3684
|
+
bx("sidewalk", u0, 0, v0, u1, 0.05, v1, color2);
|
|
3406
3685
|
}
|
|
3407
3686
|
}
|
|
3408
3687
|
}
|
|
@@ -3758,7 +4037,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3758
4037
|
const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
|
|
3759
4038
|
const sh = (...a) => K.sh(...a);
|
|
3760
4039
|
const R_STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
|
|
3761
|
-
function tileRelief(mat, pts,
|
|
4040
|
+
function tileRelief(mat, pts, color2, type) {
|
|
3762
4041
|
const n = pts.length;
|
|
3763
4042
|
if (n < 3) return;
|
|
3764
4043
|
const [a, b, c] = pts;
|
|
@@ -3822,7 +4101,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
3822
4101
|
}
|
|
3823
4102
|
col.push(lo <= hi ? [lo, hi] : null);
|
|
3824
4103
|
}
|
|
3825
|
-
const AC = accFor(mat), m = L.length, [cr, cg, cb] = rgbOf(
|
|
4104
|
+
const AC = accFor(mat), m = L.length, [cr, cg, cb] = rgbOf(color2), O = cursor.org;
|
|
3826
4105
|
AC.ensure(m * 2, (m - 1) * 6);
|
|
3827
4106
|
const base = AC.nv, w2 = 2 * Math.PI / P;
|
|
3828
4107
|
for (let j = 0; j < m; j++) {
|
|
@@ -4200,15 +4479,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4200
4479
|
}
|
|
4201
4480
|
});
|
|
4202
4481
|
const parts = [];
|
|
4203
|
-
for (const { m, list, vc } of byMaterial.values()) {
|
|
4482
|
+
for (const { m, list: list2, vc } of byMaterial.values()) {
|
|
4204
4483
|
let nv = 0, ni = 0;
|
|
4205
|
-
for (const e of
|
|
4484
|
+
for (const e of list2) {
|
|
4206
4485
|
nv += e.P.length / 3;
|
|
4207
4486
|
ni += e.I ? e.I.length : e.P.length / 3;
|
|
4208
4487
|
}
|
|
4209
4488
|
const P = new Float32Array(nv * 3), N = new Float32Array(nv * 3), U = new Float32Array(nv * 2), I = new Uint32Array(ni);
|
|
4210
4489
|
let ov = 0, oi = 0;
|
|
4211
|
-
for (const e of
|
|
4490
|
+
for (const e of list2) {
|
|
4212
4491
|
const n = e.P.length / 3;
|
|
4213
4492
|
P.set(e.P, ov * 3);
|
|
4214
4493
|
N.set(e.N, ov * 3);
|
|
@@ -4225,7 +4504,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4225
4504
|
if (vc) {
|
|
4226
4505
|
const C = new Float32Array(nv * 3);
|
|
4227
4506
|
let q = 0;
|
|
4228
|
-
for (const e of
|
|
4507
|
+
for (const e of list2) {
|
|
4229
4508
|
const n = e.P.length / 3, cr = e.color;
|
|
4230
4509
|
for (let i = 0; i < n; i++, q++) {
|
|
4231
4510
|
C[q * 3] = cr.r;
|
|
@@ -4336,7 +4615,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4336
4615
|
const x = u.ry ? [u.u - uw, u.u] : [u.u, u.u + uw], z = u.ry ? [u.v - ud, u.v] : [u.v, u.v + ud];
|
|
4337
4616
|
return [x[0], z[0], x[1], z[1]];
|
|
4338
4617
|
};
|
|
4339
|
-
const un0 = unitBox(un[0]),
|
|
4618
|
+
const un0 = unitBox(un[0]), color2 = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
|
|
4340
4619
|
const sel = un[shared.ctx.pu] || un[0], selR = unitBox(sel);
|
|
4341
4620
|
const shell = (rc, y0, y1, thickness = 0.15) => {
|
|
4342
4621
|
const [a, b, c, d] = rc;
|
|
@@ -4356,10 +4635,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4356
4635
|
bx("glass", rc[0] + 0.5, y0 + 0.9, u.ry ? rc[1] - 1e-3 : rc[3] + 1e-3, rc[2] - 0.5, y0 + 2, u.ry ? rc[1] + 1e-3 : rc[3] + 2e-3, 16777215);
|
|
4357
4636
|
}
|
|
4358
4637
|
}
|
|
4359
|
-
for (const rc of [
|
|
4638
|
+
for (const rc of [color2, hall]) {
|
|
4360
4639
|
bx("plaster", rc[0], y0 - 0.2, rc[1], rc[2], y0, rc[3], 12104874);
|
|
4361
4640
|
}
|
|
4362
|
-
shell([Math.min(
|
|
4641
|
+
shell([Math.min(color2[0], hall[0]), hall[1], color2[2], color2[3]], y0, y0 + pe - 0.2);
|
|
4363
4642
|
bx("metal", el[0] + 0.05, y0, el[1] + 0.05, el[2] - 0.05, y0 + pe, el[3] - 0.05, 8291466);
|
|
4364
4643
|
bx("building", es[0], y0, es[1], es[2], y0 + pe - 0.2, es[3], 13618114);
|
|
4365
4644
|
const ns = 16, rise = pe / ns, wl = es[2] - es[0] - 0.2;
|
|
@@ -4375,8 +4654,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4375
4654
|
}
|
|
4376
4655
|
}
|
|
4377
4656
|
const ytop = N * pe - 0.2;
|
|
4378
|
-
bx("plaster", Math.min(hall[0] - 3,
|
|
4379
|
-
shared.ctx.limits = { x0: Math.min(hall[0] - 3,
|
|
4657
|
+
bx("plaster", Math.min(hall[0] - 3, color2[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color2[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
|
|
4658
|
+
shared.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
|
|
4380
4659
|
}
|
|
4381
4660
|
Object.assign(K, { building });
|
|
4382
4661
|
}
|
|
@@ -4466,11 +4745,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4466
4745
|
return api;
|
|
4467
4746
|
}
|
|
4468
4747
|
const PIPE_COLOR = 11897429;
|
|
4469
|
-
function pipe(a, b, diameter,
|
|
4748
|
+
function pipe(a, b, diameter, color2) {
|
|
4470
4749
|
const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
|
|
4471
4750
|
if (L < 1e-3) return;
|
|
4472
4751
|
_q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
|
|
4473
|
-
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter,
|
|
4752
|
+
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
|
|
4474
4753
|
}
|
|
4475
4754
|
const _v3 = new THREE.Vector3();
|
|
4476
4755
|
function waterPipes() {
|
|
@@ -4567,9 +4846,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4567
4846
|
const g0 = cursor.group, noDrawing = !!(KV && KV.picture);
|
|
4568
4847
|
cursor.group = "f" + Math.max(0, Math.min(nA - 1, Q.floor || 0));
|
|
4569
4848
|
const frontU = Q.frontU || 0, frontV = Q.frontV || 0, w = Q.w || 0.3, h = Q.h || 0.4, hw = w / 2, d = 0.05;
|
|
4570
|
-
const bq = (a0, y0_, a1, y1_, o0, o1, mat,
|
|
4571
|
-
if (frontV) bx(mat, Q.u + a0, Q.y + y0_, Q.v + (frontV > 0 ? o0 : -o1), Q.u + a1, Q.y + y1_, Q.v + (frontV > 0 ? o1 : -o0),
|
|
4572
|
-
else bx(mat, Q.u + (frontU > 0 ? o0 : -o1), Q.y + y0_, Q.v + a0, Q.u + (frontU > 0 ? o1 : -o0), Q.y + y1_, Q.v + a1,
|
|
4849
|
+
const bq = (a0, y0_, a1, y1_, o0, o1, mat, color2) => {
|
|
4850
|
+
if (frontV) bx(mat, Q.u + a0, Q.y + y0_, Q.v + (frontV > 0 ? o0 : -o1), Q.u + a1, Q.y + y1_, Q.v + (frontV > 0 ? o1 : -o0), color2);
|
|
4851
|
+
else bx(mat, Q.u + (frontU > 0 ? o0 : -o1), Q.y + y0_, Q.v + a0, Q.u + (frontU > 0 ? o1 : -o0), Q.y + y1_, Q.v + a1, color2);
|
|
4573
4852
|
};
|
|
4574
4853
|
if (!noDrawing) {
|
|
4575
4854
|
bq(-hw, -h / 2, hw, h / 2, -0.015, 0.06, "plain", 13619926);
|
|
@@ -4613,11 +4892,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4613
4892
|
for (const t of E.switches || []) info.switches.push({ id: t.id, pos: [t.u, t.y, t.v], normal: [t.frontU || 0, 0, t.frontV || 0], room: t.room, floor: t.floor, controls: t.controls });
|
|
4614
4893
|
shared.ctx.electricalInfo = info;
|
|
4615
4894
|
}
|
|
4616
|
-
function pipe2(a, b, diameter,
|
|
4895
|
+
function pipe2(a, b, diameter, color2) {
|
|
4617
4896
|
const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
|
|
4618
4897
|
if (L < 1e-3) return;
|
|
4619
4898
|
_q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
|
|
4620
|
-
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter,
|
|
4899
|
+
put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
|
|
4621
4900
|
}
|
|
4622
4901
|
Object.assign(K, { electricalStructure, pipe2 });
|
|
4623
4902
|
}
|
|
@@ -4627,7 +4906,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4627
4906
|
const { Y0, bx, cursor, sideOf } = K;
|
|
4628
4907
|
const sh = (...a) => K.sh(...a);
|
|
4629
4908
|
function baseboardAndSidewalk() {
|
|
4630
|
-
const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35,
|
|
4909
|
+
const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared.ctx.colors.facade != null ? shared.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
|
|
4631
4910
|
const ws = R.walls.filter((w) => w.floor === 0 && w.type === "wall").map((w) => {
|
|
4632
4911
|
const au = w.axis === "u";
|
|
4633
4912
|
return { w, au, L: au ? w.v0 : w.u0, a: Math.min(au ? w.u0 : w.v0, au ? w.u1 : w.v1), b: Math.max(au ? w.u0 : w.v0, au ? w.u1 : w.v1), th: w.thickness || 0.15 };
|
|
@@ -4653,7 +4932,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4653
4932
|
if (A.au) bx(mat, s0, y1, lo, s1, y2, hi, c);
|
|
4654
4933
|
else bx(mat, lo, y1, s0, hi, y2, s1, c);
|
|
4655
4934
|
};
|
|
4656
|
-
strip(t, y0, y0 + ht, 0, t, "plaster",
|
|
4935
|
+
strip(t, y0, y0 + ht, 0, t, "plaster", color2);
|
|
4657
4936
|
strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
|
|
4658
4937
|
}
|
|
4659
4938
|
}
|
|
@@ -4702,7 +4981,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4702
4981
|
tilt = Math.atan2(yA - yB, d);
|
|
4703
4982
|
yc = yC + 0.13;
|
|
4704
4983
|
}
|
|
4705
|
-
const co = Math.cos(tilt), si = Math.sin(tilt), pb = (lx, ly, lz, sx, sy, sz, mat,
|
|
4984
|
+
const co = Math.cos(tilt), si = Math.sin(tilt), pb = (lx, ly, lz, sx, sy, sz, mat, color2) => boxC(mat, p.u + lx, yc + ly * co - lz * si, p.v + ly * si + lz * co, sx, sy, sz, color2, tilt, 0, 0), L = p.length;
|
|
4706
4985
|
pb(0, 0, 0, p.w, 0.04, L, "metal", silver);
|
|
4707
4986
|
pb(0, 0.0205, 0, p.w - 0.07, 6e-3, L - 0.07, "plain", blue);
|
|
4708
4987
|
for (let k = 1; k < 4; k++) pb(-hw + 0.035 + k * (p.w - 0.07) / 4, 0.0245, 0, 6e-3, 3e-3, L - 0.07, "metal", line);
|
|
@@ -4794,39 +5073,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4794
5073
|
return [M.x + lx * c + lz * s, M.z - lx * s + lz * c];
|
|
4795
5074
|
};
|
|
4796
5075
|
return {
|
|
4797
|
-
box(M, mat, x, y, z, w, h, d,
|
|
5076
|
+
box(M, mat, x, y, z, w, h, d, color2, ry = 0, rx = 0, rz = 0) {
|
|
4798
5077
|
const [px, pz] = loc(M, x, z);
|
|
4799
|
-
boxC(mm(mat), px, M.base + y + h / 2, pz, w, h, d,
|
|
5078
|
+
boxC(mm(mat), px, M.base + y + h / 2, pz, w, h, d, color2, rx, M.ry + ry, rz);
|
|
4800
5079
|
},
|
|
4801
|
-
cylinder(M, mat, x, y, z, r, h,
|
|
5080
|
+
cylinder(M, mat, x, y, z, r, h, color2, rx = 0, rz = 0, seg) {
|
|
4802
5081
|
const [px, pz] = loc(M, x, z);
|
|
4803
5082
|
_q.setFromEuler(_e.set(rx || 0, M.ry, rz || 0, "YXZ"));
|
|
4804
|
-
put(mm(mat), seg || "cyl", px, M.base + y + (rx || rz ? 0 : h / 2), pz, _q, r * 2, h, r * 2,
|
|
5083
|
+
put(mm(mat), seg || "cyl", px, M.base + y + (rx || rz ? 0 : h / 2), pz, _q, r * 2, h, r * 2, color2);
|
|
4805
5084
|
},
|
|
4806
|
-
leaf(M, x, y, z, w, h,
|
|
5085
|
+
leaf(M, x, y, z, w, h, color2, ry = 0, rx = 0) {
|
|
4807
5086
|
const [px, pz] = loc(M, x, z), a = M.ry + (ry || 0), ca = Math.cos(a), sa = Math.sin(a), t1 = (rx || 0) * 0.8, t2 = (rx || 0) * 1.5, y0 = M.base + y;
|
|
4808
5087
|
const P = (lx, ly, lz) => [px + lx * ca + lz * sa, y0 + ly, pz - lx * sa + lz * ca];
|
|
4809
5088
|
const my = Math.cos(t1) * h * 0.5, mz = Math.sin(t1) * h * 0.5, ty = my + Math.cos(t2) * h * 0.5, tz = mz + Math.sin(t2) * h * 0.5, f = w * 0.5, dn = f * 0.32;
|
|
4810
5089
|
const B = P(0, 0, 0), Mi = P(0, my + 4e-3, mz), T2 = P(0, ty, tz), L = P(-f, my - dn, mz - dn * 0.3), R = P(f, my - dn, mz - dn * 0.3);
|
|
4811
|
-
polyFace("plant", [B, L, T2, Mi],
|
|
4812
|
-
polyFace("plant", [B, Mi, T2, R], sh(
|
|
5090
|
+
polyFace("plant", [B, L, T2, Mi], color2, [0, 1, 0]);
|
|
5091
|
+
polyFace("plant", [B, Mi, T2, R], sh(color2, 0.92), [0, 1, 0]);
|
|
4813
5092
|
},
|
|
4814
|
-
plane(M, mat, x, y, z, w, h,
|
|
5093
|
+
plane(M, mat, x, y, z, w, h, color2, ry = 0, rx = 0, rz = 0, uv) {
|
|
4815
5094
|
const [px, pz] = loc(M, x, z);
|
|
4816
5095
|
_q.setFromEuler(_e.set(rx || 0, M.ry + (ry || 0), rz || 0, "YXZ"));
|
|
4817
5096
|
if (uv && mat === "atlas_floor") {
|
|
4818
5097
|
const col = Math.floor(uv.u0 * 4 + 1e-6), lin = uv.v0 < 0.5 ? 1 : 0, cell = col + 4 * lin, h0 = _h2(Math.round(px * 8), Math.round(pz * 8)), type = cell === 5 ? "dirt" : cell === 0 || cell === 1 ? "lawn" : null;
|
|
4819
5098
|
if (type === "dirt") {
|
|
4820
|
-
put("dirt", "plane", px, M.base + y, pz, _q, w, h, 1, sh(
|
|
5099
|
+
put("dirt", "plane", px, M.base + y, pz, _q, w, h, 1, sh(color2, 1 / 0.965));
|
|
4821
5100
|
return;
|
|
4822
5101
|
}
|
|
4823
5102
|
if (type) uv = { u0: uv.u0, u1: uv.u1, v0: uv.v0, v1: uv.v1, rot: h0 * 4 | 0, fx: h0 > 0.5 ? 1 : 0, vc: (wx, wz) => macroGround(wx, wz, type) };
|
|
4824
5103
|
}
|
|
4825
|
-
put(mm(mat), "plane", px, M.base + y, pz, _q, w, h, 1,
|
|
5104
|
+
put(mm(mat), "plane", px, M.base + y, pz, _q, w, h, 1, color2, uv);
|
|
4826
5105
|
},
|
|
4827
|
-
light(M, x, y, z,
|
|
5106
|
+
light(M, x, y, z, color2, range2, type, ex) {
|
|
4828
5107
|
const [px, pz] = loc(M, x, z);
|
|
4829
|
-
LIGHTS.push(Object.assign({ x: px, y: M.base + y, z: pz, color, range, type, floor: M.floor, group: cursor.group, base: M.base, room: M.room, id: M.lampId }, ex || null));
|
|
5108
|
+
LIGHTS.push(Object.assign({ x: px, y: M.base + y, z: pz, color: color2, range: range2, type, floor: M.floor, group: cursor.group, base: M.base, room: M.room, id: M.lampId }, ex || null));
|
|
4830
5109
|
}
|
|
4831
5110
|
};
|
|
4832
5111
|
}
|
|
@@ -4841,7 +5120,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
4841
5120
|
}
|
|
4842
5121
|
function kk(M, A) {
|
|
4843
5122
|
const y0 = M.y || 0;
|
|
4844
|
-
return { b: (mat, x, y, z, w, h, d,
|
|
5123
|
+
return { b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color2, rx, rz, seg) => A.cylinder(M, mat, x, y0 + y, z, r, h, color2, rx || 0, rz || 0, seg), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
|
|
4845
5124
|
}
|
|
4846
5125
|
const PE = Math.PI / 2;
|
|
4847
5126
|
Object.assign(K, { MATERIAL_MAP: MATERIAL_MAP2, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE });
|
|
@@ -5016,13 +5295,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5016
5295
|
lb("metal", 0, h - 0.23, d / 2 + 0.04, w - 0.12, 0.02, 0.02, 10526880);
|
|
5017
5296
|
},
|
|
5018
5297
|
kitchen_cabinet(M, A, o = {}) {
|
|
5019
|
-
const { b: lb, c: lc } = kk(M, A), w = M.w, d = M.d, h = M.h || 0.95,
|
|
5020
|
-
lb("plain", 0, 0.08, -0.02, w, h - 0.15, d - 0.05,
|
|
5298
|
+
const { b: lb, c: lc } = kk(M, A), w = M.w, d = M.d, h = M.h || 0.95, color2 = paletteColor(M, "wall_kitchen", 15262420), wood = paletteColor(M, "wood", 11571296);
|
|
5299
|
+
lb("plain", 0, 0.08, -0.02, w, h - 0.15, d - 0.05, color2);
|
|
5021
5300
|
lb("plain", 0, 0, 0, w - 0.04, 0.08, d - 0.12, 2763306);
|
|
5022
5301
|
const nd = Math.max(2, Math.round(w / 0.55));
|
|
5023
5302
|
for (let k = 0; k < nd; k++) {
|
|
5024
5303
|
const u = -w / 2 + (k + 0.5) * w / nd;
|
|
5025
|
-
lb("plain", u, 0.12, d / 2 - 0.02, w / nd - 0.03, h - 0.28, 0.02, sh(
|
|
5304
|
+
lb("plain", u, 0.12, d / 2 - 0.02, w / nd - 0.03, h - 0.28, 0.02, sh(color2, 1.06));
|
|
5026
5305
|
lb("metal", u + (k % 2 ? -0.2 : 0.2) * (w / nd), h * 0.62, d / 2, 0.012, 0.12, 0.015, 9079434);
|
|
5027
5306
|
}
|
|
5028
5307
|
if (o.noBasin) lb("plain", 0, h - 0.07, 0, w + 0.03, 0.035, d + 0.03, 4868164);
|
|
@@ -5044,13 +5323,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5044
5323
|
}
|
|
5045
5324
|
if (!o.noOverhead && (M.overhead === true || M.overhead == null && w >= 1.2)) {
|
|
5046
5325
|
const ya = 1.55;
|
|
5047
|
-
lb("plain", 0, ya, -d / 2 + 0.18, w, 0.6, 0.35,
|
|
5048
|
-
for (let k = 0; k < 3; k++) lb("plain", -w / 2 + (k + 0.5) * w / 3, ya + 0.02, -d / 2 + 0.36, w / 3 - 0.03, 0.56, 0.015, sh(
|
|
5326
|
+
lb("plain", 0, ya, -d / 2 + 0.18, w, 0.6, 0.35, color2);
|
|
5327
|
+
for (let k = 0; k < 3; k++) lb("plain", -w / 2 + (k + 0.5) * w / 3, ya + 0.02, -d / 2 + 0.36, w / 3 - 0.03, 0.56, 0.015, sh(color2, 1.06));
|
|
5049
5328
|
}
|
|
5050
5329
|
},
|
|
5051
5330
|
counter(M, A, o = {}) {
|
|
5052
|
-
const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h,
|
|
5053
|
-
lb("plain", 0, 0, 0, w, h * (o.glass ? 0.45 : 1) - 0.04, d,
|
|
5331
|
+
const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, color2 = o.color != null ? o.color : paletteColor(M, "wood", 9071176), top = o.top != null ? o.top : 14210252;
|
|
5332
|
+
lb("plain", 0, 0, 0, w, h * (o.glass ? 0.45 : 1) - 0.04, d, color2);
|
|
5054
5333
|
lb("plain", 0, h * (o.glass ? 0.45 : 1) - 0.04, 0, w + 0.03, 0.04, d + 0.03, top);
|
|
5055
5334
|
if (o.glass) {
|
|
5056
5335
|
lb("glass", 0, h * 0.45, 0, w - 0.04, h * 0.55, d - 0.04, 16777215);
|
|
@@ -5320,9 +5599,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5320
5599
|
lb("glass", w * 0.28, 1, d / 2 + 0.01, 0.8, 0.9, 0.02, 16777215);
|
|
5321
5600
|
},
|
|
5322
5601
|
motorcycle(M, A) {
|
|
5323
|
-
const { b: lb, c: lc } = kk(M, A), d = M.d,
|
|
5602
|
+
const { b: lb, c: lc } = kk(M, A), d = M.d, color2 = M.color != null ? M.color : 11024948;
|
|
5324
5603
|
for (const s of [-1, 1]) lc("plain", 0, 0.3, s * d * 0.34, 0.3, 0.12, 1710618, 0, PE);
|
|
5325
|
-
lb("plain", 0, 0.35, 0, 0.18, 0.28, d * 0.5,
|
|
5604
|
+
lb("plain", 0, 0.35, 0, 0.18, 0.28, d * 0.5, color2);
|
|
5326
5605
|
lb("plain", 0, 0.62, -0.1, 0.22, 0.1, 0.6, 2236962);
|
|
5327
5606
|
lb("metal", 0, 0.7, d * 0.28, 0.5, 0.04, 0.04, 11580600);
|
|
5328
5607
|
},
|
|
@@ -5667,13 +5946,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5667
5946
|
};
|
|
5668
5947
|
FURNITURE.curtain = function(M, A) {
|
|
5669
5948
|
const w = M.w || 1.6, h = M.h || 2.3, y = M.y != null && M.y > 0 ? M.y : 0.1, K2 = kit2(M, A, 0), top = y + h;
|
|
5670
|
-
const rnd = rngString(SEED() + "|" + seedKey(M.seed) + "|cort"),
|
|
5949
|
+
const rnd = rngString(SEED() + "|" + seedKey(M.seed) + "|cort"), color2 = M.color != null ? M.color : [14208436, 10465470, 12953740, 14736592][rnd() * 4 | 0], gold = M.palette && M.palette.metal != null ? M.palette.metal : 5918792;
|
|
5671
5950
|
K2.t("metal", [-w / 2 - 0.05, top + 0.02, 0], [w / 2 + 0.05, top + 0.02, 0], 0.012, gold);
|
|
5672
5951
|
for (const s of [-1, 1]) K2.e("metal", s * (w / 2 + 0.07), top + 0.02, 0, 0.022, 0.045, gold);
|
|
5673
5952
|
const pw = w / 2 + 0.03, n = Math.max(8, Math.round(pw / 0.075));
|
|
5674
5953
|
for (const s of [-1, 1]) for (let i = 0; i < n; i++) {
|
|
5675
5954
|
const ux = s * (i + 0.5) * pw / n;
|
|
5676
|
-
K2.b("fabric", ux, y, i % 2 ? 0.03 : -0.012, pw / n * 1.12, h - 0.04, 0.018, i % 2 ? sh(
|
|
5955
|
+
K2.b("fabric", ux, y, i % 2 ? 0.03 : -0.012, pw / n * 1.12, h - 0.04, 0.018, i % 2 ? sh(color2, 0.88) : color2);
|
|
5677
5956
|
}
|
|
5678
5957
|
for (const s of [-1, 1]) for (let i = 0; i < n; i += 2) K2.e("metal", s * (i + 0.5) * pw / n, top + 0.012, 0, 0.012, 0.024, gold);
|
|
5679
5958
|
};
|
|
@@ -5696,15 +5975,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5696
5975
|
}
|
|
5697
5976
|
}
|
|
5698
5977
|
}
|
|
5699
|
-
function potModel(K2, x, y, z, r, h,
|
|
5978
|
+
function potModel(K2, x, y, z, r, h, color2, soil = true) {
|
|
5700
5979
|
const rimR = r * 1.1;
|
|
5701
|
-
K2.c("plain", x, y, z, r * 0.62, h * 0.55, sh(
|
|
5702
|
-
K2.c("plain", x, y + h * 0.5, z, r * 0.84, h * 0.34,
|
|
5703
|
-
K2.c("plain", x, y + h * 0.82, z, rimR, h * 0.18, sh(
|
|
5980
|
+
K2.c("plain", x, y, z, r * 0.62, h * 0.55, sh(color2, 0.92));
|
|
5981
|
+
K2.c("plain", x, y + h * 0.5, z, r * 0.84, h * 0.34, color2);
|
|
5982
|
+
K2.c("plain", x, y + h * 0.82, z, rimR, h * 0.18, sh(color2, 1.08));
|
|
5704
5983
|
if (soil) K2.c("plain", x, y + h * 0.995, z, r * 0.92, h * 0.012, 3811870);
|
|
5705
5984
|
return y + h;
|
|
5706
5985
|
}
|
|
5707
|
-
function arcLeaf(K2, bx_, by, bz, az, len, elev, drop, wmax,
|
|
5986
|
+
function arcLeaf(K2, bx_, by, bz, az, len, elev, drop, wmax, color2, serrated, nSeg = 6) {
|
|
5708
5987
|
const c = Math.cos(az), s = Math.sin(az), pts = [];
|
|
5709
5988
|
for (let i = 0; i <= nSeg; i++) {
|
|
5710
5989
|
const f = i / nSeg, d = f * len;
|
|
@@ -5713,14 +5992,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5713
5992
|
const px = -s, pz = c;
|
|
5714
5993
|
for (let i = 0; i < nSeg; i++) {
|
|
5715
5994
|
const f0 = i / nSeg, f1 = (i + 1) / nSeg, w0 = wmax * Math.sin(Math.PI * Math.min(1, f0 * 0.85 + 0.12)) * (serrated && i % 2 ? 0.7 : 1), w1 = wmax * Math.sin(Math.PI * Math.min(1, f1 * 0.85 + 0.12)) * (serrated && i % 2 ? 1 : 0.7), dn = 0.35;
|
|
5716
|
-
for (const sd of [-1, 1]) K2.polyFace("plant", [pts[i], pts[i + 1], [pts[i + 1][0] + px * sd * w1, pts[i + 1][1] - w1 * dn, pts[i + 1][2] + pz * sd * w1], [pts[i][0] + px * sd * w0, pts[i][1] - w0 * dn, pts[i][2] + pz * sd * w0]], i % 2 ? sh(
|
|
5995
|
+
for (const sd of [-1, 1]) K2.polyFace("plant", [pts[i], pts[i + 1], [pts[i + 1][0] + px * sd * w1, pts[i + 1][1] - w1 * dn, pts[i + 1][2] + pz * sd * w1], [pts[i][0] + px * sd * w0, pts[i][1] - w0 * dn, pts[i][2] + pz * sd * w0]], i % 2 ? sh(color2, 0.9) : color2, [0, 1, 0]);
|
|
5717
5996
|
}
|
|
5718
5997
|
return pts[nSeg];
|
|
5719
5998
|
}
|
|
5720
|
-
function tuft(K2, x, y, z, r, n,
|
|
5999
|
+
function tuft(K2, x, y, z, r, n, color2, rnd) {
|
|
5721
6000
|
for (let i = 0; i < n; i++) {
|
|
5722
6001
|
const a = rnd() * 6.283, d0 = rnd() * r * 0.35, L = r * (0.8 + rnd() * 1.1), bw = 0.012 + rnd() * 8e-3, lean = 0.25 + rnd() * 0.5, c = Math.cos(a), s = Math.sin(a), px = -s, pz = c, x0 = x + c * d0, z0 = z + s * d0;
|
|
5723
|
-
const m = [x0 + c * lean * L * 0.35, y + L * 0.55, z0 + s * lean * L * 0.35], t = [x0 + c * lean * L, y + L * (0.95 - lean * 0.2), z0 + s * lean * L], vc = sh(
|
|
6002
|
+
const m = [x0 + c * lean * L * 0.35, y + L * 0.55, z0 + s * lean * L * 0.35], t = [x0 + c * lean * L, y + L * (0.95 - lean * 0.2), z0 + s * lean * L], vc = sh(color2, 0.78 + rnd() * 0.4);
|
|
5724
6003
|
K2.polyFace("plant", [[x0 - px * bw, y, z0 - pz * bw], [x0 + px * bw, y, z0 + pz * bw], [m[0] + px * bw * 0.6, m[1], m[2] + pz * bw * 0.6], t, [m[0] - px * bw * 0.6, m[1], m[2] - pz * bw * 0.6]], vc, [0, 1, 0]);
|
|
5725
6004
|
}
|
|
5726
6005
|
}
|
|
@@ -5811,31 +6090,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5811
6090
|
const seedKey = (id) => K.seedKey(id);
|
|
5812
6091
|
const { FURNITURE, SEED, STYLE, kit2, rngString, sh, wallTap } = K;
|
|
5813
6092
|
FURNITURE.laundry_tub = function(M, A) {
|
|
5814
|
-
const K2 = kit2(M, A), w = M.w || 0.6, d = M.d || 0.55, H = M.h || 0.9, structure = STYLE(), upper = structure === "budget",
|
|
6093
|
+
const K2 = kit2(M, A), w = M.w || 0.6, d = M.d || 0.55, H = M.h || 0.9, structure = STYLE(), upper = structure === "budget", color2 = upper ? 11841700 : 15790058, int2 = upper ? 10134694 : 14870248, rim = sh(color2, 1.06);
|
|
5815
6094
|
const yb = H - 0.36, t = 0.04, rc = 0.055, zw = -d / 2;
|
|
5816
|
-
for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), yb, sz * (d / 2 - rc), rc, 0.36,
|
|
5817
|
-
K2.b("plain", 0, yb, d / 2 - t / 2, w - 2 * rc + 0.01, 0.36, t,
|
|
5818
|
-
K2.b("plain", 0, yb, -d / 2 + t / 2, w - 2 * rc + 0.01, 0.36, t,
|
|
5819
|
-
K2.b("plain", -w / 2 + t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01,
|
|
5820
|
-
K2.b("plain", w / 2 - t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01,
|
|
5821
|
-
K2.b("plain", 0, yb, 0, w - 2 * t, 0.06, d - 2 * t,
|
|
6095
|
+
for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), yb, sz * (d / 2 - rc), rc, 0.36, color2);
|
|
6096
|
+
K2.b("plain", 0, yb, d / 2 - t / 2, w - 2 * rc + 0.01, 0.36, t, color2);
|
|
6097
|
+
K2.b("plain", 0, yb, -d / 2 + t / 2, w - 2 * rc + 0.01, 0.36, t, color2);
|
|
6098
|
+
K2.b("plain", -w / 2 + t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color2);
|
|
6099
|
+
K2.b("plain", w / 2 - t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color2);
|
|
6100
|
+
K2.b("plain", 0, yb, 0, w - 2 * t, 0.06, d - 2 * t, int2);
|
|
5822
6101
|
for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), H - 4e-3, sz * (d / 2 - rc), rc + 8e-3, 0.012, rim);
|
|
5823
6102
|
K2.b("plain", 0, H - 4e-3, d / 2 - 0.011, w - 2 * rc, 0.012, 0.022, rim);
|
|
5824
6103
|
K2.b("plain", 0, H - 4e-3, -d / 2 + 0.011, w - 2 * rc, 0.012, 0.022, rim);
|
|
5825
6104
|
K2.b("plain", -w / 2 + 0.011, H - 4e-3, 0, 0.022, 0.012, d - 2 * rc, rim);
|
|
5826
6105
|
K2.b("plain", w / 2 - 0.011, H - 4e-3, 0, 0.022, 0.012, d - 2 * rc, rim);
|
|
5827
6106
|
const tw = Math.min(0.2, w * 0.34), tx = -w / 2 + t + tw / 2 + 0.01, zt1 = d / 2 - t - 0.01, zt0 = -d / 2 + t + 0.08, ytop = H - 0.03, ybot = yb + 0.14, L = Math.hypot(zt1 - zt0, ytop - ybot), al = Math.atan2(ytop - ybot, zt1 - zt0);
|
|
5828
|
-
K2.b("plain", tx, (ytop + ybot) / 2 - 0.015, (zt0 + zt1) / 2, tw, 0.03, L, sh(
|
|
6107
|
+
K2.b("plain", tx, (ytop + ybot) / 2 - 0.015, (zt0 + zt1) / 2, tw, 0.03, L, sh(color2, 0.96), 0, -al, 0);
|
|
5829
6108
|
const nr = 7;
|
|
5830
6109
|
for (let i = 0; i < nr; i++) {
|
|
5831
6110
|
const f = (i + 0.5) / nr, zz = zt0 + (zt1 - zt0) * f, yy = ybot + (ytop - ybot) * f;
|
|
5832
|
-
K2.b("plain", tx, yy + 3e-3, zz, tw - 0.02, 0.014, 0.018, sh(
|
|
6111
|
+
K2.b("plain", tx, yy + 3e-3, zz, tw - 0.02, 0.014, 0.018, sh(color2, 0.88), 0, -al, 0);
|
|
5833
6112
|
}
|
|
5834
6113
|
K2.c("metal", 0.1, yb + 0.06, 0, 0.034, 8e-3, 11580600);
|
|
5835
6114
|
K2.c("plain", 0.1, yb + 0.068, 0, 0.026, 0.01, 3817026);
|
|
5836
6115
|
if (upper) {
|
|
5837
|
-
for (const sx of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.035), 0, 0, 0.07, yb, d - 0.05, sh(
|
|
5838
|
-
K2.b("plain", 0, yb - 0.04, 0, w - 0.1, 0.04, d - 0.06, sh(
|
|
6116
|
+
for (const sx of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.035), 0, 0, 0.07, yb, d - 0.05, sh(color2, 0.94));
|
|
6117
|
+
K2.b("plain", 0, yb - 0.04, 0, w - 0.1, 0.04, d - 0.06, sh(color2, 0.9));
|
|
5839
6118
|
} else for (const sx of [-1, 1]) for (const sz of [-1, 1]) {
|
|
5840
6119
|
K2.c("metal", sx * (w / 2 - 0.07), 0, sz * (d / 2 - 0.07), 0.022, yb, 11843772);
|
|
5841
6120
|
K2.c("metal", sx * (w / 2 - 0.07), 0, sz * (d / 2 - 0.07), 0.03, 0.012, 6975090);
|
|
@@ -5843,30 +6122,30 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5843
6122
|
wallTap(K2, 0, H + 0.14, zw + 0, 1, yb + 0.06, { laundry_tub: true });
|
|
5844
6123
|
};
|
|
5845
6124
|
const CLOTHES_COLORS = [14209208, 4876938, 12077114, 15262936, 6982234, 14856266, 9067146, 3099242, 13925002, 8038072];
|
|
5846
|
-
function strip(K2, rows, zc, rot,
|
|
6125
|
+
function strip(K2, rows, zc, rot, color2, cx) {
|
|
5847
6126
|
const c = Math.cos(rot), s = Math.sin(rot), P = (x, y) => [cx + (x - cx) * c, y, zc + (x - cx) * s];
|
|
5848
6127
|
for (let i = 0; i < rows.length - 1; i++) {
|
|
5849
6128
|
const a = rows[i], b = rows[i + 1];
|
|
5850
|
-
K2.polyFace("clothes", [P(a[1], a[0]), P(a[2], a[0]), P(b[2], b[0]), P(b[1], b[0])], i % 2 ? sh(
|
|
6129
|
+
K2.polyFace("clothes", [P(a[1], a[0]), P(a[2], a[0]), P(b[2], b[0]), P(b[1], b[0])], i % 2 ? sh(color2, 0.96) : color2, [0, 0, 1]);
|
|
5851
6130
|
}
|
|
5852
6131
|
}
|
|
5853
|
-
function garment(K2, type, cx, ly, zc, rot,
|
|
6132
|
+
function garment(K2, type, cx, ly, zc, rot, color2, rnd) {
|
|
5854
6133
|
const sh0 = (rows, dx = 0) => rows.map((r) => [ly + r[0], cx + dx + r[1], cx + dx + r[2]]);
|
|
5855
|
-
if (type === "shirt") strip(K2, sh0([[0, -0.13, 0.13], [-0.03, -0.27, 0.27], [-0.15, -0.3, 0.3], [-0.2, -0.2, 0.2], [-0.62, -0.2, 0.2], [-0.63, -0.2, 0.2]]), zc, rot,
|
|
6134
|
+
if (type === "shirt") strip(K2, sh0([[0, -0.13, 0.13], [-0.03, -0.27, 0.27], [-0.15, -0.3, 0.3], [-0.2, -0.2, 0.2], [-0.62, -0.2, 0.2], [-0.63, -0.2, 0.2]]), zc, rot, color2, cx);
|
|
5856
6135
|
else if (type === "trousers") {
|
|
5857
|
-
strip(K2, sh0([[0, -0.19, -0.01], [-0.4, -0.18, -0.02], [-0.78, -0.16, -0.03], [-0.79, -0.16, -0.03]]), zc, rot,
|
|
5858
|
-
strip(K2, sh0([[0, 0.01, 0.19], [-0.4, 0.02, 0.18], [-0.78, 0.03, 0.16], [-0.79, 0.03, 0.16]]), zc, rot, sh(
|
|
6136
|
+
strip(K2, sh0([[0, -0.19, -0.01], [-0.4, -0.18, -0.02], [-0.78, -0.16, -0.03], [-0.79, -0.16, -0.03]]), zc, rot, color2, cx);
|
|
6137
|
+
strip(K2, sh0([[0, 0.01, 0.19], [-0.4, 0.02, 0.18], [-0.78, 0.03, 0.16], [-0.79, 0.03, 0.16]]), zc, rot, sh(color2, 0.95), cx);
|
|
5859
6138
|
} else if (type === "shorts") {
|
|
5860
|
-
strip(K2, sh0([[0, -0.2, -0.01], [-0.3, -0.2, -0.02], [-0.31, -0.2, -0.02]]), zc, rot,
|
|
5861
|
-
strip(K2, sh0([[0, 0.01, 0.2], [-0.3, 0.02, 0.2], [-0.31, 0.02, 0.2]]), zc, rot, sh(
|
|
6139
|
+
strip(K2, sh0([[0, -0.2, -0.01], [-0.3, -0.2, -0.02], [-0.31, -0.2, -0.02]]), zc, rot, color2, cx);
|
|
6140
|
+
strip(K2, sh0([[0, 0.01, 0.2], [-0.3, 0.02, 0.2], [-0.31, 0.02, 0.2]]), zc, rot, sh(color2, 0.95), cx);
|
|
5862
6141
|
} else if (type === "towel") {
|
|
5863
|
-
strip(K2, sh0([[0, -0.32, 0.32], [-0.2, -0.32, 0.32], [-0.22, -0.32, 0.32], [-0.5, -0.32, 0.32], [-0.9, -0.32, 0.32], [-0.91, -0.32, 0.32]]), zc, rot,
|
|
5864
|
-
strip(K2, sh0([[-0.22, -0.32, 0.32], [-0.3, -0.32, 0.32]]), zc, rot, sh(
|
|
5865
|
-
} else if (type === "sheet") strip(K2, sh0([[0, -0.5, 0.5], [-0.35, -0.5, 0.5], [-0.7, -0.5, 0.5], [-1.05, -0.5, 0.5], [-1.06, -0.5, 0.5]]), zc, rot,
|
|
5866
|
-
else if (type === "dress") strip(K2, sh0([[0, -0.14, 0.14], [-0.06, -0.2, 0.2], [-0.3, -0.16, 0.16], [-0.62, -0.28, 0.28], [-0.63, -0.28, 0.28]]), zc, rot,
|
|
6142
|
+
strip(K2, sh0([[0, -0.32, 0.32], [-0.2, -0.32, 0.32], [-0.22, -0.32, 0.32], [-0.5, -0.32, 0.32], [-0.9, -0.32, 0.32], [-0.91, -0.32, 0.32]]), zc, rot, color2, cx);
|
|
6143
|
+
strip(K2, sh0([[-0.22, -0.32, 0.32], [-0.3, -0.32, 0.32]]), zc, rot, sh(color2, 1.25), cx);
|
|
6144
|
+
} else if (type === "sheet") strip(K2, sh0([[0, -0.5, 0.5], [-0.35, -0.5, 0.5], [-0.7, -0.5, 0.5], [-1.05, -0.5, 0.5], [-1.06, -0.5, 0.5]]), zc, rot, color2, cx);
|
|
6145
|
+
else if (type === "dress") strip(K2, sh0([[0, -0.14, 0.14], [-0.06, -0.2, 0.2], [-0.3, -0.16, 0.16], [-0.62, -0.28, 0.28], [-0.63, -0.28, 0.28]]), zc, rot, color2, cx);
|
|
5867
6146
|
else {
|
|
5868
|
-
strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], -0.06), zc, rot,
|
|
5869
|
-
strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], 0.06), zc, rot, sh(
|
|
6147
|
+
strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], -0.06), zc, rot, color2, cx);
|
|
6148
|
+
strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], 0.06), zc, rot, sh(color2, 0.9), cx);
|
|
5870
6149
|
}
|
|
5871
6150
|
K2.b("plain", cx - 0.05, ly - 0.02, zc, 0.018, 0.05, 0.016, 15261896);
|
|
5872
6151
|
K2.b("plain", cx + 0.05, ly - 0.02, zc, 0.018, 0.05, 0.016, 13125690);
|
|
@@ -5900,7 +6179,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5900
6179
|
(shared.ctx.clotheslines || (shared.ctx.clotheslines = [])).push(M.seed);
|
|
5901
6180
|
};
|
|
5902
6181
|
FURNITURE.water_tank = function(M, A) {
|
|
5903
|
-
const K2 = kit2(M, A), w = M.w || 1, d = M.d || 1, onGround = !M.onSlab && (M.y || 0) < 0.5,
|
|
6182
|
+
const K2 = kit2(M, A), w = M.w || 1, d = M.d || 1, onGround = !M.onSlab && (M.y || 0) < 0.5, color2 = M.palette && M.palette.tank_water != null ? M.palette.tank_water : 3107496, r = Math.min(w, d) * 0.46, rc = 11841700;
|
|
5904
6183
|
let y0 = 0;
|
|
5905
6184
|
if (onGround) {
|
|
5906
6185
|
for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.08), 0, sz * (d / 2 - 0.08), 0.14, 1, 0.14, rc);
|
|
@@ -5912,10 +6191,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5912
6191
|
}
|
|
5913
6192
|
const H = Math.max(0.7, (M.h || 1.8) - (onGround ? 1.12 : 0.1) - 0), th = Math.min(0.95, H * 0.88);
|
|
5914
6193
|
K2.part("water_tank", 0, y0, 0, () => {
|
|
5915
|
-
K2.c("plain", 0, y0, 0, r, th,
|
|
5916
|
-
for (const f of [0.18, 0.5, 0.82]) K2.c("plain", 0, y0 + th * f - 0.025, 0, r * 1.028, 0.05, sh(
|
|
5917
|
-
K2.e("plain", 0, y0 + th + 0.03, 0, r * 1, 0.16, sh(
|
|
5918
|
-
K2.c("plain", 0, y0 + th + 0.09, 0, r * 0.5, 0.05, sh(
|
|
6194
|
+
K2.c("plain", 0, y0, 0, r, th, color2);
|
|
6195
|
+
for (const f of [0.18, 0.5, 0.82]) K2.c("plain", 0, y0 + th * f - 0.025, 0, r * 1.028, 0.05, sh(color2, 0.88));
|
|
6196
|
+
K2.e("plain", 0, y0 + th + 0.03, 0, r * 1, 0.16, sh(color2, 0.95));
|
|
6197
|
+
K2.c("plain", 0, y0 + th + 0.09, 0, r * 0.5, 0.05, sh(color2, 0.8));
|
|
5919
6198
|
K2.c("plain", 0, y0 + th + 0.14, 0, r * 0.18, 0.035, 1916262);
|
|
5920
6199
|
}, { id: "tank_" + M.seed, breakable: true, fluid: "water", volume: Math.PI * r * r * th, radius: r, height: th });
|
|
5921
6200
|
K2.t("metal", [r * 0.7, y0 + th * 0.25, 0], [r * 0.7, y0 + 0.03, 0], 0.02, 3159096);
|
|
@@ -5924,13 +6203,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5924
6203
|
K2.t("metal", [-r * 0.5, y0 + th + 0.35, 0], [-r * 0.2, y0 + th + 0.35, 0], 0.014, 2763306);
|
|
5925
6204
|
};
|
|
5926
6205
|
FURNITURE.cooking_gas_cylinder = function(M, A) {
|
|
5927
|
-
const K2 = kit2(M, A), r = Math.min(M.w || 0.36, M.d || 0.36) / 2, H = M.h || 0.47,
|
|
6206
|
+
const K2 = kit2(M, A), r = Math.min(M.w || 0.36, M.d || 0.36) / 2, H = M.h || 0.47, color2 = 4157096, scale = sh(color2, 0.7), brass = 13214282, c = Math.cos(M.ry || 0), s = Math.sin(M.ry || 0);
|
|
5928
6207
|
K2.part("gas_cylinder", 0, 0, 0, () => {
|
|
5929
6208
|
K2.c("plain", 0, 0, 0, r * 0.88, 0.05, scale);
|
|
5930
|
-
K2.c("plain", 0, 0.04, 0, r, H * 0.5,
|
|
5931
|
-
K2.e("plain", 0, 0.04 + H * 0.5, 0, r * 0.99, 0.08, sh(
|
|
6209
|
+
K2.c("plain", 0, 0.04, 0, r, H * 0.5, color2);
|
|
6210
|
+
K2.e("plain", 0, 0.04 + H * 0.5, 0, r * 0.99, 0.08, sh(color2, 0.9));
|
|
5932
6211
|
K2.c("plain", 0, H * 0.5 + 0.04, 0, r * 1.012, 0.018, scale);
|
|
5933
|
-
K2.e("plain", 0, H * 0.77, 0, r * 0.98, H * 0.36,
|
|
6212
|
+
K2.e("plain", 0, H * 0.77, 0, r * 0.98, H * 0.36, color2);
|
|
5934
6213
|
K2.c("metal", 0, H * 0.86, 0, 0.05, 0.05, 9080466);
|
|
5935
6214
|
for (let k = 0; k < 3; k++) {
|
|
5936
6215
|
const a = k * 2.0944 + 0.5, x = Math.cos(a) * r * 0.62, z = Math.sin(a) * r * 0.62;
|
|
@@ -5989,8 +6268,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
5989
6268
|
function extraTypes(T2, props) {
|
|
5990
6269
|
const origCar = T2.garage_car;
|
|
5991
6270
|
const car = (M, A) => {
|
|
5992
|
-
const structure = STYLE(),
|
|
5993
|
-
const k =
|
|
6271
|
+
const structure = STYLE(), list2 = CAR_BY_STYLE[structure] || CAR_BY_STYLE.mid, r = rngString(SEED() + "|" + (seedKey(M.seed) || M.id || "") + "|" + Math.round((M.x || 0) * 10) + "|" + Math.round((M.z || 0) * 10) + "|carro");
|
|
6272
|
+
const k = list2[Math.floor(r() * list2.length)], paint = 1 + Math.floor(r() * 8);
|
|
5994
6273
|
if (!carModel(k, paint)) {
|
|
5995
6274
|
if (origCar) origCar.f(M, A);
|
|
5996
6275
|
return;
|
|
@@ -6050,14 +6329,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6050
6329
|
const vegItem = (...a) => K.vegItem(...a);
|
|
6051
6330
|
function houseItems() {
|
|
6052
6331
|
const R = shared.ctx.r, T2 = shared.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
|
|
6053
|
-
const
|
|
6332
|
+
const list2 = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
|
|
6054
6333
|
const rect = (poly) => {
|
|
6055
6334
|
let a = 0;
|
|
6056
6335
|
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) a += poly[j][0] * poly[i][1] - poly[i][0] * poly[j][1];
|
|
6057
6336
|
const xs = poly.map((p) => p[0]), zs = poly.map((p) => p[1]);
|
|
6058
6337
|
return Math.abs(a) / 2 > 0.98 * (Math.max(...xs) - Math.min(...xs)) * (Math.max(...zs) - Math.min(...zs));
|
|
6059
6338
|
};
|
|
6060
|
-
for (const m of
|
|
6339
|
+
for (const m of list2) {
|
|
6061
6340
|
if (m.type === "stairs") continue;
|
|
6062
6341
|
const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
|
|
6063
6342
|
cursor.group = exterior ? "lot" : "f" + f;
|
|
@@ -6111,19 +6390,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6111
6390
|
const base = lc ? cd.platform.topY : cd.y + (shared.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
|
|
6112
6391
|
cursor.group = slab ? "f" + f : "attic_tank";
|
|
6113
6392
|
if (lc) {
|
|
6114
|
-
const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness,
|
|
6393
|
+
const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668;
|
|
6115
6394
|
cursor.pc = structurePiece("tank_slab");
|
|
6116
|
-
boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0,
|
|
6395
|
+
boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color2, 0, 0, 0);
|
|
6117
6396
|
P.pillars.forEach((p, k) => {
|
|
6118
6397
|
cursor.pc = structurePiece("tank_column_" + k);
|
|
6119
|
-
boxC("plain", p.u, (P.baseY + P.topY - e) / 2, p.v, p.side, P.topY - e - P.baseY, p.side,
|
|
6398
|
+
boxC("plain", p.u, (P.baseY + P.topY - e) / 2, p.v, p.side, P.topY - e - P.baseY, p.side, color2, 0, 0, 0);
|
|
6120
6399
|
});
|
|
6121
6400
|
cursor.pc = null;
|
|
6122
6401
|
}
|
|
6123
6402
|
if (!slab) {
|
|
6124
|
-
const
|
|
6125
|
-
boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2,
|
|
6126
|
-
for (const sx of [-1, 1]) for (const sz of [-1, 1]) boxC("plain", cd.u + sx * (hw - 0.07), (yp + base - 0.12) / 2, cd.v + sz * (hd - 0.07), 0.1, base - 0.12 - yp, 0.1,
|
|
6403
|
+
const color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
|
|
6404
|
+
boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color2);
|
|
6405
|
+
for (const sx of [-1, 1]) for (const sz of [-1, 1]) boxC("plain", cd.u + sx * (hw - 0.07), (yp + base - 0.12) / 2, cd.v + sz * (hd - 0.07), 0.1, base - 0.12 - yp, 0.1, color2);
|
|
6127
6406
|
}
|
|
6128
6407
|
const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
|
|
6129
6408
|
shared.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
|
|
@@ -6135,8 +6414,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6135
6414
|
return _col.setHSL((h >>> 0) % 360 / 360, 0.45, 0.55).getHex();
|
|
6136
6415
|
}
|
|
6137
6416
|
function labeledBox(m, M, group) {
|
|
6138
|
-
const
|
|
6139
|
-
boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d,
|
|
6417
|
+
const color2 = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
|
|
6418
|
+
boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
|
|
6140
6419
|
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" });
|
|
6141
6420
|
}
|
|
6142
6421
|
Object.assign(K, { houseItems, waterTankOfHouse, hashColor, labeledBox });
|
|
@@ -6650,10 +6929,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6650
6929
|
if (!lt) return;
|
|
6651
6930
|
const cz0 = (lt.rect[1] + lt.rect[3]) / 2;
|
|
6652
6931
|
const orig = K.getBx(), gs = lt.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
|
|
6653
|
-
const
|
|
6654
|
-
return { g, a, b, v: g.v, x0: Infinity, x1: -Infinity, y1: 0, color, dx, zc, lo:
|
|
6932
|
+
const color2 = g.model === "sliding", dx = color2 ? slideDirection(g, lt) : 0, a = g.u - g.width / 2, b = g.u + g.width / 2, zc = g.v + (cz0 - g.v >= 0 ? 1 : -1) * 0.19;
|
|
6933
|
+
return { g, a, b, v: g.v, x0: Infinity, x1: -Infinity, y1: 0, color: color2, dx, zc, lo: color2 ? dx > 0 ? a + 0.04 : a - 0.9 : a + 0.05, hi: color2 ? dx > 0 ? b + 0.9 + 0.01 : b - 0.04 : b + 0.01, zv: color2 ? 0.07 : 0.04, zm: color2 ? zc : g.v };
|
|
6655
6934
|
});
|
|
6656
|
-
K.setBx(function(mat, x0, y0, z0, x1, y1, z1,
|
|
6935
|
+
K.setBx(function(mat, x0, y0, z0, x1, y1, z1, color2) {
|
|
6657
6936
|
if (mat === "metal") {
|
|
6658
6937
|
for (const r of reg) if (r.g.axis === "u" && x0 >= r.lo && x1 <= r.hi && z0 >= r.zm - r.zv && z1 <= r.zm + r.zv && y0 >= 0.03) {
|
|
6659
6938
|
r.x0 = Math.min(r.x0, x0);
|
|
@@ -6661,12 +6940,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6661
6940
|
r.y1 = Math.max(r.y1, y1);
|
|
6662
6941
|
const g0 = cursor.group;
|
|
6663
6942
|
cursor.group = "ix:gate:" + r.g.id;
|
|
6664
|
-
orig(mat, x0, y0, z0, x1, y1, z1,
|
|
6943
|
+
orig(mat, x0, y0, z0, x1, y1, z1, color2);
|
|
6665
6944
|
cursor.group = g0;
|
|
6666
6945
|
return;
|
|
6667
6946
|
}
|
|
6668
6947
|
}
|
|
6669
|
-
return orig(mat, x0, y0, z0, x1, y1, z1,
|
|
6948
|
+
return orig(mat, x0, y0, z0, x1, y1, z1, color2);
|
|
6670
6949
|
});
|
|
6671
6950
|
const n0 = shared.ctx.colliders.length;
|
|
6672
6951
|
try {
|
|
@@ -6741,10 +7020,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6741
7020
|
else bx("plain", Math.min(f2, f3), yc - 0.032, u - 0.016, Math.max(f2, f3), yc + 0.032, u + 0.016, 16250092);
|
|
6742
7021
|
cursor.group = g0;
|
|
6743
7022
|
const pv = alongU ? [u, yc, f2] : [f2, yc, u];
|
|
6744
|
-
const
|
|
6745
|
-
|
|
7023
|
+
const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
|
|
7024
|
+
piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
|
|
6746
7025
|
const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
|
|
6747
|
-
shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [
|
|
7026
|
+
shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
|
|
6748
7027
|
return true;
|
|
6749
7028
|
}
|
|
6750
7029
|
return false;
|
|
@@ -6914,11 +7193,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6914
7193
|
const IV_WIRE = { conduit: 13618628, cable: 2762532, drop: 1381653, cord: 1776413, earth: 3111482, hose: 11556124 };
|
|
6915
7194
|
const IV_DOOR = /^(door|drawer)/;
|
|
6916
7195
|
const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared.ctx.r.floors.length - 1);
|
|
6917
|
-
function ivAccumulate(mat, g, ox, oy, oz, ry,
|
|
6918
|
-
const P = g.attributes.position, N = g.attributes.normal, C =
|
|
7196
|
+
function ivAccumulate(mat, g, ox, oy, oz, ry, color2) {
|
|
7197
|
+
const P = g.attributes.position, N = g.attributes.normal, C = color2 == null ? g.attributes.color : null, U = g.attributes.uv, I = g.index, nv = P.count, ni = I ? I.count : nv;
|
|
6919
7198
|
const A = accFor(mat);
|
|
6920
7199
|
A.ensure(nv, ni);
|
|
6921
|
-
const c = Math.cos(ry), s = Math.sin(ry), b = A.nv, rgb =
|
|
7200
|
+
const c = Math.cos(ry), s = Math.sin(ry), b = A.nv, rgb = color2 != null ? rgbOf(color2) : [1, 1, 1];
|
|
6922
7201
|
for (let k = 0; k < nv; k++) {
|
|
6923
7202
|
const x = P.getX(k), y = P.getY(k), z = P.getZ(k), o = b + k;
|
|
6924
7203
|
A.p[o * 3] = x * c + z * s + ox;
|
|
@@ -6959,14 +7238,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6959
7238
|
function ivBuild(h, water) {
|
|
6960
7239
|
const ik = K.IVK, r = shared.ctx.r, A = ik.A, world0 = null;
|
|
6961
7240
|
void world0;
|
|
6962
|
-
const
|
|
6963
|
-
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 };
|
|
7241
|
+
const plane2 = A.plan(r, { seed: r.seed });
|
|
7242
|
+
const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
|
|
6964
7243
|
h.IV = IV;
|
|
6965
7244
|
const t0 = performance.now();
|
|
6966
|
-
const lamps = new Set(
|
|
6967
|
-
for (const id of
|
|
7245
|
+
const lamps = new Set(plane2.items.filter((e) => e.type === "lamp").map((e) => e.id));
|
|
7246
|
+
for (const id of plane2.mapped) if (!lamps.has(id)) IV.replace.add(id);
|
|
6968
7247
|
const furnitureById = new Map(r.items.map((m) => [m.id, m]));
|
|
6969
|
-
for (const e of
|
|
7248
|
+
for (const e of plane2.items) {
|
|
6970
7249
|
if (e.type !== "lamp") continue;
|
|
6971
7250
|
const m = furnitureById.get(e.id);
|
|
6972
7251
|
if (!m || !LIGHT_TYPES.has(m.type) || !m.room) continue;
|
|
@@ -6976,8 +7255,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6976
7255
|
IV.lampRoom.set(e.id, m.room);
|
|
6977
7256
|
}
|
|
6978
7257
|
const wants = (roomId) => lightBase(roomId);
|
|
6979
|
-
const entById = new Map(
|
|
6980
|
-
const entByItem = new Map(
|
|
7258
|
+
const entById = new Map(plane2.items.map((e) => [e.id, e]));
|
|
7259
|
+
const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
|
|
6981
7260
|
IV.mats = { plain: shared.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 };
|
|
6982
7261
|
const ev = (e) => ivEvent(h, e);
|
|
6983
7262
|
const world = IV.world = A.createWorld(r, { water, seed: r.seed, onEvent: ev });
|
|
@@ -6997,7 +7276,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6997
7276
|
}
|
|
6998
7277
|
return add0(id, spec, tr);
|
|
6999
7278
|
};
|
|
7000
|
-
const added = A.add(world,
|
|
7279
|
+
const added = A.add(world, plane2, { isBlocked: A.blockedOf(r), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
|
|
7001
7280
|
world.add = add0;
|
|
7002
7281
|
IV.warnings = added.warnings;
|
|
7003
7282
|
IV.added = added;
|
|
@@ -7023,7 +7302,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
7023
7302
|
console.warn("interactables: state", err);
|
|
7024
7303
|
}
|
|
7025
7304
|
}
|
|
7026
|
-
for (const e of
|
|
7305
|
+
for (const e of plane2.items) if (e.type === "wall_switch") for (const l of e.connections.controls || []) {
|
|
7027
7306
|
const roomId = IV.lampRoom.get(l);
|
|
7028
7307
|
if (roomId) {
|
|
7029
7308
|
IV.switchRooms.add(roomId);
|
|
@@ -7102,10 +7381,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
7102
7381
|
}
|
|
7103
7382
|
function ivCords(IV) {
|
|
7104
7383
|
const ik = IV.k, w = IV.world, wl = (o, p) => ik.GI.localToWorld(o.transform, p), g0 = cursor.group;
|
|
7105
|
-
const tube = (pts, radius,
|
|
7384
|
+
const tube = (pts, radius, color2, ox, oy, oz, ry) => {
|
|
7106
7385
|
try {
|
|
7107
7386
|
const m = ik.gfx.createCord(pts, radius, shared.mats.plain);
|
|
7108
|
-
ivAccumulate("plain", m.geometry, ox, oy, oz, ry,
|
|
7387
|
+
ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color2);
|
|
7109
7388
|
m.geometry.dispose();
|
|
7110
7389
|
} catch (e) {
|
|
7111
7390
|
}
|
|
@@ -7288,7 +7567,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
7288
7567
|
function ivItems(IV, h) {
|
|
7289
7568
|
IV.itemsDirty = false;
|
|
7290
7569
|
IV.itemsT = IV.t;
|
|
7291
|
-
const w = IV.world, items = IV.k.A.household.items, f = IV.focus, g0 = cursor.group,
|
|
7570
|
+
const w = IV.world, items = IV.k.A.household.items, f = IV.focus, g0 = cursor.group, list2 = [];
|
|
7292
7571
|
let fl = null;
|
|
7293
7572
|
if (f) {
|
|
7294
7573
|
h.houseGroup.updateWorldMatrix(true, false);
|
|
@@ -7302,23 +7581,23 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
7302
7581
|
if (c.access && w.partT(E.id, c.access) < 0.02) continue;
|
|
7303
7582
|
const st = w.contents(E.id, c.id);
|
|
7304
7583
|
for (let i = 0; i < st.length; i++) {
|
|
7305
|
-
if (st[i] && items[st[i].type])
|
|
7584
|
+
if (st[i] && items[st[i].type]) list2.push([E, c.id, i, items[st[i].type]]);
|
|
7306
7585
|
}
|
|
7307
7586
|
}
|
|
7308
7587
|
}
|
|
7309
|
-
if (!
|
|
7588
|
+
if (!list2.length) {
|
|
7310
7589
|
if (IV.items) IV.items.visible = false;
|
|
7311
7590
|
return;
|
|
7312
7591
|
}
|
|
7313
7592
|
cursor.group = "iv-items";
|
|
7314
7593
|
try {
|
|
7315
|
-
for (const [E, cid, slot, def] of
|
|
7594
|
+
for (const [E, cid, slot, def] of list2) {
|
|
7316
7595
|
const p = w.slotPosition(E.id, cid, slot), form = IV_SHAPE[def.shape] || IV_SHAPE.box;
|
|
7317
7596
|
for (const [geo, fx, fy, fz, y0, tone] of form) {
|
|
7318
7597
|
const sx = def.size[0] * fx, sy = def.size[1] * fy, sz = def.size[2] * fz;
|
|
7319
7598
|
_q.setFromAxisAngle(_Y, E.ry);
|
|
7320
|
-
const
|
|
7321
|
-
put("plain", geo, p[0], p[1] + def.size[1] * y0 + sy / 2, p[2], _q, sx, sy, sz, tone === 1 ?
|
|
7599
|
+
const color2 = def.color == null ? 13421772 : def.color;
|
|
7600
|
+
put("plain", geo, p[0], p[1] + def.size[1] * y0 + sy / 2, p[2], _q, sx, sy, sz, tone === 1 ? color2 : sh(color2, tone));
|
|
7322
7601
|
}
|
|
7323
7602
|
}
|
|
7324
7603
|
const A = cursor.accs.get("iv-items|plain");
|
|
@@ -7443,7 +7722,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
7443
7722
|
})),
|
|
7444
7723
|
seatInfo: () => ivSeat(IV),
|
|
7445
7724
|
// {object, seat, pose: 'sit'|'lie', eye, yaw, pitch, exit, floor} if the player is sitting/lying
|
|
7446
|
-
sit: com((
|
|
7725
|
+
sit: com((object2, seatInfo) => !!w.sit(object2, seatInfo, "player")),
|
|
7447
7726
|
stand: com(() => w.stand("player")),
|
|
7448
7727
|
opens: com((mid, target) => {
|
|
7449
7728
|
for (const E of IV.entries.values()) if (E.origin === mid) {
|
|
@@ -8091,10 +8370,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8091
8370
|
const f = (res.floors || []).find((x) => x.index === floor);
|
|
8092
8371
|
return r3(o.base + (f ? f.y0 : 0));
|
|
8093
8372
|
}
|
|
8094
|
-
function colorOf(res,
|
|
8095
|
-
if (
|
|
8096
|
-
if (typeof
|
|
8097
|
-
const v = res.colors && res.colors[
|
|
8373
|
+
function colorOf(res, color2) {
|
|
8374
|
+
if (color2 == null) return void 0;
|
|
8375
|
+
if (typeof color2 === "number") return color2;
|
|
8376
|
+
const v = res.colors && res.colors[color2];
|
|
8098
8377
|
return typeof v === "number" ? v : void 0;
|
|
8099
8378
|
}
|
|
8100
8379
|
function paletteOf(res) {
|
|
@@ -8237,8 +8516,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8237
8516
|
seed: seedOf2(m.id),
|
|
8238
8517
|
palette
|
|
8239
8518
|
};
|
|
8240
|
-
const
|
|
8241
|
-
if (
|
|
8519
|
+
const color2 = colorOf(res, m.color);
|
|
8520
|
+
if (color2 != null) item.color = color2;
|
|
8242
8521
|
return item;
|
|
8243
8522
|
}
|
|
8244
8523
|
function entry2(id, type, item, origin, floor, extra) {
|
|
@@ -8385,17 +8664,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8385
8664
|
item.seed = seedOf2(id);
|
|
8386
8665
|
return entry2(id, type, item, m.id, m.floor);
|
|
8387
8666
|
};
|
|
8388
|
-
const
|
|
8667
|
+
const list2 = [];
|
|
8389
8668
|
const overhead = contents[m.id + "#overhead"];
|
|
8390
8669
|
if (kind === "rustic_sink") {
|
|
8391
8670
|
const dd = Math.max(m.d, 0.56);
|
|
8392
8671
|
const basin = part(m.id, "sink_kitchen", m.w, dd, m.h + 0.3, 0, 0, -(dd - m.d) / 2);
|
|
8393
|
-
|
|
8672
|
+
list2.push(basin);
|
|
8394
8673
|
const over = overhead || [];
|
|
8395
8674
|
if (m.overhead !== false && over.length) {
|
|
8396
8675
|
const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", m.w, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
|
|
8397
8676
|
store([["kitchen_cabinet_wall", wall.item]], over);
|
|
8398
|
-
|
|
8677
|
+
list2.push(wall);
|
|
8399
8678
|
}
|
|
8400
8679
|
if (contents[m.id]) store([["sink_kitchen", basin.item]], contents[m.id]);
|
|
8401
8680
|
if (m.outlet) basin.connections.outlet = m.outlet;
|
|
@@ -8405,33 +8684,33 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8405
8684
|
const rest = r3(width - basinW);
|
|
8406
8685
|
const left = seedOf2(m.id) % 2 === 0;
|
|
8407
8686
|
const sink = part(m.id, "sink_kitchen", basinW, m.d, m.h + 0.25, 0, left ? -(width / 2) + basinW / 2 : width / 2 - basinW / 2, 0);
|
|
8408
|
-
|
|
8687
|
+
list2.push(sink);
|
|
8409
8688
|
let cabinet = null;
|
|
8410
8689
|
if (rest >= 0.35) {
|
|
8411
8690
|
cabinet = part(m.id + "#cabinet", "kitchen_cabinet_base", rest, m.d, m.h, 0, left ? width / 2 - rest / 2 : -(width / 2) + rest / 2, 0);
|
|
8412
|
-
|
|
8691
|
+
list2.push(cabinet);
|
|
8413
8692
|
}
|
|
8414
8693
|
if (contents[m.id]) store(cabinet ? [["kitchen_cabinet_base", cabinet.item], ["sink_kitchen", sink.item]] : [["sink_kitchen", sink.item]], contents[m.id]);
|
|
8415
8694
|
if (m.overhead !== false) {
|
|
8416
8695
|
const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", width, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
|
|
8417
8696
|
store([["kitchen_cabinet_wall", wall.item]], overhead || []);
|
|
8418
|
-
|
|
8697
|
+
list2.push(wall);
|
|
8419
8698
|
}
|
|
8420
8699
|
if (m.outlet) sink.connections.outlet = m.outlet;
|
|
8421
8700
|
} else {
|
|
8422
8701
|
const basin = part(m.id, "sink_bathroom", m.w, m.d, m.h + 0.2, 0, 0, 0);
|
|
8423
|
-
|
|
8702
|
+
list2.push(basin);
|
|
8424
8703
|
if (contents[m.id]) {
|
|
8425
8704
|
if (contents[m.id].length) {
|
|
8426
8705
|
const cabinet = part(m.id + "#cabinet", "bathroom_cabinet", Math.max(0.45, Math.min(0.6, m.w)), 0.15, 0.75, 1.3, 0, -(m.d / 2) + 0.075);
|
|
8427
|
-
|
|
8706
|
+
list2.push(cabinet);
|
|
8428
8707
|
store([["bathroom_cabinet", cabinet.item], ["sink_bathroom", basin.item]], contents[m.id]);
|
|
8429
8708
|
} else {
|
|
8430
8709
|
store([["sink_bathroom", basin.item]], []);
|
|
8431
8710
|
}
|
|
8432
8711
|
}
|
|
8433
8712
|
}
|
|
8434
|
-
for (const e of
|
|
8713
|
+
for (const e of list2) push(e);
|
|
8435
8714
|
}
|
|
8436
8715
|
function circuitOfLight(id) {
|
|
8437
8716
|
const direct = circuits.find((c) => (c.lamps || []).indexOf(id) >= 0);
|
|
@@ -8755,9 +9034,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8755
9034
|
}
|
|
8756
9035
|
return function blocked(x, z, floor) {
|
|
8757
9036
|
const a = floor == null || floor < 0 ? 0 : floor;
|
|
8758
|
-
const
|
|
8759
|
-
if (!
|
|
8760
|
-
for (const s of
|
|
9037
|
+
const list2 = grid.get(key(a, Math.floor(x / CELL2), Math.floor(z / CELL2)));
|
|
9038
|
+
if (!list2) return false;
|
|
9039
|
+
for (const s of list2) if (x > s.x0 && x < s.x1 && z > s.z0 && z < s.z1) return true;
|
|
8761
9040
|
return false;
|
|
8762
9041
|
};
|
|
8763
9042
|
}
|
|
@@ -8975,13 +9254,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8975
9254
|
}
|
|
8976
9255
|
for (const g of by.values()) {
|
|
8977
9256
|
const ls = g.ls, n = ls.length;
|
|
8978
|
-
let cx = 0, cy = 0, cz = 0,
|
|
9257
|
+
let cx = 0, cy = 0, cz = 0, range2 = 0;
|
|
8979
9258
|
for (const l of ls) {
|
|
8980
9259
|
_p.set(l.x, l.y, l.z).applyMatrix4(M);
|
|
8981
9260
|
cx += _p.x;
|
|
8982
9261
|
cy += _p.y;
|
|
8983
9262
|
cz += _p.z;
|
|
8984
|
-
|
|
9263
|
+
range2 = Math.max(range2, l.range || 5);
|
|
8985
9264
|
}
|
|
8986
9265
|
cx /= n;
|
|
8987
9266
|
cy /= n;
|
|
@@ -8989,7 +9268,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8989
9268
|
g.pos = [cx, cy, cz];
|
|
8990
9269
|
g.color = ls[0].color;
|
|
8991
9270
|
g.n = n;
|
|
8992
|
-
g.range =
|
|
9271
|
+
g.range = range2;
|
|
8993
9272
|
if (g.exterior) {
|
|
8994
9273
|
g.rects = [[cx - 7, cz - 7, cx + 7, cz + 7]];
|
|
8995
9274
|
g.y = [cy - 3.2, cy + 4];
|
|
@@ -10262,8 +10541,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10262
10541
|
const resting = /* @__PURE__ */ new Map();
|
|
10263
10542
|
const carrying = /* @__PURE__ */ new Map();
|
|
10264
10543
|
const push = (map, key, value) => {
|
|
10265
|
-
const
|
|
10266
|
-
if (
|
|
10544
|
+
const list2 = map.get(key);
|
|
10545
|
+
if (list2) list2.push(value);
|
|
10267
10546
|
else map.set(key, [value]);
|
|
10268
10547
|
};
|
|
10269
10548
|
for (const support of supports) {
|
|
@@ -10319,7 +10598,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10319
10598
|
if (!splits.size) return input;
|
|
10320
10599
|
const boxes = new Map(input.parts.map((part) => [part.id, part.aabb]));
|
|
10321
10600
|
const pieceBox = /* @__PURE__ */ new Map();
|
|
10322
|
-
for (const split of splits.values()) for (const
|
|
10601
|
+
for (const split of splits.values()) for (const piece2 of split.pieces) pieceBox.set(piece2.id, piece2.aabb);
|
|
10323
10602
|
const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part]);
|
|
10324
10603
|
const supports = [];
|
|
10325
10604
|
for (const support of input.supports) {
|
|
@@ -10367,12 +10646,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10367
10646
|
for (const [a, b] of cutAt(from, to, openings.filter((o) => o.wall === wall.id), y0, y1)) for (const [x0, x1] of unitsOf(a, b, row, spec)) cells.push({ from: x0, to: x1, row, y0, y1 });
|
|
10368
10647
|
}
|
|
10369
10648
|
const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0);
|
|
10370
|
-
const
|
|
10649
|
+
const box2 = (cell) => alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to];
|
|
10371
10650
|
const pieces = cells.map((cell, index) => ({
|
|
10372
10651
|
id: `${wall.id}_${spec.unitLength ? "u" : "log"}${cell.row}_${index}`,
|
|
10373
10652
|
role: wall.role,
|
|
10374
10653
|
material: wall.material,
|
|
10375
|
-
aabb:
|
|
10654
|
+
aabb: box2(cell),
|
|
10376
10655
|
y0: cell.y0,
|
|
10377
10656
|
y1: cell.y1,
|
|
10378
10657
|
floor: wall.floor,
|
|
@@ -10498,9 +10777,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10498
10777
|
const capacity = input.capacities.get(id);
|
|
10499
10778
|
capacities.delete(id);
|
|
10500
10779
|
if (capacity === void 0) continue;
|
|
10501
|
-
const along = (
|
|
10780
|
+
const along = (box2) => Math.max(box2[2] - box2[0], box2[3] - box2[1]);
|
|
10502
10781
|
const length = along(input.parts.find((part) => part.id === id).aabb);
|
|
10503
|
-
for (const
|
|
10782
|
+
for (const piece2 of split.pieces) capacities.set(piece2.id, Math.max(1, capacity * along(piece2.aabb) / length));
|
|
10504
10783
|
}
|
|
10505
10784
|
return { ...next, capacities };
|
|
10506
10785
|
}
|
|
@@ -10777,7 +11056,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10777
11056
|
const per = Math.max(1, Math.round(len / ul));
|
|
10778
11057
|
const w = len / per;
|
|
10779
11058
|
const edge = fragmentMaterial(part.material).color.getHex();
|
|
10780
|
-
const
|
|
11059
|
+
const list2 = [];
|
|
10781
11060
|
for (let r = 0; r < rows; r++) {
|
|
10782
11061
|
const shift = units.bond === "running" && r & 1 ? w / 2 : 0;
|
|
10783
11062
|
const cells = per + (shift ? 1 : 0);
|
|
@@ -10792,10 +11071,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10792
11071
|
const y = part.y0 + (r + 0.5) * rowH;
|
|
10793
11072
|
const d = Math.hypot(x - opening.center[0], y - opening.center[1], z - opening.center[2]);
|
|
10794
11073
|
if (d < opening.radius) continue;
|
|
10795
|
-
|
|
11074
|
+
list2.push({ x, y, z, sx: alongU ? b - a : thick, sy: rowH, sz: alongU ? thick : b - a, colour: d < opening.radius + 0.25 || paint === null ? edge : paint });
|
|
10796
11075
|
}
|
|
10797
11076
|
}
|
|
10798
|
-
return
|
|
11077
|
+
return list2;
|
|
10799
11078
|
}
|
|
10800
11079
|
function open(event) {
|
|
10801
11080
|
if (lod !== 0 || views.has(event.part) || !event.opening) return false;
|
|
@@ -10804,27 +11083,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10804
11083
|
if (!part || !spec || !spec.units) return false;
|
|
10805
11084
|
const items = structure.meshesOf(event.part).filter((it) => it.mesh);
|
|
10806
11085
|
if (!items.length) return false;
|
|
10807
|
-
const
|
|
10808
|
-
const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1,
|
|
11086
|
+
const list2 = courses(part, spec.units, event.opening, wallColour(items));
|
|
11087
|
+
const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1, list2.length));
|
|
10809
11088
|
mesh.name = "breach:" + event.part;
|
|
10810
|
-
|
|
11089
|
+
list2.forEach((u, i) => {
|
|
10811
11090
|
tmp.m.compose(tmp.p.set(u.x, u.y, u.z), tmp.q.identity(), tmp.s.set(u.sx, u.sy, u.sz));
|
|
10812
11091
|
mesh.setMatrixAt(i, tmp.m);
|
|
10813
11092
|
mesh.setColorAt(i, tmp.c.setHex(u.colour));
|
|
10814
11093
|
});
|
|
10815
|
-
mesh.count =
|
|
11094
|
+
mesh.count = list2.length;
|
|
10816
11095
|
mesh.instanceMatrix.needsUpdate = true;
|
|
10817
11096
|
if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true;
|
|
10818
11097
|
mesh.castShadow = true;
|
|
10819
11098
|
mesh.receiveShadow = true;
|
|
10820
11099
|
house.add(mesh);
|
|
10821
11100
|
const saved = items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
|
|
10822
|
-
views.set(event.part, { mesh, saved, units:
|
|
11101
|
+
views.set(event.part, { mesh, saved, units: list2.length, opening: event.opening });
|
|
10823
11102
|
invalidate();
|
|
10824
11103
|
invalidateShadow();
|
|
10825
11104
|
return true;
|
|
10826
11105
|
}
|
|
10827
|
-
function
|
|
11106
|
+
function plain2(view, shown) {
|
|
10828
11107
|
for (const s of view.saved) {
|
|
10829
11108
|
if (shown) restoreRange(s.it.mesh, s.v0, s.data);
|
|
10830
11109
|
else s.data = collapseRange(s.it.mesh, s.v0, s.it.v1);
|
|
@@ -10850,7 +11129,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10850
11129
|
if (was === 0 === (level === 0)) return;
|
|
10851
11130
|
for (const v of views.values()) {
|
|
10852
11131
|
v.mesh.visible = level === 0;
|
|
10853
|
-
|
|
11132
|
+
plain2(v, level !== 0);
|
|
10854
11133
|
}
|
|
10855
11134
|
invalidate();
|
|
10856
11135
|
invalidateShadow();
|
|
@@ -10860,7 +11139,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10860
11139
|
for (const v of views.values()) {
|
|
10861
11140
|
v.mesh.removeFromParent();
|
|
10862
11141
|
v.mesh.dispose();
|
|
10863
|
-
if (lod === 0)
|
|
11142
|
+
if (lod === 0) plain2(v, true);
|
|
10864
11143
|
}
|
|
10865
11144
|
views.clear();
|
|
10866
11145
|
},
|
|
@@ -10967,7 +11246,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10967
11246
|
};
|
|
10968
11247
|
D.dropPiece = (id) => {
|
|
10969
11248
|
if (hiddenPieces.has(id) || bodies.has(id)) return;
|
|
10970
|
-
const
|
|
11249
|
+
const list2 = [], rr = rngString(id);
|
|
10971
11250
|
for (const it of structure.meshesOf(id)) {
|
|
10972
11251
|
if (it.obj) {
|
|
10973
11252
|
hide(it);
|
|
@@ -10976,10 +11255,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10976
11255
|
const m = extract(it);
|
|
10977
11256
|
hide(it);
|
|
10978
11257
|
const hy = (m.geometry.boundingBox.max.y - m.geometry.boundingBox.min.y) / 2;
|
|
10979
|
-
|
|
11258
|
+
list2.push({ mesh: m, vy: 0, hy, y0: m.position.y, rot: 0, w: [(rr() - 0.5) * 0.5, (rr() - 0.5) * 0.3, (rr() - 0.5) * 0.5], landing: false });
|
|
10980
11259
|
}
|
|
10981
11260
|
hiddenPieces.add(id);
|
|
10982
|
-
if (
|
|
11261
|
+
if (list2.length) bodies.set(id, list2);
|
|
10983
11262
|
invalidate();
|
|
10984
11263
|
invalidateShadow();
|
|
10985
11264
|
};
|
|
@@ -11151,8 +11430,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
11151
11430
|
D.animate = (dt) => {
|
|
11152
11431
|
if (R) return;
|
|
11153
11432
|
let moved = false;
|
|
11154
|
-
for (const [id,
|
|
11155
|
-
for (const b of
|
|
11433
|
+
for (const [id, list2] of bodies) {
|
|
11434
|
+
for (const b of list2) {
|
|
11156
11435
|
if (b.landing) continue;
|
|
11157
11436
|
moved = true;
|
|
11158
11437
|
b.vy -= 9.8 * dt;
|
|
@@ -11168,10 +11447,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
11168
11447
|
b.landing = true;
|
|
11169
11448
|
}
|
|
11170
11449
|
}
|
|
11171
|
-
if (!
|
|
11172
|
-
|
|
11450
|
+
if (!list2.impacted && list2.every((b) => b.landing)) {
|
|
11451
|
+
list2.impacted = true;
|
|
11173
11452
|
const ps = D.active ? D.world.part(D.id, id) : null;
|
|
11174
|
-
const b =
|
|
11453
|
+
const b = list2[0];
|
|
11175
11454
|
if (ps && ps.status !== "broken") {
|
|
11176
11455
|
const h = Math.max(0.5, b.y0 - b.hy), c = worldPoint(b.mesh.parent, b.mesh.position);
|
|
11177
11456
|
D.world.hitPart(D.id, id, { type: "blunt", point: [c.x, c.y, c.z], energy: ps.mass * 9.8 * h, radius: 0.5, source: "fall" });
|
|
@@ -12102,20 +12381,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12102
12381
|
const g = c.grids[floor];
|
|
12103
12382
|
if (!g) return 0;
|
|
12104
12383
|
let x0, z0, x1, z1;
|
|
12105
|
-
const
|
|
12106
|
-
if (
|
|
12107
|
-
x0 =
|
|
12108
|
-
z0 =
|
|
12109
|
-
x1 =
|
|
12110
|
-
z1 =
|
|
12384
|
+
const circle2 = "circle" in shape ? shape.circle : null;
|
|
12385
|
+
if (circle2) {
|
|
12386
|
+
x0 = circle2[0] - circle2[2];
|
|
12387
|
+
z0 = circle2[1] - circle2[2];
|
|
12388
|
+
x1 = circle2[0] + circle2[2];
|
|
12389
|
+
z1 = circle2[1] + circle2[2];
|
|
12111
12390
|
} else [x0, z0, x1, z1] = shape.rect;
|
|
12112
12391
|
const i0 = Math.max(0, Math.ceil((Math.min(x0, x1) - c.ox) / CELL - 0.5)), i1 = Math.min(c.nx - 1, Math.floor((Math.max(x0, x1) - c.ox) / CELL - 0.5));
|
|
12113
12392
|
const j0 = Math.max(0, Math.ceil((Math.min(z0, z1) - c.oz) / CELL - 0.5)), j1 = Math.min(c.nz - 1, Math.floor((Math.max(z0, z1) - c.oz) / CELL - 0.5));
|
|
12114
12393
|
let n = 0;
|
|
12115
12394
|
for (let j = j0; j <= j1; j++) for (let i = i0; i <= i1; i++) {
|
|
12116
|
-
if (
|
|
12117
|
-
const dx = c.ox + (i + 0.5) * CELL -
|
|
12118
|
-
if (dx * dx + dz * dz >
|
|
12395
|
+
if (circle2) {
|
|
12396
|
+
const dx = c.ox + (i + 0.5) * CELL - circle2[0], dz = c.oz + (j + 0.5) * CELL - circle2[1];
|
|
12397
|
+
if (dx * dx + dz * dz > circle2[2] * circle2[2]) continue;
|
|
12119
12398
|
}
|
|
12120
12399
|
fn(g, j * c.nx + i);
|
|
12121
12400
|
n++;
|
|
@@ -12352,11 +12631,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12352
12631
|
};
|
|
12353
12632
|
const role = (p) => p.structure && p.structure.role;
|
|
12354
12633
|
const events = (room) => {
|
|
12355
|
-
const
|
|
12356
|
-
room.world.on("*", (e) =>
|
|
12357
|
-
return
|
|
12634
|
+
const list2 = [];
|
|
12635
|
+
room.world.on("*", (e) => list2.push(e));
|
|
12636
|
+
return list2;
|
|
12358
12637
|
};
|
|
12359
|
-
const collapsed = (
|
|
12638
|
+
const collapsed = (list2) => list2.filter((e) => e.type === "collapse").flatMap((e) => e.parts.map((p) => p.id || p));
|
|
12360
12639
|
const whole = (room, oid, pid) => {
|
|
12361
12640
|
const p = room.world.part(oid, pid);
|
|
12362
12641
|
return !!p && p.status !== "broken" && !p.stripped;
|
|
@@ -12375,14 +12654,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12375
12654
|
name: text.scenarios.house_one_pillar,
|
|
12376
12655
|
run({ room, step, expect }) {
|
|
12377
12656
|
const { oid, parts, centre } = spawn(room, "house_casa_portico");
|
|
12378
|
-
const
|
|
12657
|
+
const list2 = events(room);
|
|
12379
12658
|
const columns = groundColumns(parts);
|
|
12380
12659
|
const laj = slabs(parts);
|
|
12381
12660
|
blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
|
|
12382
12661
|
step(20);
|
|
12383
12662
|
expect(!whole(room, oid, columns[0].id), fill(T2.one_pillar_broke, { id: columns[0].id }));
|
|
12384
12663
|
expect(laj.length > 0 && laj.every((id) => whole(room, oid, id)), T2.slabs_whole);
|
|
12385
|
-
expect(!collapsed(
|
|
12664
|
+
expect(!collapsed(list2).some((id) => laj.includes(id)), T2.no_slab_fell);
|
|
12386
12665
|
}
|
|
12387
12666
|
},
|
|
12388
12667
|
{
|
|
@@ -12390,17 +12669,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12390
12669
|
name: text.scenarios.house_two_pillars,
|
|
12391
12670
|
run({ room, step, expect }) {
|
|
12392
12671
|
const { oid, parts, centre } = spawn(room, "house_casa_portico");
|
|
12393
|
-
const
|
|
12672
|
+
const list2 = events(room);
|
|
12394
12673
|
const columns = groundColumns(parts);
|
|
12395
12674
|
const laj = slabs(parts);
|
|
12396
12675
|
blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
|
|
12397
12676
|
blunt(room, oid, columns[1].id, centre(columns[1].id), 3e6);
|
|
12398
12677
|
step(90);
|
|
12399
|
-
for (let next = 2; next < columns.length && !slabs(parts).some((id) => collapsed(
|
|
12678
|
+
for (let next = 2; next < columns.length && !slabs(parts).some((id) => collapsed(list2).includes(id)); next++) {
|
|
12400
12679
|
blunt(room, oid, columns[next].id, centre(columns[next].id), 3e6);
|
|
12401
12680
|
step(90);
|
|
12402
12681
|
}
|
|
12403
|
-
const fell = collapsed(
|
|
12682
|
+
const fell = collapsed(list2);
|
|
12404
12683
|
expect(laj.some((id) => fell.includes(id)), fill(T2.two_slab_fell, { n: fell.length }));
|
|
12405
12684
|
expect(parts.filter((p) => role(p) === "roof").some((p) => fell.includes(p.id)), T2.two_roof_fell);
|
|
12406
12685
|
}
|
|
@@ -12410,13 +12689,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12410
12689
|
name: text.scenarios.house_partition,
|
|
12411
12690
|
run({ room, step, expect }) {
|
|
12412
12691
|
const { oid, parts, centre } = spawn(room, "house_casa_inteira");
|
|
12413
|
-
const
|
|
12692
|
+
const list2 = events(room);
|
|
12414
12693
|
const partition = parts.find((p) => role(p) === "partition");
|
|
12415
12694
|
const laj = slabs(parts);
|
|
12416
12695
|
blunt(room, oid, partition.id, centre(partition.id), 3e6);
|
|
12417
12696
|
step(20);
|
|
12418
12697
|
expect(!whole(room, oid, partition.id), fill(T2.partition_broke, { id: partition.id }));
|
|
12419
|
-
expect(laj.every((id) => whole(room, oid, id)) && !collapsed(
|
|
12698
|
+
expect(laj.every((id) => whole(room, oid, id)) && !collapsed(list2).some((id) => laj.includes(id)), T2.slab_stayed);
|
|
12420
12699
|
}
|
|
12421
12700
|
},
|
|
12422
12701
|
{
|
|
@@ -12455,12 +12734,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
12455
12734
|
name: text.scenarios.house_gas_explodes,
|
|
12456
12735
|
run({ room, step, expect }) {
|
|
12457
12736
|
const { oid, parts, centre } = spawn(room, "house_casa_inteira");
|
|
12458
|
-
const
|
|
12737
|
+
const list2 = events(room);
|
|
12459
12738
|
const bottle = parts.find((p) => p.explodes);
|
|
12460
12739
|
room.world.hitPart(oid, bottle.id, { type: "fire", point: centre(bottle.id), temperature: 900, radius: 0.6, duration: 8 });
|
|
12461
12740
|
step(12);
|
|
12462
|
-
expect(
|
|
12463
|
-
const damage =
|
|
12741
|
+
expect(list2.filter((e) => e.type === "explode").length > 0, T2.gas_exploded);
|
|
12742
|
+
const damage = list2.filter((e) => e.type === "damage" && e.part !== bottle.id && e.damageType === "explosive");
|
|
12464
12743
|
expect(damage.length > 0, fill(T2.gas_damaged, { n: new Set(damage.map((e) => e.part)).size }));
|
|
12465
12744
|
}
|
|
12466
12745
|
}
|