@pascal-app/viewer 0.7.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/dist/components/renderers/node-renderer.d.ts +1 -1
  2. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  3. package/dist/components/renderers/node-renderer.js +38 -22
  4. package/dist/components/renderers/parametric-node-renderer.d.ts +5 -0
  5. package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -0
  6. package/dist/components/renderers/parametric-node-renderer.js +34 -0
  7. package/dist/components/renderers/scene-renderer.d.ts +1 -1
  8. package/dist/components/renderers/scene-renderer.d.ts.map +1 -1
  9. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  10. package/dist/components/viewer/frame-limiter.js +5 -1
  11. package/dist/components/viewer/ground-occluder.d.ts +1 -1
  12. package/dist/components/viewer/ground-occluder.d.ts.map +1 -1
  13. package/dist/components/viewer/ground-occluder.js +12 -24
  14. package/dist/components/viewer/index.d.ts +38 -1
  15. package/dist/components/viewer/index.d.ts.map +1 -1
  16. package/dist/components/viewer/index.js +183 -60
  17. package/dist/components/viewer/lights.d.ts +1 -1
  18. package/dist/components/viewer/lights.d.ts.map +1 -1
  19. package/dist/components/viewer/lights.js +170 -43
  20. package/dist/components/viewer/perf-monitor.d.ts +1 -1
  21. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  22. package/dist/components/viewer/perf-monitor.js +99 -11
  23. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  24. package/dist/components/viewer/post-processing.js +217 -61
  25. package/dist/components/viewer/registered-systems.d.ts +12 -0
  26. package/dist/components/viewer/registered-systems.d.ts.map +1 -0
  27. package/dist/components/viewer/registered-systems.js +47 -0
  28. package/dist/components/viewer/scene-bvh.d.ts +17 -0
  29. package/dist/components/viewer/scene-bvh.d.ts.map +1 -0
  30. package/dist/components/viewer/scene-bvh.js +94 -0
  31. package/dist/components/viewer/selection-manager.d.ts +1 -1
  32. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  33. package/dist/components/viewer/selection-manager.js +20 -5
  34. package/dist/components/viewer/viewer-camera.d.ts +1 -1
  35. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  36. package/dist/components/viewer/walkthrough-controls.d.ts +1 -1
  37. package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
  38. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  39. package/dist/hooks/use-node-events.d.ts +5 -73
  40. package/dist/hooks/use-node-events.d.ts.map +1 -1
  41. package/dist/hooks/use-node-events.js +19 -7
  42. package/dist/index.d.ts +36 -4
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +67 -3
  45. package/dist/lib/csg-utils.d.ts +16 -0
  46. package/dist/lib/csg-utils.d.ts.map +1 -0
  47. package/dist/lib/csg-utils.js +33 -0
  48. package/dist/lib/drawable-geometry.d.ts +21 -0
  49. package/dist/lib/drawable-geometry.d.ts.map +1 -0
  50. package/dist/lib/drawable-geometry.js +22 -0
  51. package/dist/lib/edge-style.d.ts +3 -0
  52. package/dist/lib/edge-style.d.ts.map +1 -0
  53. package/dist/lib/edge-style.js +11 -0
  54. package/dist/lib/gpu-perf.d.ts +4 -0
  55. package/dist/lib/gpu-perf.d.ts.map +1 -0
  56. package/dist/lib/gpu-perf.js +23 -0
  57. package/dist/lib/ink-edges.d.ts +9 -0
  58. package/dist/lib/ink-edges.d.ts.map +1 -0
  59. package/dist/lib/ink-edges.js +43 -0
  60. package/dist/lib/isolation.d.ts +39 -0
  61. package/dist/lib/isolation.d.ts.map +1 -0
  62. package/dist/lib/isolation.js +103 -0
  63. package/dist/lib/layers.d.ts +18 -0
  64. package/dist/lib/layers.d.ts.map +1 -1
  65. package/dist/lib/layers.js +18 -0
  66. package/dist/lib/materials.d.ts +25 -15
  67. package/dist/lib/materials.d.ts.map +1 -1
  68. package/dist/lib/materials.js +277 -63
  69. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  70. package/dist/lib/merged-outline-node.js +11 -11
  71. package/dist/lib/polygon-union.d.ts +4 -0
  72. package/dist/lib/polygon-union.d.ts.map +1 -0
  73. package/dist/lib/polygon-union.js +289 -0
  74. package/dist/lib/polygon-union.test.d.ts +2 -0
  75. package/dist/lib/polygon-union.test.d.ts.map +1 -0
  76. package/dist/lib/polygon-union.test.js +105 -0
  77. package/dist/lib/scene-themes.d.ts +29 -0
  78. package/dist/lib/scene-themes.d.ts.map +1 -0
  79. package/dist/lib/scene-themes.js +193 -0
  80. package/dist/store/use-viewer.d.ts +42 -4
  81. package/dist/store/use-viewer.d.ts.map +1 -1
  82. package/dist/store/use-viewer.js +26 -3
  83. package/dist/systems/ceiling/ceiling-system.d.ts +6 -2
  84. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  85. package/dist/systems/ceiling/ceiling-system.js +62 -12
  86. package/dist/systems/door/door-system.d.ts.map +1 -1
  87. package/dist/systems/door/door-system.js +373 -22
  88. package/dist/systems/elevator/elevator-interaction-system.d.ts +2 -0
  89. package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -0
  90. package/dist/systems/elevator/elevator-interaction-system.js +62 -0
  91. package/dist/systems/fence/fence-system.d.ts +3 -0
  92. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  93. package/dist/systems/fence/fence-system.js +10 -6
  94. package/dist/systems/floor-elevation/floor-elevation-system.d.ts +20 -0
  95. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -0
  96. package/dist/systems/floor-elevation/floor-elevation-system.js +78 -0
  97. package/dist/systems/geometry/geometry-system.d.ts +34 -0
  98. package/dist/systems/geometry/geometry-system.d.ts.map +1 -0
  99. package/dist/systems/geometry/geometry-system.js +279 -0
  100. package/dist/systems/guide/guide-system.d.ts.map +1 -1
  101. package/dist/systems/guide/guide-system.js +1 -26
  102. package/dist/systems/interactive/interactive-system.d.ts +1 -1
  103. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  104. package/dist/systems/item/item-system.d.ts +7 -0
  105. package/dist/systems/item/item-system.d.ts.map +1 -1
  106. package/dist/systems/item/item-system.js +8 -11
  107. package/dist/systems/item-light/item-light-system.d.ts +1 -1
  108. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  109. package/dist/systems/item-light/item-light-system.js +18 -5
  110. package/dist/systems/roof/roof-materials.d.ts +3 -2
  111. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  112. package/dist/systems/roof/roof-materials.js +38 -14
  113. package/dist/systems/roof/roof-system.d.ts +27 -0
  114. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  115. package/dist/systems/roof/roof-system.js +411 -71
  116. package/dist/systems/scan/scan-system.d.ts.map +1 -1
  117. package/dist/systems/scan/scan-system.js +1 -26
  118. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  119. package/dist/systems/slab/slab-system.js +167 -49
  120. package/dist/systems/slab/slab-system.test.d.ts +2 -0
  121. package/dist/systems/slab/slab-system.test.d.ts.map +1 -0
  122. package/dist/systems/slab/slab-system.test.js +62 -0
  123. package/dist/systems/stair/stair-materials.d.ts +4 -3
  124. package/dist/systems/stair/stair-materials.d.ts.map +1 -1
  125. package/dist/systems/stair/stair-materials.js +30 -15
  126. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  127. package/dist/systems/stair/stair-system.js +58 -71
  128. package/dist/systems/surface-hole-geometry.d.ts +3 -0
  129. package/dist/systems/surface-hole-geometry.d.ts.map +1 -0
  130. package/dist/systems/surface-hole-geometry.js +4 -0
  131. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  132. package/dist/systems/wall/wall-cutout.js +18 -2
  133. package/dist/systems/wall/wall-materials.d.ts +4 -3
  134. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  135. package/dist/systems/wall/wall-materials.js +52 -28
  136. package/dist/systems/wall/wall-system.d.ts +1 -1
  137. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  138. package/dist/systems/wall/wall-system.js +179 -31
  139. package/dist/systems/window/window-system.d.ts.map +1 -1
  140. package/dist/systems/window/window-system.js +71 -7
  141. package/package.json +4 -5
  142. package/dist/components/renderers/building/building-renderer.d.ts +0 -5
  143. package/dist/components/renderers/building/building-renderer.d.ts.map +0 -1
  144. package/dist/components/renderers/building/building-renderer.js +0 -11
  145. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts +0 -5
  146. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +0 -1
  147. package/dist/components/renderers/ceiling/ceiling-renderer.js +0 -58
  148. package/dist/components/renderers/column/column-renderer.d.ts +0 -5
  149. package/dist/components/renderers/column/column-renderer.d.ts.map +0 -1
  150. package/dist/components/renderers/column/column-renderer.js +0 -594
  151. package/dist/components/renderers/door/door-renderer.d.ts +0 -5
  152. package/dist/components/renderers/door/door-renderer.d.ts.map +0 -1
  153. package/dist/components/renderers/door/door-renderer.js +0 -16
  154. package/dist/components/renderers/fence/fence-renderer.d.ts +0 -5
  155. package/dist/components/renderers/fence/fence-renderer.d.ts.map +0 -1
  156. package/dist/components/renderers/fence/fence-renderer.js +0 -29
  157. package/dist/components/renderers/guide/guide-renderer.d.ts +0 -5
  158. package/dist/components/renderers/guide/guide-renderer.d.ts.map +0 -1
  159. package/dist/components/renderers/guide/guide-renderer.js +0 -38
  160. package/dist/components/renderers/item/item-renderer.d.ts +0 -5
  161. package/dist/components/renderers/item/item-renderer.d.ts.map +0 -1
  162. package/dist/components/renderers/item/item-renderer.js +0 -172
  163. package/dist/components/renderers/level/level-renderer.d.ts +0 -5
  164. package/dist/components/renderers/level/level-renderer.d.ts.map +0 -1
  165. package/dist/components/renderers/level/level-renderer.js +0 -11
  166. package/dist/components/renderers/roof/roof-materials.d.ts +0 -4
  167. package/dist/components/renderers/roof/roof-materials.d.ts.map +0 -1
  168. package/dist/components/renderers/roof/roof-materials.js +0 -16
  169. package/dist/components/renderers/roof/roof-renderer.d.ts +0 -5
  170. package/dist/components/renderers/roof/roof-renderer.d.ts.map +0 -1
  171. package/dist/components/renderers/roof/roof-renderer.js +0 -32
  172. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts +0 -5
  173. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +0 -1
  174. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +0 -40
  175. package/dist/components/renderers/scan/scan-renderer.d.ts +0 -5
  176. package/dist/components/renderers/scan/scan-renderer.d.ts.map +0 -1
  177. package/dist/components/renderers/scan/scan-renderer.js +0 -54
  178. package/dist/components/renderers/site/site-renderer.d.ts +0 -5
  179. package/dist/components/renderers/site/site-renderer.d.ts.map +0 -1
  180. package/dist/components/renderers/site/site-renderer.js +0 -106
  181. package/dist/components/renderers/slab/slab-renderer.d.ts +0 -5
  182. package/dist/components/renderers/slab/slab-renderer.d.ts.map +0 -1
  183. package/dist/components/renderers/slab/slab-renderer.js +0 -58
  184. package/dist/components/renderers/spawn/spawn-renderer.d.ts +0 -5
  185. package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +0 -1
  186. package/dist/components/renderers/spawn/spawn-renderer.js +0 -32
  187. package/dist/components/renderers/stair/stair-renderer.d.ts +0 -5
  188. package/dist/components/renderers/stair/stair-renderer.d.ts.map +0 -1
  189. package/dist/components/renderers/stair/stair-renderer.js +0 -603
  190. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts +0 -5
  191. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +0 -1
  192. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +0 -32
  193. package/dist/components/renderers/wall/wall-renderer.d.ts +0 -5
  194. package/dist/components/renderers/wall/wall-renderer.d.ts.map +0 -1
  195. package/dist/components/renderers/wall/wall-renderer.js +0 -16
  196. package/dist/components/renderers/window/window-renderer.d.ts +0 -5
  197. package/dist/components/renderers/window/window-renderer.d.ts.map +0 -1
  198. package/dist/components/renderers/window/window-renderer.js +0 -21
  199. package/dist/components/renderers/zone/zone-renderer.d.ts +0 -5
  200. package/dist/components/renderers/zone/zone-renderer.d.ts.map +0 -1
  201. package/dist/components/renderers/zone/zone-renderer.js +0 -181
  202. package/dist/lib/suppress-three-clock-warning.d.ts +0 -25
  203. package/dist/lib/suppress-three-clock-warning.d.ts.map +0 -1
  204. package/dist/lib/suppress-three-clock-warning.js +0 -51
  205. package/dist/systems/export/export-system.d.ts +0 -2
  206. package/dist/systems/export/export-system.d.ts.map +0 -1
  207. package/dist/systems/export/export-system.js +0 -60
  208. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts +0 -14
  209. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts.map +0 -1
  210. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.js +0 -155
  211. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts +0 -6
  212. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts.map +0 -1
  213. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.js +0 -75
  214. package/dist/systems/item-mesh-metadata/sync-request.d.ts +0 -7
  215. package/dist/systems/item-mesh-metadata/sync-request.d.ts.map +0 -1
  216. package/dist/systems/item-mesh-metadata/sync-request.js +0 -25
