@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,10 @@
|
|
|
1
|
+
import { type AnyNode } from '@pascal-app/core';
|
|
2
|
+
/** Where a window mesh keeps the corner side its frame was built fused on (-1, 0 or 1). */
|
|
3
|
+
export declare const FUSED_CORNER_SIDE = "fusedCornerSide";
|
|
4
|
+
/**
|
|
5
|
+
* Whether a window's frame was built for a corner pair that has since been made or broken without
|
|
6
|
+
* the window changing (its partner deleted or moved, a wall moved apart): a build reads the pair
|
|
7
|
+
* once, so the window rebuilds.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cornerFrameStale(node: AnyNode, nodes: Readonly<Record<string, AnyNode>>): boolean;
|
|
10
|
+
//# sourceMappingURL=corner-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corner-frame.d.ts","sourceRoot":"","sources":["../../../src/systems/window/corner-frame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAA4C,MAAM,kBAAkB,CAAA;AAEzF,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB,oBAAoB,CAAA;AAElD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAMjG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cornerPair, fusesAtCorner, sceneRegistry } from '@pascal-app/core';
|
|
2
|
+
/** Where a window mesh keeps the corner side its frame was built fused on (-1, 0 or 1). */
|
|
3
|
+
export const FUSED_CORNER_SIDE = 'fusedCornerSide';
|
|
4
|
+
/**
|
|
5
|
+
* Whether a window's frame was built for a corner pair that has since been made or broken without
|
|
6
|
+
* the window changing (its partner deleted or moved, a wall moved apart): a build reads the pair
|
|
7
|
+
* once, so the window rebuilds.
|
|
8
|
+
*/
|
|
9
|
+
export function cornerFrameStale(node, nodes) {
|
|
10
|
+
if (node.type !== 'window')
|
|
11
|
+
return false;
|
|
12
|
+
const mesh = sceneRegistry.nodes.get(node.id);
|
|
13
|
+
if (!mesh)
|
|
14
|
+
return false;
|
|
15
|
+
const fused = cornerPair(nodes, node)?.post === 'none' && fusesAtCorner(node);
|
|
16
|
+
return Boolean(mesh.userData[FUSED_CORNER_SIDE]) !== fused;
|
|
17
|
+
}
|
|
@@ -10,7 +10,7 @@ export declare const DOUBLE_HUNG_BOTTOM_SASH_NAME = "double-hung-bottom-sash";
|
|
|
10
10
|
export declare const LOUVERED_WINDOW_SLATS_NAME = "louvered-window-slats";
|
|
11
11
|
export declare const AWNING_WINDOW_SASH_NAME = "awning-window-sash";
|
|
12
12
|
export declare const HOPPER_WINDOW_SASH_NAME = "hopper-window-sash";
|
|
13
|
-
export declare const pendingWindowAnimationRebuilds: Set<`
|
|
13
|
+
export declare const pendingWindowAnimationRebuilds: Set<`block_${string}` | `building_${string}` | `bvent_${string}` | `cabinet-module_${string}` | `cabinet_${string}` | `ceiling_${string}` | `chimney_${string}` | `column_${string}` | `construction-dimension_${string}` | `cupola_${string}` | `door_${string}` | `dormer_${string}` | `downspout_${string}` | `duct-fitting_${string}` | `duct-segment_${string}` | `duct-terminal_${string}` | `elevator_${string}` | `eyebrow-vent_${string}` | `fence-gate_${string}` | `fence-opening_${string}` | `fence_${string}` | `floor-opening_${string}` | `guide_${string}` | `gutter_${string}` | `hvac-equipment_${string}` | `imesh_${string}` | `item_${string}` | `leanto_${string}` | `level_${string}` | `lineset_${string}` | `liquid-line_${string}` | `measurement_${string}` | `pipe-fitting_${string}` | `pipe-segment_${string}` | `pipe-trap_${string}` | `procedural-item_${string}` | `roof_${string}` | `rseg_${string}` | `rvent_${string}` | `scan_${string}` | `separator_${string}` | `shelf_${string}` | `site_${string}` | `skylight_${string}` | `slab_${string}` | `solarpanel_${string}` | `spawn_${string}` | `sseg_${string}` | `stair_${string}` | `structural-grid_${string}` | `tvent_${string}` | `unit_${string}` | `wall_${string}` | `window_${string}` | `zone_${string}`>;
|
|
14
14
|
export declare const WindowSystem: () => null;
|
|
15
15
|
/**
|
|
16
16
|
* Build a fresh window mesh for preview/ghost rendering.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window-system.d.ts","sourceRoot":"","sources":["../../../src/systems/window/window-system.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"window-system.d.ts","sourceRoot":"","sources":["../../../src/systems/window/window-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EAeL,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA4B9B,eAAO,MAAM,yBAAyB,yBAAyB,CAAA;AAC/D,eAAO,MAAM,8BAA8B,8BAA8B,CAAA;AACzE,eAAO,MAAM,+BAA+B,+BAA+B,CAAA;AAC3E,eAAO,MAAM,gCAAgC,gCAAgC,CAAA;AAC7E,eAAO,MAAM,4BAA4B,4BAA4B,CAAA;AACrE,eAAO,MAAM,yBAAyB,yBAAyB,CAAA;AAC/D,eAAO,MAAM,4BAA4B,4BAA4B,CAAA;AACrE,eAAO,MAAM,0BAA0B,0BAA0B,CAAA;AACjE,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAC3D,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAS3D,eAAO,MAAM,8BAA8B,gvCAAuB,CAAA;AAElE,eAAO,MAAM,YAAY,YA2HxB,CAAA;AA8+GD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC,IAAI,CAInE"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { DEFAULT_WALL_THICKNESS, getEffectiveNode, getWallThickness, sceneRegistry, useInteractive, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
|
|
1
|
+
import { cornerPair, DEFAULT_WALL_THICKNESS, getEffectiveNode, getOpeningWallPlacement, getWallThickness, sceneRegistry, scriptedSize, useInteractive, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
|
|
2
2
|
import { useFrame } from '@react-three/fiber';
|
|
3
3
|
import { useEffect, useRef } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { applyWorldScaleBoxUVs } from '../../lib/box-uv';
|
|
6
|
-
import { createSurfaceRoleMaterial, glassMaterial as defaultGlassMaterial, baseMaterial as getBaseMaterial, resolveMaterialRef, } from '../../lib/materials';
|
|
6
|
+
import { createMaterial, createSurfaceRoleMaterial, glassMaterial as defaultGlassMaterial, baseMaterial as getBaseMaterial, resolveMaterialRef, } from '../../lib/materials';
|
|
7
7
|
import { timeSpan } from '../../lib/perf-tracks';
|
|
8
|
+
import { settleScriptedOpening } from '../../lib/scripted-opening';
|
|
8
9
|
import useViewer from '../../store/use-viewer';
|
|
9
10
|
import { getOpeningCutoutProxyDepth } from '../wall/opening-cutout-geometry';
|
|
11
|
+
import { cornerFrameStale, FUSED_CORNER_SIDE } from './corner-frame';
|
|
10
12
|
// Invisible material for root mesh — used as selection hitbox only
|
|
11
13
|
const hitboxMaterial = new THREE.MeshBasicMaterial({ visible: false });
|
|
12
14
|
let baseMaterial = getBaseMaterial();
|
|
@@ -128,11 +130,19 @@ export const WindowSystem = () => {
|
|
|
128
130
|
// Merge any live override (width / height / position) so the mesh
|
|
129
131
|
// rebuild reflects the in-flight drag without zustand churn.
|
|
130
132
|
const effectiveNode = getEffectiveNode(node);
|
|
131
|
-
timeSpan('window', () => updateWindowMesh(effectiveNode, mesh), {
|
|
133
|
+
const built = timeSpan('window', () => updateWindowMesh(effectiveNode, mesh), {
|
|
132
134
|
properties: [['node', id]],
|
|
133
135
|
});
|
|
136
|
+
// A scripted opening stays dirty until its artifact has loaded.
|
|
137
|
+
if (!built)
|
|
138
|
+
continue;
|
|
134
139
|
clearDirty(id);
|
|
135
140
|
rebuiltWindowsThisFrame += 1;
|
|
141
|
+
// This window's change can make or break its pair: the partner's frame follows.
|
|
142
|
+
const partnerId = node.corner?.partnerId;
|
|
143
|
+
const partner = partnerId ? nodes[partnerId] : undefined;
|
|
144
|
+
if (partner && cornerFrameStale(partner, nodes))
|
|
145
|
+
useScene.getState().markDirty(partner.id);
|
|
136
146
|
// Rebuild the parent wall so its cutout reflects the updated window geometry
|
|
137
147
|
// Avoid triggering expensive wall CSG rebuilds while the window is being interactively moved/duplicated.
|
|
138
148
|
// The editor tools will request a final wall rebuild on commit.
|
|
@@ -192,16 +202,19 @@ function windowSlotDefault(slotId) {
|
|
|
192
202
|
getBaseMaterial(currentShading));
|
|
193
203
|
}
|
|
194
204
|
// Resolve a window's slot to a material: the `node.slots` override (colored mode
|
|
195
|
-
// only) → the
|
|
196
|
-
// escape hatch.
|
|
205
|
+
// only) → the window-wide `material` for the frame (glass keeps its own) → the
|
|
206
|
+
// role/base default. Textures-off ignores overrides — the monochrome escape hatch.
|
|
197
207
|
function resolveWindowSlotMaterial(node, slotId) {
|
|
198
208
|
const fallback = windowSlotDefault(slotId);
|
|
199
209
|
if (!currentTextures)
|
|
200
210
|
return fallback;
|
|
201
211
|
const ref = node.slots?.[slotId];
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
212
|
+
const painted = ref ? resolveMaterialRef(ref, currentSceneMaterials, currentShading) : null;
|
|
213
|
+
if (painted)
|
|
214
|
+
return painted;
|
|
215
|
+
if (node.material && slotId === 'frame')
|
|
216
|
+
return createMaterial(node.material, currentShading);
|
|
217
|
+
return fallback;
|
|
205
218
|
}
|
|
206
219
|
function addBox(parent, material, w, h, d, x, y, z) {
|
|
207
220
|
const geometry = new THREE.BoxGeometry(w, h, d);
|
|
@@ -1519,15 +1532,39 @@ function addShapedLouveredWindowVisuals(node, mesh) {
|
|
|
1519
1532
|
addBox(mesh, baseMaterial, sillW, sillThickness, sillDepth, 0, -height / 2 - sillThickness / 2, sillZ);
|
|
1520
1533
|
}
|
|
1521
1534
|
}
|
|
1535
|
+
/**
|
|
1536
|
+
* The side of a corner window fused at the corner, in the window's own frame: 1 its +x side, -1 its
|
|
1537
|
+
* -x side, 0 none. A window facing its wall's back is turned half round, so its +x then points to
|
|
1538
|
+
* the wall's start.
|
|
1539
|
+
*/
|
|
1540
|
+
function fusedCornerSide(node, rotationY) {
|
|
1541
|
+
const pair = cornerPair(useScene.getState().nodes, node);
|
|
1542
|
+
if (pair?.post !== 'none')
|
|
1543
|
+
return 0;
|
|
1544
|
+
const flipped = Math.abs(rotationY) > Math.PI / 2;
|
|
1545
|
+
return (pair.end === 'end') !== flipped ? 1 : -1;
|
|
1546
|
+
}
|
|
1522
1547
|
function updateWindowMesh(node, mesh) {
|
|
1523
1548
|
currentWindowSlot = undefined;
|
|
1549
|
+
mesh.userData[FUSED_CORNER_SIDE] = 0;
|
|
1524
1550
|
// Root mesh is an invisible hitbox; all visuals live in child meshes
|
|
1525
1551
|
mesh.geometry.dispose();
|
|
1526
1552
|
mesh.geometry = new THREE.BoxGeometry(node.width, node.height, node.frameDepth);
|
|
1527
1553
|
mesh.material = hitboxMaterial;
|
|
1528
1554
|
// Sync transform from node (React may lag behind the system by a frame during drag)
|
|
1529
|
-
|
|
1530
|
-
|
|
1555
|
+
const parent = node.parentId ? useScene.getState().nodes[node.parentId] : undefined;
|
|
1556
|
+
const placement = parent?.type === 'wall' && !node.roofSegmentId
|
|
1557
|
+
? getOpeningWallPlacement(getEffectiveNode(parent), node, useScene.getState().nodes)
|
|
1558
|
+
: node;
|
|
1559
|
+
mesh.position.set(...placement.position);
|
|
1560
|
+
mesh.rotation.set(...placement.rotation);
|
|
1561
|
+
// Built from a script: the renderer shows its artifact, not the parametric
|
|
1562
|
+
// frame, and the hit box is what the script built.
|
|
1563
|
+
if (node.source) {
|
|
1564
|
+
mesh.geometry.dispose();
|
|
1565
|
+
mesh.geometry = new THREE.BoxGeometry(...scriptedSize(node.source.manifest));
|
|
1566
|
+
return settleScriptedOpening(mesh);
|
|
1567
|
+
}
|
|
1531
1568
|
// Dispose and remove all old visual children; preserve 'cutout'
|
|
1532
1569
|
for (const child of [...mesh.children]) {
|
|
1533
1570
|
if (child.name === 'cutout')
|
|
@@ -1543,64 +1580,68 @@ function updateWindowMesh(node, mesh) {
|
|
|
1543
1580
|
const { width, height, frameDepth, frameThickness, columnRatios, rowRatios, columnDividerThickness, rowDividerThickness, sill, sillDepth, sillThickness, openingKind, openingShape, windowType, } = node;
|
|
1544
1581
|
if (openingKind === 'opening') {
|
|
1545
1582
|
syncWindowCutout(node, mesh);
|
|
1546
|
-
return;
|
|
1583
|
+
return true;
|
|
1547
1584
|
}
|
|
1548
1585
|
if (windowType === 'sliding') {
|
|
1549
1586
|
addSlidingWindowVisuals(node, mesh);
|
|
1550
1587
|
syncWindowCutout(node, mesh);
|
|
1551
|
-
return;
|
|
1588
|
+
return true;
|
|
1552
1589
|
}
|
|
1553
1590
|
if (windowType === 'casement') {
|
|
1554
1591
|
addCasementWindowVisuals(node, mesh);
|
|
1555
1592
|
syncWindowCutout(node, mesh);
|
|
1556
|
-
return;
|
|
1593
|
+
return true;
|
|
1557
1594
|
}
|
|
1558
1595
|
if (windowType === 'awning') {
|
|
1559
1596
|
addAwningWindowVisuals(node, mesh);
|
|
1560
1597
|
syncWindowCutout(node, mesh);
|
|
1561
|
-
return;
|
|
1598
|
+
return true;
|
|
1562
1599
|
}
|
|
1563
1600
|
if (windowType === 'hopper') {
|
|
1564
1601
|
addAwningWindowVisuals(node, mesh);
|
|
1565
1602
|
syncWindowCutout(node, mesh);
|
|
1566
|
-
return;
|
|
1603
|
+
return true;
|
|
1567
1604
|
}
|
|
1568
1605
|
if (windowType === 'single-hung') {
|
|
1569
1606
|
addSingleHungWindowVisuals(node, mesh);
|
|
1570
1607
|
syncWindowCutout(node, mesh);
|
|
1571
|
-
return;
|
|
1608
|
+
return true;
|
|
1572
1609
|
}
|
|
1573
1610
|
if (windowType === 'double-hung') {
|
|
1574
1611
|
addDoubleHungWindowVisuals(node, mesh);
|
|
1575
1612
|
syncWindowCutout(node, mesh);
|
|
1576
|
-
return;
|
|
1613
|
+
return true;
|
|
1577
1614
|
}
|
|
1578
1615
|
if (windowType === 'bay') {
|
|
1579
1616
|
addBayWindowVisuals(node, mesh);
|
|
1580
1617
|
syncWindowCutout(node, mesh);
|
|
1581
|
-
return;
|
|
1618
|
+
return true;
|
|
1582
1619
|
}
|
|
1583
1620
|
if (windowType === 'bow') {
|
|
1584
1621
|
addBowWindowVisuals(node, mesh);
|
|
1585
1622
|
syncWindowCutout(node, mesh);
|
|
1586
|
-
return;
|
|
1623
|
+
return true;
|
|
1587
1624
|
}
|
|
1588
1625
|
if (windowType === 'louvered') {
|
|
1589
1626
|
addLouveredWindowVisuals(node, mesh);
|
|
1590
1627
|
syncWindowCutout(node, mesh);
|
|
1591
|
-
return;
|
|
1628
|
+
return true;
|
|
1592
1629
|
}
|
|
1593
1630
|
if (openingShape === 'arch') {
|
|
1594
1631
|
addArchedWindowVisuals(node, mesh);
|
|
1595
1632
|
syncWindowCutout(node, mesh);
|
|
1596
|
-
return;
|
|
1633
|
+
return true;
|
|
1597
1634
|
}
|
|
1598
1635
|
if (openingShape === 'rounded') {
|
|
1599
1636
|
addRoundedWindowVisuals(node, mesh);
|
|
1600
1637
|
syncWindowCutout(node, mesh);
|
|
1601
|
-
return;
|
|
1638
|
+
return true;
|
|
1602
1639
|
}
|
|
1603
|
-
|
|
1640
|
+
// A corner window fused at the corner: no jamb on that side, the glass runs to the corner.
|
|
1641
|
+
const fused = fusedCornerSide(node, placement.rotation[1]);
|
|
1642
|
+
mesh.userData[FUSED_CORNER_SIDE] = fused;
|
|
1643
|
+
const innerW = width - (fused ? 1 : 2) * frameThickness;
|
|
1644
|
+
const innerX = (fused * frameThickness) / 2;
|
|
1604
1645
|
const innerH = height - 2 * frameThickness;
|
|
1605
1646
|
// ── Frame members ──
|
|
1606
1647
|
// Top / bottom — full width
|
|
@@ -1608,8 +1649,10 @@ function updateWindowMesh(node, mesh) {
|
|
|
1608
1649
|
addBox(mesh, baseMaterial, width, frameThickness, frameDepth, 0, height / 2 - frameThickness / 2, 0);
|
|
1609
1650
|
addBox(mesh, baseMaterial, width, frameThickness, frameDepth, 0, -height / 2 + frameThickness / 2, 0);
|
|
1610
1651
|
// Left / right — inner height to avoid corner overlap
|
|
1611
|
-
|
|
1612
|
-
|
|
1652
|
+
if (fused !== -1)
|
|
1653
|
+
addBox(mesh, baseMaterial, frameThickness, innerH, frameDepth, -width / 2 + frameThickness / 2, 0, 0);
|
|
1654
|
+
if (fused !== 1)
|
|
1655
|
+
addBox(mesh, baseMaterial, frameThickness, innerH, frameDepth, width / 2 - frameThickness / 2, 0, 0);
|
|
1613
1656
|
// ── Pane grid ──
|
|
1614
1657
|
const numCols = columnRatios.length;
|
|
1615
1658
|
const numRows = rowRatios.length;
|
|
@@ -1621,7 +1664,7 @@ function updateWindowMesh(node, mesh) {
|
|
|
1621
1664
|
const rowHeights = rowRatios.map((r) => (r / rowSum) * usableH);
|
|
1622
1665
|
// Compute column x-centers starting from left edge of inner area
|
|
1623
1666
|
const colXCenters = [];
|
|
1624
|
-
let cx = -innerW / 2;
|
|
1667
|
+
let cx = innerX - innerW / 2;
|
|
1625
1668
|
for (let c = 0; c < numCols; c++) {
|
|
1626
1669
|
colXCenters.push(cx + colWidths[c] / 2);
|
|
1627
1670
|
cx += colWidths[c];
|
|
@@ -1638,7 +1681,7 @@ function updateWindowMesh(node, mesh) {
|
|
|
1638
1681
|
cy -= rowDividerThickness;
|
|
1639
1682
|
}
|
|
1640
1683
|
// Column dividers — full inner height
|
|
1641
|
-
cx = -innerW / 2;
|
|
1684
|
+
cx = innerX - innerW / 2;
|
|
1642
1685
|
currentWindowSlot = 'frame';
|
|
1643
1686
|
for (let c = 0; c < numCols - 1; c++) {
|
|
1644
1687
|
cx += colWidths[c];
|
|
@@ -1673,6 +1716,7 @@ function updateWindowMesh(node, mesh) {
|
|
|
1673
1716
|
addBox(mesh, baseMaterial, sillW, sillThickness, sillDepth, 0, -height / 2 - sillThickness / 2, sillZ);
|
|
1674
1717
|
}
|
|
1675
1718
|
syncWindowCutout(node, mesh);
|
|
1719
|
+
return true;
|
|
1676
1720
|
}
|
|
1677
1721
|
function syncWindowCutout(node, mesh) {
|
|
1678
1722
|
// ── Cutout: invisible raycast hit target for the whole opening ──
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascal-app/viewer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "3D viewer component for Pascal building editor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"prepublishOnly": "npm run build"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@pascal-app/core": "^1.0.
|
|
36
|
+
"@pascal-app/core": "^1.0.5",
|
|
37
37
|
"@react-three/drei": "^10",
|
|
38
38
|
"@react-three/fiber": "^9",
|
|
39
39
|
"react": "^18 || ^19",
|
|
@@ -42,18 +42,18 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"three-bvh-csg": "^0.0.18",
|
|
45
|
-
"three-mesh-bvh": "
|
|
45
|
+
"three-mesh-bvh": "~0.9.16",
|
|
46
46
|
"zustand": "^5"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@pascal-app/core": "^1.0.
|
|
49
|
+
"@pascal-app/core": "^1.0.5",
|
|
50
50
|
"@pascal/typescript-config": "*",
|
|
51
|
-
"@react-three/test-renderer": "^9.1.
|
|
52
|
-
"@types/node": "^
|
|
53
|
-
"@types/react": "
|
|
54
|
-
"@types/react-dom": "19.
|
|
55
|
-
"@types/three": "^0.
|
|
56
|
-
"typescript": "
|
|
51
|
+
"@react-three/test-renderer": "^9.1.1",
|
|
52
|
+
"@types/node": "^26",
|
|
53
|
+
"@types/react": "19.3.0",
|
|
54
|
+
"@types/react-dom": "19.3.0",
|
|
55
|
+
"@types/three": "^0.186.0",
|
|
56
|
+
"typescript": "7.0.2"
|
|
57
57
|
},
|
|
58
58
|
"keywords": [
|
|
59
59
|
"3d",
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type FenceNode } from '@pascal-app/core';
|
|
2
|
-
import * as THREE from 'three';
|
|
3
|
-
type FencePart = {
|
|
4
|
-
geometry?: THREE.BufferGeometry;
|
|
5
|
-
position: [number, number, number];
|
|
6
|
-
rotationY?: number;
|
|
7
|
-
scale: [number, number, number];
|
|
8
|
-
shape?: 'box' | 'pyramid';
|
|
9
|
-
};
|
|
10
|
-
export type FenceSlotId = 'posts' | 'infill' | 'base' | 'rail';
|
|
11
|
-
export type FenceSlotParts = Record<FenceSlotId, FencePart[]>;
|
|
12
|
-
/**
|
|
13
|
-
* Geometry split by paint slot — posts, infill, base, rail — each a separate
|
|
14
|
-
* merged BufferGeometry (empty ones included) so the fence renderer can give
|
|
15
|
-
* each its own material + `userData.slotId`. Slots match the panel's build
|
|
16
|
-
* options 1:1.
|
|
17
|
-
*/
|
|
18
|
-
export declare function generateFenceSlotGeometries(fence: FenceNode): Record<FenceSlotId, THREE.BufferGeometry>;
|
|
19
|
-
export declare function generateFenceGeometry(fence: FenceNode): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
|
|
20
|
-
export declare const FenceSystem: () => null;
|
|
21
|
-
export {};
|
|
22
|
-
//# sourceMappingURL=fence-system.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fence-system.d.ts","sourceRoot":"","sources":["../../../src/systems/fence/fence-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC,cAAc,CAAA;IAC/B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAG/B,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;CAC1B,CAAA;AAqPD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;AAE9D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAA;AAsQ7D;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,SAAS,GACf,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC,CAQ3C;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,oFAGrD;AAgBD,eAAO,MAAM,WAAW,YAiBvB,CAAA"}
|