@pascal-app/viewer 0.8.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 (194) 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/ground-occluder.d.ts +1 -1
  10. package/dist/components/viewer/ground-occluder.d.ts.map +1 -1
  11. package/dist/components/viewer/ground-occluder.js +12 -24
  12. package/dist/components/viewer/index.d.ts +37 -1
  13. package/dist/components/viewer/index.d.ts.map +1 -1
  14. package/dist/components/viewer/index.js +186 -63
  15. package/dist/components/viewer/lights.d.ts +1 -1
  16. package/dist/components/viewer/lights.d.ts.map +1 -1
  17. package/dist/components/viewer/lights.js +170 -43
  18. package/dist/components/viewer/perf-monitor.d.ts +1 -1
  19. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  20. package/dist/components/viewer/perf-monitor.js +99 -11
  21. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  22. package/dist/components/viewer/post-processing.js +231 -54
  23. package/dist/components/viewer/registered-systems.d.ts +12 -0
  24. package/dist/components/viewer/registered-systems.d.ts.map +1 -0
  25. package/dist/components/viewer/registered-systems.js +47 -0
  26. package/dist/components/viewer/scene-bvh.d.ts +17 -0
  27. package/dist/components/viewer/scene-bvh.d.ts.map +1 -0
  28. package/dist/components/viewer/scene-bvh.js +94 -0
  29. package/dist/components/viewer/selection-manager.d.ts +1 -1
  30. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  31. package/dist/components/viewer/selection-manager.js +20 -5
  32. package/dist/components/viewer/viewer-camera.d.ts +1 -1
  33. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  34. package/dist/components/viewer/walkthrough-controls.d.ts +1 -1
  35. package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
  36. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  37. package/dist/hooks/use-node-events.d.ts +5 -73
  38. package/dist/hooks/use-node-events.d.ts.map +1 -1
  39. package/dist/hooks/use-node-events.js +19 -7
  40. package/dist/index.d.ts +36 -4
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +67 -3
  43. package/dist/lib/csg-utils.d.ts +16 -0
  44. package/dist/lib/csg-utils.d.ts.map +1 -0
  45. package/dist/lib/csg-utils.js +33 -0
  46. package/dist/lib/drawable-geometry.d.ts +21 -0
  47. package/dist/lib/drawable-geometry.d.ts.map +1 -0
  48. package/dist/lib/drawable-geometry.js +22 -0
  49. package/dist/lib/edge-style.d.ts +3 -0
  50. package/dist/lib/edge-style.d.ts.map +1 -0
  51. package/dist/lib/edge-style.js +11 -0
  52. package/dist/lib/gpu-perf.d.ts +4 -0
  53. package/dist/lib/gpu-perf.d.ts.map +1 -0
  54. package/dist/lib/gpu-perf.js +23 -0
  55. package/dist/lib/ink-edges.d.ts +9 -0
  56. package/dist/lib/ink-edges.d.ts.map +1 -0
  57. package/dist/lib/ink-edges.js +43 -0
  58. package/dist/lib/isolation.d.ts +39 -0
  59. package/dist/lib/isolation.d.ts.map +1 -0
  60. package/dist/lib/isolation.js +103 -0
  61. package/dist/lib/layers.d.ts +18 -0
  62. package/dist/lib/layers.d.ts.map +1 -1
  63. package/dist/lib/layers.js +18 -0
  64. package/dist/lib/materials.d.ts +25 -15
  65. package/dist/lib/materials.d.ts.map +1 -1
  66. package/dist/lib/materials.js +277 -62
  67. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  68. package/dist/lib/merged-outline-node.js +7 -0
  69. package/dist/lib/polygon-union.d.ts +4 -0
  70. package/dist/lib/polygon-union.d.ts.map +1 -0
  71. package/dist/lib/polygon-union.js +289 -0
  72. package/dist/lib/polygon-union.test.d.ts +2 -0
  73. package/dist/lib/polygon-union.test.d.ts.map +1 -0
  74. package/dist/lib/polygon-union.test.js +105 -0
  75. package/dist/lib/scene-themes.d.ts +29 -0
  76. package/dist/lib/scene-themes.d.ts.map +1 -0
  77. package/dist/lib/scene-themes.js +193 -0
  78. package/dist/store/use-viewer.d.ts +42 -4
  79. package/dist/store/use-viewer.d.ts.map +1 -1
  80. package/dist/store/use-viewer.js +26 -3
  81. package/dist/systems/ceiling/ceiling-system.d.ts +6 -2
  82. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  83. package/dist/systems/ceiling/ceiling-system.js +62 -12
  84. package/dist/systems/door/door-system.d.ts.map +1 -1
  85. package/dist/systems/door/door-system.js +373 -22
  86. package/dist/systems/elevator/elevator-interaction-system.d.ts +2 -0
  87. package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -0
  88. package/dist/systems/elevator/elevator-interaction-system.js +62 -0
  89. package/dist/systems/fence/fence-system.d.ts +3 -0
  90. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  91. package/dist/systems/fence/fence-system.js +9 -5
  92. package/dist/systems/floor-elevation/floor-elevation-system.d.ts +20 -0
  93. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -0
  94. package/dist/systems/floor-elevation/floor-elevation-system.js +78 -0
  95. package/dist/systems/geometry/geometry-system.d.ts +34 -0
  96. package/dist/systems/geometry/geometry-system.d.ts.map +1 -0
  97. package/dist/systems/geometry/geometry-system.js +279 -0
  98. package/dist/systems/interactive/interactive-system.d.ts +1 -1
  99. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  100. package/dist/systems/item/item-system.d.ts +7 -0
  101. package/dist/systems/item/item-system.d.ts.map +1 -1
  102. package/dist/systems/item/item-system.js +8 -11
  103. package/dist/systems/item-light/item-light-system.d.ts +1 -1
  104. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  105. package/dist/systems/item-light/item-light-system.js +18 -5
  106. package/dist/systems/roof/roof-materials.d.ts +3 -2
  107. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  108. package/dist/systems/roof/roof-materials.js +38 -14
  109. package/dist/systems/roof/roof-system.d.ts +27 -0
  110. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  111. package/dist/systems/roof/roof-system.js +396 -59
  112. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  113. package/dist/systems/slab/slab-system.js +167 -49
  114. package/dist/systems/slab/slab-system.test.d.ts +2 -0
  115. package/dist/systems/slab/slab-system.test.d.ts.map +1 -0
  116. package/dist/systems/slab/slab-system.test.js +62 -0
  117. package/dist/systems/stair/stair-materials.d.ts +4 -3
  118. package/dist/systems/stair/stair-materials.d.ts.map +1 -1
  119. package/dist/systems/stair/stair-materials.js +30 -15
  120. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  121. package/dist/systems/stair/stair-system.js +50 -61
  122. package/dist/systems/surface-hole-geometry.d.ts +3 -0
  123. package/dist/systems/surface-hole-geometry.d.ts.map +1 -0
  124. package/dist/systems/surface-hole-geometry.js +4 -0
  125. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  126. package/dist/systems/wall/wall-cutout.js +18 -2
  127. package/dist/systems/wall/wall-materials.d.ts +4 -3
  128. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  129. package/dist/systems/wall/wall-materials.js +52 -28
  130. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  131. package/dist/systems/wall/wall-system.js +171 -26
  132. package/dist/systems/window/window-system.d.ts.map +1 -1
  133. package/dist/systems/window/window-system.js +71 -7
  134. package/package.json +3 -4
  135. package/dist/components/renderers/building/building-renderer.d.ts +0 -5
  136. package/dist/components/renderers/building/building-renderer.d.ts.map +0 -1
  137. package/dist/components/renderers/building/building-renderer.js +0 -11
  138. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts +0 -5
  139. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +0 -1
  140. package/dist/components/renderers/ceiling/ceiling-renderer.js +0 -58
  141. package/dist/components/renderers/column/column-renderer.d.ts +0 -5
  142. package/dist/components/renderers/column/column-renderer.d.ts.map +0 -1
  143. package/dist/components/renderers/column/column-renderer.js +0 -597
  144. package/dist/components/renderers/door/door-renderer.d.ts +0 -5
  145. package/dist/components/renderers/door/door-renderer.d.ts.map +0 -1
  146. package/dist/components/renderers/door/door-renderer.js +0 -16
  147. package/dist/components/renderers/fence/fence-renderer.d.ts +0 -5
  148. package/dist/components/renderers/fence/fence-renderer.d.ts.map +0 -1
  149. package/dist/components/renderers/fence/fence-renderer.js +0 -15
  150. package/dist/components/renderers/guide/guide-renderer.d.ts +0 -5
  151. package/dist/components/renderers/guide/guide-renderer.d.ts.map +0 -1
  152. package/dist/components/renderers/guide/guide-renderer.js +0 -38
  153. package/dist/components/renderers/item/item-renderer.d.ts +0 -5
  154. package/dist/components/renderers/item/item-renderer.d.ts.map +0 -1
  155. package/dist/components/renderers/item/item-renderer.js +0 -172
  156. package/dist/components/renderers/level/level-renderer.d.ts +0 -5
  157. package/dist/components/renderers/level/level-renderer.d.ts.map +0 -1
  158. package/dist/components/renderers/level/level-renderer.js +0 -11
  159. package/dist/components/renderers/roof/roof-materials.d.ts +0 -4
  160. package/dist/components/renderers/roof/roof-materials.d.ts.map +0 -1
  161. package/dist/components/renderers/roof/roof-materials.js +0 -16
  162. package/dist/components/renderers/roof/roof-renderer.d.ts +0 -5
  163. package/dist/components/renderers/roof/roof-renderer.d.ts.map +0 -1
  164. package/dist/components/renderers/roof/roof-renderer.js +0 -32
  165. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts +0 -5
  166. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +0 -1
  167. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +0 -40
  168. package/dist/components/renderers/scan/scan-renderer.d.ts +0 -5
  169. package/dist/components/renderers/scan/scan-renderer.d.ts.map +0 -1
  170. package/dist/components/renderers/scan/scan-renderer.js +0 -54
  171. package/dist/components/renderers/site/site-renderer.d.ts +0 -5
  172. package/dist/components/renderers/site/site-renderer.d.ts.map +0 -1
  173. package/dist/components/renderers/site/site-renderer.js +0 -106
  174. package/dist/components/renderers/slab/slab-renderer.d.ts +0 -5
  175. package/dist/components/renderers/slab/slab-renderer.d.ts.map +0 -1
  176. package/dist/components/renderers/slab/slab-renderer.js +0 -58
  177. package/dist/components/renderers/spawn/spawn-renderer.d.ts +0 -5
  178. package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +0 -1
  179. package/dist/components/renderers/spawn/spawn-renderer.js +0 -32
  180. package/dist/components/renderers/stair/stair-renderer.d.ts +0 -5
  181. package/dist/components/renderers/stair/stair-renderer.d.ts.map +0 -1
  182. package/dist/components/renderers/stair/stair-renderer.js +0 -603
  183. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts +0 -5
  184. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +0 -1
  185. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +0 -51
  186. package/dist/components/renderers/wall/wall-renderer.d.ts +0 -5
  187. package/dist/components/renderers/wall/wall-renderer.d.ts.map +0 -1
  188. package/dist/components/renderers/wall/wall-renderer.js +0 -16
  189. package/dist/components/renderers/window/window-renderer.d.ts +0 -5
  190. package/dist/components/renderers/window/window-renderer.d.ts.map +0 -1
  191. package/dist/components/renderers/window/window-renderer.js +0 -21
  192. package/dist/components/renderers/zone/zone-renderer.d.ts +0 -5
  193. package/dist/components/renderers/zone/zone-renderer.d.ts.map +0 -1
  194. package/dist/components/renderers/zone/zone-renderer.js +0 -181
