@pascal-app/viewer 1.0.3 → 1.0.5
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/capture/capture-runtime.js +1 -1
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.d.ts +1 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +12 -4
- package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -1
- package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -1
- 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 +253 -86
- 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-reference-nodes.js +1 -1
- package/dist/components/viewer/glb-replace-instances.js +1 -1
- 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 +421 -508
- 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 +13 -2
- package/dist/components/viewer/index.d.ts +24 -1
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +111 -37
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +113 -22
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +6 -0
- package/dist/components/viewer/perf-panel.d.ts.map +1 -1
- package/dist/components/viewer/perf-panel.js +1 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +104 -36
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +17 -3
- 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-bvh.d.ts.map +1 -1
- package/dist/components/viewer/scene-bvh.js +1 -1
- package/dist/components/viewer/scene-environment.d.ts.map +1 -1
- package/dist/components/viewer/scene-environment.js +31 -11
- 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 +25 -7
- package/dist/components/viewer/underground-ambiance.d.ts +9 -0
- package/dist/components/viewer/underground-ambiance.d.ts.map +1 -0
- package/dist/components/viewer/underground-ambiance.js +105 -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 +12 -2
- package/dist/components/viewer/viewer-presentations.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +2 -0
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/index.d.ts +36 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -19
- package/dist/lib/asset-url.d.ts.map +1 -1
- package/dist/lib/asset-url.js +7 -1
- package/dist/lib/backdrop.d.ts +17 -0
- package/dist/lib/backdrop.d.ts.map +1 -1
- package/dist/lib/backdrop.js +18 -1
- package/dist/lib/construction-dust.d.ts +57 -0
- package/dist/lib/construction-dust.d.ts.map +1 -0
- package/dist/lib/construction-dust.js +187 -0
- package/dist/lib/csg-utils.js +1 -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/foundation-materials.d.ts +26 -0
- package/dist/lib/foundation-materials.d.ts.map +1 -0
- package/dist/lib/foundation-materials.js +65 -0
- package/dist/lib/gltf-unlit.d.ts +10 -0
- package/dist/lib/gltf-unlit.d.ts.map +1 -0
- package/dist/lib/gltf-unlit.js +23 -0
- package/dist/lib/ground-window.d.ts +33 -0
- package/dist/lib/ground-window.d.ts.map +1 -0
- package/dist/lib/ground-window.js +114 -0
- package/dist/lib/hero-pose.d.ts +13 -3
- 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 +6 -3
- 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/ktx2-loader.d.ts +7 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -1
- package/dist/lib/ktx2-loader.js +35 -0
- package/dist/lib/layer-pass.d.ts.map +1 -1
- package/dist/lib/layers.d.ts +11 -7
- package/dist/lib/layers.d.ts.map +1 -1
- package/dist/lib/layers.js +16 -6
- 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 +19 -7
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +65 -9
- package/dist/lib/merged-outline-node.d.ts +5 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +80 -2
- 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 +26 -2
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +99 -12
- package/dist/lib/post-processing-resources.d.ts.map +1 -1
- 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/reveal-candidates.d.ts +80 -0
- package/dist/lib/reveal-candidates.d.ts.map +1 -0
- package/dist/lib/reveal-candidates.js +524 -0
- package/dist/lib/reveal-ghost.d.ts +9 -0
- package/dist/lib/reveal-ghost.d.ts.map +1 -0
- package/dist/lib/reveal-ghost.js +62 -0
- package/dist/lib/reveal-pending.d.ts +12 -0
- package/dist/lib/reveal-pending.d.ts.map +1 -0
- package/dist/lib/reveal-pending.js +12 -0
- package/dist/lib/reveal-pose.d.ts +70 -0
- package/dist/lib/reveal-pose.d.ts.map +1 -0
- package/dist/lib/reveal-pose.js +248 -0
- package/dist/lib/reveal-schedule.d.ts +208 -0
- package/dist/lib/reveal-schedule.d.ts.map +1 -0
- package/dist/lib/reveal-schedule.js +410 -0
- package/dist/lib/reveal-texture-scale.d.ts +5 -0
- package/dist/lib/reveal-texture-scale.d.ts.map +1 -0
- package/dist/lib/reveal-texture-scale.js +113 -0
- package/dist/lib/reveal-windows.d.ts +23 -0
- package/dist/lib/reveal-windows.d.ts.map +1 -0
- package/dist/lib/reveal-windows.js +31 -0
- package/dist/lib/reveal-wipe.d.ts +71 -0
- package/dist/lib/reveal-wipe.d.ts.map +1 -0
- package/dist/lib/reveal-wipe.js +105 -0
- package/dist/lib/scene-pass-mrt.d.ts +12 -0
- package/dist/lib/scene-pass-mrt.d.ts.map +1 -0
- package/dist/lib/scene-pass-mrt.js +23 -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-themes.d.ts +30 -8
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +36 -0
- package/dist/lib/scene-visibility.d.ts +17 -1
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +53 -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/site-surfaces.d.ts +32 -0
- package/dist/lib/site-surfaces.d.ts.map +1 -0
- package/dist/lib/site-surfaces.js +70 -0
- package/dist/lib/snapshot-pipeline.d.ts +34 -3
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +247 -117
- package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -1
- package/dist/lib/terrain-perimeter-fill.js +22 -14
- package/dist/lib/tsl-compat.d.ts +2 -2
- package/dist/lib/tsl-compat.d.ts.map +1 -1
- package/dist/lib/underground-ambiance.d.ts +168 -0
- package/dist/lib/underground-ambiance.d.ts.map +1 -0
- package/dist/lib/underground-ambiance.js +334 -0
- 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 +194 -26
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +164 -21
- 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 +88 -6
- package/dist/systems/construction-reveal/construction-dust.d.ts +16 -0
- package/dist/systems/construction-reveal/construction-dust.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-dust.js +92 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts +276 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-reveal.js +2383 -0
- package/dist/systems/construction-reveal/dust-material.d.ts +10 -0
- package/dist/systems/construction-reveal/dust-material.d.ts.map +1 -0
- package/dist/systems/construction-reveal/dust-material.js +17 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts +10 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts.map +1 -0
- package/dist/systems/construction-reveal/ghost-dress.js +24 -0
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +55 -17
- package/dist/systems/elevator/elevator-interaction-system.d.ts +7 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-interaction-system.js +18 -1
- 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/control-widget.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +52 -17
- 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 +48 -53
- package/dist/systems/level/level-hold.d.ts +4 -0
- package/dist/systems/level/level-hold.d.ts.map +1 -0
- package/dist/systems/level/level-hold.js +14 -0
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +19 -6
- package/dist/systems/level/level-utils.d.ts +19 -6
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +68 -9
- 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/__fixtures__/roof-plane-cases.d.ts +103 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.d.ts.map +1 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.js +317 -0
- package/dist/systems/roof/roof-materials.d.ts +16 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +64 -31
- package/dist/systems/roof/roof-system.d.ts +21 -4
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +374 -49
- 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 +39 -3
- package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout-cache.js +141 -19
- 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-material-variant.d.ts.map +1 -1
- 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 +135 -153
- package/dist/systems/wall/wall-placeholder-sweep.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.d.ts +33 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +621 -159
- package/dist/systems/window/corner-frame.d.ts +10 -0
- package/dist/systems/window/corner-frame.d.ts.map +1 -0
- package/dist/systems/window/corner-frame.js +17 -0
- 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 +71 -27
- package/package.json +10 -10
- 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
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every roof the hosted Architect plugin's `hip_roof_planes` and `gable_roof_planes` built, each
|
|
3
|
+
* beside the `roof_segment_add` call that covers it and the roof segment that call writes, so the
|
|
4
|
+
* two plane tools can retire into it (catalogue slice R). No stored thread called either tool, so
|
|
5
|
+
* the cases are what their contracts take (both ridge axes, a hip either way and square, the
|
|
6
|
+
* default, wide, flush and wider-than-the-eaves gable overhangs, a thickness, an eave on the plate,
|
|
7
|
+
* over it and on posts) and the plugin's own call (a hip at the walls' 2.6 m tops).
|
|
8
|
+
*
|
|
9
|
+
* The plane tools took the rectangle of the walls' outside faces, a rise per 12, the overhang past
|
|
10
|
+
* those faces in metres (a gable's ends their own), a thickness square to the slope (0.29 m by
|
|
11
|
+
* default) and an eave height that was the roof's SURFACE at the outside wall face. The segment
|
|
12
|
+
* takes the same rectangle (`rectAt: 'outside'`), the pitch, the overhangs and the thickness in
|
|
13
|
+
* any unit, and an eave that is the plate it bears on, its default the walls' tops; the walls'
|
|
14
|
+
* thickness, which it reads from the walls along those faces (6.5 in where none stand, a porch on
|
|
15
|
+
* posts), puts their centre lines inside the faces.
|
|
16
|
+
*
|
|
17
|
+
* A plane call whose roof stood on its walls, or over them, is the same roof as a segment: same
|
|
18
|
+
* outline, surface, ridge and thickness (`lift` 0).
|
|
19
|
+
*
|
|
20
|
+
* Not reproduced, on purpose (no stored call made either, so each is a call a model could make):
|
|
21
|
+
* - A plane call with its eave at the walls' tops, the plugin's own and the likeliest, sank its roof
|
|
22
|
+
* into them: its slab's underside stood `thickness / cos(pitch)` under the plate at the wall face.
|
|
23
|
+
* A segment is never sunk under the walls it sits on (`eave_under_walls`); the replacement leaves
|
|
24
|
+
* the eave out and the roof sits on them, the same outline, pitch and thickness, its surface
|
|
25
|
+
* `lift` higher. Those rows say so.
|
|
26
|
+
* - Planes over a storey with another over it stood inside that storey; a segment refuses that
|
|
27
|
+
* (`into_storey_above`). The hosted table checks the refusal.
|
|
28
|
+
* - The plane tools answered each plane's id, so one slope could be edited or painted on its own
|
|
29
|
+
* (`update_roof_plane`). A segment is one mass whose slopes change together; one slope on its own
|
|
30
|
+
* is `create_roof_plane`'s, which stays, and the retired tools' answer says so.
|
|
31
|
+
*
|
|
32
|
+
* The viewer runs the segments through the roof geometry against the planes' own geometry
|
|
33
|
+
* (`roof-plane-cases.test.ts`); the hosted plugin runs each replacement call through
|
|
34
|
+
* `roof_segment_add` and reads back the segment it wrote.
|
|
35
|
+
*/
|
|
36
|
+
const IN = 0.0254;
|
|
37
|
+
/** The walls' thickness, a 2x6 wall finished: what `roof_segment_add` reads from them. */
|
|
38
|
+
export const ROOF_PLANE_WALL_THICKNESS = 6.5 * IN;
|
|
39
|
+
/** The covering a segment lays over its deck, in the thickness the plane tools took whole. */
|
|
40
|
+
export const ROOF_PLANE_COVERING = 0.02;
|
|
41
|
+
/** The plane tools' defaults. */
|
|
42
|
+
const PLANE_OVERHANG = 0.457;
|
|
43
|
+
const PLANE_GABLE_OVERHANG = 0.305;
|
|
44
|
+
const PLANE_THICKNESS = 0.29;
|
|
45
|
+
const slopeOf = (pitch) => Math.atan(pitch / 12);
|
|
46
|
+
/** Where a plane call put the roof's surface at the wall face for a roof bearing on `plate`. */
|
|
47
|
+
function surfaceOnPlate(plate, pitch, thickness = PLANE_THICKNESS) {
|
|
48
|
+
const slope = slopeOf(pitch);
|
|
49
|
+
return plate - (ROOF_PLANE_WALL_THICKNESS / 2) * Math.tan(slope) + thickness / Math.cos(slope);
|
|
50
|
+
}
|
|
51
|
+
/** The plate under a plane call's surface: what `eaveHeight` is to a segment. */
|
|
52
|
+
function plateUnder(call) {
|
|
53
|
+
const slope = slopeOf(call.pitch);
|
|
54
|
+
return (call.eaveHeight +
|
|
55
|
+
(ROOF_PLANE_WALL_THICKNESS / 2) * Math.tan(slope) -
|
|
56
|
+
(call.thickness ?? PLANE_THICKNESS) / Math.cos(slope));
|
|
57
|
+
}
|
|
58
|
+
function roofPlaneCase(name, walls, call, replacement) {
|
|
59
|
+
const [ax, az, bx, bz] = call.rect;
|
|
60
|
+
const t = ROOF_PLANE_WALL_THICKNESS;
|
|
61
|
+
const w = Math.abs(bx - ax) - t;
|
|
62
|
+
const d = Math.abs(bz - az) - t;
|
|
63
|
+
const axis = replacement.ridgeAxis;
|
|
64
|
+
const slope = slopeOf(call.pitch);
|
|
65
|
+
const thickness = call.thickness ?? PLANE_THICKNESS;
|
|
66
|
+
const under = plateUnder(call);
|
|
67
|
+
// a segment bears on its walls' tops at the lowest; over them, where the planes put it
|
|
68
|
+
const eave = walls ? Math.max(under, walls.height) : under;
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
walls,
|
|
72
|
+
call,
|
|
73
|
+
replacement,
|
|
74
|
+
segment: {
|
|
75
|
+
roofType: replacement.roofType,
|
|
76
|
+
name: replacement.name,
|
|
77
|
+
centre: [(ax + bx) / 2, (az + bz) / 2],
|
|
78
|
+
width: axis === 'x' ? w : d,
|
|
79
|
+
depth: axis === 'x' ? d : w,
|
|
80
|
+
rotation: axis === 'x' ? 0 : -Math.PI / 2,
|
|
81
|
+
pitch: (slope * 180) / Math.PI,
|
|
82
|
+
overhang: (call.overhang ?? PLANE_OVERHANG) / Math.cos(slope),
|
|
83
|
+
...(call.tool === 'gable_roof_planes'
|
|
84
|
+
? { gableOverhang: call.gableOverhang ?? PLANE_GABLE_OVERHANG }
|
|
85
|
+
: {}),
|
|
86
|
+
wallThickness: t,
|
|
87
|
+
deckThickness: thickness - ROOF_PLANE_COVERING,
|
|
88
|
+
shingleThickness: ROOF_PLANE_COVERING,
|
|
89
|
+
eave,
|
|
90
|
+
},
|
|
91
|
+
lift: eave - under,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** The 12 × 8 m house, walls 2.6 m tall: its outside faces. */
|
|
95
|
+
const WIDE = [-0.08255, -0.08255, 12.08255, 8.08255];
|
|
96
|
+
/** The same house turned: 8 m wide, 12 m deep. */
|
|
97
|
+
const DEEP = [-0.08255, -0.08255, 8.08255, 12.08255];
|
|
98
|
+
/** A 10 m square house. */
|
|
99
|
+
const SQUARE = [-0.08255, -0.08255, 10.08255, 10.08255];
|
|
100
|
+
/** A porch roof on posts, clear of the house, their outside faces. */
|
|
101
|
+
const PORCH = [14, 2, 18, 6];
|
|
102
|
+
const PLATE = 2.6;
|
|
103
|
+
const house = (rect) => ({ rect, height: PLATE });
|
|
104
|
+
export const ROOF_PLANE_CASES = [
|
|
105
|
+
roofPlaneCase('hip_roof_planes defaults, its surface where a roof on the 2.6 m plate has it', house(WIDE), {
|
|
106
|
+
tool: 'hip_roof_planes',
|
|
107
|
+
rect: WIDE,
|
|
108
|
+
pitch: 6,
|
|
109
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
110
|
+
name: 'Hip',
|
|
111
|
+
}, {
|
|
112
|
+
roofType: 'hip',
|
|
113
|
+
name: 'Hip',
|
|
114
|
+
rect: WIDE,
|
|
115
|
+
rectAt: 'outside',
|
|
116
|
+
ridgeAxis: 'x',
|
|
117
|
+
pitchTwelfths: 6,
|
|
118
|
+
overhangIn: '0.457 m',
|
|
119
|
+
thicknessIn: '0.29 m',
|
|
120
|
+
}),
|
|
121
|
+
roofPlaneCase("hip_roof_planes at the walls' tops (the plugin's own call): the planes sank into the walls", house(WIDE), { tool: 'hip_roof_planes', rect: WIDE, pitch: 6, eaveHeight: PLATE }, {
|
|
122
|
+
roofType: 'hip',
|
|
123
|
+
name: 'Hip',
|
|
124
|
+
rect: WIDE,
|
|
125
|
+
rectAt: 'outside',
|
|
126
|
+
ridgeAxis: 'x',
|
|
127
|
+
pitchTwelfths: 6,
|
|
128
|
+
overhangIn: '0.457 m',
|
|
129
|
+
thicknessIn: '0.29 m',
|
|
130
|
+
}),
|
|
131
|
+
roofPlaneCase('hip_roof_planes deeper than wide (its ridge north-south), 5:12, 0.6 m eaves, 0.2 m thick', house(DEEP), {
|
|
132
|
+
tool: 'hip_roof_planes',
|
|
133
|
+
rect: DEEP,
|
|
134
|
+
pitch: 5,
|
|
135
|
+
eaveHeight: surfaceOnPlate(PLATE, 5, 0.2),
|
|
136
|
+
overhang: 0.6,
|
|
137
|
+
thickness: 0.2,
|
|
138
|
+
name: 'Main',
|
|
139
|
+
}, {
|
|
140
|
+
roofType: 'hip',
|
|
141
|
+
name: 'Main',
|
|
142
|
+
rect: DEEP,
|
|
143
|
+
rectAt: 'outside',
|
|
144
|
+
ridgeAxis: 'z',
|
|
145
|
+
pitchTwelfths: 5,
|
|
146
|
+
overhangIn: '0.6 m',
|
|
147
|
+
thicknessIn: '0.2 m',
|
|
148
|
+
}),
|
|
149
|
+
roofPlaneCase('hip_roof_planes over a square: a pyramid, 8:12, 0.3 m eaves', house(SQUARE), {
|
|
150
|
+
tool: 'hip_roof_planes',
|
|
151
|
+
rect: SQUARE,
|
|
152
|
+
pitch: 8,
|
|
153
|
+
eaveHeight: surfaceOnPlate(PLATE, 8),
|
|
154
|
+
overhang: 0.3,
|
|
155
|
+
}, {
|
|
156
|
+
roofType: 'hip',
|
|
157
|
+
name: 'Hip',
|
|
158
|
+
rect: SQUARE,
|
|
159
|
+
rectAt: 'outside',
|
|
160
|
+
ridgeAxis: 'x',
|
|
161
|
+
pitchTwelfths: 8,
|
|
162
|
+
overhangIn: '0.3 m',
|
|
163
|
+
thicknessIn: '0.29 m',
|
|
164
|
+
}),
|
|
165
|
+
roofPlaneCase('hip_roof_planes flush with the walls (no eaves), 4:12', house(WIDE), {
|
|
166
|
+
tool: 'hip_roof_planes',
|
|
167
|
+
rect: WIDE,
|
|
168
|
+
pitch: 4,
|
|
169
|
+
eaveHeight: surfaceOnPlate(PLATE, 4),
|
|
170
|
+
overhang: 0,
|
|
171
|
+
}, {
|
|
172
|
+
roofType: 'hip',
|
|
173
|
+
name: 'Hip',
|
|
174
|
+
rect: WIDE,
|
|
175
|
+
rectAt: 'outside',
|
|
176
|
+
ridgeAxis: 'x',
|
|
177
|
+
pitchTwelfths: 4,
|
|
178
|
+
overhangIn: '0 m',
|
|
179
|
+
thicknessIn: '0.29 m',
|
|
180
|
+
}),
|
|
181
|
+
roofPlaneCase('hip_roof_planes on a plate 0.3 m over the walls: the eave given (floating over them, it stays on their storey)', house(WIDE), {
|
|
182
|
+
tool: 'hip_roof_planes',
|
|
183
|
+
rect: WIDE,
|
|
184
|
+
pitch: 6,
|
|
185
|
+
eaveHeight: surfaceOnPlate(PLATE + 0.3, 6),
|
|
186
|
+
}, {
|
|
187
|
+
roofType: 'hip',
|
|
188
|
+
name: 'Hip',
|
|
189
|
+
rect: WIDE,
|
|
190
|
+
rectAt: 'outside',
|
|
191
|
+
ridgeAxis: 'x',
|
|
192
|
+
pitchTwelfths: 6,
|
|
193
|
+
overhangIn: '0.457 m',
|
|
194
|
+
thicknessIn: '0.29 m',
|
|
195
|
+
eaveHeight: PLATE + 0.3,
|
|
196
|
+
}),
|
|
197
|
+
roofPlaneCase('gable_roof_planes defaults, the ridge east-west: 18 in eaves, 12 in at the gable ends', house(WIDE), {
|
|
198
|
+
tool: 'gable_roof_planes',
|
|
199
|
+
rect: WIDE,
|
|
200
|
+
ridgeAxis: 'x',
|
|
201
|
+
pitch: 6,
|
|
202
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
203
|
+
name: 'Gable',
|
|
204
|
+
}, {
|
|
205
|
+
roofType: 'gable',
|
|
206
|
+
name: 'Gable',
|
|
207
|
+
rect: WIDE,
|
|
208
|
+
rectAt: 'outside',
|
|
209
|
+
ridgeAxis: 'x',
|
|
210
|
+
pitchTwelfths: 6,
|
|
211
|
+
overhangIn: '0.457 m',
|
|
212
|
+
gableOverhangIn: '0.305 m',
|
|
213
|
+
thicknessIn: '0.29 m',
|
|
214
|
+
}),
|
|
215
|
+
roofPlaneCase("gable_roof_planes at the walls' tops: the planes sank into the walls", house(WIDE), { tool: 'gable_roof_planes', rect: WIDE, ridgeAxis: 'x', pitch: 6, eaveHeight: PLATE }, {
|
|
216
|
+
roofType: 'gable',
|
|
217
|
+
name: 'Gable',
|
|
218
|
+
rect: WIDE,
|
|
219
|
+
rectAt: 'outside',
|
|
220
|
+
ridgeAxis: 'x',
|
|
221
|
+
pitchTwelfths: 6,
|
|
222
|
+
overhangIn: '0.457 m',
|
|
223
|
+
gableOverhangIn: '0.305 m',
|
|
224
|
+
thicknessIn: '0.29 m',
|
|
225
|
+
}),
|
|
226
|
+
roofPlaneCase('gable_roof_planes, the ridge north-south over the deep house, 8:12', house(DEEP), {
|
|
227
|
+
tool: 'gable_roof_planes',
|
|
228
|
+
rect: DEEP,
|
|
229
|
+
ridgeAxis: 'z',
|
|
230
|
+
pitch: 8,
|
|
231
|
+
eaveHeight: surfaceOnPlate(PLATE, 8),
|
|
232
|
+
}, {
|
|
233
|
+
roofType: 'gable',
|
|
234
|
+
name: 'Gable',
|
|
235
|
+
rect: DEEP,
|
|
236
|
+
rectAt: 'outside',
|
|
237
|
+
ridgeAxis: 'z',
|
|
238
|
+
pitchTwelfths: 8,
|
|
239
|
+
overhangIn: '0.457 m',
|
|
240
|
+
gableOverhangIn: '0.305 m',
|
|
241
|
+
thicknessIn: '0.29 m',
|
|
242
|
+
}),
|
|
243
|
+
roofPlaneCase('gable_roof_planes, the ridge north-south across the wide house, 4:12', house(WIDE), {
|
|
244
|
+
tool: 'gable_roof_planes',
|
|
245
|
+
rect: WIDE,
|
|
246
|
+
ridgeAxis: 'z',
|
|
247
|
+
pitch: 4,
|
|
248
|
+
eaveHeight: surfaceOnPlate(PLATE, 4),
|
|
249
|
+
}, {
|
|
250
|
+
roofType: 'gable',
|
|
251
|
+
name: 'Gable',
|
|
252
|
+
rect: WIDE,
|
|
253
|
+
rectAt: 'outside',
|
|
254
|
+
ridgeAxis: 'z',
|
|
255
|
+
pitchTwelfths: 4,
|
|
256
|
+
overhangIn: '0.457 m',
|
|
257
|
+
gableOverhangIn: '0.305 m',
|
|
258
|
+
thicknessIn: '0.29 m',
|
|
259
|
+
}),
|
|
260
|
+
roofPlaneCase('gable_roof_planes with gable ends reaching past the eaves: 0.9 m rakes, 0.3 m eaves, 3:12', house(WIDE), {
|
|
261
|
+
tool: 'gable_roof_planes',
|
|
262
|
+
rect: WIDE,
|
|
263
|
+
ridgeAxis: 'x',
|
|
264
|
+
pitch: 3,
|
|
265
|
+
eaveHeight: surfaceOnPlate(PLATE, 3, 0.25),
|
|
266
|
+
overhang: 0.3,
|
|
267
|
+
gableOverhang: 0.9,
|
|
268
|
+
thickness: 0.25,
|
|
269
|
+
}, {
|
|
270
|
+
roofType: 'gable',
|
|
271
|
+
name: 'Gable',
|
|
272
|
+
rect: WIDE,
|
|
273
|
+
rectAt: 'outside',
|
|
274
|
+
ridgeAxis: 'x',
|
|
275
|
+
pitchTwelfths: 3,
|
|
276
|
+
overhangIn: '0.3 m',
|
|
277
|
+
gableOverhangIn: '0.9 m',
|
|
278
|
+
thicknessIn: '0.25 m',
|
|
279
|
+
}),
|
|
280
|
+
roofPlaneCase('gable_roof_planes with flush gable ends', house(WIDE), {
|
|
281
|
+
tool: 'gable_roof_planes',
|
|
282
|
+
rect: WIDE,
|
|
283
|
+
ridgeAxis: 'x',
|
|
284
|
+
pitch: 6,
|
|
285
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
286
|
+
gableOverhang: 0,
|
|
287
|
+
}, {
|
|
288
|
+
roofType: 'gable',
|
|
289
|
+
name: 'Gable',
|
|
290
|
+
rect: WIDE,
|
|
291
|
+
rectAt: 'outside',
|
|
292
|
+
ridgeAxis: 'x',
|
|
293
|
+
pitchTwelfths: 6,
|
|
294
|
+
overhangIn: '0.457 m',
|
|
295
|
+
gableOverhangIn: '0 m',
|
|
296
|
+
thicknessIn: '0.29 m',
|
|
297
|
+
}),
|
|
298
|
+
roofPlaneCase('gable_roof_planes over a porch on posts: its eave on the beam, given', null, {
|
|
299
|
+
tool: 'gable_roof_planes',
|
|
300
|
+
rect: PORCH,
|
|
301
|
+
ridgeAxis: 'z',
|
|
302
|
+
pitch: 6,
|
|
303
|
+
eaveHeight: surfaceOnPlate(2.4, 6),
|
|
304
|
+
name: 'Porch',
|
|
305
|
+
}, {
|
|
306
|
+
roofType: 'gable',
|
|
307
|
+
name: 'Porch',
|
|
308
|
+
rect: PORCH,
|
|
309
|
+
rectAt: 'outside',
|
|
310
|
+
ridgeAxis: 'z',
|
|
311
|
+
pitchTwelfths: 6,
|
|
312
|
+
overhangIn: '0.457 m',
|
|
313
|
+
gableOverhangIn: '0.305 m',
|
|
314
|
+
thicknessIn: '0.29 m',
|
|
315
|
+
eaveHeight: 2.4,
|
|
316
|
+
}),
|
|
317
|
+
];
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import { type RoofNode } from '@pascal-app/core';
|
|
1
|
+
import { type AnyNode, type RoofNode, type SceneMaterial, type SceneMaterialId } from '@pascal-app/core';
|
|
2
2
|
import type * as THREE from 'three';
|
|
3
3
|
import { type ColorPreset, type RenderShading } from '../../lib/materials';
|
|
4
|
+
type SceneMaterials = Record<SceneMaterialId, SceneMaterial> | undefined;
|
|
4
5
|
export type RoofMaterialArray = [THREE.Material, THREE.Material, THREE.Material, THREE.Material];
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
8
|
+
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
9
|
+
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
10
|
+
* like the walls it sits on instead of the bare drywall default. The walls are
|
|
11
|
+
* the roof's level's, or for a roof on a level of its own (a building's roof
|
|
12
|
+
* level), the storey's directly below. The most common ref among them wins;
|
|
13
|
+
* null when none declares one.
|
|
14
|
+
*/
|
|
15
|
+
export declare function levelWallCladdingRef(nodes: Readonly<Record<string, AnyNode | undefined>>, roof: Pick<RoofNode, 'parentId'>): string | null;
|
|
16
|
+
export declare function getRoofMaterialArray(node: RoofNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string,
|
|
17
|
+
/** Catalog ref for the gable/trim band when unpainted — see `levelWallCladdingRef`. */
|
|
18
|
+
wallCladdingRef?: string | null, sceneMaterials?: SceneMaterials): RoofMaterialArray | null;
|
|
19
|
+
export {};
|
|
6
20
|
//# sourceMappingURL=roof-materials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAMZ,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAGnB,MAAM,qBAAqB,CAAA;AAE5B,KAAK,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,SAAS,CAAA;AAaxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;AAqChG;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,EACpD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAC/B,MAAM,GAAG,IAAI,CAyBf;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM;AACnB,uFAAuF;AACvF,eAAe,GAAE,MAAM,GAAG,IAAW,EACrC,cAAc,CAAC,EAAE,cAAc,GAC9B,iBAAiB,GAAG,IAAI,CA4D1B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getEffectiveRoofSurfaceMaterial, } from '@pascal-app/core';
|
|
2
|
-
import { createMaterial,
|
|
1
|
+
import { findLevelBelowId, getEffectiveRoofSurfaceMaterial, getLevelElevations, parseMaterialRef, wallAssemblyFinishRef, } from '@pascal-app/core';
|
|
2
|
+
import { createMaterial, createSurfaceRoleMaterial, resolveMaterialRef, resolveSlotDefaultMaterial, } from '../../lib/materials';
|
|
3
3
|
// Declared catalog defaults for an unpainted roof, per the 4-slot layout
|
|
4
4
|
// (0 wall/trim · 1 deck · 2 interior soffit · 3 shingle top). The wall/trim
|
|
5
5
|
// band mirrors the wall kind's default (WALL_SLOT_DEFAULT = concrete-drywall)
|
|
@@ -11,22 +11,64 @@ const ROOF_DEFAULT_REFS = [
|
|
|
11
11
|
'library:roof-terracottatiles',
|
|
12
12
|
];
|
|
13
13
|
const roofMaterialArrayCache = new Map();
|
|
14
|
-
function getSurfaceMaterialSignature(spec) {
|
|
14
|
+
function getSurfaceMaterialSignature(spec, sceneMaterials) {
|
|
15
|
+
const ref = parseMaterialRef(spec.materialPreset);
|
|
15
16
|
return JSON.stringify({
|
|
16
17
|
material: spec.material ?? null,
|
|
17
18
|
materialPreset: spec.materialPreset ?? null,
|
|
19
|
+
sceneMaterial: ref?.kind === 'scene'
|
|
20
|
+
? (sceneMaterials?.[ref.id]?.material ?? null)
|
|
21
|
+
: null,
|
|
18
22
|
});
|
|
19
23
|
}
|
|
20
|
-
function createResolvedMaterial(material, materialPreset, shading) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
function createResolvedMaterial(material, materialPreset, sceneMaterials, shading) {
|
|
25
|
+
// An unknown or dangling ref resolves to nothing: fall through to the
|
|
26
|
+
// colour, then the slot default, as the segment renderer does.
|
|
27
|
+
const preset = resolveMaterialRef(materialPreset, sceneMaterials, shading);
|
|
28
|
+
if (preset)
|
|
29
|
+
return preset;
|
|
24
30
|
if (material) {
|
|
25
31
|
return createMaterial(material, shading);
|
|
26
32
|
}
|
|
27
33
|
return null;
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
37
|
+
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
38
|
+
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
39
|
+
* like the walls it sits on instead of the bare drywall default. The walls are
|
|
40
|
+
* the roof's level's, or for a roof on a level of its own (a building's roof
|
|
41
|
+
* level), the storey's directly below. The most common ref among them wins;
|
|
42
|
+
* null when none declares one.
|
|
43
|
+
*/
|
|
44
|
+
export function levelWallCladdingRef(nodes, roof) {
|
|
45
|
+
const levelId = roof.parentId;
|
|
46
|
+
if (!levelId)
|
|
47
|
+
return null;
|
|
48
|
+
const wallsOn = (id) => Object.values(nodes).filter((node) => node?.type === 'wall' && node.parentId === id);
|
|
49
|
+
const own = wallsOn(levelId);
|
|
50
|
+
const walls = own.length
|
|
51
|
+
? own
|
|
52
|
+
: wallsOn(findLevelBelowId(levelId, getLevelElevations(nodes)));
|
|
53
|
+
const counts = new Map();
|
|
54
|
+
for (const wall of walls) {
|
|
55
|
+
const ref = wallAssemblyFinishRef(wall);
|
|
56
|
+
if (ref)
|
|
57
|
+
counts.set(ref, (counts.get(ref) ?? 0) + 1);
|
|
58
|
+
}
|
|
59
|
+
let best = null;
|
|
60
|
+
let bestCount = 0;
|
|
61
|
+
for (const [ref, count] of counts) {
|
|
62
|
+
if (count > bestCount) {
|
|
63
|
+
best = ref;
|
|
64
|
+
bestCount = count;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return best;
|
|
68
|
+
}
|
|
69
|
+
export function getRoofMaterialArray(node, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme,
|
|
70
|
+
/** Catalog ref for the gable/trim band when unpainted — see `levelWallCladdingRef`. */
|
|
71
|
+
wallCladdingRef = null, sceneMaterials) {
|
|
30
72
|
const top = getEffectiveRoofSurfaceMaterial(node, 'top');
|
|
31
73
|
const edge = getEffectiveRoofSurfaceMaterial(node, 'edge');
|
|
32
74
|
const wall = getEffectiveRoofSurfaceMaterial(node, 'wall');
|
|
@@ -35,9 +77,10 @@ export function getRoofMaterialArray(node, shading = 'rendered', textures = true
|
|
|
35
77
|
textures,
|
|
36
78
|
colorPreset,
|
|
37
79
|
sceneTheme,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
80
|
+
wallCladdingRef,
|
|
81
|
+
top: getSurfaceMaterialSignature(top, sceneMaterials),
|
|
82
|
+
edge: getSurfaceMaterialSignature(edge, sceneMaterials),
|
|
83
|
+
wall: getSurfaceMaterialSignature(wall, sceneMaterials),
|
|
41
84
|
});
|
|
42
85
|
const cached = roofMaterialArrayCache.get(cacheKey);
|
|
43
86
|
if (cached)
|
|
@@ -59,32 +102,22 @@ export function getRoofMaterialArray(node, shading = 'rendered', textures = true
|
|
|
59
102
|
roofMaterialArrayCache.set(cacheKey, roleArray);
|
|
60
103
|
return roleArray;
|
|
61
104
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[0], shading),
|
|
67
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
68
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
69
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
70
|
-
];
|
|
71
|
-
const topMaterial = createResolvedMaterial(top.material, top.materialPreset, shading);
|
|
72
|
-
const edgeMaterial = createResolvedMaterial(edge.material, edge.materialPreset, shading);
|
|
73
|
-
const wallMaterial = createResolvedMaterial(wall.material, wall.materialPreset, shading);
|
|
74
|
-
if (!(topMaterial || edgeMaterial || wallMaterial)) {
|
|
75
|
-
roofMaterialArrayCache.set(cacheKey, defaultArray);
|
|
76
|
-
return defaultArray;
|
|
77
|
-
}
|
|
105
|
+
const resolve = (spec) => createResolvedMaterial(spec.material, spec.materialPreset, sceneMaterials, shading);
|
|
106
|
+
const topMaterial = resolve(top);
|
|
107
|
+
const edgeMaterial = resolve(edge);
|
|
108
|
+
const wallMaterial = resolve(wall);
|
|
78
109
|
// Each slot resolves to its own role only, then the declared default — never
|
|
79
110
|
// another role. Cross-role fallback here used to splatter a single painted
|
|
80
111
|
// surface (e.g. the edge) across the shingle and soffit slots. The legacy
|
|
81
112
|
// catch-all still fills every role because `getEffectiveRoofSurfaceMaterial`
|
|
82
113
|
// returns it for top/edge/wall alike.
|
|
114
|
+
// Resolve an unpainted slot's catalog default lazily: painted roofs must
|
|
115
|
+
// not load unused finish assets (or make capture readiness depend on them).
|
|
83
116
|
const materialArray = [
|
|
84
|
-
edgeMaterial ??
|
|
85
|
-
wallMaterial ??
|
|
86
|
-
wallMaterial ??
|
|
87
|
-
topMaterial ??
|
|
117
|
+
edgeMaterial ?? resolveSlotDefaultMaterial(wallCladdingRef ?? ROOF_DEFAULT_REFS[0], shading),
|
|
118
|
+
wallMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
119
|
+
wallMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
120
|
+
topMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
88
121
|
];
|
|
89
122
|
roofMaterialArrayCache.set(cacheKey, materialArray);
|
|
90
123
|
return materialArray;
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { type AnyNode, type RoofSegmentNode } from '@pascal-app/core';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { Brush } from 'three-bvh-csg';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Roofs whose merged shell is still to build: until it is, the roof shows its segments apart (or
|
|
6
|
+
* an old shell), and a capture would show that. Only roofs on screen count, a first merge (a
|
|
7
|
+
* mounted group with no shell yet) included: one never mounted stays queued and would hold every
|
|
8
|
+
* capture.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPendingRoofMergeCount(): number;
|
|
11
|
+
export declare function countPendingRoofShells(pending: Iterable<string>, mounted: (id: string) => THREE.Object3D | undefined): number;
|
|
12
|
+
/** What a plugin adds to a segment mesh after its geometry is rebuilt. */
|
|
13
|
+
export type RoofGeometryAdapter = {
|
|
14
|
+
syncGeometry: (node: RoofSegmentNode, mesh: THREE.Mesh) => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const RoofSystem: ({ geometryAdapter }?: {
|
|
17
|
+
geometryAdapter?: RoofGeometryAdapter;
|
|
18
|
+
}) => null;
|
|
5
19
|
/**
|
|
6
20
|
* Four dummy materials used as identity placeholders during CSG. Shared
|
|
7
21
|
* across every input brush so three-bvh-csg can preserve reference
|
|
@@ -36,11 +50,14 @@ export declare function mapRoofGroupMaterialIndex(groupMaterialIndex: number | u
|
|
|
36
50
|
*/
|
|
37
51
|
export declare function clipGeometryBySegmentTrim(geometry: THREE.BufferGeometry | null, segment: RoofSegmentNode): THREE.BufferGeometry | null;
|
|
38
52
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
53
|
+
* `fascia`: build the segment's fascia boards into its deck. Only the roof
|
|
54
|
+
* renderer asks; a dormer, a chimney or a sibling's clip takes the bare shell.
|
|
41
55
|
*/
|
|
42
|
-
export declare function getRoofSegmentBrushes(node: RoofSegmentNode
|
|
56
|
+
export declare function getRoofSegmentBrushes(node: RoofSegmentNode, options?: {
|
|
57
|
+
fascia?: boolean;
|
|
58
|
+
}): RoofSegmentBrushSet | null;
|
|
43
59
|
export declare function generateRoofSegmentGeometry(node: RoofSegmentNode, nodes?: Record<string, AnyNode>): THREE.BufferGeometry;
|
|
60
|
+
export declare function clipDirectRoofGeometryAgainstSiblings(geometry: THREE.BufferGeometry, node: RoofSegmentNode, nodes: Record<string, AnyNode>, space: 'roof' | 'segment'): THREE.BufferGeometry;
|
|
44
61
|
export declare function remapRoofShellFaces(geometry: THREE.BufferGeometry, node: RoofSegmentNode): void;
|
|
45
62
|
export type SurfaceFrame = {
|
|
46
63
|
point: THREE.Vector3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EA6BZ,KAAK,eAAe,EAQrB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,EAA0B,MAAM,eAAe,CAAA;AA4JvE;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAIjD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC,QAAQ,GAAG,SAAS,GAClD,MAAM,CAIR;AAiFD,0EAA0E;AAC1E,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,CAAA;CAChE,CAAA;AAED,eAAO,MAAM,UAAU,yBAAyB;IAAE,eAAe,CAAC,EAAE,mBAAmB,CAAA;CAAE,SA0JxF,CAAA;AAqbD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAC7B,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;CAMxB,CAAA;AAID,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAA;IACf,QAAQ,EAAE,KAAK,CAAA;IACf,SAAS,EAAE,KAAK,CAAA;IAChB,UAAU,EAAE,KAAK,CAAA;IACjB,UAAU,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,CAAA;CACxC,CAAA;AA4FD,wBAAgB,yBAAyB,CACvC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,EAC9B,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,GACtC,MAAM,CAuBR;AA4XD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,EACrC,OAAO,EAAE,eAAe,GACvB,KAAK,CAAC,cAAc,GAAG,IAAI,CAgC7B;AAuHD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,mBAAmB,GAAG,IAAI,CA4V5B;AAkFD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,eAAe,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,KAAK,CAAC,cAAc,CA8GtB;AAED,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,KAAK,CAAC,cAAc,CAiCtB;AA+vCD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,eAAe,QA0ExF;AAirBD,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAA;IACpB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,YAAY,CA+Ld"}
|