@@ -1,6 +1,5 @@
1
+ import { getEffectiveNode, getFloorStackedPosition, sceneRegistry, useScene, } from '@pascal-app/core';
1
2
  import { useFrame } from '@react-three/fiber';
2
- import { resolveLevelId, sceneRegistry, spatialGridManager, syncAutoStairOpenings, useScene, } from '@pascal-app/core';
3
- import { useEffect, useRef } from 'react';
4
3
  import * as THREE from 'three';
5
4
  import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
6
5
  const pendingStairUpdates = new Set();
@@ -17,26 +16,6 @@ export const StairSystem = () => {
17
16
  const dirtyNodes = useScene((state) => state.dirtyNodes);
18
17
  const clearDirty = useScene((state) => state.clearDirty);
19
18
  const rootNodeIds = useScene((state) => state.rootNodeIds);
20
- const syncingAutoOpeningsRef = useRef(false);
21
- useEffect(() => {
22
- const applyUpdates = (updates) => {
23
- if (updates.length === 0)
24
- return;
25
- syncingAutoOpeningsRef.current = true;
26
- useScene.getState().updateNodes(updates);
27
- queueMicrotask(() => {
28
- syncingAutoOpeningsRef.current = false;
29
- });
30
- };
31
- applyUpdates(syncAutoStairOpenings(useScene.getState().nodes));
32
- return useScene.subscribe((state, prevState) => {
33
- if (syncingAutoOpeningsRef.current)
34
- return;
35
- if (state.nodes === prevState.nodes)
36
- return;
37
- applyUpdates(syncAutoStairOpenings(state.nodes));
38
- });
39
- }, []);
40
19
  useFrame(() => {
41
20
  if (rootNodeIds.length === 0) {
42
21
  pendingStairUpdates.clear();
@@ -58,8 +37,13 @@ export const StairSystem = () => {
58
37
  if (mesh) {
59
38
  const isVisible = mesh.parent?.visible !== false;
60
39
  if (isVisible && segmentsProcessed < MAX_SEGMENTS_PER_FRAME) {
61
- // Geometry will be updated; chained position is applied in the parent sync pass below
62
- updateStairSegmentGeometry(node, mesh);
40
+ // Geometry will be updated; chained position is applied in the parent sync pass below.
41
+ // Merge live overrides so width / length / height drags update the
42
+ // mesh in real time — the resize arrows publish to
43
+ // `useLiveNodeOverrides` and only commit to scene on pointer-up, so
44
+ // without this the geometry would rebuild from the pre-drag values.
45
+ const effectiveSegment = getEffectiveNode(node);
46
+ updateStairSegmentGeometry(effectiveSegment, mesh);
63
47
  if (node.parentId)
64
48
  parentsNeedingSegmentSync.add(node.parentId);
65
49
  segmentsProcessed++;
@@ -68,11 +52,9 @@ export const StairSystem = () => {
68
52
  return; // Over budget — keep dirty, process next frame
69
53
  }
70
54
  else if (mesh.geometry.type === 'BoxGeometry') {
71
- // Replace BoxGeometry placeholder with empty geometry
55
+ // Replace BoxGeometry placeholder with a non-drawing degenerate one.
72
56
  mesh.geometry.dispose();
73
- const placeholder = new THREE.BufferGeometry();
74
- placeholder.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
75
- mesh.geometry = placeholder;
57
+ mesh.geometry = createEmptyGeometry();
76
58
  }
77
59
  clearDirty(id);
78
60
  }
@@ -93,9 +75,17 @@ export const StairSystem = () => {
93
75
  });
94
76
  // --- Pass 1b: Sync chained transforms to individual segment meshes (edit mode) ---
95
77
  for (const stairId of parentsNeedingSegmentSync) {
96
- const stairNode = nodes[stairId];
97
- if (!stairNode || stairNode.type !== 'stair')
78
+ const baseStairNode = nodes[stairId];
79
+ if (!baseStairNode || baseStairNode.type !== 'stair')
98
80
  continue;
81
+ // Merge any in-flight drag override (e.g. parent-stair rotate handle)
82
+ // so slab-elevation spatial queries match where the segments are
83
+ // actually being rendered. Without this, dragging the rotate gizmo
84
+ // looks up slabs at the pre-drag world XZ — if rotation carries a
85
+ // segment off the original slab footprint, the floor-stack
86
+ // resolver would otherwise read the pre-drag footprint and drop
87
+ // the flight or landing below the floor mid-drag.
88
+ const stairNode = getEffectiveNode(baseStairNode);
99
89
  const group = sceneRegistry.nodes.get(stairId);
100
90
  if (group) {
101
91
  syncStairGroupElevation(stairNode, group, nodes);
@@ -217,9 +207,14 @@ function updateStairSegmentGeometry(node, mesh) {
217
207
  * not by the node's stored position field.
218
208
  */
219
209
  function syncSegmentMeshTransforms(stairNode, nodes) {
210
+ // Merge live overrides into each segment so the chain math reflects the
211
+ // in-flight drag (a width / length change shifts every downstream segment's
212
+ // anchor). Without this, dragging a width handle would resize the dragged
213
+ // segment's mesh but leave subsequent segments at their pre-drag positions.
220
214
  const segments = (stairNode.children ?? [])
221
215
  .map((childId) => nodes[childId])
222
- .filter((n) => n?.type === 'stair-segment');
216
+ .filter((n) => n?.type === 'stair-segment')
217
+ .map((n) => getEffectiveNode(n));
223
218
  if (segments.length === 0)
224
219
  return;
225
220
  const transforms = computeSegmentTransforms(segments);
@@ -234,35 +229,20 @@ function syncSegmentMeshTransforms(stairNode, nodes) {
234
229
  }
235
230
  }
236
231
  function syncStairGroupElevation(stairNode, group, nodes) {
237
- const levelId = resolveLevelId(stairNode, nodes);
238
- const slabElevation = getStairSlabElevation(levelId, stairNode, nodes);
239
- group.position.y = stairNode.position[1] + slabElevation;
240
- }
241
- function getStairSlabElevation(levelId, stairNode, nodes) {
242
- const segments = (stairNode.children ?? [])
243
- .map((childId) => nodes[childId])
244
- .filter((n) => n?.type === 'stair-segment');
245
- if (segments.length === 0)
246
- return 0;
247
- const transforms = computeSegmentTransforms(segments);
248
- let maxElevation = Number.NEGATIVE_INFINITY;
249
- for (let i = 0; i < segments.length; i++) {
250
- const segment = segments[i];
251
- const transform = transforms[i];
252
- const [centerOffsetX, centerOffsetZ] = rotateXZ(0, segment.length / 2, transform.rotation);
253
- const centerInGroupX = transform.position[0] + centerOffsetX;
254
- const centerInGroupZ = transform.position[2] + centerOffsetZ;
255
- const [centerOffsetWorldX, centerOffsetWorldZ] = rotateXZ(centerInGroupX, centerInGroupZ, stairNode.rotation);
256
- const slabElevation = spatialGridManager.getSlabElevationForItem(levelId, [
257
- stairNode.position[0] + centerOffsetWorldX,
258
- stairNode.position[1] + transform.position[1],
259
- stairNode.position[2] + centerOffsetWorldZ,
260
- ], [segment.width, Math.max(segment.height, segment.thickness, 0.01), segment.length], [0, stairNode.rotation + transform.rotation, 0]);
261
- if (slabElevation > maxElevation) {
262
- maxElevation = slabElevation;
232
+ const effectiveNodes = { ...nodes, [stairNode.id]: stairNode };
233
+ for (const childId of stairNode.children ?? []) {
234
+ const segment = nodes[childId];
235
+ if (segment?.type === 'stair-segment') {
236
+ effectiveNodes[segment.id] = getEffectiveNode(segment);
263
237
  }
264
238
  }
265
- return maxElevation === Number.NEGATIVE_INFINITY ? 0 : maxElevation;
239
+ const visualPosition = getFloorStackedPosition({
240
+ node: stairNode,
241
+ nodes: effectiveNodes,
242
+ position: stairNode.position,
243
+ rotation: stairNode.rotation,
244
+ });
245
+ group.position.y = visualPosition[1];
266
246
  }
267
247
  // ============================================================================
268
248
  // MERGED STAIR GEOMETRY
@@ -281,9 +261,14 @@ function updateMergedStairGeometry(stairNode, group, nodes) {
281
261
  return;
282
262
  }
283
263
  const children = stairNode.children ?? [];
264
+ // Merge live overrides — same reason as `syncSegmentMeshTransforms`: a
265
+ // width / length / height drag publishes the new value to
266
+ // `useLiveNodeOverrides`, so the merged geometry has to read through that
267
+ // overlay or the merged mesh stays at pre-drag values until pointer-up.
284
268
  const segments = children
285
269
  .map((childId) => nodes[childId])
286
- .filter((n) => n?.type === 'stair-segment');
270
+ .filter((n) => n?.type === 'stair-segment')
271
+ .map((n) => getEffectiveNode(n));
287
272
  if (segments.length === 0) {
288
273
  replaceMeshGeometry(mergedMesh, createEmptyGeometry());
289
274
  return;
@@ -362,7 +347,7 @@ function applyStraightStairMaterialGroups(geometry) {
362
347
  function applyStairSegmentUvs(geometry) {
363
348
  const position = geometry.getAttribute('position');
364
349
  const normal = geometry.getAttribute('normal');
365
- if (!position || !normal || position.count === 0) {
350
+ if (!(position && normal) || position.count === 0) {
366
351
  geometry.deleteAttribute('uv');
367
352
  return;
368
353
  }
@@ -444,7 +429,11 @@ function rotateXZ(x, z, angle) {
444
429
  }
445
430
  function createEmptyGeometry() {
446
431
  const geometry = new THREE.BufferGeometry();
447
- geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
432
+ // Three zero-vertices (one degenerate, invisible triangle), not an empty
433
+ // attribute: an empty position (count 0) leaves WebGPU vertex buffer slot 0
434
+ // unbound and the draw is rejected ("Vertex buffer slot 0 … was not set"),
435
+ // poisoning the command encoder. The count-0 groups keep nothing drawn.
436
+ geometry.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(9), 3));
448
437
  geometry.addGroup(0, 0, STAIR_TREAD_MATERIAL_INDEX);
449
438
  geometry.addGroup(0, 0, STAIR_SIDE_MATERIAL_INDEX);
450
439
  return geometry;
@@ -479,7 +468,7 @@ function generateStairRailingGeometry(stairNode, segments, transforms) {
479
468
  for (let index = 1; index < segmentRailPaths.length; index++) {
480
469
  const previousPath = segmentRailPaths[index - 1];
481
470
  const currentPath = segmentRailPaths[index];
482
- if (!(previousPath && currentPath && currentPath.connectFromPrevious))
471
+ if (!(previousPath && currentPath?.connectFromPrevious))
483
472
  continue;
484
473
  if (previousPath.segment.segmentType === 'landing')
485
474
  continue;
@@ -554,9 +543,9 @@ function buildStairRailPaths(segments, transforms, railingMode, inset, landingIn
554
543
  return {
555
544
  segment,
556
545
  sidePaths: isStraightLineDoubleLandingLayout && index === 1
557
- ? (['left', 'right']
546
+ ? ['left', 'right']
558
547
  .map((side) => buildSegmentRailPath(layout, side, previousSegment, nextSegment, inset, landingInset))
559
- .filter((entry) => entry !== null))
548
+ .filter((entry) => entry !== null)
560
549
  : sidePaths,
561
550
  connectFromPrevious: index > 0 &&
562
551
  !(previousSegment?.segmentType === 'landing' && segment.segmentType === 'landing'),
@@ -652,7 +641,9 @@ function buildSegmentRailPath(layout, side, previousSegment, nextSegment, inset,
652
641
  const segmentStepHeight = segment.segmentType === 'landing' ? 0 : segment.height / segmentSteps;
653
642
  const segmentTopThickness = getSegmentTopThickness(segment);
654
643
  const flightSideOffset = side === 'left' ? segment.width / 2 - 0.045 : -segment.width / 2 + 0.045;
655
- const flightStartX = previousSegment?.segmentType === 'landing' ? -segment.length / 2 + landingInset : -segment.length / 2;
644
+ const flightStartX = previousSegment?.segmentType === 'landing'
645
+ ? -segment.length / 2 + landingInset
646
+ : -segment.length / 2;
656
647
  const flightEndX = nextSegment?.segmentType === 'landing' ? segment.length / 2 - landingInset : segment.length / 2;
657
648
  if (segment.segmentType === 'landing') {
658
649
  return buildLandingRailPathFromScratch(layout, side, previousSegment, nextSegment, segmentTopThickness, landingInset);
@@ -662,15 +653,11 @@ function buildSegmentRailPath(layout, side, previousSegment, nextSegment, inset,
662
653
  points: [
663
654
  ...(previousSegment?.segmentType === 'landing'
664
655
  ? []
665
- : [
666
- toRailLayoutWorldPoint(layout, flightStartX, segmentTopThickness, flightSideOffset),
667
- ]),
656
+ : [toRailLayoutWorldPoint(layout, flightStartX, segmentTopThickness, flightSideOffset)]),
668
657
  ...Array.from({ length: segmentSteps }).map((_, index) => toRailLayoutWorldPoint(layout, -segment.length / 2 + segmentStepDepth * index + segmentStepDepth / 2, segmentStepHeight * (index + 1), flightSideOffset)),
669
658
  ...(nextSegment?.segmentType === 'landing'
670
659
  ? []
671
- : [
672
- toRailLayoutWorldPoint(layout, flightEndX, segment.height, flightSideOffset),
673
- ]),
660
+ : [toRailLayoutWorldPoint(layout, flightEndX, segment.height, flightSideOffset)]),
674
661
  ],
675
662
  };
676
663
  }
@@ -0,0 +1,3 @@
1
+ import { type Point2D } from '../lib/polygon-union';
2
+ export declare function mergeSurfaceHolePolygons(holes: Point2D[][]): Point2D[][];
3
+ //# sourceMappingURL=surface-hole-geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-hole-geometry.d.ts","sourceRoot":"","sources":["../../src/systems/surface-hole-geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,sBAAsB,CAAA;AAElE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,CAExE"}
@@ -0,0 +1,4 @@
1
+ import { unionPolygons } from '../lib/polygon-union';
2
+ export function mergeSurfaceHolePolygons(holes) {
3
+ return unionPolygons(holes);
4
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"wall-cutout.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-cutout.tsx"],"names":[],"mappings":"AAsCA,eAAO,MAAM,UAAU,YAkHtB,CAAA"}
1
+ {"version":3,"file":"wall-cutout.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-cutout.tsx"],"names":[],"mappings":"AAsCA,eAAO,MAAM,UAAU,YAwItB,CAAA"}
@@ -33,10 +33,18 @@ export const WallCutout = () => {
33
33
  const lastCameraTarget = useRef(new Vector3());
34
34
  const lastUpdateTime = useRef(0);
35
35
  const lastWallMode = useRef(useViewer.getState().wallMode);
36
+ const lastShading = useRef(useViewer.getState().shading);
36
37
  const lastNumberOfWalls = useRef(0);
37
38
  const lastHighlightKey = useRef('');
39
+ const lastTextures = useRef(useViewer.getState().textures);
40
+ const lastColorPreset = useRef(useViewer.getState().colorPreset);
41
+ const lastSceneTheme = useRef(useViewer.getState().sceneTheme);
38
42
  useFrame(({ camera, clock }) => {
39
43
  const wallMode = useViewer.getState().wallMode;
44
+ const shading = useViewer.getState().shading;
45
+ const textures = useViewer.getState().textures;
46
+ const colorPreset = useViewer.getState().colorPreset;
47
+ const sceneTheme = useViewer.getState().sceneTheme;
40
48
  const selectedIds = useViewer.getState().selection.selectedIds;
41
49
  const previewSelectedIds = useViewer.getState().previewSelectedIds;
42
50
  const hoveredId = useViewer.getState().hoveredId;
@@ -57,6 +65,10 @@ export const WallCutout = () => {
57
65
  const timeSinceUpdate = currentTime - lastUpdateTime.current;
58
66
  if (((distanceMoved > 0.5 || directionChanged > 0.3) && timeSinceUpdate > 0.1) ||
59
67
  lastWallMode.current !== wallMode ||
68
+ lastShading.current !== shading ||
69
+ lastTextures.current !== textures ||
70
+ lastColorPreset.current !== colorPreset ||
71
+ lastSceneTheme.current !== sceneTheme ||
60
72
  sceneRegistry.byType.wall.size !== lastNumberOfWalls.current ||
61
73
  lastHighlightKey.current !== highlightKey) {
62
74
  lastCameraPosition.current.copy(currentCameraPosition);
@@ -74,7 +86,7 @@ export const WallCutout = () => {
74
86
  const hideWall = getWallHideState(wallNode, wallMesh, wallMode, u);
75
87
  const isDeleteHighlighted = deleteHoveredWallId === wallId;
76
88
  const isSelectionHighlighted = !isDeleteHighlighted && highlightedWallIds.has(wallId);
77
- const materials = getMaterialsForWall(wallNode);
89
+ const materials = getMaterialsForWall(wallNode, shading, textures, colorPreset, sceneTheme);
78
90
  if (hideWall) {
79
91
  ;
80
92
  wallMesh.material = isDeleteHighlighted
@@ -93,6 +105,10 @@ export const WallCutout = () => {
93
105
  }
94
106
  });
95
107
  lastWallMode.current = wallMode;
108
+ lastShading.current = shading;
109
+ lastTextures.current = textures;
110
+ lastColorPreset.current = colorPreset;
111
+ lastSceneTheme.current = sceneTheme;
96
112
  lastNumberOfWalls.current = sceneRegistry.byType.wall.size;
97
113
  lastHighlightKey.current = highlightKey;
98
114
  }
@@ -107,7 +123,7 @@ export const WallCutout = () => {
107
123
  const wallNode = useScene.getState().nodes[wallId];
108
124
  if (!wallNode || wallNode.type !== 'wall')
109
125
  return;
110
- const mats = getMaterialsForWall(wallNode);
126
+ const mats = getMaterialsForWall(wallNode, useViewer.getState().shading, useViewer.getState().textures, useViewer.getState().colorPreset, useViewer.getState().sceneTheme);
111
127
  const current = wallMesh.material;
112
128
  snapshot.set(wallMesh, current);
113
129
  if (current === mats.highlightedVisible || current === mats.deleteVisible) {
@@ -1,5 +1,6 @@
1
1
  import { type WallNode } from '@pascal-app/core';
2
2
  import { type Material } from 'three';
3
+ import { type ColorPreset, type RenderShading } from '../../lib/materials';
3
4
  export type WallMaterialArray = [Material, Material, Material];
4
5
  export interface WallMaterials {
5
6
  visible: WallMaterialArray;
@@ -10,7 +11,7 @@ export interface WallMaterials {
10
11
  highlightedInvisible: WallMaterialArray;
11
12
  materialHash: string;
12
13
  }
13
- export declare function getWallMaterialHash(wallNode: WallNode): string;
14
- export declare function getMaterialsForWall(wallNode: WallNode): WallMaterials;
15
- export declare function getVisibleWallMaterials(wallNode: WallNode): WallMaterialArray;
14
+ export declare function getWallMaterialHash(wallNode: WallNode, shading: RenderShading): string;
15
+ export declare function getMaterialsForWall(wallNode: WallNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string): WallMaterials;
16
+ export declare function getVisibleWallMaterials(wallNode: WallNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string): WallMaterialArray;
16
17
  //# sourceMappingURL=wall-materials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wall-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAwB5C,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,iBAAiB,CAAA;IAC1B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,aAAa,EAAE,iBAAiB,CAAA;IAChC,eAAe,EAAE,iBAAiB,CAAA;IAClC,kBAAkB,EAAE,iBAAiB,CAAA;IACrC,oBAAoB,EAAE,iBAAiB,CAAA;IACvC,YAAY,EAAE,MAAM,CAAA;CACrB;AA4GD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAS9D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CA2DrE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CAE7E"}
1
+ {"version":3,"file":"wall-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAG5C,OAAO,EAEL,KAAK,WAAW,EAIhB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAA;AAqB5B,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAE9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,iBAAiB,CAAA;IAC1B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,aAAa,EAAE,iBAAiB,CAAA;IAChC,eAAe,EAAE,iBAAiB,CAAA;IAClC,kBAAkB,EAAE,iBAAiB,CAAA;IACrC,oBAAoB,EAAE,iBAAiB,CAAA;IACvC,YAAY,EAAE,MAAM,CAAA;CACrB;AA6HD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAUtF;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM,GAClB,aAAa,CA6Ef;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM,GAClB,iBAAiB,CAEnB"}
@@ -1,8 +1,8 @@
1
1
  import { getEffectiveWallSurfaceMaterial, getMaterialPresetByRef, getWallSurfaceMaterialSignature, resolveMaterial, } 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
- import { MeshStandardNodeMaterial } from 'three/webgpu';
5
- import { baseMaterial, createMaterial, createMaterialFromPresetRef } from '../../lib/materials';
4
+ import { MeshLambertNodeMaterial, MeshStandardNodeMaterial } from 'three/webgpu';
5
+ import { baseMaterial, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, resolveSurfaceColor, } from '../../lib/materials';
6
6
  const DEFAULT_WALL_COLOR = '#f2f0ed';
7
7
  const WALL_HIGHLIGHT_PROFILES = {
8
8
  delete: {
@@ -30,14 +30,17 @@ const dotPattern = Fn(() => {
30
30
  const yFade = float(1).sub(smoothstep(float(0), fadeHeight, positionLocal.y));
31
31
  return dots.mul(yFade);
32
32
  });
33
- function getSurfaceVisibleMaterial(spec) {
33
+ function getSurfaceVisibleMaterial(spec, shading) {
34
34
  if (spec.materialPreset) {
35
- return createMaterialFromPresetRef(spec.materialPreset) ?? baseMaterial;
35
+ return createMaterialFromPresetRef(spec.materialPreset, shading) ?? baseMaterial(shading);
36
36
  }
37
37
  if (spec.material) {
38
- return createMaterial(spec.material);
38
+ return createMaterial(spec.material, shading);
39
39
  }
40
- return baseMaterial;
40
+ return baseMaterial(shading);
41
+ }
42
+ function hasExplicitMaterial(spec) {
43
+ return Boolean(spec.materialPreset || spec.material);
41
44
  }
42
45
  function getSurfaceColor(spec, fallback = DEFAULT_WALL_COLOR) {
43
46
  const preset = getMaterialPresetByRef(spec.materialPreset);
@@ -70,14 +73,22 @@ function createHighlightedWallMaterial(material, kind) {
70
73
  highlightedMaterial.needsUpdate = true;
71
74
  return highlightedMaterial;
72
75
  }
73
- function createInvisibleWallMaterial(color) {
74
- return new MeshStandardNodeMaterial({
75
- transparent: true,
76
- opacityNode: mix(float(0.0), float(0.24), dotPattern()),
77
- color,
78
- depthWrite: false,
79
- emissive: color,
80
- });
76
+ function createInvisibleWallMaterial(color, shading) {
77
+ const material = shading === 'solid'
78
+ ? new MeshLambertNodeMaterial({
79
+ transparent: true,
80
+ color,
81
+ depthWrite: false,
82
+ emissive: color,
83
+ })
84
+ : new MeshStandardNodeMaterial({
85
+ transparent: true,
86
+ color,
87
+ depthWrite: false,
88
+ emissive: color,
89
+ });
90
+ material.opacityNode = mix(float(0.0), float(0.24), dotPattern());
91
+ return material;
81
92
  }
82
93
  function mapWallMaterialArray(materials, iteratee) {
83
94
  return materials.map(iteratee);
@@ -93,15 +104,18 @@ function disposeOwnedMaterials(materials) {
93
104
  material.dispose();
94
105
  });
95
106
  }
96
- export function getWallMaterialHash(wallNode) {
107
+ export function getWallMaterialHash(wallNode, shading) {
97
108
  return JSON.stringify({
109
+ shading,
98
110
  interior: getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(wallNode, 'interior')),
99
111
  exterior: getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(wallNode, 'exterior')),
100
112
  });
101
113
  }
102
- export function getMaterialsForWall(wallNode) {
103
- const cacheKey = wallNode.id;
104
- const materialHash = getWallMaterialHash(wallNode);
114
+ export function getMaterialsForWall(wallNode, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme) {
115
+ const cacheKey = `${wallNode.id}-${shading}-${textures}-${colorPreset}-${sceneTheme ?? 'base'}`;
116
+ const materialHash = textures
117
+ ? getWallMaterialHash(wallNode, shading)
118
+ : JSON.stringify({ textures, colorPreset, sceneTheme });
105
119
  const existing = wallMaterialCache.get(cacheKey);
106
120
  if (existing && existing.materialHash === materialHash) {
107
121
  return existing;
@@ -117,15 +131,25 @@ export function getMaterialsForWall(wallNode) {
117
131
  }
118
132
  const interiorSpec = getEffectiveWallSurfaceMaterial(wallNode, 'interior');
119
133
  const exteriorSpec = getEffectiveWallSurfaceMaterial(wallNode, 'exterior');
120
- const visible = [
121
- baseMaterial,
122
- getSurfaceVisibleMaterial(interiorSpec),
123
- getSurfaceVisibleMaterial(exteriorSpec),
124
- ];
134
+ const wallRoleMaterial = createSurfaceRoleMaterial('wall', colorPreset, undefined, sceneTheme);
135
+ // Untextured surfaces take the themed wall role colour even with textures on;
136
+ // only surfaces with an explicit preset/material keep their texture.
137
+ const visible = textures
138
+ ? [
139
+ wallRoleMaterial,
140
+ hasExplicitMaterial(interiorSpec)
141
+ ? getSurfaceVisibleMaterial(interiorSpec, shading)
142
+ : wallRoleMaterial,
143
+ hasExplicitMaterial(exteriorSpec)
144
+ ? getSurfaceVisibleMaterial(exteriorSpec, shading)
145
+ : wallRoleMaterial,
146
+ ]
147
+ : [wallRoleMaterial, wallRoleMaterial, wallRoleMaterial];
148
+ const wallRoleColor = resolveSurfaceColor('wall', colorPreset, sceneTheme);
125
149
  const invisible = [
126
- createInvisibleWallMaterial(DEFAULT_WALL_COLOR),
127
- createInvisibleWallMaterial(getSurfaceColor(interiorSpec, DEFAULT_WALL_COLOR)),
128
- createInvisibleWallMaterial(getSurfaceColor(exteriorSpec, DEFAULT_WALL_COLOR)),
150
+ createInvisibleWallMaterial(wallRoleColor, textures ? shading : 'solid'),
151
+ createInvisibleWallMaterial(textures ? getSurfaceColor(interiorSpec, wallRoleColor) : wallRoleColor, textures ? shading : 'solid'),
152
+ createInvisibleWallMaterial(textures ? getSurfaceColor(exteriorSpec, wallRoleColor) : wallRoleColor, textures ? shading : 'solid'),
129
153
  ];
130
154
  const highlightedVisible = mapWallMaterialArray(visible, (material) => createHighlightedWallMaterial(material, 'selection'));
131
155
  const highlightedInvisible = mapWallMaterialArray(invisible, (material) => createHighlightedWallMaterial(material, 'selection'));
@@ -143,6 +167,6 @@ export function getMaterialsForWall(wallNode) {
143
167
  wallMaterialCache.set(cacheKey, result);
144
168
  return result;
145
169
  }
146
- export function getVisibleWallMaterials(wallNode) {
147
- return getMaterialsForWall(wallNode).visible;
170
+ export function getVisibleWallMaterials(wallNode, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme) {
171
+ return getMaterialsForWall(wallNode, shading, textures, colorPreset, sceneTheme).visible;
148
172
  }
@@ -7,5 +7,5 @@ export declare const WallSystem: () => null;
7
7
  * Key insight from demo: polygon is built in WORLD coordinates first,
8
8
  * then we transform to wall-local for the 3D mesh.
9
9
  */
10
- export declare function generateExtrudedWall(wallNode: WallNode, childrenNodes: AnyNode[], miterData: WallMiterData, slabElevation?: number): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
10
+ export declare function generateExtrudedWall(wallNode: WallNode, childrenNodes: AnyNode[], miterData: WallMiterData, slabElevation?: number): THREE.BufferGeometry;
11
11
  //# 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,EAkBZ,KAAK,aAAa,EAClB,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA6R9B,eAAO,MAAM,UAAU,YAuDtB,CAAA;AA0DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,OAAO,EAAE,EACxB,SAAS,EAAE,aAAa,EACxB,aAAa,SAAI,oFA0GlB"}
1
+ {"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAqBZ,KAAK,aAAa,EAClB,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA8T9B,eAAO,MAAM,UAAU,YAwJtB,CAAA;AAkGD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,OAAO,EAAE,EACxB,SAAS,EAAE,aAAa,EACxB,aAAa,SAAI,GAChB,KAAK,CAAC,cAAc,CAyGtB"}