@@ -1,51 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRegistry, useScene, } from '@pascal-app/core';
3
- import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
4
- import * as THREE from 'three';
5
- import { useNodeEvents } from '../../../hooks/use-node-events';
6
- import { getStraightStairSegmentBodyMaterials } from '../../../systems/stair/stair-materials';
7
- export const StairSegmentRenderer = ({ node }) => {
8
- const ref = useRef(null);
9
- const nodes = useScene((state) => state.nodes);
10
- useRegistry(node.id, 'stair-segment', ref);
11
- useLayoutEffect(() => {
12
- useScene.getState().markDirty(node.id);
13
- }, [node.id]);
14
- const handlers = useNodeEvents(node, 'stair-segment');
15
- const parentNode = node.parentId
16
- ? nodes[node.parentId]
17
- : undefined;
18
- const material = useMemo(() => {
19
- return getStraightStairSegmentBodyMaterials(node, parentNode);
20
- }, [
21
- node.materialPreset,
22
- node.material,
23
- node.material?.preset,
24
- node.material?.properties,
25
- node.material?.texture,
26
- parentNode?.materialPreset,
27
- parentNode?.material,
28
- parentNode?.material?.preset,
29
- parentNode?.material?.properties,
30
- parentNode?.material?.texture,
31
- parentNode?.railingMaterialPreset,
32
- parentNode?.railingMaterial,
33
- parentNode?.sideMaterialPreset,
34
- parentNode?.sideMaterial,
35
- parentNode?.treadMaterialPreset,
36
- parentNode?.treadMaterial,
37
- ]);
38
- const placeholderGeometry = useMemo(() => {
39
- const geometry = new THREE.BufferGeometry();
40
- geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
41
- geometry.addGroup(0, 0, 0);
42
- geometry.addGroup(0, 0, 1);
43
- return geometry;
44
- }, []);
45
- useEffect(() => {
46
- return () => {
47
- placeholderGeometry.dispose();
48
- };
49
- }, [placeholderGeometry]);
50
- return (_jsx("mesh", { geometry: placeholderGeometry, material: material, position: node.position, ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers }));
51
- };
@@ -1,5 +0,0 @@
1
- import { type WallNode } from '@pascal-app/core';
2
- export declare const WallRenderer: ({ node }: {
3
- node: WallNode;
4
- }) => import("react/jsx-runtime").JSX.Element;
5
- //# sourceMappingURL=wall-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wall-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/wall/wall-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAOvE,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAwBxD,CAAA"}
@@ -1,16 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useRegistry, useScene } from '@pascal-app/core';
3
- import { useLayoutEffect, useRef } from 'react';
4
- import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { getVisibleWallMaterials } from '../../../systems/wall/wall-materials';
6
- import { NodeRenderer } from '../node-renderer';
7
- export const WallRenderer = ({ node }) => {
8
- const ref = useRef(null);
9
- useRegistry(node.id, 'wall', ref);
10
- useLayoutEffect(() => {
11
- useScene.getState().markDirty(node.id);
12
- }, [node.id]);
13
- const handlers = useNodeEvents(node, 'wall');
14
- const material = getVisibleWallMaterials(node);
15
- return (_jsxs("mesh", { castShadow: true, material: material, receiveShadow: true, ref: ref, visible: node.visible, children: [_jsx("boxGeometry", { args: [0, 0, 0] }), _jsx("mesh", { name: "collision-mesh", visible: false, ...handlers, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }), node.children.map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, `${node.id}:${childId}`)))] }));
16
- };
@@ -1,5 +0,0 @@
1
- import { type WindowNode } from '@pascal-app/core';
2
- export declare const WindowRenderer: ({ node }: {
3
- node: WindowNode;
4
- }) => import("react/jsx-runtime").JSX.Element;
5
- //# sourceMappingURL=window-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"window-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/window/window-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAMzE,eAAO,MAAM,cAAc,GAAI,UAAU;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,4CA8B5D,CAAA"}
@@ -1,21 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRegistry, useScene } from '@pascal-app/core';
3
- import { useLayoutEffect, useMemo, useRef } from 'react';
4
- import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { createMaterial, DEFAULT_WINDOW_MATERIAL } from '../../../lib/materials';
6
- export const WindowRenderer = ({ node }) => {
7
- const ref = useRef(null);
8
- useRegistry(node.id, 'window', ref);
9
- useLayoutEffect(() => {
10
- useScene.getState().markDirty(node.id);
11
- }, [node.id]);
12
- const handlers = useNodeEvents(node, 'window');
13
- const isTransient = !!node.metadata?.isTransient;
14
- const material = useMemo(() => {
15
- const mat = node.material;
16
- if (!mat)
17
- return DEFAULT_WINDOW_MATERIAL;
18
- return createMaterial(mat);
19
- }, [node.material, node.material?.preset, node.material?.properties, node.material?.texture]);
20
- return (_jsx("mesh", { castShadow: true, material: material, position: node.position, receiveShadow: true, ref: ref, rotation: node.rotation, visible: node.visible, ...(isTransient ? {} : handlers), children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
21
- };
@@ -1,5 +0,0 @@
1
- import { type ZoneNode } from '@pascal-app/core';
2
- export declare const ZoneRenderer: ({ node }: {
3
- node: ZoneNode;
4
- }) => import("react/jsx-runtime").JSX.Element | null;
5
- //# sourceMappingURL=zone-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"zone-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/zone/zone-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAyG7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,mDAqJxD,CAAA"}
@@ -1,181 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useRegistry } from '@pascal-app/core';
3
- import { Html } from '@react-three/drei';
4
- import { useMemo, useRef } from 'react';
5
- import { BufferGeometry, Color, DoubleSide, Float32BufferAttribute, Shape } from 'three';
6
- import { color, float, uniform, uv } from 'three/tsl';
7
- import { MeshBasicNodeMaterial } from 'three/webgpu';
8
- import { useNodeEvents } from '../../../hooks/use-node-events';
9
- import { ZONE_LAYER } from '../../../lib/layers';
10
- const Y_OFFSET = 0.01;
11
- const WALL_HEIGHT = 2.3;
12
- /**
13
- * Creates a gradient material for zone walls using TSL
14
- * Gradient goes from zone color at bottom to transparent at top
15
- */
16
- const createWallGradientMaterial = (zoneColor) => {
17
- const baseColor = color(new Color(zoneColor));
18
- // Use UV y coordinate for vertical gradient (0 at bottom, 1 at top)
19
- const gradientT = uv().y;
20
- const opacity = uniform(0);
21
- // Fade opacity from 0.6 at bottom to 0 at top
22
- const finalOpacity = float(0.6).mul(float(1).sub(gradientT)).mul(opacity);
23
- return new MeshBasicNodeMaterial({
24
- transparent: true,
25
- colorNode: baseColor,
26
- opacityNode: finalOpacity,
27
- side: DoubleSide,
28
- depthWrite: true,
29
- depthTest: false,
30
- userData: {
31
- uOpacity: opacity,
32
- },
33
- });
34
- };
35
- /**
36
- * Creates a floor material for zones using TSL
37
- */
38
- const createFloorMaterial = (zoneColor) => {
39
- const baseColor = color(new Color(zoneColor));
40
- const opacity = uniform(0);
41
- return new MeshBasicNodeMaterial({
42
- transparent: true,
43
- colorNode: baseColor,
44
- opacityNode: float(0.25).mul(opacity),
45
- side: DoubleSide,
46
- depthWrite: false,
47
- depthTest: false,
48
- userData: { uOpacity: opacity },
49
- });
50
- };
51
- /**
52
- * Creates wall geometry for zone borders
53
- * Each wall segment is a vertical quad from one polygon point to the next
54
- */
55
- const createWallGeometry = (polygon) => {
56
- const geometry = new BufferGeometry();
57
- if (polygon.length < 2)
58
- return geometry;
59
- const positions = [];
60
- const uvs = [];
61
- const indices = [];
62
- // Create a wall segment for each edge of the polygon
63
- for (let i = 0; i < polygon.length; i++) {
64
- const current = polygon[i];
65
- const next = polygon[(i + 1) % polygon.length];
66
- const baseIndex = i * 4;
67
- // Four vertices per wall segment (two triangles forming a quad)
68
- // Bottom-left
69
- positions.push(current[0], Y_OFFSET, current[1]);
70
- uvs.push(0, 0);
71
- // Bottom-right
72
- positions.push(next[0], Y_OFFSET, next[1]);
73
- uvs.push(1, 0);
74
- // Top-right
75
- positions.push(next[0], Y_OFFSET + WALL_HEIGHT, next[1]);
76
- uvs.push(1, 1);
77
- // Top-left
78
- positions.push(current[0], Y_OFFSET + WALL_HEIGHT, current[1]);
79
- uvs.push(0, 1);
80
- // Two triangles for the quad
81
- indices.push(baseIndex, baseIndex + 1, baseIndex + 2, baseIndex, baseIndex + 2, baseIndex + 3);
82
- }
83
- geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
84
- geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
85
- geometry.setIndex(indices);
86
- geometry.computeVertexNormals();
87
- return geometry;
88
- };
89
- export const ZoneRenderer = ({ node }) => {
90
- const ref = useRef(null);
91
- useRegistry(node.id, 'zone', ref);
92
- // Create floor shape from polygon
93
- const floorShape = useMemo(() => {
94
- if (!node?.polygon || node.polygon.length < 3)
95
- return null;
96
- const shape = new Shape();
97
- const firstPt = node.polygon[0];
98
- // Shape is in X-Y plane, we rotate it to X-Z plane
99
- // Negate Y (which becomes Z) to get correct orientation
100
- shape.moveTo(firstPt[0], -firstPt[1]);
101
- for (let i = 1; i < node.polygon.length; i++) {
102
- const pt = node.polygon[i];
103
- shape.lineTo(pt[0], -pt[1]);
104
- }
105
- shape.closePath();
106
- return shape;
107
- }, [node?.polygon]);
108
- // Create wall geometry from polygon
109
- const wallGeometry = useMemo(() => {
110
- if (!node?.polygon || node.polygon.length < 2)
111
- return null;
112
- return createWallGeometry(node.polygon);
113
- }, [node?.polygon]);
114
- // Calculate polygon centroid for label positioning using the geometric centroid formula
115
- // This correctly handles polygons regardless of vertex distribution along edges
116
- const centroid = useMemo(() => {
117
- if (!node?.polygon || node.polygon.length < 3)
118
- return [0, 0];
119
- const polygon = node.polygon;
120
- let signedArea = 0;
121
- let cx = 0;
122
- let cz = 0;
123
- for (let i = 0; i < polygon.length; i++) {
124
- const [x0, z0] = polygon[i];
125
- const [x1, z1] = polygon[(i + 1) % polygon.length];
126
- // Cross product for signed area
127
- const cross = x0 * z1 - x1 * z0;
128
- signedArea += cross;
129
- cx += (x0 + x1) * cross;
130
- cz += (z0 + z1) * cross;
131
- }
132
- signedArea /= 2;
133
- const factor = 1 / (6 * signedArea);
134
- return [cx * factor, cz * factor];
135
- }, [node?.polygon]);
136
- // Create materials
137
- const floorMaterial = useMemo(() => {
138
- if (!node?.color)
139
- return null;
140
- return createFloorMaterial(node.color);
141
- }, [node?.color]);
142
- const wallMaterial = useMemo(() => {
143
- if (!node?.color)
144
- return null;
145
- return createWallGradientMaterial(node.color);
146
- }, [node?.color]);
147
- const handlers = useNodeEvents(node, 'zone');
148
- if (!(node && floorShape && wallGeometry && floorMaterial && wallMaterial)) {
149
- return null;
150
- }
151
- return (_jsxs("group", { ref: ref, ...handlers, userData: { labelPosition: [centroid[0], 1, centroid[1]] }, children: [_jsx(Html, { name: "label", position: [centroid[0], 1, centroid[1]], style: { pointerEvents: 'none' }, zIndexRange: [10, 0], children: _jsxs("div", { id: `${node.id}-label`, style: {
152
- display: 'flex',
153
- flexDirection: 'column',
154
- alignItems: 'center',
155
- transform: 'translate3d(-50%, -50%, 0)',
156
- opacity: 0,
157
- transition: 'opacity 0.3s ease-in-out',
158
- }, children: [_jsx("div", { style: {
159
- width: 'max-content',
160
- color: 'white',
161
- textShadow: `-1px -1px 0 ${node.color}, 1px -1px 0 ${node.color}, -1px 1px 0 ${node.color}, 1px 1px 0 ${node.color}`,
162
- textAlign: 'center',
163
- }, children: _jsx("span", { children: node.name }) }), _jsxs("div", { className: "label-pin", style: {
164
- display: 'flex',
165
- flexDirection: 'column',
166
- alignItems: 'center',
167
- marginTop: '2px',
168
- opacity: 0,
169
- transition: 'opacity 0.5s ease-in-out',
170
- }, children: [_jsx("div", { style: {
171
- width: '2px',
172
- height: '40px',
173
- backgroundColor: node.color,
174
- } }), _jsx("div", { style: {
175
- width: '10px',
176
- height: '10px',
177
- borderRadius: '50%',
178
- backgroundColor: node.color,
179
- border: '1px solid white',
180
- } })] })] }) }), _jsx("mesh", { layers: ZONE_LAYER, material: floorMaterial, name: "floor", position: [0, Y_OFFSET, 0], rotation: [-Math.PI / 2, 0, 0], children: _jsx("shapeGeometry", { args: [floorShape] }) }), _jsx("mesh", { geometry: wallGeometry, layers: ZONE_LAYER, material: wallMaterial, name: "walls" })] }));
181
- };