@pascal-app/viewer 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +8 -3
- package/dist/components/viewer/frame-limiter.d.ts +1 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.js +22 -3
- package/dist/components/viewer/glb-interactive.d.ts +25 -1
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +252 -85
- package/dist/components/viewer/glb-mechanisms.d.ts +10 -0
- package/dist/components/viewer/glb-mechanisms.d.ts.map +1 -0
- package/dist/components/viewer/glb-mechanisms.js +19 -0
- package/dist/components/viewer/glb-scene.d.ts +45 -27
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +420 -506
- package/dist/components/viewer/glb-walkthrough-controller.d.ts +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.js +12 -1
- package/dist/components/viewer/index.d.ts +14 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +84 -26
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +6 -1
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +6 -0
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +8 -3
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +16 -2
- package/dist/components/viewer/render-error.d.ts +18 -0
- package/dist/components/viewer/render-error.d.ts.map +1 -0
- package/dist/components/viewer/render-error.js +29 -0
- package/dist/components/viewer/scene-ground-replacement.d.ts +6 -0
- package/dist/components/viewer/scene-ground-replacement.d.ts.map +1 -1
- package/dist/components/viewer/scene-ground-replacement.js +15 -0
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +10 -0
- package/dist/components/viewer/viewer-camera.d.ts +4 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +11 -1
- package/dist/index.d.ts +22 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -14
- package/dist/lib/asset-url.d.ts.map +1 -1
- package/dist/lib/asset-url.js +7 -1
- package/dist/lib/display-state.d.ts +25 -0
- package/dist/lib/display-state.d.ts.map +1 -0
- package/dist/lib/display-state.js +1 -0
- package/dist/lib/hero-pose.d.ts +12 -2
- package/dist/lib/hero-pose.d.ts.map +1 -1
- package/dist/lib/hero-pose.js +72 -5
- package/dist/lib/ink-edges.d.ts +4 -2
- package/dist/lib/ink-edges.d.ts.map +1 -1
- package/dist/lib/ink-edges.js +17 -7
- package/dist/lib/key-light-override.d.ts +11 -0
- package/dist/lib/key-light-override.d.ts.map +1 -0
- package/dist/lib/key-light-override.js +14 -0
- package/dist/lib/live-frame-hold.d.ts +14 -0
- package/dist/lib/live-frame-hold.d.ts.map +1 -0
- package/dist/lib/live-frame-hold.js +28 -0
- package/dist/lib/materials.d.ts +14 -7
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +31 -5
- package/dist/lib/node-top-surface-height.d.ts +6 -0
- package/dist/lib/node-top-surface-height.d.ts.map +1 -0
- package/dist/lib/node-top-surface-height.js +74 -0
- package/dist/lib/perf-probe-state.d.ts +39 -0
- package/dist/lib/perf-probe-state.d.ts.map +1 -0
- package/dist/lib/perf-probe-state.js +17 -0
- package/dist/lib/pointer-events.d.ts +8 -0
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +27 -4
- package/dist/lib/procedural-emission.d.ts +7 -0
- package/dist/lib/procedural-emission.d.ts.map +1 -0
- package/dist/lib/procedural-emission.js +54 -0
- package/dist/lib/scene-support-height.d.ts +4 -0
- package/dist/lib/scene-support-height.d.ts.map +1 -0
- package/dist/lib/scene-support-height.js +34 -0
- package/dist/lib/scene-visibility.d.ts +6 -0
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +15 -3
- package/dist/lib/scripted-opening.d.ts +11 -0
- package/dist/lib/scripted-opening.d.ts.map +1 -0
- package/dist/lib/scripted-opening.js +20 -0
- package/dist/lib/snapshot-pipeline.d.ts +32 -2
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +215 -105
- package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -1
- package/dist/lib/terrain-perimeter-fill.js +22 -14
- package/dist/lib/zone-geometry.d.ts +11 -0
- package/dist/lib/zone-geometry.d.ts.map +1 -0
- package/dist/lib/zone-geometry.js +46 -0
- package/dist/store/use-item-light-pool.d.ts +14 -10
- package/dist/store/use-item-light-pool.d.ts.map +1 -1
- package/dist/store/use-item-light-pool.js +52 -26
- package/dist/store/use-viewer.d.ts +11 -0
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +13 -6
- package/dist/systems/ceiling/ceiling-system.d.ts +15 -1
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +86 -6
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +55 -17
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts +3 -1
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
- package/dist/systems/floor-elevation/floor-elevation-system.js +33 -5
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
- package/dist/systems/geometry/geometry-system.js +71 -11
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +40 -15
- package/dist/systems/interactive/procedural-controls.d.ts +13 -0
- package/dist/systems/interactive/procedural-controls.d.ts.map +1 -0
- package/dist/systems/interactive/procedural-controls.js +17 -0
- package/dist/systems/interactive/scripted-clips.d.ts +19 -0
- package/dist/systems/interactive/scripted-clips.d.ts.map +1 -0
- package/dist/systems/interactive/scripted-clips.js +134 -0
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +9 -3
- package/dist/systems/item/object-cut-invalidation.d.ts +3 -0
- package/dist/systems/item/object-cut-invalidation.d.ts.map +1 -0
- package/dist/systems/item/object-cut-invalidation.js +68 -0
- package/dist/systems/item-light/item-light-system.d.ts +1 -1
- package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
- package/dist/systems/item-light/item-light-system.js +47 -52
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +3 -5
- package/dist/systems/level/level-utils.d.ts +7 -4
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +17 -6
- package/dist/systems/level/shadow-only-levels.d.ts +9 -0
- package/dist/systems/level/shadow-only-levels.d.ts.map +1 -0
- package/dist/systems/level/shadow-only-levels.js +7 -0
- package/dist/systems/roof/roof-materials.d.ts +14 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +54 -15
- package/dist/systems/roof/roof-system.d.ts +13 -3
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +188 -13
- package/dist/systems/slab/slab-system.d.ts +1 -1
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +49 -19
- package/dist/systems/stair/stair-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-system.js +133 -354
- package/dist/systems/wall/wall-cutout-cache.d.ts +7 -0
- package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout-cache.js +46 -17
- package/dist/systems/wall/wall-cutout.d.ts +6 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +42 -28
- package/dist/systems/wall/wall-finish-data.d.ts +22 -0
- package/dist/systems/wall/wall-finish-data.d.ts.map +1 -0
- package/dist/systems/wall/wall-finish-data.js +17 -0
- package/dist/systems/wall/wall-materials.d.ts +9 -4
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +99 -152
- package/dist/systems/wall/wall-system.d.ts +28 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +582 -143
- package/dist/systems/window/window-system.d.ts +1 -1
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +41 -22
- package/package.json +5 -5
- package/dist/systems/fence/fence-system.d.ts +0 -22
- package/dist/systems/fence/fence-system.d.ts.map +0 -1
- package/dist/systems/fence/fence-system.js +0 -357
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getEffectiveWallFaceMaterial, getMaterialPresetByRef, getWallSurfaceMaterialSignature, parseMaterialColor, parseMaterialRef, resolveMaterial, resolveWallExteriorSide, resolveWallFaceChain, WALL_SLOT_DEFAULT, wallAssemblyFinishRef, } from '@pascal-app/core';
|
|
2
2
|
import { Color } from 'three';
|
|
3
3
|
import { Fn, float, fract, length, mix, positionLocal, smoothstep, step, vec2 } from 'three/tsl';
|
|
4
4
|
import { MeshLambertNodeMaterial, MeshStandardNodeMaterial } from 'three/webgpu';
|
|
5
|
-
import { baseMaterial, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, materialPresetRefSignature, resolveMaterialRef, resolveSurfaceColor, } from '../../lib/materials';
|
|
5
|
+
import { baseMaterial, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, materialPresetRefSignature, resolveMaterialRef, resolveSlotDefaultRef, resolveSurfaceColor, } from '../../lib/materials';
|
|
6
6
|
const DEFAULT_WALL_COLOR = '#e9e7e3';
|
|
7
7
|
const WALL_HIGHLIGHT_PROFILES = {
|
|
8
8
|
delete: {
|
|
@@ -33,112 +33,95 @@ function getSurfaceVisibleMaterial(spec, shading) {
|
|
|
33
33
|
}
|
|
34
34
|
return baseMaterial(shading);
|
|
35
35
|
}
|
|
36
|
-
function hasExplicitMaterial(spec) {
|
|
37
|
-
return Boolean(spec.materialPreset || spec.material);
|
|
38
|
-
}
|
|
39
36
|
// Resolve a wall face's declared default — a catalog `library:` finish or a
|
|
40
37
|
// flat colour — to a renderable material.
|
|
41
|
-
function resolveWallSlotDefault(
|
|
38
|
+
function resolveWallSlotDefault(declaredDefault, shading) {
|
|
39
|
+
const slotDefault = resolveSlotDefaultRef(declaredDefault);
|
|
42
40
|
if (parseMaterialRef(slotDefault)?.kind === 'library') {
|
|
43
41
|
return createMaterialFromPresetRef(slotDefault, shading) ?? baseMaterial(shading);
|
|
44
42
|
}
|
|
45
43
|
return createDefaultMaterial(slotDefault, 0.9, shading);
|
|
46
44
|
}
|
|
45
|
+
// The assembly cladding's ref when `face` is the wall's exterior face (a is the
|
|
46
|
+
// +normal face; an unresolved side keeps the cladding on b, as legacy did).
|
|
47
|
+
function wallAssemblyFaceFinishRef(wallNode, face) {
|
|
48
|
+
const exteriorFace = resolveWallExteriorSide(wallNode) === 1 ? 'a' : 'b';
|
|
49
|
+
return face === exteriorFace ? wallAssemblyFinishRef(wallNode) : null;
|
|
50
|
+
}
|
|
47
51
|
// Slot-first resolution for one wall face, matching every other paintable kind:
|
|
48
|
-
// node.slots[
|
|
52
|
+
// node.slots[face] ref → legacy inline finish → declared slot default.
|
|
49
53
|
// A dangling `scene:` ref (material deleted / copied across scenes) falls back
|
|
50
54
|
// to the declared default — it never blocks rendering (the dangling-ref rule).
|
|
51
|
-
function resolveWallFaceMaterial(wallNode,
|
|
52
|
-
const
|
|
53
|
-
if (ref) {
|
|
54
|
-
return (resolveMaterialRef(ref, sceneMaterials, shading) ??
|
|
55
|
-
resolveWallSlotDefault(WALL_SLOT_DEFAULT[
|
|
55
|
+
function resolveWallFaceMaterial(wallNode, face, shading, sceneMaterials) {
|
|
56
|
+
const finish = resolveWallFaceChain(wallNode, face);
|
|
57
|
+
if (finish.kind === 'ref') {
|
|
58
|
+
return (resolveMaterialRef(finish.ref, sceneMaterials, shading) ??
|
|
59
|
+
resolveWallSlotDefault(WALL_SLOT_DEFAULT[face], shading));
|
|
56
60
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
if (finish.kind === 'legacy')
|
|
62
|
+
return getSurfaceVisibleMaterial(finish.spec, shading);
|
|
63
|
+
// No paint on this face: the wall ASSEMBLY's cladding (WS5) skins the
|
|
64
|
+
// exterior — a "2x6 lap siding" wall reads as lap siding without the user
|
|
65
|
+
// painting it. Painting the face still wins.
|
|
66
|
+
const assemblyRef = wallAssemblyFaceFinishRef(wallNode, face);
|
|
67
|
+
return resolveWallSlotDefault(assemblyRef ?? finish.ref, shading);
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
resolveWallSlotDefault(WALL_SURFACE_SLOT_DEFAULTS[slotId], shading));
|
|
68
|
-
}
|
|
69
|
-
const side = getWallSurfaceSideFromBandSlot(slotId);
|
|
70
|
-
if (side) {
|
|
71
|
-
return resolveWallFaceMaterial(wallNode, side, shading, sceneMaterials);
|
|
72
|
-
}
|
|
73
|
-
return resolveWallSlotDefault(WALL_SURFACE_SLOT_DEFAULTS[slotId], shading);
|
|
69
|
+
// A region or room finish: its ref, else the face default (same dangling rule).
|
|
70
|
+
function resolveWallFinishMaterial(ref, shading, sceneMaterials) {
|
|
71
|
+
return (resolveMaterialRef(ref, sceneMaterials, shading) ??
|
|
72
|
+
resolveWallSlotDefault(WALL_SLOT_DEFAULT.a, shading));
|
|
74
73
|
}
|
|
75
|
-
// Cache-key fragment for
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
ref,
|
|
88
|
-
material: sceneMaterials?.[parsed.id]?.material ?? null,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
return JSON.stringify({ ref: materialPresetRefSignature(ref) });
|
|
74
|
+
// Cache-key fragment for a ref: for a `scene:` ref, the referenced material's
|
|
75
|
+
// *content* — so editing a scene material assigned to a wall invalidates the
|
|
76
|
+
// cache. A `library:` ref carries its resolution state instead: AI-generated
|
|
77
|
+
// materials register asynchronously, and a dangling ref resolved to the slot
|
|
78
|
+
// default must not stay cached once the library lands.
|
|
79
|
+
function refMaterialSignature(ref, sceneMaterials) {
|
|
80
|
+
const parsed = parseMaterialRef(ref);
|
|
81
|
+
if (parsed?.kind === 'scene') {
|
|
82
|
+
return JSON.stringify({
|
|
83
|
+
ref,
|
|
84
|
+
material: sceneMaterials?.[parsed.id]?.material ?? null,
|
|
85
|
+
});
|
|
92
86
|
}
|
|
93
|
-
return
|
|
87
|
+
return JSON.stringify({ ref: materialPresetRefSignature(ref) });
|
|
94
88
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return JSON.stringify({ ref: materialPresetRefSignature(ref) });
|
|
106
|
-
}
|
|
107
|
-
const side = getWallSurfaceSideFromBandSlot(slotId);
|
|
108
|
-
if (side)
|
|
109
|
-
return wallFaceMaterialSignature(wallNode, side, sceneMaterials);
|
|
110
|
-
return JSON.stringify({ default: WALL_SURFACE_SLOT_DEFAULTS[slotId] });
|
|
89
|
+
// Falls back to the legacy signature when the face has no slot ref.
|
|
90
|
+
function wallFaceMaterialSignature(wallNode, face, sceneMaterials) {
|
|
91
|
+
const ref = wallNode.slots?.[face];
|
|
92
|
+
if (ref)
|
|
93
|
+
return refMaterialSignature(ref, sceneMaterials);
|
|
94
|
+
return JSON.stringify({
|
|
95
|
+
legacy: getWallSurfaceMaterialSignature(getEffectiveWallFaceMaterial(wallNode, face)),
|
|
96
|
+
// Changing the assembly's cladding must re-skin the face.
|
|
97
|
+
assemblyFinish: wallAssemblyFaceFinishRef(wallNode, face),
|
|
98
|
+
});
|
|
111
99
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
if (parsed?.kind === 'scene') {
|
|
121
|
-
const sceneMaterial = sceneMaterials?.[parsed.id];
|
|
122
|
-
return sceneMaterial ? resolveMaterial(sceneMaterial.material).color : fallback;
|
|
123
|
-
}
|
|
124
|
-
return fallback;
|
|
100
|
+
function resolveRefColor(ref, sceneMaterials, fallback) {
|
|
101
|
+
const color = parseMaterialColor(ref);
|
|
102
|
+
if (color)
|
|
103
|
+
return color;
|
|
104
|
+
const parsed = parseMaterialRef(ref);
|
|
105
|
+
if (parsed?.kind === 'library') {
|
|
106
|
+
return getMaterialPresetByRef(ref)?.mapProperties?.color ?? fallback;
|
|
125
107
|
}
|
|
126
|
-
|
|
108
|
+
if (parsed?.kind === 'scene') {
|
|
109
|
+
const sceneMaterial = sceneMaterials?.[parsed.id];
|
|
110
|
+
return sceneMaterial ? resolveMaterial(sceneMaterial.material).color : fallback;
|
|
111
|
+
}
|
|
112
|
+
return fallback;
|
|
127
113
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return sceneMaterial ? resolveMaterial(sceneMaterial.material).color : fallback;
|
|
138
|
-
}
|
|
114
|
+
// Slot-first tint for the cutaway/invisible wall variant.
|
|
115
|
+
function resolveWallFaceColor(wallNode, face, sceneMaterials, fallback) {
|
|
116
|
+
const ref = wallNode.slots?.[face];
|
|
117
|
+
if (ref)
|
|
118
|
+
return resolveRefColor(ref, sceneMaterials, fallback);
|
|
119
|
+
const spec = getEffectiveWallFaceMaterial(wallNode, face);
|
|
120
|
+
const assemblyRef = wallAssemblyFaceFinishRef(wallNode, face);
|
|
121
|
+
if (assemblyRef && !(spec.materialPreset || spec.material)) {
|
|
122
|
+
return getMaterialPresetByRef(assemblyRef)?.mapProperties?.color ?? fallback;
|
|
139
123
|
}
|
|
140
|
-
|
|
141
|
-
return side ? resolveWallFaceColor(wallNode, side, sceneMaterials, fallback) : fallback;
|
|
124
|
+
return getSurfaceColor(spec, fallback);
|
|
142
125
|
}
|
|
143
126
|
function getSurfaceColor(spec, fallback = DEFAULT_WALL_COLOR) {
|
|
144
127
|
const preset = getMaterialPresetByRef(spec.materialPreset);
|
|
@@ -286,27 +269,25 @@ function disposeOwnedMaterials(materials) {
|
|
|
286
269
|
material.dispose();
|
|
287
270
|
});
|
|
288
271
|
}
|
|
289
|
-
export function getWallMaterialHash(wallNode, shading, sceneMaterials, overrideHash) {
|
|
272
|
+
export function getWallMaterialHash(wallNode, shading, sceneMaterials, finishRefs = [], overrideHash) {
|
|
290
273
|
return JSON.stringify({
|
|
291
274
|
shading,
|
|
292
275
|
overrideHash,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
middleInterior: wallSlotMaterialSignature(wallNode, 'middleInterior', sceneMaterials),
|
|
297
|
-
upperInterior: wallSlotMaterialSignature(wallNode, 'upperInterior', sceneMaterials),
|
|
298
|
-
topInterior: wallSlotMaterialSignature(wallNode, 'topInterior', sceneMaterials),
|
|
299
|
-
lowerExterior: wallSlotMaterialSignature(wallNode, 'lowerExterior', sceneMaterials),
|
|
300
|
-
middleExterior: wallSlotMaterialSignature(wallNode, 'middleExterior', sceneMaterials),
|
|
301
|
-
upperExterior: wallSlotMaterialSignature(wallNode, 'upperExterior', sceneMaterials),
|
|
302
|
-
topExterior: wallSlotMaterialSignature(wallNode, 'topExterior', sceneMaterials),
|
|
276
|
+
a: wallFaceMaterialSignature(wallNode, 'a', sceneMaterials),
|
|
277
|
+
b: wallFaceMaterialSignature(wallNode, 'b', sceneMaterials),
|
|
278
|
+
finishes: finishRefs.map((ref) => refMaterialSignature(ref, sceneMaterials)),
|
|
303
279
|
});
|
|
304
280
|
}
|
|
305
|
-
|
|
281
|
+
/**
|
|
282
|
+
* A wall's material palette: 0 caps/edges (themed role), 1 face a, 2 face b,
|
|
283
|
+
* then one entry per `finishRefs` — the region and room finishes the built
|
|
284
|
+
* geometry's groups point at (`getWallFinishRefs(mesh.geometry)`).
|
|
285
|
+
*/
|
|
286
|
+
export function getMaterialsForWall(wallNode, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme, sceneMaterials, finishRefs = [], override) {
|
|
306
287
|
const cacheKey = `${wallNode.id}-${shading}-${textures}-${colorPreset}-${sceneTheme ?? 'base'}`;
|
|
307
288
|
const materialHash = textures
|
|
308
|
-
? getWallMaterialHash(wallNode, shading, sceneMaterials, override?.hash)
|
|
309
|
-
: JSON.stringify({ textures, colorPreset, sceneTheme });
|
|
289
|
+
? getWallMaterialHash(wallNode, shading, sceneMaterials, finishRefs, override?.hash)
|
|
290
|
+
: JSON.stringify({ textures, colorPreset, sceneTheme, finishes: finishRefs.length });
|
|
310
291
|
const existing = wallMaterialCache.get(cacheKey);
|
|
311
292
|
if (existing && existing.materialHash === materialHash) {
|
|
312
293
|
return existing;
|
|
@@ -332,55 +313,22 @@ export function getMaterialsForWall(wallNode, shading = 'rendered', textures = t
|
|
|
332
313
|
: textures
|
|
333
314
|
? [
|
|
334
315
|
wallRoleMaterial,
|
|
335
|
-
resolveWallFaceMaterial(wallNode, '
|
|
336
|
-
resolveWallFaceMaterial(wallNode, '
|
|
337
|
-
|
|
338
|
-
resolveWallSlotMaterial(wallNode, 'middleInterior', shading, sceneMaterials),
|
|
339
|
-
resolveWallSlotMaterial(wallNode, 'upperInterior', shading, sceneMaterials),
|
|
340
|
-
resolveWallSlotMaterial(wallNode, 'topInterior', shading, sceneMaterials),
|
|
341
|
-
resolveWallSlotMaterial(wallNode, 'lowerExterior', shading, sceneMaterials),
|
|
342
|
-
resolveWallSlotMaterial(wallNode, 'middleExterior', shading, sceneMaterials),
|
|
343
|
-
resolveWallSlotMaterial(wallNode, 'upperExterior', shading, sceneMaterials),
|
|
344
|
-
resolveWallSlotMaterial(wallNode, 'topExterior', shading, sceneMaterials),
|
|
316
|
+
resolveWallFaceMaterial(wallNode, 'a', shading, sceneMaterials),
|
|
317
|
+
resolveWallFaceMaterial(wallNode, 'b', shading, sceneMaterials),
|
|
318
|
+
...finishRefs.map((ref) => resolveWallFinishMaterial(ref, shading, sceneMaterials)),
|
|
345
319
|
]
|
|
346
|
-
: Array.from({ length:
|
|
320
|
+
: Array.from({ length: 3 + finishRefs.length }, () => wallRoleMaterial);
|
|
347
321
|
const wallRoleColor = resolveSurfaceColor('wall', colorPreset, sceneTheme);
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
'middleInterior',
|
|
356
|
-
'upperInterior',
|
|
357
|
-
'topInterior',
|
|
358
|
-
'lowerExterior',
|
|
359
|
-
'middleExterior',
|
|
360
|
-
'upperExterior',
|
|
361
|
-
'topExterior',
|
|
362
|
-
].map((slotId) => createInvisibleWallMaterial(textures
|
|
363
|
-
? resolveWallSlotColor(wallNode, slotId, sceneMaterials, wallRoleColor)
|
|
364
|
-
: wallRoleColor, textures ? shading : 'solid')),
|
|
365
|
-
];
|
|
366
|
-
const translucent = [
|
|
367
|
-
createTranslucentWallMaterial(wallRoleColor, textures ? shading : 'solid'),
|
|
368
|
-
...['interior', 'exterior'].map((side) => createTranslucentWallMaterial(textures
|
|
369
|
-
? resolveWallFaceColor(wallNode, side, sceneMaterials, wallRoleColor)
|
|
370
|
-
: wallRoleColor, textures ? shading : 'solid')),
|
|
371
|
-
...[
|
|
372
|
-
'lowerInterior',
|
|
373
|
-
'middleInterior',
|
|
374
|
-
'upperInterior',
|
|
375
|
-
'topInterior',
|
|
376
|
-
'lowerExterior',
|
|
377
|
-
'middleExterior',
|
|
378
|
-
'upperExterior',
|
|
379
|
-
'topExterior',
|
|
380
|
-
].map((slotId) => createTranslucentWallMaterial(textures
|
|
381
|
-
? resolveWallSlotColor(wallNode, slotId, sceneMaterials, wallRoleColor)
|
|
382
|
-
: wallRoleColor, textures ? shading : 'solid')),
|
|
322
|
+
const variantShading = textures ? shading : 'solid';
|
|
323
|
+
const paletteColors = [
|
|
324
|
+
wallRoleColor,
|
|
325
|
+
...['a', 'b'].map((face) => textures
|
|
326
|
+
? resolveWallFaceColor(wallNode, face, sceneMaterials, wallRoleColor)
|
|
327
|
+
: wallRoleColor),
|
|
328
|
+
...finishRefs.map((ref) => textures ? resolveRefColor(ref, sceneMaterials, wallRoleColor) : wallRoleColor),
|
|
383
329
|
];
|
|
330
|
+
const invisible = paletteColors.map((color) => createInvisibleWallMaterial(color, variantShading));
|
|
331
|
+
const translucent = paletteColors.map((color) => createTranslucentWallMaterial(color, variantShading));
|
|
384
332
|
const deleteVisible = mapWallMaterialArray(visible, (material) => createHighlightedWallMaterial(material, 'delete'));
|
|
385
333
|
const deleteInvisible = mapWallMaterialArray(invisible, (material) => createHighlightedWallMaterial(material, 'delete'));
|
|
386
334
|
const deleteTranslucent = mapWallMaterialArray(translucent, (material) => createHighlightedWallMaterial(material, 'delete'));
|
|
@@ -397,7 +345,6 @@ export function getMaterialsForWall(wallNode, shading = 'rendered', textures = t
|
|
|
397
345
|
wallMaterialCache.set(cacheKey, result);
|
|
398
346
|
return result;
|
|
399
347
|
}
|
|
400
|
-
export function getVisibleWallMaterials(wallNode, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme, sceneMaterials) {
|
|
401
|
-
return getMaterialsForWall(wallNode, shading, textures, colorPreset, sceneTheme, sceneMaterials)
|
|
402
|
-
.visible;
|
|
348
|
+
export function getVisibleWallMaterials(wallNode, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme, sceneMaterials, finishRefs = []) {
|
|
349
|
+
return getMaterialsForWall(wallNode, shading, textures, colorPreset, sceneTheme, sceneMaterials, finishRefs).visible;
|
|
403
350
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type AnyNode, type AnyNodeId, type WallMiterData, type WallNode, type WallSlabSupportSegment } from '@pascal-app/core';
|
|
1
|
+
import { type AnyNode, type AnyNodeId, type WallFinishLayout, type WallMiterData, type WallNode, type WallSlabSupportSegment } from '@pascal-app/core';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { Brush } from 'three-bvh-csg';
|
|
4
|
+
import { type WallFaceBaseRun } from './wall-finish-data';
|
|
4
5
|
export { isWallInitialBuildActive } from './wall-build-lifecycle';
|
|
5
6
|
export { drainRebuiltWalls } from './wall-rebuild-notifications';
|
|
6
7
|
export declare function mergeWallCutoutBrushes(brushes: readonly Brush[]): {
|
|
@@ -8,6 +9,22 @@ export declare function mergeWallCutoutBrushes(brushes: readonly Brush[]): {
|
|
|
8
9
|
fallbackBrushes: Brush[];
|
|
9
10
|
droppedCount: number;
|
|
10
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* What decides a face triangle's material: the wall's finish layout (regions and
|
|
14
|
+
* room spans) and, where the faces stand on different floors, each face's base —
|
|
15
|
+
* region heights are measured from the face's own base.
|
|
16
|
+
*/
|
|
17
|
+
export type WallFinishContext = {
|
|
18
|
+
layout: WallFinishLayout;
|
|
19
|
+
faceBase: Record<'a' | 'b', WallFaceBaseRun[]> | null;
|
|
20
|
+
/** The palette's finish refs (material indices 3..): the layout's, then the foundation's. */
|
|
21
|
+
refs: readonly string[];
|
|
22
|
+
/** The underpinning's stemwall: triangles below local y `top` take material `index`. */
|
|
23
|
+
foundation: {
|
|
24
|
+
index: number;
|
|
25
|
+
top: number;
|
|
26
|
+
} | null;
|
|
27
|
+
};
|
|
11
28
|
export declare function shouldDeferWallRebuild(wallId: string, nodes: Record<AnyNodeId, AnyNode>, rebuiltThisFrame: number, elapsedMs: number): boolean;
|
|
12
29
|
/** Rebuilds this system still owes — neighbours deferred during a drag. */
|
|
13
30
|
export declare function getPendingWallRebuildCount(): number;
|
|
@@ -26,6 +43,15 @@ export declare const WallSystem: ({ geometryAdapter }?: {
|
|
|
26
43
|
geometryAdapter?: WallGeometryAdapter;
|
|
27
44
|
}) => null;
|
|
28
45
|
export declare function runWallBuildFrame(geometryAdapter?: WallGeometryAdapter): void;
|
|
46
|
+
/**
|
|
47
|
+
* A room's wall finish lives on its zone, so a zone edit must rebuild the walls
|
|
48
|
+
* bounding it — the old boundary and the new one. Zones without a wall finish
|
|
49
|
+
* never touch their walls, so ordinary room edits cost nothing here.
|
|
50
|
+
*/
|
|
51
|
+
export declare function markWallsForZoneFinishChanges(): void;
|
|
29
52
|
type WallTerrainBottomSampler = (x: number, z: number) => number | null;
|
|
30
|
-
export declare function generateExtrudedWall(wallNode: WallNode, childrenNodes: AnyNode[], miterData: WallMiterData, slabElevation?: number, baseElevation?: number, baseSegments?: readonly WallSlabSupportSegment[], storeyHeight?: number, terrainBottomAt?: WallTerrainBottomSampler
|
|
53
|
+
export declare function generateExtrudedWall(wallNode: WallNode, childrenNodes: AnyNode[], miterData: WallMiterData, slabElevation?: number, baseElevation?: number, baseSegments?: readonly WallSlabSupportSegment[], storeyHeight?: number, terrainBottomAt?: WallTerrainBottomSampler, faceBase?: {
|
|
54
|
+
a: readonly WallSlabSupportSegment[];
|
|
55
|
+
b: readonly WallSlabSupportSegment[];
|
|
56
|
+
}, finishLayout?: WallFinishLayout, sceneNodes?: Readonly<Record<string, AnyNode>>): THREE.BufferGeometry;
|
|
31
57
|
//# sourceMappingURL=wall-system.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"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"}
|