@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,597 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useLiveTransforms, useRegistry } from '@pascal-app/core';
3
- import { createContext, useContext, useMemo, useRef } from 'react';
4
- import { useNodeEvents } from '../../../hooks/use-node-events';
5
- import { baseMaterial, createMaterial, createMaterialFromPresetRef } from '../../../lib/materials';
6
- import { createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, } from '../../../systems/column/column-geometry';
7
- const ColumnMaterialContext = createContext(baseMaterial);
8
- const ColumnEdgeSoftnessContext = createContext(0.025);
9
- function ColumnMaterial() {
10
- const material = useContext(ColumnMaterialContext);
11
- return _jsx("primitive", { attach: "material", object: material });
12
- }
13
- function createColumnMaterial({ material, materialPreset, }) {
14
- const presetMaterial = createMaterialFromPresetRef(materialPreset);
15
- if (presetMaterial)
16
- return presetMaterial;
17
- if (material)
18
- return createMaterial(material);
19
- return baseMaterial;
20
- }
21
- function getSegments(node) {
22
- if (node.crossSection === 'octagonal')
23
- return 8;
24
- if (node.crossSection === 'sixteen-sided')
25
- return 16;
26
- return 32;
27
- }
28
- function getShaftProfile(node) {
29
- return node.shaftProfile ?? (node.shaftTaper > 0 ? 'tapered' : 'straight');
30
- }
31
- function getShaftSegmentCount(node) {
32
- const shaftProfile = getShaftProfile(node);
33
- const shaftTaper = node.shaftTaper ?? 0;
34
- const hasTwist = Math.abs(node.shaftTwistStep ?? 0) > 0.001;
35
- return Math.max(hasTwist ? 4 : 1, shaftProfile === 'straight' && shaftTaper <= 0 && !hasTwist
36
- ? 1
37
- : (node.shaftSegmentCount ?? (hasTwist ? 12 : 24)));
38
- }
39
- function getShaftTwistRadians(node, index) {
40
- return ((node.shaftTwistStep ?? 0) * Math.PI * index) / 180;
41
- }
42
- function getShaftScaleAt(node, t) {
43
- const shaftProfile = getShaftProfile(node);
44
- const shaftTaper = Math.min(node.shaftTaper ?? 0, 0.85);
45
- const startScale = node.shaftStartScale ?? 0.72;
46
- const endScale = node.shaftEndScale ?? startScale;
47
- const shaftBulge = node.shaftBulge ??
48
- (shaftProfile === 'bulged'
49
- ? 0.16
50
- : shaftProfile === 'baluster'
51
- ? 0.2
52
- : shaftProfile === 'hourglass'
53
- ? 0.18
54
- : 0);
55
- const taperedScale = 1 - shaftTaper * t;
56
- const linearScale = (startScale + (endScale - startScale) * t) * taperedScale;
57
- const bulgeCurve = Math.sin(Math.PI * t);
58
- const hourglassCurve = Math.abs(t - 0.5) * 2;
59
- const profileScale = shaftProfile === 'bulged' || shaftProfile === 'baluster'
60
- ? linearScale + shaftBulge * bulgeCurve
61
- : shaftProfile === 'hourglass'
62
- ? linearScale - shaftBulge * (1 - hourglassCurve)
63
- : linearScale;
64
- return Math.max(0.1, profileScale);
65
- }
66
- function MappedBox({ depth, height, position, rotation, softenEdges = true, width, }) {
67
- const edgeSoftness = useContext(ColumnEdgeSoftnessContext);
68
- const minDimension = Math.max(0, Math.min(width, height, depth));
69
- const bevelRadius = softenEdges ? Math.min(Math.max(0, edgeSoftness), minDimension * 0.35) : 0;
70
- const geometry = useMemo(() => {
71
- if (height <= 0 || width <= 0 || depth <= 0)
72
- return null;
73
- return createColumnBoxGeometry(width, height, depth, bevelRadius);
74
- }, [bevelRadius, depth, height, width]);
75
- if (!geometry)
76
- return null;
77
- return (_jsxs("mesh", { dispose: null, position: position, rotation: rotation, children: [_jsx("primitive", { attach: "geometry", dispose: null, object: geometry }), _jsx(ColumnMaterial, {})] }));
78
- }
79
- function MappedCylinder({ height, position, radius, radiusBottom = radius, radiusTop = radius, radiusX = 1, radiusZ = 1, rotation, segments = 32, }) {
80
- const geometry = useMemo(() => {
81
- if (height <= 0 || radius <= 0 || radiusBottom < 0 || radiusTop < 0)
82
- return null;
83
- return createColumnCylinderGeometry({
84
- height,
85
- radiusBottom,
86
- radiusTop,
87
- radiusX,
88
- radiusZ,
89
- segments,
90
- });
91
- }, [height, radius, radiusBottom, radiusTop, radiusX, radiusZ, segments]);
92
- if (!geometry)
93
- return null;
94
- return (_jsxs("mesh", { dispose: null, position: position, rotation: rotation, children: [_jsx("primitive", { attach: "geometry", dispose: null, object: geometry }), _jsx(ColumnMaterial, {})] }));
95
- }
96
- function MappedCone({ height, position, radiusX, radiusZ = radiusX, rotation, segments = 6, }) {
97
- const geometry = useMemo(() => {
98
- if (height <= 0 || radiusX <= 0 || radiusZ <= 0)
99
- return null;
100
- return createColumnCylinderGeometry({
101
- height,
102
- radiusBottom: 1,
103
- radiusTop: 0,
104
- radiusX,
105
- radiusZ,
106
- segments,
107
- });
108
- }, [height, radiusX, radiusZ, segments]);
109
- if (!geometry)
110
- return null;
111
- return (_jsxs("mesh", { dispose: null, position: position, rotation: rotation, children: [_jsx("primitive", { attach: "geometry", dispose: null, object: geometry }), _jsx(ColumnMaterial, {})] }));
112
- }
113
- function MappedSphere({ position, radius, segments = 10, verticalSegments = 8, }) {
114
- const geometry = useMemo(() => {
115
- if (radius <= 0)
116
- return null;
117
- return createColumnSphereGeometry(radius, segments, verticalSegments);
118
- }, [radius, segments, verticalSegments]);
119
- if (!geometry)
120
- return null;
121
- return (_jsxs("mesh", { dispose: null, position: position, children: [_jsx("primitive", { attach: "geometry", dispose: null, object: geometry }), _jsx(ColumnMaterial, {})] }));
122
- }
123
- function MappedTorus({ arc, position, ringRadius, rotation, scaleX, scaleY, scaleZ, tubeRadius, }) {
124
- const geometry = useMemo(() => {
125
- if (ringRadius <= 0 || tubeRadius <= 0)
126
- return null;
127
- return createColumnTorusGeometry({ arc, ringRadius, scaleX, scaleY, scaleZ, tubeRadius });
128
- }, [arc, ringRadius, scaleX, scaleY, scaleZ, tubeRadius]);
129
- if (!geometry)
130
- return null;
131
- return (_jsxs("mesh", { dispose: null, position: position, rotation: rotation, children: [_jsx("primitive", { attach: "geometry", dispose: null, object: geometry }), _jsx(ColumnMaterial, {})] }));
132
- }
133
- function SquareBlock({ y, height, width, depth, softenEdges = true, }) {
134
- return (_jsx(MappedBox, { depth: depth, height: height, position: [0, y + height / 2, 0], softenEdges: softenEdges, width: width }));
135
- }
136
- function RoundBlock({ x = 0, y, z = 0, height, radius, segments = 32, }) {
137
- return (_jsx(MappedCylinder, { height: height, position: [x, y + height / 2, z], radius: radius, segments: segments }));
138
- }
139
- function RoundedRectangleShaftSegment({ y, height, width, depth, cornerRadius, }) {
140
- if (height <= 0)
141
- return null;
142
- const radius = Math.min(Math.max(0, cornerRadius), Math.min(width, depth) * 0.45);
143
- if (radius <= 0.001) {
144
- return _jsx(SquareBlock, { depth: depth, height: height, width: width, y: y });
145
- }
146
- const innerWidth = Math.max(0, width - radius * 2);
147
- const innerDepth = Math.max(0, depth - radius * 2);
148
- const cornerX = width / 2 - radius;
149
- const cornerZ = depth / 2 - radius;
150
- return (_jsxs("group", { children: [innerWidth > 0 && (_jsx(SquareBlock, { depth: depth, height: height, softenEdges: false, width: innerWidth, y: y })), innerDepth > 0 && (_jsx(SquareBlock, { depth: innerDepth, height: height, softenEdges: false, width: width, y: y })), [
151
- [cornerX, cornerZ],
152
- [cornerX, -cornerZ],
153
- [-cornerX, cornerZ],
154
- [-cornerX, -cornerZ],
155
- ].map(([x, z], index) => (_jsx(RoundBlock, { height: height, radius: radius, segments: 18, x: x, y: y, z: z }, index)))] }));
156
- }
157
- function OvalBlock({ y, height, width, depth, segments = 32, }) {
158
- return (_jsx(MappedCylinder, { height: height, position: [0, y + height / 2, 0], radius: 1, radiusX: width / 2, radiusZ: depth / 2, segments: segments }));
159
- }
160
- function ColumnBlock({ node, y, height, scale = 1, }) {
161
- if (height <= 0)
162
- return null;
163
- const width = node.width * scale;
164
- const depth = node.depth * scale;
165
- const radius = node.radius * scale;
166
- if (node.crossSection === 'square' || node.crossSection === 'rectangular') {
167
- return _jsx(SquareBlock, { depth: depth, height: height, width: width, y: y });
168
- }
169
- return _jsx(RoundBlock, { height: height, radius: radius, segments: getSegments(node), y: y });
170
- }
171
- function TaperedRoundShaft({ node, y, height }) {
172
- const segmentCount = getShaftSegmentCount(node);
173
- const segmentHeight = height / segmentCount;
174
- return (_jsx("group", { children: Array.from({ length: segmentCount }, (_, index) => {
175
- const t = (index + 0.5) / segmentCount;
176
- const profileScale = getShaftScaleAt(node, t);
177
- return (_jsx("group", { rotation: [0, getShaftTwistRadians(node, index), 0], children: _jsx(RoundBlock, { height: segmentHeight * 1.015, radius: node.radius * profileScale, segments: getSegments(node), y: y + index * segmentHeight }) }, index));
178
- }) }));
179
- }
180
- function TaperedSquareShaft({ node, y, height }) {
181
- const segmentCount = getShaftSegmentCount(node);
182
- const segmentHeight = height / segmentCount;
183
- return (_jsx("group", { children: Array.from({ length: segmentCount }, (_, index) => {
184
- const t = (index + 0.5) / segmentCount;
185
- const profileScale = getShaftScaleAt(node, t);
186
- return (_jsx("group", { rotation: [0, getShaftTwistRadians(node, index), 0], children: _jsx(RoundedRectangleShaftSegment, { cornerRadius: (node.shaftCornerRadius ?? 0.035) * profileScale, depth: node.depth * profileScale, height: segmentHeight * 1.015, width: node.width * profileScale, y: y + index * segmentHeight }) }, index));
187
- }) }));
188
- }
189
- function Shaft({ node, y, height }) {
190
- if (height <= 0)
191
- return null;
192
- if (node.style === 'cluster') {
193
- const sideRadius = Math.max(0.04, node.radius * 0.36);
194
- const offset = Math.max(node.radius * 0.78, node.width * 0.22);
195
- return (_jsxs("group", { children: [_jsx(RoundBlock, { height: height, radius: node.radius * 0.62, segments: 24, y: y }), [
196
- [offset, 0],
197
- [-offset, 0],
198
- [0, offset],
199
- [0, -offset],
200
- ].map(([x, z], index) => (_jsx(RoundBlock, { height: height, radius: sideRadius, segments: 16, x: x, y: y, z: z }, `${x}-${z}-${index}`)))] }));
201
- }
202
- if (node.crossSection === 'round' ||
203
- node.crossSection === 'octagonal' ||
204
- node.crossSection === 'sixteen-sided') {
205
- return _jsx(TaperedRoundShaft, { height: height, node: node, y: y });
206
- }
207
- return _jsx(TaperedSquareShaft, { height: height, node: node, y: y });
208
- }
209
- function Base({ node, height }) {
210
- if (height <= 0)
211
- return null;
212
- const baseStyle = node.baseStyle ?? 'round-rings';
213
- const widthScale = node.baseWidthScale ?? 1.24;
214
- const depthScale = node.baseDepthScale ?? widthScale;
215
- if (baseStyle === 'none')
216
- return null;
217
- if (baseStyle === 'simple-square') {
218
- return (_jsx(SquareBlock, { depth: node.depth * depthScale, height: height, width: node.width * widthScale, y: 0 }));
219
- }
220
- if (baseStyle === 'square-plinth') {
221
- return (_jsxs("group", { children: [_jsx(SquareBlock, { depth: node.depth * depthScale, height: height * 0.35, width: node.width * widthScale, y: 0 }), _jsx(SquareBlock, { depth: node.depth * Math.max(0.9, depthScale * 0.84), height: height * 0.65, width: node.width * Math.max(0.9, widthScale * 0.84), y: height * 0.35 })] }));
222
- }
223
- if (baseStyle === 'stepped-square') {
224
- const tierCount = Math.max(3, node.baseTierCount ?? 3);
225
- const tierHeight = height / tierCount;
226
- const stepSpread = node.baseStepSpread ?? 0.42;
227
- return (_jsx("group", { children: Array.from({ length: tierCount }, (_, index) => {
228
- const t = index / Math.max(1, tierCount - 1);
229
- const widthScaleAt = Math.max(0.5, widthScale - t * stepSpread);
230
- const depthScaleAt = Math.max(0.5, depthScale - t * stepSpread);
231
- return (_jsx(SquareBlock, { depth: node.depth * depthScaleAt, height: tierHeight * 1.01, width: node.width * widthScaleAt, y: index * tierHeight }, index));
232
- }) }));
233
- }
234
- if (baseStyle === 'round-rings') {
235
- const baseWidth = node.width * widthScale;
236
- const baseDepth = node.depth * depthScale;
237
- const plinthRatio = Math.min(0.7, Math.max(0.2, node.basePlinthHeightRatio ?? 0.44));
238
- const plinthHeight = height * plinthRatio;
239
- const roundedHeight = height - plinthHeight;
240
- const bandHeight = roundedHeight * 0.57;
241
- const neckHeight = roundedHeight - bandHeight;
242
- const bandScale = node.baseRoundBandScale ?? 0.92;
243
- const neckScale = node.baseNeckScale ?? 0.72;
244
- return (_jsxs("group", { children: [_jsx(SquareBlock, { depth: baseDepth, height: plinthHeight, width: baseWidth, y: 0 }), _jsx(OvalBlock, { depth: baseDepth * bandScale, height: bandHeight, segments: 32, width: baseWidth * bandScale, y: plinthHeight }), _jsx(OvalBlock, { depth: baseDepth * neckScale, height: neckHeight, segments: 32, width: baseWidth * neckScale, y: plinthHeight + bandHeight })] }));
245
- }
246
- if (baseStyle === 'lotus' || baseStyle === 'ribbed-lotus') {
247
- const ribCount = node.baseRibCount ?? (baseStyle === 'ribbed-lotus' ? 24 : 14);
248
- const ribRadius = Math.max(0.01, node.width * 0.025);
249
- const baseRadius = Math.max(node.radius * widthScale, node.width * widthScale * 0.5);
250
- return (_jsxs("group", { children: [_jsx(SquareBlock, { depth: node.depth * 1.28, height: height * 0.22, width: node.width * 1.28, y: 0 }), _jsx(RoundBlock, { height: height * 0.24, radius: baseRadius * 0.86, segments: 32, y: height * 0.22 }), Array.from({ length: ribCount }, (_, index) => {
251
- const angle = (index / ribCount) * Math.PI * 2;
252
- return (_jsx(MappedCylinder, { height: height * 0.38, position: [
253
- Math.cos(angle) * baseRadius * 0.86,
254
- height * 0.58,
255
- Math.sin(angle) * baseRadius * 0.86,
256
- ], radius: ribRadius, rotation: [0, -angle, 0], segments: 6 }, index));
257
- }), _jsx(RoundBlock, { height: height * 0.16, radius: baseRadius * 0.72, segments: 32, y: height * 0.82 })] }));
258
- }
259
- if (baseStyle === 'panelled-pedestal') {
260
- const inset = node.basePanelInset ?? 0.02;
261
- return (_jsxs("group", { children: [_jsx(SquareBlock, { depth: node.depth * widthScale, height: height, width: node.width * widthScale, y: 0 }), [
262
- [0, node.depth * widthScale * 0.51, 0],
263
- [0, -node.depth * widthScale * 0.51, 0],
264
- [node.width * widthScale * 0.51, 0, Math.PI / 2],
265
- [-node.width * widthScale * 0.51, 0, Math.PI / 2],
266
- ].map(([x, z, rotation], index) => (_jsx(MappedBox, { depth: inset, height: height * 0.42, position: [x, height * 0.5, z], rotation: [0, rotation, 0], softenEdges: false, width: node.width * 0.36 }, index)))] }));
267
- }
268
- return _jsx(ColumnBlock, { height: height, node: node, scale: 1.12, y: 0 });
269
- }
270
- function BaseCarvings({ node, height }) {
271
- const placement = node.carvingPlacement ?? 'capital';
272
- const carvingLevel = node.baseCarvingLevel ?? 0;
273
- if (carvingLevel <= 0 || height <= 0 || (placement !== 'base' && placement !== 'all')) {
274
- return null;
275
- }
276
- const count = Math.max(8, carvingLevel * 8);
277
- const radius = Math.max(node.radius * 1.04, Math.max(node.width, node.depth) * 0.5);
278
- const y = height * 0.52;
279
- return (_jsx("group", { children: Array.from({ length: count }, (_, index) => {
280
- const angle = (index / count) * Math.PI * 2;
281
- return (_jsx(MappedCone, { height: height * 0.28, position: [Math.cos(angle) * radius, y, Math.sin(angle) * radius], radiusX: 0.014, radiusZ: 0.01, rotation: [0.36, -angle, 0], segments: 5 }, index));
282
- }) }));
283
- }
284
- function Rings({ node, shaftY, shaftHeight, }) {
285
- if (node.ringCount <= 0 || shaftHeight <= 0)
286
- return null;
287
- const ringPlacement = node.ringPlacement ?? 'ends';
288
- const ringSpread = Math.min(0.45, Math.max(0.04, node.ringSpread ?? 0.16));
289
- const ringHeight = Math.min(node.ringThickness ?? 0.055, shaftHeight / Math.max(8, node.ringCount * 3));
290
- const rings = Array.from({ length: node.ringCount }, (_, index) => {
291
- const pairIndex = Math.floor(index / 2);
292
- const nearTop = index % 2 === 1;
293
- const pairCount = Math.ceil(node.ringCount / 2);
294
- const pairT = pairCount <= 1 ? 0 : pairIndex / (pairCount - 1);
295
- const offset = Math.min(0.48, 0.06 + pairT * Math.max(0, ringSpread - 0.06));
296
- const oneSideT = 0.06 + (index / Math.max(1, node.ringCount - 1)) * Math.max(0, ringSpread - 0.06);
297
- const t = ringPlacement === 'even'
298
- ? (index + 1) / (node.ringCount + 1)
299
- : ringPlacement === 'top'
300
- ? 1 - Math.min(0.48, oneSideT)
301
- : ringPlacement === 'bottom'
302
- ? Math.min(0.48, oneSideT)
303
- : nearTop
304
- ? 1 - offset
305
- : offset;
306
- return {
307
- scale: Math.min(1.4, getShaftScaleAt(node, t) + 0.12),
308
- y: shaftY + shaftHeight * t - ringHeight / 2,
309
- };
310
- }).sort((a, b) => a.y - b.y);
311
- return (_jsx("group", { children: rings.map((ring, index) => (_jsx(ColumnBlock, { height: ringHeight, node: node, scale: ring.scale, y: ring.y }, index))) }));
312
- }
313
- function LatheBands({ node, shaftY, shaftHeight, }) {
314
- const latheRingCount = Math.max(node.latheRingCount ?? 0, node.shaftDetail === 'lathe-turned' ? 8 : 0);
315
- if (latheRingCount <= 0 || shaftHeight <= 0)
316
- return null;
317
- const placement = node.latheRingSpacing ?? 'ends';
318
- const bandHeight = Math.min(0.04, shaftHeight / Math.max(12, latheRingCount * 3));
319
- const bands = Array.from({ length: latheRingCount }, (_, index) => {
320
- const pairIndex = Math.floor(index / 2);
321
- const nearTop = index % 2 === 1;
322
- const offset = Math.min(0.48, 0.1 + pairIndex * 0.04);
323
- const t = placement === 'even'
324
- ? (index + 1) / (latheRingCount + 1)
325
- : placement === 'top'
326
- ? 1 - Math.min(0.48, 0.08 + index * 0.04)
327
- : placement === 'bottom'
328
- ? Math.min(0.48, 0.08 + index * 0.04)
329
- : nearTop
330
- ? 1 - offset
331
- : offset;
332
- return shaftY + shaftHeight * t - bandHeight / 2;
333
- }).sort((a, b) => a - b);
334
- return (_jsx("group", { children: bands.map((y, index) => (_jsx(ColumnBlock, { height: bandHeight, node: node, scale: 0.82 + (index % 2) * 0.08, y: y }, index))) }));
335
- }
336
- function Flutes({ node, shaftY, shaftHeight, }) {
337
- const fluteCount = Math.max(node.fluteCount, node.shaftDetail === 'fluted' ? 16 : 0);
338
- if (fluteCount <= 0 || shaftHeight <= 0 || node.crossSection !== 'round')
339
- return null;
340
- const fluteDepth = node.fluteDepth ?? 0.02;
341
- const fluteWidth = node.fluteWidth ?? fluteDepth;
342
- const fluteRadius = Math.max(0.006, fluteWidth * 0.42);
343
- const shaftRadius = node.radius * 0.74;
344
- return (_jsx("group", { children: Array.from({ length: fluteCount }, (_, index) => {
345
- const angle = (index / fluteCount) * Math.PI * 2;
346
- const x = Math.cos(angle) * shaftRadius;
347
- const z = Math.sin(angle) * shaftRadius;
348
- return (_jsx(MappedCylinder, { height: shaftHeight * 0.92, position: [x, shaftY + shaftHeight / 2, z], radius: fluteRadius, segments: 8 }, index));
349
- }) }));
350
- }
351
- function DravidianPanelFace({ position, rotation = 0, panelHeight, panelWidth, rail, reliefDepth, panelShape, }) {
352
- return (_jsxs("group", { position: position, rotation: [0, rotation, 0], children: [_jsx(MappedBox, { depth: reliefDepth, height: rail, position: [0, panelHeight / 2, 0], softenEdges: false, width: panelWidth }), _jsx(MappedBox, { depth: reliefDepth, height: rail, position: [0, -panelHeight / 2, 0], softenEdges: false, width: panelWidth }), _jsx(MappedBox, { depth: reliefDepth, height: panelHeight, position: [panelWidth / 2, 0, 0], softenEdges: false, width: rail }), _jsx(MappedBox, { depth: reliefDepth, height: panelHeight, position: [-panelWidth / 2, 0, 0], softenEdges: false, width: rail }), panelShape === 'diamond' && (_jsx(MappedBox, { depth: reliefDepth, height: panelHeight * 0.42, position: [0, 0, 0], rotation: [0, 0, Math.PI / 4], softenEdges: false, width: rail * 1.2 })), panelShape === 'arched' && (_jsx(MappedTorus, { arc: Math.PI, position: [0, panelHeight * 0.28, 0], ringRadius: panelWidth * 0.42, scaleX: panelWidth * 0.42, scaleY: rail, scaleZ: reliefDepth, tubeRadius: Math.max(rail, reliefDepth) * 0.18 }))] }));
353
- }
354
- function DravidianShaftPanels({ node, shaftY, shaftHeight, }) {
355
- const panelCount = Math.max(node.panelCount ?? 0, node.style === 'dravidian-carved' || node.shaftDetail === 'panelled' ? 3 : 0);
356
- if (panelCount <= 0 || shaftHeight <= 0)
357
- return null;
358
- const shaftWidth = node.width * 0.72;
359
- const shaftDepth = node.depth * 0.72;
360
- const panelHeight = Math.min(0.42, shaftHeight / Math.max(4, panelCount + 2));
361
- const panelWidth = node.width * 0.26;
362
- const rail = Math.max(0.012, node.width * 0.028);
363
- const reliefDepth = Math.max(0.012, node.panelInsetDepth ?? node.width * 0.025);
364
- const rows = Array.from({ length: panelCount }, (_, index) => (index + 1) / (panelCount + 1));
365
- const panelShape = node.panelShape ?? 'rectangle';
366
- const faceProps = { panelHeight, panelWidth, rail, reliefDepth, panelShape };
367
- return (_jsx("group", { children: rows.map((t, rowIndex) => {
368
- const y = shaftY + shaftHeight * t;
369
- return (_jsxs("group", { children: [_jsx(DravidianPanelFace, { position: [0, y, shaftDepth / 2 + reliefDepth / 2], ...faceProps }), _jsx(DravidianPanelFace, { position: [0, y, -shaftDepth / 2 - reliefDepth / 2], ...faceProps }), _jsx(DravidianPanelFace, { position: [shaftWidth / 2 + reliefDepth / 2, y, 0], rotation: Math.PI / 2, ...faceProps }), _jsx(DravidianPanelFace, { position: [-shaftWidth / 2 - reliefDepth / 2, y, 0], rotation: Math.PI / 2, ...faceProps })] }, rowIndex));
370
- }) }));
371
- }
372
- function SpiralRibs({ node, shaftY, shaftHeight, }) {
373
- const spiralRibCount = node.spiralRibCount ?? 0;
374
- const spiralTwist = node.spiralTwist ?? 0;
375
- const shaftTaper = node.shaftTaper ?? 0;
376
- const ribCountSetting = Math.max(spiralRibCount, node.shaftDetail === 'spiral' ? 12 : 0);
377
- if (ribCountSetting <= 0 || spiralTwist === 0 || shaftHeight <= 0)
378
- return null;
379
- const ribCount = Math.min(ribCountSetting, 24);
380
- const stepCount = 28;
381
- const ribDistance = node.radius * 0.78;
382
- const ribWidth = Math.max(0.012, node.radius * 0.06);
383
- const segmentHeight = (shaftHeight / stepCount) * 1.18;
384
- const lean = spiralTwist > 0 ? -0.55 : 0.55;
385
- return (_jsx("group", { children: Array.from({ length: ribCount * stepCount }, (_, index) => {
386
- const ribIndex = index % ribCount;
387
- const stepIndex = Math.floor(index / ribCount);
388
- const t = (stepIndex + 0.5) / stepCount;
389
- const angle = (ribIndex / ribCount) * Math.PI * 2 + t * spiralTwist * Math.PI * 2;
390
- const taperScale = 1 - Math.min(shaftTaper, 0.85) * t;
391
- return (_jsx(MappedCylinder, { height: segmentHeight, position: [
392
- Math.cos(angle) * ribDistance * taperScale,
393
- shaftY + shaftHeight * t,
394
- Math.sin(angle) * ribDistance * taperScale,
395
- ], radius: ribWidth, rotation: [0, -angle, lean], segments: 8 }, index));
396
- }) }));
397
- }
398
- function LowerCarvedBand({ node, shaftY, shaftHeight, }) {
399
- const placement = node.carvingPlacement ?? 'capital';
400
- if (!node.lowerBandEnabled ||
401
- shaftHeight <= 0 ||
402
- (placement !== 'shaft' && placement !== 'all')) {
403
- return null;
404
- }
405
- const bandHeight = Math.min(node.lowerBandHeight ?? 0.24, shaftHeight * 0.35);
406
- const y = shaftY + shaftHeight * 0.12;
407
- const level = Math.max(1, node.lowerBandCarvingLevel ?? 1);
408
- const count = Math.max(6, level * 6);
409
- const distance = Math.max(node.radius * 0.82, Math.max(node.width, node.depth) * 0.36);
410
- return (_jsxs("group", { children: [_jsx(ColumnBlock, { height: bandHeight, node: node, scale: 0.84, y: y }), Array.from({ length: count }, (_, index) => {
411
- const angle = (index / count) * Math.PI * 2;
412
- return (_jsx(MappedCylinder, { height: bandHeight * 0.62, position: [
413
- Math.cos(angle) * distance,
414
- y + bandHeight * 0.5,
415
- Math.sin(angle) * distance,
416
- ], radius: 0.012, rotation: [0, -angle, 0], segments: 5 }, index));
417
- })] }));
418
- }
419
- function CapitalCarvings({ node, capitalY, capitalHeight, }) {
420
- const placement = node.carvingPlacement ?? 'capital';
421
- const carvingLevel = Math.max(node.carvingLevel ?? 0, node.capitalCarvingLevel ?? 0);
422
- const bandSetting = node.capitalBandCount ?? 0;
423
- if ((carvingLevel <= 0 && bandSetting <= 0) ||
424
- capitalHeight <= 0 ||
425
- (placement !== 'capital' && placement !== 'all')) {
426
- return null;
427
- }
428
- const level = Math.min(Math.max(carvingLevel, bandSetting > 0 ? 1 : 0), 4);
429
- const bandHeight = Math.min(0.035, capitalHeight / 8);
430
- const bandCount = Math.min(bandSetting > 0 ? bandSetting : level + 1, 16);
431
- const bands = Array.from({ length: bandCount }, (_, index) => {
432
- const t = (index + 1) / (bandCount + 1);
433
- return capitalY + capitalHeight * t - bandHeight / 2;
434
- });
435
- if (node.crossSection === 'square' || node.crossSection === 'rectangular') {
436
- const dentilCount = Math.max(node.dentilCount ?? 0, level * 4, 4);
437
- const dentilHeight = Math.min(0.08, capitalHeight * 0.28);
438
- const dentilDepth = Math.min(0.08, Math.min(node.width, node.depth) * 0.16);
439
- const dentilWidth = Math.max(0.025, node.width / (dentilCount * 1.75));
440
- const halfWidth = node.width * 0.56;
441
- const halfDepth = node.depth * 0.56;
442
- const y = capitalY + capitalHeight * 0.28;
443
- const xPositions = Array.from({ length: dentilCount }, (_, index) => {
444
- const t = dentilCount === 1 ? 0.5 : index / (dentilCount - 1);
445
- return -halfWidth + t * halfWidth * 2;
446
- });
447
- const zPositions = Array.from({ length: dentilCount }, (_, index) => {
448
- const t = dentilCount === 1 ? 0.5 : index / (dentilCount - 1);
449
- return -halfDepth + t * halfDepth * 2;
450
- });
451
- return (_jsxs("group", { children: [bands.map((bandY, index) => (_jsx(ColumnBlock, { height: bandHeight, node: node, scale: 1.28, y: bandY }, `band-${index}`))), xPositions.map((x, index) => (_jsxs("group", { children: [_jsx(MappedBox, { depth: dentilDepth, height: dentilHeight, position: [x, y, halfDepth], softenEdges: false, width: dentilWidth }), _jsx(MappedBox, { depth: dentilDepth, height: dentilHeight, position: [x, y, -halfDepth], softenEdges: false, width: dentilWidth })] }, `front-back-dentil-${index}`))), zPositions.map((z, index) => (_jsxs("group", { children: [_jsx(MappedBox, { depth: dentilWidth, height: dentilHeight, position: [halfWidth, y, z], softenEdges: false, width: dentilDepth }), _jsx(MappedBox, { depth: dentilWidth, height: dentilHeight, position: [-halfWidth, y, z], softenEdges: false, width: dentilDepth })] }, `side-dentil-${index}`)))] }));
452
- }
453
- const beadCount = Math.max(node.beadCount ?? 0, 8, level * 8);
454
- const beadRadius = Math.max(0.012, Math.min(0.03, node.radius * 0.12));
455
- const beadDistance = node.radius * 1.24;
456
- const beadY = capitalY + capitalHeight * 0.24;
457
- return (_jsxs("group", { children: [bands.map((bandY, index) => (_jsx(ColumnBlock, { height: bandHeight, node: node, scale: 1.24, y: bandY }, `band-${index}`))), Array.from({ length: beadCount }, (_, index) => {
458
- const angle = (index / beadCount) * Math.PI * 2;
459
- return (_jsx(MappedSphere, { position: [Math.cos(angle) * beadDistance, beadY, Math.sin(angle) * beadDistance], radius: beadRadius }, `bead-${index}`));
460
- })] }));
461
- }
462
- function Volutes({ node, capitalY, capitalHeight, }) {
463
- if (!['volute', 'ionic-volute'].includes(node.capitalStyle ?? 'simple') || capitalHeight <= 0)
464
- return null;
465
- const y = capitalY + capitalHeight * 0.62;
466
- const radius = node.voluteSize ?? Math.min(0.085, Math.max(0.04, node.width * 0.12));
467
- const x = node.width * 0.46;
468
- const z = node.depth * 0.7;
469
- const maxVolutes = Math.max(0, Math.min(node.voluteCount ?? 4, 8));
470
- const volutes = [
471
- {
472
- position: [x, y, z],
473
- rotation: [0, 0, 0],
474
- },
475
- {
476
- position: [-x, y, z],
477
- rotation: [0, 0, 0],
478
- },
479
- {
480
- position: [x, y, -z],
481
- rotation: [0, Math.PI, 0],
482
- },
483
- {
484
- position: [-x, y, -z],
485
- rotation: [0, Math.PI, 0],
486
- },
487
- {
488
- position: [z, y, x],
489
- rotation: [0, Math.PI / 2, 0],
490
- },
491
- {
492
- position: [z, y, -x],
493
- rotation: [0, Math.PI / 2, 0],
494
- },
495
- {
496
- position: [-z, y, x],
497
- rotation: [0, -Math.PI / 2, 0],
498
- },
499
- {
500
- position: [-z, y, -x],
501
- rotation: [0, -Math.PI / 2, 0],
502
- },
503
- ].slice(0, maxVolutes);
504
- return (_jsx("group", { children: volutes.map((volute, index) => (_jsx(MappedTorus, { position: volute.position, ringRadius: radius, rotation: volute.rotation, scaleZ: radius * 0.28, tubeRadius: radius * 0.18 }, index))) }));
505
- }
506
- function LeafCarvings({ node, capitalY, capitalHeight, }) {
507
- if (!['leaf-carved', 'corinthian-leaf'].includes(node.capitalStyle ?? 'simple') ||
508
- capitalHeight <= 0) {
509
- return null;
510
- }
511
- const leafCount = node.leafCount ?? (node.crossSection === 'round' ? 18 : 12);
512
- const distance = Math.max(node.radius * 1.05, Math.max(node.width, node.depth) * 0.48);
513
- const rowCount = Math.max(0, Math.min(node.leafRows ?? 2, 4));
514
- const rows = Array.from({ length: rowCount }, (_, index) => ({
515
- y: capitalY + capitalHeight * (0.3 + index * 0.16),
516
- scale: 0.28 - index * 0.04,
517
- offset: index % 2 === 0 ? 0 : Math.PI / leafCount,
518
- }));
519
- return (_jsx("group", { children: rows.flatMap((row, rowIndex) => Array.from({ length: leafCount }, (_, index) => {
520
- const angle = (index / leafCount) * Math.PI * 2 + row.offset;
521
- return (_jsx(MappedCone, { height: capitalHeight * row.scale, position: [Math.cos(angle) * distance, row.y, Math.sin(angle) * distance], radiusX: 0.018, radiusZ: 0.01, rotation: [0.48, -angle, 0], segments: 6 }, `${rowIndex}-${index}`));
522
- })) }));
523
- }
524
- function Capital({ node, y, height }) {
525
- if (height <= 0)
526
- return null;
527
- const capitalStyle = node.capitalStyle ?? 'simple';
528
- if (capitalStyle === 'none')
529
- return null;
530
- if (capitalStyle === 'south-indian-bracket' || capitalStyle === 'wood-bracket') {
531
- const tierCount = Math.max(1, node.bracketTierCount ?? 3);
532
- const tierHeight = height / tierCount;
533
- const bracketDepth = node.bracketDepth ?? 0.35;
534
- return (_jsxs("group", { children: [Array.from({ length: tierCount }, (_, index) => {
535
- const t = index / Math.max(1, tierCount - 1);
536
- const scale = (node.capitalWidthScale ?? 1.6) + t * 0.32;
537
- return (_jsx(SquareBlock, { depth: node.depth * scale + bracketDepth * t, height: tierHeight, width: node.width * scale + bracketDepth * t, y: y + index * tierHeight }, index));
538
- }), Array.from({ length: node.pendantCount ?? 0 }, (_, index) => {
539
- const count = Math.max(1, node.pendantCount ?? 0);
540
- const angle = (index / count) * Math.PI * 2;
541
- const distance = Math.max(node.width, node.depth) * 0.56;
542
- return (_jsx(MappedCone, { height: height * 0.28, position: [Math.cos(angle) * distance, y - height * 0.1, Math.sin(angle) * distance], radiusX: 0.035, rotation: [0, 0, 0], segments: 6 }, index));
543
- })] }));
544
- }
545
- if (capitalStyle === 'rounded' || capitalStyle === 'doric') {
546
- const topWidth = node.width * (node.capitalWidthScale ?? 1.34);
547
- const topDepth = node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.34);
548
- return (_jsxs("group", { children: [_jsx(OvalBlock, { depth: topDepth * 0.72, height: height * 0.24, segments: 32, width: topWidth * 0.72, y: y }), _jsx(OvalBlock, { depth: topDepth * 0.92, height: height * 0.32, segments: 32, width: topWidth * 0.92, y: y + height * 0.24 }), _jsx(SquareBlock, { depth: topDepth, height: height * 0.44, width: topWidth, y: y + height * 0.56 })] }));
549
- }
550
- if (capitalStyle === 'stepped') {
551
- const widthScale = node.capitalWidthScale ?? 1.46;
552
- const depthScale = node.capitalDepthScale ?? widthScale;
553
- const tierCount = Math.max(3, node.capitalTierCount ?? 3);
554
- const tierHeight = height / tierCount;
555
- const stepSpread = node.capitalStepSpread ?? 0.42;
556
- return (_jsx("group", { children: Array.from({ length: tierCount }, (_, index) => {
557
- const t = index / Math.max(1, tierCount - 1);
558
- const widthScaleAt = Math.max(0.5, widthScale - (1 - t) * stepSpread);
559
- const depthScaleAt = Math.max(0.5, depthScale - (1 - t) * stepSpread);
560
- return (_jsx(SquareBlock, { depth: node.depth * depthScaleAt, height: tierHeight * 1.01, width: node.width * widthScaleAt, y: y + index * tierHeight }, index));
561
- }) }));
562
- }
563
- if (capitalStyle === 'volute' ||
564
- capitalStyle === 'ionic-volute' ||
565
- capitalStyle === 'leaf-carved' ||
566
- capitalStyle === 'corinthian-leaf') {
567
- const topWidth = node.width * (node.capitalWidthScale ?? 1.46);
568
- const topDepth = node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.46);
569
- return (_jsxs("group", { children: [_jsx(ColumnBlock, { height: height * 0.24, node: node, scale: 0.9, y: y }), _jsx(ColumnBlock, { height: height * 0.2, node: node, scale: 1.08, y: y + height * 0.24 }), _jsx(SquareBlock, { depth: topDepth, height: height * 0.28, width: topWidth, y: y + height * 0.44 }), _jsx(Volutes, { capitalHeight: height, capitalY: y, node: node }), _jsx(LeafCarvings, { capitalHeight: height, capitalY: y, node: node })] }));
570
- }
571
- const widthScale = node.capitalWidthScale ?? (capitalStyle === 'simple-slab' ? 1.28 : 1.18);
572
- const depthScale = node.capitalDepthScale ?? widthScale;
573
- if (node.crossSection === 'square' || node.crossSection === 'rectangular') {
574
- return (_jsx(SquareBlock, { depth: node.depth * depthScale, height: height, width: node.width * widthScale, y: y }));
575
- }
576
- return (_jsx(RoundBlock, { height: height, radius: Math.max(node.radius * widthScale, node.width * widthScale * 0.5), segments: getSegments(node), y: y }));
577
- }
578
- export const ColumnRenderer = ({ node }) => {
579
- const ref = useRef(null);
580
- const handlers = useNodeEvents(node, 'column');
581
- const liveTransform = useLiveTransforms((state) => state.get(node.id));
582
- const material = useMemo(() => createColumnMaterial({ material: node.material, materialPreset: node.materialPreset }), [
583
- node.material,
584
- node.material?.preset,
585
- node.material?.properties,
586
- node.material?.texture,
587
- node.materialPreset,
588
- ]);
589
- useRegistry(node.id, node.type, ref);
590
- const shaftLayout = useMemo(() => {
591
- const baseHeight = node.baseStyle === 'none' ? 0 : Math.min(node.baseHeight, node.height * 0.4);
592
- const capitalHeight = node.capitalStyle === 'none' ? 0 : Math.min(node.capitalHeight, node.height * 0.4);
593
- const shaftHeight = Math.max(0.1, node.height - baseHeight - capitalHeight);
594
- return { baseHeight, capitalHeight, shaftY: baseHeight, shaftHeight };
595
- }, [node.baseHeight, node.baseStyle, node.capitalHeight, node.capitalStyle, node.height]);
596
- return (_jsx(ColumnMaterialContext.Provider, { value: material, children: _jsx(ColumnEdgeSoftnessContext.Provider, { value: node.edgeSoftness ?? 0.025, children: _jsxs("group", { position: liveTransform?.position ?? node.position, ref: ref, rotation: [0, liveTransform?.rotation ?? node.rotation, 0], visible: node.visible, ...handlers, children: [_jsx(Base, { height: shaftLayout.baseHeight, node: node }), _jsx(BaseCarvings, { height: shaftLayout.baseHeight, node: node }), _jsx(Shaft, { height: shaftLayout.shaftHeight, node: node, y: shaftLayout.shaftY }), _jsx(Rings, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(LatheBands, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(Flutes, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(LowerCarvedBand, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(DravidianShaftPanels, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(SpiralRibs, { node: node, shaftHeight: shaftLayout.shaftHeight, shaftY: shaftLayout.shaftY }), _jsx(Capital, { height: shaftLayout.capitalHeight, node: node, y: shaftLayout.baseHeight + shaftLayout.shaftHeight }), _jsx(CapitalCarvings, { capitalHeight: shaftLayout.capitalHeight, capitalY: shaftLayout.baseHeight + shaftLayout.shaftHeight, node: node })] }) }) }));
597
- };
@@ -1,5 +0,0 @@
1
- import { type DoorNode } from '@pascal-app/core';
2
- export declare const DoorRenderer: ({ node }: {
3
- node: DoorNode;
4
- }) => import("react/jsx-runtime").JSX.Element;
5
- //# sourceMappingURL=door-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"door-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/door/door-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAyB,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 } from "react/jsx-runtime";
2
- import { useRegistry, useScene } from '@pascal-app/core';
3
- import { useLayoutEffect, useRef } from 'react';
4
- import { MeshBasicMaterial } from 'three';
5
- import { useNodeEvents } from '../../../hooks/use-node-events';
6
- const doorHitboxMaterial = new MeshBasicMaterial({ visible: false });
7
- export const DoorRenderer = ({ node }) => {
8
- const ref = useRef(null);
9
- useRegistry(node.id, 'door', ref);
10
- useLayoutEffect(() => {
11
- useScene.getState().markDirty(node.id);
12
- }, [node.id]);
13
- const handlers = useNodeEvents(node, 'door');
14
- const isTransient = !!node.metadata?.isTransient;
15
- return (_jsx("mesh", { castShadow: true, material: doorHitboxMaterial, position: node.position, receiveShadow: true, ref: ref, rotation: node.rotation, visible: node.visible, ...(isTransient ? {} : handlers), children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
16
- };
@@ -1,5 +0,0 @@
1
- import { type FenceNode } from '@pascal-app/core';
2
- export declare const FenceRenderer: ({ node }: {
3
- node: FenceNode;
4
- }) => import("react/jsx-runtime").JSX.Element;
5
- //# sourceMappingURL=fence-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fence-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/fence/fence-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,kBAAkB,CAAA;AAMxE,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CAsB1D,CAAA"}
@@ -1,15 +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 { DEFAULT_STAIR_MATERIAL } from '../../../lib/materials';
6
- export const FenceRenderer = ({ node }) => {
7
- const ref = useRef(null);
8
- const handlers = useNodeEvents(node, 'fence');
9
- const material = useMemo(() => DEFAULT_STAIR_MATERIAL, []);
10
- useRegistry(node.id, 'fence', ref);
11
- useLayoutEffect(() => {
12
- useScene.getState().markDirty(node.id);
13
- }, [node.id]);
14
- return (_jsx("mesh", { castShadow: true, material: material, receiveShadow: true, ref: ref, visible: node.visible, ...handlers, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
15
- };