@adatechnology/game-floorplan-three 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-Y3Y7NYOL.js → chunk-PJ4WEP6U.js} +36 -12
- package/dist/chunk-PJ4WEP6U.js.map +1 -0
- package/dist/index.d.ts +27 -3
- package/dist/index.global.js +107 -20
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/{testing-BK7QmoUq.d.ts → testing-Db8KbfLm.d.ts} +123 -6
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +1 -1
- package/package.json +10 -10
- package/dist/chunk-Y3Y7NYOL.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RoomRects, T as Three, H as HouseRendererOptions, a as HouseRenderer, b as HouseRecord } from './testing-
|
|
2
|
-
export { A as AreaContext, B as BuildOptions, D as DEFAULT_SPECIMENS, c as Damageable, F as FLOORPLAN_AREA_ID, d as FloorplanEngineLike, e as FloorplanTestOptions, f as House, g as HouseBoxCollider, h as HouseFurnitureCollider, i as HouseInteractable, j as HouseInteractives, k as HousePart, l as HousePlan, m as HousePoint, n as HouseTargetOptions, L as LightingOptions, M as Messages, S as SPECIMEN_AT, o as SpecimenDef, p as TemplateGroup, q as Translate, r as buildSpecimenMeshes, s as createFloorplanTestModule, t as createHouseScenarios, u as createTranslator, v as en, w as locales, x as ptBR, y as specimenSpec } from './testing-
|
|
1
|
+
import { R as RoomRects, T as Three, H as HouseRendererOptions, a as HouseRenderer, b as HouseRecord } from './testing-Db8KbfLm.js';
|
|
2
|
+
export { A as AreaContext, B as BuildOptions, D as DEFAULT_SPECIMENS, c as Damageable, F as FLOORPLAN_AREA_ID, d as FloorplanEngineLike, e as FloorplanTestOptions, f as House, g as HouseBoxCollider, h as HouseFurnitureCollider, i as HouseInteractable, j as HouseInteractives, k as HousePart, l as HousePlan, m as HousePoint, n as HouseTargetOptions, L as LightingOptions, M as Messages, S as SPECIMEN_AT, o as SpecimenDef, p as TemplateGroup, q as Translate, r as buildSpecimenMeshes, s as createFloorplanTestModule, t as createHouseScenarios, u as createTranslator, v as en, w as locales, x as ptBR, y as specimenSpec } from './testing-Db8KbfLm.js';
|
|
3
3
|
import { DestructionEvent, DestructionWorld } from '@adatechnology/game-destruction';
|
|
4
4
|
import { DestructibleSpec, WarmUpProbes } from '@adatechnology/game-contracts';
|
|
5
5
|
import * as THREE_NS from 'three';
|
|
@@ -397,4 +397,28 @@ declare function wallPlan(options: WallPieceOptions): WallPlan;
|
|
|
397
397
|
*/
|
|
398
398
|
declare function wallPiece(THREE: Three, options: WallPieceOptions): WallPiece;
|
|
399
399
|
|
|
400
|
-
|
|
400
|
+
/**
|
|
401
|
+
* The outer baseboard is a band of glazed ceramic tiles (cerâmica esmaltada, 8 mm, on 4 mm of tile adhesive: 12 mm out of the plaster), the usual barrado of a
|
|
402
|
+
* facade, which takes the splashes of rain and the knocks at foot height. Each tile is a piece of its own (`baseboard:<wall>:<side>:<n>`, `length` long with a
|
|
403
|
+
* `joint` of grout between tiles), glued to the wall: a shot craters the tile it hits, more shots or a kick crack and shatter that tile and the wall shows
|
|
404
|
+
* behind it, a blast breaks the tiles it reaches, and a tile comes off when its wall goes. `BuildOptions.baseboard: 'band'` draws it as one strip per face
|
|
405
|
+
* (the Visor de casas 3D's drawing), still ceramic.
|
|
406
|
+
*/
|
|
407
|
+
declare const BASEBOARD_TILES: {
|
|
408
|
+
readonly length: 0.6;
|
|
409
|
+
readonly joint: 0.003;
|
|
410
|
+
readonly material: "ceramic";
|
|
411
|
+
readonly density: 2300;
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* The protective sidewalk around the walls is cast concrete (4.5 cm on the ground, 60 cm wide) cut by expansion joints every `length` metres: each slab is a
|
|
415
|
+
* piece resting on the ground, so a blast cracks, chips and breaks the slabs it reaches and a shot marks the one it hits.
|
|
416
|
+
*/
|
|
417
|
+
declare const SIDEWALK_SLABS: {
|
|
418
|
+
readonly length: 1.2;
|
|
419
|
+
readonly joint: 0.01;
|
|
420
|
+
readonly material: "concrete";
|
|
421
|
+
readonly density: 2400;
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
export { BASEBOARD_TILES, type DestructibleHouse, type FloorNavigator, type FurnitureCatalogEntry, type FurnitureSpecOptions, type FurnitureSpecResult, HouseRenderer, HouseRendererOptions, type NavFlight, type NavFloor, type NavHouse, type NavHouseDef, type NavRect, type NavResult, type NavShape, type NavStair, type NavigableHouse, type NavigationDefOptions, type NavigatorBinding, OPEN_ROOM_TYPES, SIDEWALK_SLABS, type TapSpecOptions, type TapSpecResult, VERSION, type WallPiece, type WallPieceOptions, bindNavigator, create, createFloorNavigator, create as createHouseRenderer, furnitureSpec, isOpenArea, navigationDefOf, planLod, rectsOf, tapSpec, wallPiece, wallPlan };
|
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
var GameFloorplanThree = (() => {
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -22,9 +23,11 @@ var GameFloorplanThree = (() => {
|
|
|
22
23
|
// src/index.ts
|
|
23
24
|
var index_exports = {};
|
|
24
25
|
__export(index_exports, {
|
|
26
|
+
BASEBOARD_TILES: () => BASEBOARD_TILES,
|
|
25
27
|
DEFAULT_SPECIMENS: () => DEFAULT_SPECIMENS,
|
|
26
28
|
FLOORPLAN_AREA_ID: () => FLOORPLAN_AREA_ID,
|
|
27
29
|
OPEN_ROOM_TYPES: () => OPEN_ROOM_TYPES,
|
|
30
|
+
SIDEWALK_SLABS: () => SIDEWALK_SLABS,
|
|
28
31
|
SPECIMEN_AT: () => SPECIMEN_AT,
|
|
29
32
|
VERSION: () => VERSION,
|
|
30
33
|
bindNavigator: () => bindNavigator,
|
|
@@ -6562,8 +6565,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6562
6565
|
}
|
|
6563
6566
|
|
|
6564
6567
|
// src/house/baseboard.ts
|
|
6568
|
+
var BASEBOARD_TILES = { length: 0.6, joint: 3e-3, material: "ceramic", density: 2300 };
|
|
6569
|
+
var SIDEWALK_SLABS = { length: 1.2, joint: 0.01, material: "concrete", density: 2400 };
|
|
6565
6570
|
function installHouseBaseboard(K, shared) {
|
|
6566
|
-
const { Y0, bx, cursor, sideOf } = K;
|
|
6571
|
+
const { Y0, bx, cursor, pieceRecord, sideOf } = K;
|
|
6567
6572
|
const sh = (...a) => K.sh(...a);
|
|
6568
6573
|
function baseboardAndSidewalk() {
|
|
6569
6574
|
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;
|
|
@@ -6585,15 +6590,29 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
6585
6590
|
};
|
|
6586
6591
|
for (const A of ws) for (const [side, sd] of [[A.w.sides[0], -1], [A.w.sides[1], 1]]) {
|
|
6587
6592
|
if (!sideOf(side, false).exterior) continue;
|
|
6588
|
-
const strip = (k, y1, y2, o0, o1, mat, c,
|
|
6593
|
+
const strip = (k, y1, y2, o0, o1, mat, c, piece2, laid = BASEBOARD_TILES) => {
|
|
6589
6594
|
const ea = junction(A, A.a, sd) > 0 ? A.th / 2 + k : junction(A, A.a, sd) < 0 ? -A.th / 2 : 0, eb = junction(A, A.b, sd) > 0 ? A.th / 2 + k : junction(A, A.b, sd) < 0 ? -A.th / 2 : 0;
|
|
6590
6595
|
const s0 = A.a - ea, s1 = A.b + eb, f0 = A.L + sd * (A.th / 2 + o0), f1 = A.L + sd * (A.th / 2 + o1), lo = Math.min(f0, f1), hi = Math.max(f0, f1);
|
|
6591
6596
|
if (s1 - s0 < 1e-3) return;
|
|
6592
|
-
|
|
6593
|
-
|
|
6597
|
+
const box3 = (a, b) => {
|
|
6598
|
+
if (A.au) bx(mat, a, y1, lo, b, y2, hi, c);
|
|
6599
|
+
else bx(mat, lo, y1, a, hi, y2, b, c);
|
|
6600
|
+
};
|
|
6601
|
+
const tag = laid === BASEBOARD_TILES ? "baseboard" : "sidewalk";
|
|
6602
|
+
const tile = (id, a, b) => {
|
|
6603
|
+
cursor.pc = pieceRecord(id, laid.material, null, { floor: 0, mass: Math.round((b - a) * (y2 - y1) * (hi - lo) * laid.density * 100) / 100, tags: [tag] });
|
|
6604
|
+
box3(a, b);
|
|
6605
|
+
};
|
|
6606
|
+
if (!piece2) box3(s0, s1);
|
|
6607
|
+
else if (shared.ctx.baseboardBand) tile(piece2, s0, s1);
|
|
6608
|
+
else {
|
|
6609
|
+
const n = Math.max(1, Math.round((s1 - s0) / laid.length)), w = (s1 - s0) / n, j = laid.joint / 2;
|
|
6610
|
+
for (let i = 0; i < n; i++) tile(`${piece2}:${i}`, s0 + i * w + (i > 0 ? j : 0), s0 + (i + 1) * w - (i < n - 1 ? j : 0));
|
|
6611
|
+
}
|
|
6612
|
+
cursor.pc = null;
|
|
6594
6613
|
};
|
|
6595
|
-
strip(t, y0, y0 + ht, 0, t, "plaster", color2);
|
|
6596
|
-
strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
|
|
6614
|
+
strip(t, y0, y0 + ht, 0, t, "plaster", color2, A.w.id ? `baseboard:${A.w.id}:${sd < 0 ? 0 : 1}` : void 0);
|
|
6615
|
+
strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal, A.w.id ? `sidewalk:${A.w.id}:${sd < 0 ? 0 : 1}` : void 0, SIDEWALK_SLABS);
|
|
6597
6616
|
}
|
|
6598
6617
|
}
|
|
6599
6618
|
const defined = { baseboardAndSidewalk };
|
|
@@ -14208,23 +14227,42 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14208
14227
|
const v = table[mat.penetrationClass ?? mat.id] ?? table[mat.id];
|
|
14209
14228
|
return v === void 0 ? void 0 : v * (mat.penetrationScale ?? 1);
|
|
14210
14229
|
};
|
|
14211
|
-
var
|
|
14230
|
+
var BURIED_BLAST_REACH = 0.5;
|
|
14231
|
+
var GIVE_AT_CUT_HP = 0.5;
|
|
14232
|
+
var capacityScale = (p, borne, through) => {
|
|
14212
14233
|
const residual = p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY;
|
|
14213
14234
|
if (p.st.stripped) return residual;
|
|
14214
|
-
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1,
|
|
14235
|
+
const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, sectionKept(p, residual, borne, through));
|
|
14215
14236
|
return Math.max(p.spec.reinforcement ? residual : 0.05, kept);
|
|
14216
14237
|
};
|
|
14217
|
-
var
|
|
14238
|
+
var sectionKept = (p, residual, borne, through) => {
|
|
14239
|
+
let kept = 1;
|
|
14240
|
+
forEachSection(p, borne, (c, along, gone) => {
|
|
14241
|
+
const share = through?.(c.center, along) ?? 1;
|
|
14242
|
+
if (share <= 0) return;
|
|
14243
|
+
kept = Math.min(kept, Math.max(p.spec.reinforcement ? residual : 0, 1 - gone) / share);
|
|
14244
|
+
});
|
|
14245
|
+
return kept;
|
|
14246
|
+
};
|
|
14247
|
+
var sectionLoss = (p, borne) => {
|
|
14248
|
+
let worst = 0;
|
|
14249
|
+
forEachSection(p, borne, (_c, _along, gone) => {
|
|
14250
|
+
worst = Math.max(worst, gone);
|
|
14251
|
+
});
|
|
14252
|
+
return Math.min(1, worst);
|
|
14253
|
+
};
|
|
14254
|
+
var forEachSection = (p, borne, visit) => {
|
|
14218
14255
|
const cells = p.st.chipped;
|
|
14219
|
-
if (!cells?.length) return
|
|
14256
|
+
if (!cells?.length) return;
|
|
14220
14257
|
const [u, v] = planeAxes(p.thin);
|
|
14221
14258
|
const role = p.spec.structure?.role;
|
|
14222
14259
|
const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
|
|
14223
14260
|
const upright = Math.abs(up[1]) > 0.7 ? v : Math.abs(rotateVec(p.q, [0, 0, 0].map((_, k) => k === u ? 1 : 0))[1]) > 0.7 ? u : -1;
|
|
14224
14261
|
const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
|
|
14225
14262
|
const across = along === u ? v : u;
|
|
14226
|
-
|
|
14263
|
+
const lying = along !== upright || upright < 0;
|
|
14227
14264
|
for (const c of cells) {
|
|
14265
|
+
if (lying && borne?.(c.center, along)) continue;
|
|
14228
14266
|
const spans = [];
|
|
14229
14267
|
for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) spans.push([d.center[across] - d.size[across] / 2, d.center[across] + d.size[across] / 2]);
|
|
14230
14268
|
spans.sort((a, b) => a[0] - b[0]);
|
|
@@ -14234,9 +14272,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14234
14272
|
gone += b - Math.max(a, end);
|
|
14235
14273
|
end = b;
|
|
14236
14274
|
}
|
|
14237
|
-
|
|
14275
|
+
visit(c, along, Math.min(1, gone / Math.max(p.dims[across], 1e-6)));
|
|
14238
14276
|
}
|
|
14239
|
-
return Math.min(1, worst);
|
|
14240
14277
|
};
|
|
14241
14278
|
var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
|
|
14242
14279
|
var clone = (v) => structuredClone(v);
|
|
@@ -14547,6 +14584,26 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14547
14584
|
byTouching.set(support, { version: poseVersion, box: box3 });
|
|
14548
14585
|
return box3;
|
|
14549
14586
|
};
|
|
14587
|
+
const throughOf = (p) => {
|
|
14588
|
+
const load = p.st.load ?? 0;
|
|
14589
|
+
if (load <= 0) return void 0;
|
|
14590
|
+
const above = Math.max(0, load - p.st.mass);
|
|
14591
|
+
const up = rotateVec(p.q, [0, 1, 0]);
|
|
14592
|
+
return (local, along) => {
|
|
14593
|
+
const axis = [0, 0, 0];
|
|
14594
|
+
axis[along] = 1;
|
|
14595
|
+
const sign2 = Math.sign(rotateVec(p.q, axis)[1]);
|
|
14596
|
+
if (Math.abs(up[1]) < 0.7 && Math.abs(rotateVec(p.q, axis)[1]) < 0.7) return 1;
|
|
14597
|
+
const half = p.dims[along] / 2;
|
|
14598
|
+
const share = clamp2((half - sign2 * local[along]) / Math.max(p.dims[along], 1e-6), 0, 1);
|
|
14599
|
+
return (above + p.st.mass * share) / load;
|
|
14600
|
+
};
|
|
14601
|
+
};
|
|
14602
|
+
const borneOn = (p, supports) => {
|
|
14603
|
+
if (supports.length === 0) return void 0;
|
|
14604
|
+
const boxes = supports.map((support) => contactBox(p, support));
|
|
14605
|
+
return (local, along) => boxes.some(([lo, hi]) => local[along] >= lo[along] - SUPPORT_TOLERANCE && local[along] <= hi[along] + SUPPORT_TOLERANCE);
|
|
14606
|
+
};
|
|
14550
14607
|
const measureContact = (p, support) => {
|
|
14551
14608
|
const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
|
|
14552
14609
|
const lo = [0, 0, 0], hi = [0, 0, 0];
|
|
@@ -14754,7 +14811,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14754
14811
|
o.unsup[i] = o.anyAnchor && !isLost(p) && !p.orphan;
|
|
14755
14812
|
continue;
|
|
14756
14813
|
}
|
|
14757
|
-
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p));
|
|
14814
|
+
p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p, borneOn(p, (lowerOf.get(i) ?? []).map((k) => parts[k])), throughOf(p)));
|
|
14758
14815
|
if (p.bend) {
|
|
14759
14816
|
p.bendLoad = p.st.mass + bending[i];
|
|
14760
14817
|
const bent = restFlexure(o, p, lowerOf.get(i) ?? []);
|
|
@@ -15844,6 +15901,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15844
15901
|
debris(o, p, p.mat.breakDebris, center, [0, -1, 0], 6, 1, src);
|
|
15845
15902
|
return loose.length;
|
|
15846
15903
|
};
|
|
15904
|
+
const giveAtCut = (o, p, src) => {
|
|
15905
|
+
if (!p.spec.reinforcement || !p.spec.units || !p.st.chipped?.length || sectionLoss(p) <= 0) return false;
|
|
15906
|
+
const opened = [];
|
|
15907
|
+
for (const j of o.byPart.get(p.spec.id) ?? []) {
|
|
15908
|
+
if (j.st.open) continue;
|
|
15909
|
+
const onIt = j.bears === "a_on_b" && j.spec.b === p.spec.id || j.bears === "b_on_a" && j.spec.a === p.spec.id;
|
|
15910
|
+
if (!onIt) continue;
|
|
15911
|
+
j.st.open = true;
|
|
15912
|
+
j.st.openedBy = "break";
|
|
15913
|
+
opened.push(j);
|
|
15914
|
+
}
|
|
15915
|
+
if (opened.length === 0) return false;
|
|
15916
|
+
p.st.hp = Math.max(p.st.hp, p.st.maxHp * GIVE_AT_CUT_HP);
|
|
15917
|
+
markDamaged(p);
|
|
15918
|
+
solveStructure(o);
|
|
15919
|
+
recomputeGroups(o);
|
|
15920
|
+
detachEvents(o, opened, "break", src);
|
|
15921
|
+
exposeRebar(o, p, src);
|
|
15922
|
+
collapseCheck(o, src);
|
|
15923
|
+
return true;
|
|
15924
|
+
};
|
|
15847
15925
|
const stripPart = (o, p, reinforcement, src) => {
|
|
15848
15926
|
const bars = rebarBars(p.dims, p.thin, reinforcement.spacing);
|
|
15849
15927
|
p.st.stripped = true;
|
|
@@ -15901,6 +15979,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
15901
15979
|
hingeDrop(o, p, src);
|
|
15902
15980
|
return;
|
|
15903
15981
|
}
|
|
15982
|
+
if (!force && giveAtCut(o, p, src)) return;
|
|
15904
15983
|
const ex = p.spec.explodes;
|
|
15905
15984
|
const style = force ?? (p.snap ? "snap" : p.mat.fracture === "none" ? "snap" : p.mat.fracture);
|
|
15906
15985
|
const { c, q } = partXf(o, p);
|
|
@@ -16247,7 +16326,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16247
16326
|
const dx = local[0] - p.pos[0];
|
|
16248
16327
|
const dy = local[1] - p.pos[1];
|
|
16249
16328
|
const dz = local[2] - p.pos[2];
|
|
16250
|
-
if (dx * dx + dy * dy + dz * dz
|
|
16329
|
+
if (dx * dx + dy * dy + dz * dz >= reach * reach) continue;
|
|
16330
|
+
if (p.spec.anchored && p.spec.structure?.role === "foundation" && distToPart(o, p, point) > BURIED_BLAST_REACH) continue;
|
|
16331
|
+
near.push(p);
|
|
16251
16332
|
}
|
|
16252
16333
|
blastProbe.partsTested += o.parts.length;
|
|
16253
16334
|
blastProbe.partsNear += near.length;
|
|
@@ -20632,7 +20713,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20632
20713
|
l.push(it);
|
|
20633
20714
|
};
|
|
20634
20715
|
root.updateMatrixWorld(true);
|
|
20635
|
-
root.traverse((
|
|
20716
|
+
root.traverse((o0) => {
|
|
20717
|
+
const o = o0;
|
|
20636
20718
|
if (o.isMesh && o.userData.ranges) {
|
|
20637
20719
|
const nv = o.geometry.attributes.position.count;
|
|
20638
20720
|
for (const f of o.userData.ranges) add(f.id, { mesh: o, v0: f.v0, v1: f.v1, i0: f.i0, i1: f.i1, whole: f.v0 === 0 && f.v1 === nv });
|
|
@@ -20668,7 +20750,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20668
20750
|
if (!b) continue;
|
|
20669
20751
|
const vol = Math.max(1e-6, (b[3] - b[0]) * (b[4] - b[1]) * (b[5] - b[2]));
|
|
20670
20752
|
const p = { id, role: "none", material: pc.mat, aabb: [b[0], b[2], b[3], b[5]], y0: b[1], y1: b[4], floor: pc.floor != null ? pc.floor : floorAtY(b[1] + 0.1), mass: pc.mass != null ? pc.mass : Math.max(0.5, vol * (DENSITY[pc.mat] || 800) * (pc.fill != null ? pc.fill : 0.15)), meshes: meshes.get(id).length, extra: true };
|
|
20671
|
-
for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null) p[k] = pc[k];
|
|
20753
|
+
for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill", "units"]) if (pc[k] != null) p[k] = pc[k];
|
|
20672
20754
|
parts.push(p);
|
|
20673
20755
|
byId.set(id, p);
|
|
20674
20756
|
}
|
|
@@ -20677,7 +20759,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20677
20759
|
return cx >= q.aabb[0] - m && cx <= q.aabb[2] + m && cz >= q.aabb[1] - m && cz <= q.aabb[3] + m && cy >= q.y0 - m && cy <= q.y1 + m;
|
|
20678
20760
|
};
|
|
20679
20761
|
for (const p of parts.slice(base)) {
|
|
20680
|
-
if (
|
|
20762
|
+
if (/^sidewalk:/.test(p.id)) {
|
|
20763
|
+
supports.push({ part: p.id, on: "ground", joint: "mortar", extra: true });
|
|
20764
|
+
continue;
|
|
20765
|
+
}
|
|
20766
|
+
if (!/^(window|window_pane|door|jamb|pipe|water_tank|baseboard)/.test(p.id)) continue;
|
|
20681
20767
|
const target = /^water_tank/.test(p.id) ? ["slab"] : ["wall", "partition"];
|
|
20682
20768
|
let m = null, md = 1e9;
|
|
20683
20769
|
for (const q of parts.slice(0, base)) {
|
|
@@ -20688,7 +20774,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20688
20774
|
m = q;
|
|
20689
20775
|
}
|
|
20690
20776
|
}
|
|
20691
|
-
if (m) supports.push({ part: p.id, on: m.id, joint: /^(window|jamb)/.test(p.id) ? "glue" : "clip", bears: false, extra: true });
|
|
20777
|
+
if (m) supports.push({ part: p.id, on: m.id, joint: /^(window|jamb|baseboard)/.test(p.id) ? "glue" : "clip", bears: false, extra: true });
|
|
20692
20778
|
}
|
|
20693
20779
|
const specParts = parts.slice(), specSupports = supports.slice();
|
|
20694
20780
|
if (view.panels.length) {
|
|
@@ -21127,7 +21213,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21127
21213
|
return { center: local(chip.center), along: a, up: u };
|
|
21128
21214
|
}
|
|
21129
21215
|
function newView(hostId) {
|
|
21130
|
-
const items = structure.meshesOf(hostId).filter((it) => it.mesh);
|
|
21216
|
+
const items = structure.meshesOf(hostId).filter((it) => !!it.mesh);
|
|
21131
21217
|
if (!items.length) return null;
|
|
21132
21218
|
const parts = [hostId, ...riders(hostId)].filter((id) => structure.byId.get(id) && specOf(id)?.units);
|
|
21133
21219
|
const mask = maskOf(hostId, parts), core = maskOf(hostId, parts);
|
|
@@ -21790,6 +21876,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21790
21876
|
cursor.separate = opts.pieces === "meshes";
|
|
21791
21877
|
cursor.pc = null;
|
|
21792
21878
|
shared.ctx.showPillars = opts.pillars !== "hidden";
|
|
21879
|
+
shared.ctx.baseboardBand = opts.baseboard === "band";
|
|
21793
21880
|
shared.ctx.apartment = r.template === "apartment_modern";
|
|
21794
21881
|
shared.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
|
|
21795
21882
|
shared.ctx.pf = Math.max(1, Math.min(shared.ctx.pa, pr.floor != null ? pr.floor : 3));
|