@pascal-app/viewer 1.0.6 → 1.1.0

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 (238) hide show
  1. package/README.md +54 -21
  2. package/dist/components/viewer/daylight-atmosphere.d.ts +9 -0
  3. package/dist/components/viewer/daylight-atmosphere.d.ts.map +1 -0
  4. package/dist/components/viewer/daylight-atmosphere.js +315 -0
  5. package/dist/components/viewer/drone-controller.d.ts +15 -0
  6. package/dist/components/viewer/drone-controller.d.ts.map +1 -0
  7. package/dist/components/viewer/drone-controller.js +194 -0
  8. package/dist/components/viewer/glb-interactive.d.ts +4 -18
  9. package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
  10. package/dist/components/viewer/glb-interactive.js +32 -268
  11. package/dist/components/viewer/glb-replace-instances.d.ts +6 -3
  12. package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -1
  13. package/dist/components/viewer/glb-replace-instances.js +5 -4
  14. package/dist/components/viewer/glb-scene-motion.d.ts +8 -0
  15. package/dist/components/viewer/glb-scene-motion.d.ts.map +1 -0
  16. package/dist/components/viewer/glb-scene-motion.js +57 -0
  17. package/dist/components/viewer/glb-scene.d.ts +5 -1
  18. package/dist/components/viewer/glb-scene.d.ts.map +1 -1
  19. package/dist/components/viewer/glb-scene.js +290 -49
  20. package/dist/components/viewer/glb-selection-callout.d.ts +17 -0
  21. package/dist/components/viewer/glb-selection-callout.d.ts.map +1 -0
  22. package/dist/components/viewer/glb-selection-callout.js +54 -0
  23. package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
  24. package/dist/components/viewer/glb-walkthrough-controller.js +6 -3
  25. package/dist/components/viewer/index.d.ts +5 -0
  26. package/dist/components/viewer/index.d.ts.map +1 -1
  27. package/dist/components/viewer/index.js +38 -10
  28. package/dist/components/viewer/lights.d.ts.map +1 -1
  29. package/dist/components/viewer/lights.js +192 -5
  30. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  31. package/dist/components/viewer/post-processing.js +150 -94
  32. package/dist/components/viewer/registered-systems.d.ts.map +1 -1
  33. package/dist/components/viewer/registered-systems.js +2 -2
  34. package/dist/components/viewer/scene-environment.js +4 -5
  35. package/dist/components/viewer/selection-callout.d.ts +51 -0
  36. package/dist/components/viewer/selection-callout.d.ts.map +1 -0
  37. package/dist/components/viewer/selection-callout.js +197 -0
  38. package/dist/components/viewer/unsupported-gpu-fallback.d.ts.map +1 -1
  39. package/dist/components/viewer/unsupported-gpu-fallback.js +21 -1
  40. package/dist/components/viewer/use-daylight-rooms.d.ts +13 -0
  41. package/dist/components/viewer/use-daylight-rooms.d.ts.map +1 -0
  42. package/dist/components/viewer/use-daylight-rooms.js +278 -0
  43. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  44. package/dist/components/viewer/viewer-camera.js +12 -1
  45. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  46. package/dist/hooks/use-gltf-ktx2.js +2 -1
  47. package/dist/index.d.ts +26 -8
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +28 -8
  50. package/dist/lib/asset-url.d.ts +0 -1
  51. package/dist/lib/asset-url.d.ts.map +1 -1
  52. package/dist/lib/asset-url.js +3 -3
  53. package/dist/lib/daylight/ground.d.ts +21 -0
  54. package/dist/lib/daylight/ground.d.ts.map +1 -0
  55. package/dist/lib/daylight/ground.js +53 -0
  56. package/dist/lib/daylight/location.d.ts +32 -0
  57. package/dist/lib/daylight/location.d.ts.map +1 -0
  58. package/dist/lib/daylight/location.js +74 -0
  59. package/dist/lib/daylight/look.d.ts +33 -0
  60. package/dist/lib/daylight/look.d.ts.map +1 -0
  61. package/dist/lib/daylight/look.js +13 -0
  62. package/dist/lib/daylight/material-hooks.d.ts +2 -0
  63. package/dist/lib/daylight/material-hooks.d.ts.map +1 -0
  64. package/dist/lib/daylight/material-hooks.js +150 -0
  65. package/dist/lib/daylight/room-context.d.ts +12 -0
  66. package/dist/lib/daylight/room-context.d.ts.map +1 -0
  67. package/dist/lib/daylight/room-context.js +54 -0
  68. package/dist/lib/daylight/room-map.d.ts +124 -0
  69. package/dist/lib/daylight/room-map.d.ts.map +1 -0
  70. package/dist/lib/daylight/room-map.js +630 -0
  71. package/dist/lib/daylight/room-scene.d.ts +56 -0
  72. package/dist/lib/daylight/room-scene.d.ts.map +1 -0
  73. package/dist/lib/daylight/room-scene.js +391 -0
  74. package/dist/lib/daylight/rooms.d.ts +292 -0
  75. package/dist/lib/daylight/rooms.d.ts.map +1 -0
  76. package/dist/lib/daylight/rooms.js +1268 -0
  77. package/dist/lib/daylight/runtime.d.ts +33 -0
  78. package/dist/lib/daylight/runtime.d.ts.map +1 -0
  79. package/dist/lib/daylight/runtime.js +42 -0
  80. package/dist/lib/daylight/sky.d.ts +26 -0
  81. package/dist/lib/daylight/sky.d.ts.map +1 -0
  82. package/dist/lib/daylight/sky.js +217 -0
  83. package/dist/lib/daylight/solar.d.ts +46 -0
  84. package/dist/lib/daylight/solar.d.ts.map +1 -0
  85. package/dist/lib/daylight/solar.js +156 -0
  86. package/dist/lib/device-tier.d.ts +29 -0
  87. package/dist/lib/device-tier.d.ts.map +1 -0
  88. package/dist/lib/device-tier.js +71 -0
  89. package/dist/lib/dispose-object3d.d.ts.map +1 -1
  90. package/dist/lib/dispose-object3d.js +4 -2
  91. package/dist/lib/drone-flight.d.ts +44 -0
  92. package/dist/lib/drone-flight.d.ts.map +1 -0
  93. package/dist/lib/drone-flight.js +121 -0
  94. package/dist/lib/editor-highlight.d.ts +16 -0
  95. package/dist/lib/editor-highlight.d.ts.map +1 -0
  96. package/dist/lib/editor-highlight.js +33 -0
  97. package/dist/lib/foundation-materials.d.ts.map +1 -1
  98. package/dist/lib/foundation-materials.js +2 -4
  99. package/dist/lib/glb-merge.d.ts +23 -0
  100. package/dist/lib/glb-merge.d.ts.map +1 -0
  101. package/dist/lib/glb-merge.js +184 -0
  102. package/dist/lib/hardware-geometry.d.ts +21 -0
  103. package/dist/lib/hardware-geometry.d.ts.map +1 -0
  104. package/dist/lib/hardware-geometry.js +283 -0
  105. package/dist/lib/ktx2-loader.d.ts.map +1 -1
  106. package/dist/lib/ktx2-loader.js +2 -1
  107. package/dist/lib/layer-pass.d.ts +2 -0
  108. package/dist/lib/layer-pass.d.ts.map +1 -1
  109. package/dist/lib/layer-pass.js +20 -0
  110. package/dist/lib/materials.d.ts.map +1 -1
  111. package/dist/lib/materials.js +50 -23
  112. package/dist/lib/measurement-label.d.ts +4 -0
  113. package/dist/lib/measurement-label.d.ts.map +1 -0
  114. package/dist/lib/measurement-label.js +54 -0
  115. package/dist/lib/measurement-presentation.d.ts +5 -0
  116. package/dist/lib/measurement-presentation.d.ts.map +1 -0
  117. package/dist/lib/measurement-presentation.js +8 -0
  118. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  119. package/dist/lib/merged-outline-node.js +7 -1
  120. package/dist/lib/occlusion-culler.d.ts +34 -0
  121. package/dist/lib/occlusion-culler.d.ts.map +1 -0
  122. package/dist/lib/occlusion-culler.js +698 -0
  123. package/dist/lib/pointer-events.d.ts.map +1 -1
  124. package/dist/lib/pointer-events.js +3 -3
  125. package/dist/lib/post-processing-resources.d.ts +4 -0
  126. package/dist/lib/post-processing-resources.d.ts.map +1 -1
  127. package/dist/lib/post-processing-resources.js +5 -0
  128. package/dist/lib/readback-rows.d.ts +14 -0
  129. package/dist/lib/readback-rows.d.ts.map +1 -0
  130. package/dist/lib/readback-rows.js +31 -0
  131. package/dist/lib/reveal-pose.d.ts.map +1 -1
  132. package/dist/lib/reveal-pose.js +3 -0
  133. package/dist/lib/scene-matrices.d.ts +12 -0
  134. package/dist/lib/scene-matrices.d.ts.map +1 -0
  135. package/dist/lib/scene-matrices.js +287 -0
  136. package/dist/lib/scene-pass-mrt.d.ts +5 -2
  137. package/dist/lib/scene-pass-mrt.d.ts.map +1 -1
  138. package/dist/lib/scene-pass-mrt.js +7 -2
  139. package/dist/lib/scene-themes.d.ts +0 -2
  140. package/dist/lib/scene-themes.d.ts.map +1 -1
  141. package/dist/lib/scene-themes.js +0 -2
  142. package/dist/lib/scene-visibility.d.ts +2 -0
  143. package/dist/lib/scene-visibility.d.ts.map +1 -1
  144. package/dist/lib/scene-visibility.js +12 -3
  145. package/dist/lib/site-surfaces.d.ts +1 -8
  146. package/dist/lib/site-surfaces.d.ts.map +1 -1
  147. package/dist/lib/site-surfaces.js +0 -19
  148. package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
  149. package/dist/lib/snapshot-pipeline.js +24 -40
  150. package/dist/lib/texture-reference.d.ts.map +1 -1
  151. package/dist/lib/texture-reference.js +13 -10
  152. package/dist/lib/underground-ambiance.d.ts +0 -2
  153. package/dist/lib/underground-ambiance.d.ts.map +1 -1
  154. package/dist/lib/underground-ambiance.js +0 -2
  155. package/dist/lib/viewer-config.d.ts +21 -0
  156. package/dist/lib/viewer-config.d.ts.map +1 -0
  157. package/dist/lib/viewer-config.js +21 -0
  158. package/dist/lib/viewer-preference-storage.d.ts +7 -0
  159. package/dist/lib/viewer-preference-storage.d.ts.map +1 -0
  160. package/dist/lib/viewer-preference-storage.js +23 -0
  161. package/dist/store/use-item-light-pool.d.ts +3 -6
  162. package/dist/store/use-item-light-pool.d.ts.map +1 -1
  163. package/dist/store/use-item-light-pool.js +12 -0
  164. package/dist/store/use-viewer.d.ts +62 -59
  165. package/dist/store/use-viewer.d.ts.map +1 -1
  166. package/dist/store/use-viewer.js +106 -19
  167. package/dist/systems/ceiling/ceiling-system.d.ts +5 -0
  168. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  169. package/dist/systems/ceiling/ceiling-system.js +11 -1
  170. package/dist/systems/door/door-system.d.ts.map +1 -1
  171. package/dist/systems/door/door-system.js +501 -145
  172. package/dist/systems/door/leaf-profile.d.ts +11 -0
  173. package/dist/systems/door/leaf-profile.d.ts.map +1 -0
  174. package/dist/systems/door/leaf-profile.js +140 -0
  175. package/dist/systems/elevator/elevator-interaction-system.d.ts +16 -2
  176. package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -1
  177. package/dist/systems/elevator/elevator-interaction-system.js +41 -8
  178. package/dist/systems/geometry/geometry-status.d.ts +8 -0
  179. package/dist/systems/geometry/geometry-status.d.ts.map +1 -0
  180. package/dist/systems/geometry/geometry-status.js +24 -0
  181. package/dist/systems/interactive/callout-actions.d.ts +72 -0
  182. package/dist/systems/interactive/callout-actions.d.ts.map +1 -0
  183. package/dist/systems/interactive/callout-actions.js +212 -0
  184. package/dist/systems/interactive/interactive-system.d.ts +5 -1
  185. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  186. package/dist/systems/interactive/interactive-system.js +44 -121
  187. package/dist/systems/interactive/opening-settled.d.ts +16 -0
  188. package/dist/systems/interactive/opening-settled.d.ts.map +1 -0
  189. package/dist/systems/interactive/opening-settled.js +53 -0
  190. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  191. package/dist/systems/item-light/item-light-system.js +22 -214
  192. package/dist/systems/item-light/pooled-lights.d.ts +70 -0
  193. package/dist/systems/item-light/pooled-lights.d.ts.map +1 -0
  194. package/dist/systems/item-light/pooled-lights.js +449 -0
  195. package/dist/systems/level/level-system.d.ts.map +1 -1
  196. package/dist/systems/level/level-system.js +19 -1
  197. package/dist/systems/roof/roof-material-slots.d.ts +14 -0
  198. package/dist/systems/roof/roof-material-slots.d.ts.map +1 -0
  199. package/dist/systems/roof/roof-material-slots.js +13 -0
  200. package/dist/systems/roof/roof-materials.d.ts +25 -2
  201. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  202. package/dist/systems/roof/roof-materials.js +85 -26
  203. package/dist/systems/roof/roof-system.d.ts +34 -1
  204. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  205. package/dist/systems/roof/roof-system.js +582 -168
  206. package/dist/systems/wall/opening-casing-geometry.d.ts +14 -0
  207. package/dist/systems/wall/opening-casing-geometry.d.ts.map +1 -0
  208. package/dist/systems/wall/opening-casing-geometry.js +102 -0
  209. package/dist/systems/wall/opening-cutout-geometry.d.ts +9 -0
  210. package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -1
  211. package/dist/systems/wall/opening-cutout-geometry.js +7 -3
  212. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  213. package/dist/systems/wall/wall-materials.js +28 -35
  214. package/dist/systems/wall/wall-system.d.ts +11 -0
  215. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  216. package/dist/systems/wall/wall-system.js +86 -25
  217. package/dist/systems/wall/wall-t-junctions.d.ts +15 -0
  218. package/dist/systems/wall/wall-t-junctions.d.ts.map +1 -0
  219. package/dist/systems/wall/wall-t-junctions.js +149 -0
  220. package/dist/systems/window/window-animation-system.d.ts +3 -12
  221. package/dist/systems/window/window-animation-system.d.ts.map +1 -1
  222. package/dist/systems/window/window-animation-system.js +37 -122
  223. package/dist/systems/window/window-pose.d.ts +31 -0
  224. package/dist/systems/window/window-pose.d.ts.map +1 -0
  225. package/dist/systems/window/window-pose.js +152 -0
  226. package/dist/systems/window/window-roller-shutter.d.ts +8 -0
  227. package/dist/systems/window/window-roller-shutter.d.ts.map +1 -0
  228. package/dist/systems/window/window-roller-shutter.js +64 -0
  229. package/dist/systems/window/window-system.d.ts +2 -11
  230. package/dist/systems/window/window-system.d.ts.map +1 -1
  231. package/dist/systems/window/window-system.js +470 -303
  232. package/package.json +6 -6
  233. package/dist/systems/interactive/control-widget.d.ts +0 -10
  234. package/dist/systems/interactive/control-widget.d.ts.map +0 -1
  235. package/dist/systems/interactive/control-widget.js +0 -35
  236. package/dist/systems/interactive/procedural-controls.d.ts +0 -13
  237. package/dist/systems/interactive/procedural-controls.d.ts.map +0 -1
  238. package/dist/systems/interactive/procedural-controls.js +0 -17
@@ -0,0 +1,283 @@
1
+ import { BoxGeometry, CapsuleGeometry, CatmullRomCurve3, CylinderGeometry, LatheGeometry, SphereGeometry, TubeGeometry, Vector2, Vector3, } from 'three';
2
+ import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
3
+ import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
4
+ const cache = new Map();
5
+ const mm = (value) => Math.round(value * 1000);
6
+ function cached(name, dimensions, build) {
7
+ const sizes = dimensions.map(mm);
8
+ const key = `${name}:${sizes.join(':')}`;
9
+ let geometry = cache.get(key);
10
+ if (!geometry) {
11
+ geometry = build(...sizes.map((size) => size / 1000));
12
+ geometry.userData.shared = true;
13
+ cache.set(key, geometry);
14
+ }
15
+ return geometry;
16
+ }
17
+ function scaleUVs(geometry, u, v) {
18
+ const uv = geometry.getAttribute('uv');
19
+ for (let i = 0; i < uv.count; i++)
20
+ uv.setXY(i, uv.getX(i) * u, uv.getY(i) * v);
21
+ }
22
+ function lathe(profile, segments) {
23
+ const geometry = new LatheGeometry(profile.map(([r, y]) => new Vector2(r, y)), segments);
24
+ geometry.normalizeNormals();
25
+ const uv = geometry.getAttribute('uv');
26
+ let distance = 0;
27
+ for (let j = 0; j < profile.length; j++) {
28
+ const [r, y] = profile[j];
29
+ if (j > 0) {
30
+ const [previousR, previousY] = profile[j - 1];
31
+ distance += Math.hypot(r - previousR, y - previousY);
32
+ }
33
+ for (let i = 0; i <= segments; i++) {
34
+ uv.setXY(i * profile.length + j, (i / segments) * 2 * Math.PI * r, distance);
35
+ }
36
+ }
37
+ return geometry;
38
+ }
39
+ function cylinder(radius, length, segments) {
40
+ const geometry = new CylinderGeometry(radius, radius, length, segments);
41
+ const uv = geometry.getAttribute('uv');
42
+ const position = geometry.getAttribute('position');
43
+ const sideVertices = (segments + 1) * 2;
44
+ for (let i = 0; i < uv.count; i++) {
45
+ if (i < sideVertices) {
46
+ uv.setXY(i, uv.getX(i) * 2 * Math.PI * radius, uv.getY(i) * length);
47
+ }
48
+ else {
49
+ uv.setXY(i, position.getX(i), position.getZ(i));
50
+ }
51
+ }
52
+ return geometry;
53
+ }
54
+ function merge(parts) {
55
+ const indexed = parts.every((part) => part.index !== null);
56
+ const normalized = parts.map((part) => (!indexed && part.index ? part.toNonIndexed() : part));
57
+ const geometry = mergeGeometries(normalized);
58
+ for (const part of normalized)
59
+ if (!parts.includes(part))
60
+ part.dispose();
61
+ for (const part of parts)
62
+ part.dispose();
63
+ return geometry;
64
+ }
65
+ function hemisphere(radius, radialSegments, heightSegments) {
66
+ const geometry = new SphereGeometry(radius, radialSegments, heightSegments, 0, 2 * Math.PI, 0, Math.PI / 2);
67
+ scaleUVs(geometry, 2 * Math.PI * radius, (Math.PI * radius) / 2);
68
+ return geometry;
69
+ }
70
+ /** Origin is the spindle on the mounting face; the grip points along +X, out along +Z. */
71
+ function buildLever(curved, plate = false) {
72
+ return cached(plate ? 'lever-plate' : curved ? 'lever-curved' : 'lever-straight', [], () => {
73
+ const faceFillet = 0.0005;
74
+ const faceRadius = 0.0245 - faceFillet * (Math.SQRT2 - 1);
75
+ const profile = [
76
+ [0, 0],
77
+ [0.026, 0],
78
+ [0.026, 0.0075],
79
+ ];
80
+ for (const angle of [Math.PI / 4, Math.PI / 2]) {
81
+ profile.push([
82
+ faceRadius + faceFillet * Math.cos(angle),
83
+ 0.0085 + faceFillet * Math.sin(angle),
84
+ ]);
85
+ }
86
+ profile.push([0, 0.009]);
87
+ const rose = plate
88
+ ? roundedBox(0.04, 0.22, 0.006, 0.003).clone().translate(0, 0, 0.003)
89
+ : lathe(profile, 32).rotateX(Math.PI / 2);
90
+ const neck = cylinder(0.01, 0.037, 16)
91
+ .rotateX(Math.PI / 2)
92
+ .translate(0, 0, 0.009 + 0.037 / 2);
93
+ const neckProfile = [];
94
+ for (let i = 0; i <= 4; i++) {
95
+ const angle = (i * Math.PI) / 8;
96
+ neckProfile.push([0.009 + 0.001 * Math.cos(angle), 0.046 + 0.001 * Math.sin(angle)]);
97
+ }
98
+ neckProfile.push([0, 0.047]);
99
+ const fillet = lathe(neckProfile, 16);
100
+ const filletNormals = fillet.getAttribute('normal');
101
+ // Match the cylinder tangent exactly rather than averaging the first fillet chord.
102
+ for (let i = 0; i <= 16; i++) {
103
+ const phi = (i * 2 * Math.PI) / 16;
104
+ for (let j = 0; j < neckProfile.length; j++) {
105
+ const angle = (Math.min(j, 4) * Math.PI) / 8;
106
+ filletNormals.setXYZ(i * neckProfile.length + j, Math.cos(angle) * Math.sin(phi), Math.sin(angle), Math.cos(angle) * Math.cos(phi));
107
+ }
108
+ }
109
+ fillet.rotateX(Math.PI / 2);
110
+ const curve = new CatmullRomCurve3((curved
111
+ ? [
112
+ [0, 0],
113
+ [0.01, 0],
114
+ [0.02, 0],
115
+ [0.035, 0],
116
+ [0.065, -0.004],
117
+ [0.095, -0.011],
118
+ [0.105, -0.012],
119
+ [0.1155, -0.012],
120
+ ]
121
+ : [
122
+ [0, 0],
123
+ [0.1155, 0],
124
+ ]).map(([x, y]) => new Vector3(x, y, 0.047)));
125
+ const grip = new TubeGeometry(curve, curved ? 24 : 2, 0.0095, 16, false);
126
+ scaleUVs(grip, curve.getLength(), 2 * Math.PI * 0.0095);
127
+ const cap = hemisphere(0.0095, 12, 6)
128
+ .rotateZ(-Math.PI / 2)
129
+ .translate(0.1155, curved ? -0.012 : 0, 0.047);
130
+ // Close the heel where the horizontal grip meets the vertical neck.
131
+ const heel = hemisphere(0.0095, 12, 6)
132
+ .rotateZ(Math.PI / 2)
133
+ .translate(0, 0, 0.047);
134
+ if (plate)
135
+ for (const part of [neck, fillet, grip, cap, heel])
136
+ part.translate(0, 0, -0.003);
137
+ return merge([rose, neck, fillet, grip, cap, heel]);
138
+ });
139
+ }
140
+ export function leverOnRose() {
141
+ return buildLever(false);
142
+ }
143
+ export function leverOnRoseCurved() {
144
+ return buildLever(true);
145
+ }
146
+ export function leverOnPlate() {
147
+ return buildLever(false, true);
148
+ }
149
+ /** Origin at the mounting face; a 56 mm ball on a 20 mm neck and 56 mm rose. */
150
+ export function knobOnRose() {
151
+ return cached('knob', [], () => {
152
+ const rose = cylinder(0.028, 0.006, 32)
153
+ .rotateX(Math.PI / 2)
154
+ .translate(0, 0, 0.003);
155
+ const neck = cylinder(0.01, 0.025, 16)
156
+ .rotateX(Math.PI / 2)
157
+ .translate(0, 0, 0.0185);
158
+ const ball = new SphereGeometry(0.028, 32, 16);
159
+ scaleUVs(ball, 2 * Math.PI * 0.028, Math.PI * 0.028);
160
+ ball.translate(0, 0, 0.052);
161
+ return merge([rose, neck, ball]);
162
+ });
163
+ }
164
+ /** Origin at the face; a 40 × 120 mm open cup with a 3 mm rim, recessed 12 mm. */
165
+ export function flushPull() {
166
+ return cached('flush-pull', [], () => {
167
+ const parts = [];
168
+ const box = (w, h, d, x, y, z) => {
169
+ const geometry = new BoxGeometry(w, h, d);
170
+ boxUVs(geometry, w, h, d);
171
+ parts.push(geometry.translate(x, y, z));
172
+ };
173
+ box(0.04, 0.12, 0.002, 0, 0, -0.011);
174
+ for (const side of [-1, 1]) {
175
+ box(0.002, 0.12, 0.01, side * 0.019, 0, -0.005);
176
+ box(0.036, 0.002, 0.01, 0, side * 0.059, -0.005);
177
+ box(0.003, 0.126, 0.001, side * 0.0215, 0, 0.0005);
178
+ box(0.04, 0.003, 0.001, 0, side * 0.0615, 0.0005);
179
+ }
180
+ return merge(parts);
181
+ });
182
+ }
183
+ function hingePart(leaf, diameter, height) {
184
+ return cached(leaf ? 'hinge-leaf' : 'hinge-jamb', [diameter, height], (d, h) => {
185
+ const radialScale = d / 0.014;
186
+ const heightScale = h / 0.103;
187
+ const radius = d / 2;
188
+ const plateW = 0.0025 * radialScale;
189
+ const plateH = 0.089 * heightScale;
190
+ const plateD = 0.028 * radialScale;
191
+ const plate = new BoxGeometry(plateW, plateH, plateD);
192
+ boxUVs(plate, plateW, plateH, plateD);
193
+ plate.translate(leaf ? plateW / 2 : -plateW / 2, 0, -plateD / 2);
194
+ const parts = [plate];
195
+ for (let i = leaf ? 0 : 1; i < 5; i += 2) {
196
+ parts.push(cylinder(radius, 0.017 * heightScale, 16).translate(0, (-0.036 + i * 0.018) * heightScale, 0));
197
+ }
198
+ if (leaf) {
199
+ for (const side of [-1, 1]) {
200
+ const cap = hemisphere(radius, 12, d <= 0.01 ? 2 : 3);
201
+ const capScale = heightScale / radialScale;
202
+ cap.scale(1, capScale, 1);
203
+ const uv = cap.getAttribute('uv');
204
+ for (let i = 0; i < uv.count; i++)
205
+ uv.setY(i, uv.getY(i) * capScale);
206
+ if (side < 0)
207
+ cap.rotateX(Math.PI);
208
+ parts.push(cap.translate(0, side * 0.0445 * heightScale, 0));
209
+ }
210
+ }
211
+ return merge(parts);
212
+ });
213
+ }
214
+ /** Odd knuckles and plate on the leaf edge (+X), extending into the rebate (-Z). */
215
+ export function hingeLeafPart(diameter = 0.014, height = 0.103) {
216
+ return hingePart(true, diameter, height);
217
+ }
218
+ /** Even knuckles and plate on the jamb face (-X), extending into the rebate (-Z). */
219
+ export function hingeJambPart(diameter = 0.014, height = 0.103) {
220
+ return hingePart(false, diameter, height);
221
+ }
222
+ /** Origin on the mounting face; bar along Y, projecting along +Z. */
223
+ export function pullBar(doorScale = false) {
224
+ return cached(doorScale ? 'door-pull' : 'pull', [], () => {
225
+ if (doorScale) {
226
+ const bar = cylinder(0.0125, 0.4, 32).translate(0, 0, 0.05);
227
+ return merge([
228
+ bar,
229
+ ...[-0.15, 0.15].map((y) => cylinder(0.008, 0.05, 16)
230
+ .rotateX(Math.PI / 2)
231
+ .translate(0, y, 0.025)),
232
+ ]);
233
+ }
234
+ const bar = new CapsuleGeometry(0.009, 0.102, 6, 12);
235
+ scaleUVs(bar, 2 * Math.PI * 0.009, 0.102 + Math.PI * 0.009);
236
+ bar.translate(0, 0, 0.022);
237
+ const parts = [bar];
238
+ for (const y of [-0.02, 0.02]) {
239
+ parts.push(cylinder(0.005, 0.02, 16)
240
+ .rotateX(Math.PI / 2)
241
+ .translate(0, y, 0.01));
242
+ }
243
+ return merge(parts);
244
+ });
245
+ }
246
+ function boxUVs(geometry, width, height, depth) {
247
+ const uv = geometry.getAttribute('uv');
248
+ const faceSizes = [
249
+ [depth, height],
250
+ [depth, height],
251
+ [width, depth],
252
+ [width, depth],
253
+ [width, height],
254
+ [width, height],
255
+ ];
256
+ const verticesPerFace = uv.count / 6;
257
+ for (let i = 0; i < uv.count; i++) {
258
+ const [u, v] = faceSizes[Math.floor(i / verticesPerFace)];
259
+ uv.setXY(i, uv.getX(i) * u, uv.getY(i) * v);
260
+ }
261
+ }
262
+ export function roundedBox(w, h, d, r = Math.min(0.004, w / 4, h / 4, d / 4)) {
263
+ return cached('box', [w, h, d, r], (width, height, depth, radius) => {
264
+ const geometry = new RoundedBoxGeometry(width, height, depth, 1, radius);
265
+ boxUVs(geometry, width, height, depth);
266
+ return geometry;
267
+ });
268
+ }
269
+ /** A capped round bar along Y. */
270
+ export function tube(radius, length) {
271
+ return cached('tube', [2 * radius, length], (diameter, l) => cylinder(diameter / 2, l, 12));
272
+ }
273
+ export function sphere(radius) {
274
+ return cached('sphere', [2 * radius], (diameter) => {
275
+ const geometry = new SphereGeometry(diameter / 2, 12, 8);
276
+ scaleUVs(geometry, Math.PI * diameter, (Math.PI * diameter) / 2);
277
+ return geometry;
278
+ });
279
+ }
280
+ /** A wheel with its axle along Z. */
281
+ export function roller(radius, width) {
282
+ return cached('roller', [2 * radius, width], (diameter, w) => cylinder(diameter / 2, w, 20).rotateX(Math.PI / 2));
283
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ktx2-loader.d.ts","sourceRoot":"","sources":["../../src/lib/ktx2-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAA;AAId,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AA2BrE,oFAAoF;AACpF,wBAAgB,oBAAoB,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAE1E;AAED;;;;;;;;;;GAUG;AACH,cAAM,uBAAwB,SAAQ,UAAU;IAC9C,OAAO,CAAC,YAAY,CAA0B;IAErC,IAAI,CACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,EAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI,CA8BN;IAED,OAAO,CAAC,cAAc;IAkBtB;kEAC8D;IACxD,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAiC5F;IAED,OAAO,IAAI,IAAI,CAKd;CACF;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,yBAAgC,CAAA;AAWvD;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7C;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAkB5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,MAAM,EAAE;IAAE,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAA;CAAE,EAC/C,QAAQ,EAAE,OAAO,GAChB,OAAO,CAIT;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C"}
1
+ {"version":3,"file":"ktx2-loader.d.ts","sourceRoot":"","sources":["../../src/lib/ktx2-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAA;AAId,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AA4BrE,oFAAoF;AACpF,wBAAgB,oBAAoB,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAE1E;AAED;;;;;;;;;;GAUG;AACH,cAAM,uBAAwB,SAAQ,UAAU;IAC9C,OAAO,CAAC,YAAY,CAA0B;IAErC,IAAI,CACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,EAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI,CA8BN;IAED,OAAO,CAAC,cAAc;IAkBtB;kEAC8D;IACxD,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAiC5F;IAED,OAAO,IAAI,IAAI,CAKd;CACF;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,yBAAgC,CAAA;AAUvD;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7C;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAmB5D;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,MAAM,EAAE;IAAE,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAA;CAAE,EAC/C,QAAQ,EAAE,OAAO,GAChB,OAAO,CAIT;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C"}
@@ -3,6 +3,7 @@ import { DataTexture, LinearFilter, LinearMipmapLinearFilter, RGBAFormat, Unsign
3
3
  // LottieLoader/TTFLoader, whose CDN URL imports (`lottie-web`, `opentype.js`)
4
4
  // crash bun's test runtime for every consumer of the viewer barrel.
5
5
  import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
6
+ import { getViewerConfig } from './viewer-config';
6
7
  /** Base width/height of a Basis-supercompressed KTX2 payload needing transcode
7
8
  * (vkFormat 0 = ETC1S/UASTC) whose dimensions aren't block-aligned, or null
8
9
  * for anything safe. Little-endian u32s: vkFormat at byte 12, pixelWidth at
@@ -125,7 +126,6 @@ class AlignmentSafeKTX2Loader extends KTX2Loader {
125
126
  * the scene, so catalog `.ktx2` finishes still load).
126
127
  */
127
128
  export const ktx2Loader = new AlignmentSafeKTX2Loader();
128
- ktx2Loader.setTranscoderPath('https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/');
129
129
  const configuredRenderers = new WeakSet();
130
130
  const warnedRenderers = new WeakSet();
131
131
  let resolveKtx2Ready;
@@ -144,6 +144,7 @@ export function whenKtx2Ready() {
144
144
  }
145
145
  /** Returns true once support has been detected for this renderer (KTX2 safe to load). */
146
146
  export function ensureKtx2Support(renderer) {
147
+ ktx2Loader.setTranscoderPath(getViewerConfig().decoders.basisPath);
147
148
  const key = renderer;
148
149
  if (!key)
149
150
  return false;
@@ -1,5 +1,7 @@
1
1
  import { type Camera, Object3D, type Scene } from 'three';
2
2
  import { type NodeFrame, PassNode } from 'three/webgpu';
3
+ export declare function getLayoutRevision(): number;
4
+ export declare function isLayoutObserved(scene: Object3D): boolean;
3
5
  export declare class LayerPassIndex {
4
6
  readonly source: Scene;
5
7
  private readonly members;
@@ -1 +1 @@
1
- {"version":3,"file":"layer-pass.d.ts","sourceRoot":"","sources":["../../src/lib/layer-pass.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAiB,QAAQ,EAAE,KAAK,KAAK,EAAW,MAAM,OAAO,CAAA;AACjF,OAAO,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAoBvD,qBAAa,cAAc;IAKvB,QAAQ,CAAC,MAAM,EAAE,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,YACW,MAAM,EAAE,KAAK,EACtB,MAAM,EAAE,MAAM,EAAE,EASjB;IAED,QAAQ,CAAC,OAAO,EAAE,QAAQ,QAQzB;IAED,OAAO,CAAC,MAAM,CA2Cb;IAED,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;;;MAkCvC;IAED,OAAO,SAGN;CACF;AAiBD,qBAAa,aAAc,SAAQ,QAAQ;IAMvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAO;IAEzB,YACmB,KAAK,EAAE,cAAc,EACtC,MAAM,EAAE,MAAM,EACG,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,EAYpC;IAEQ,OAAO,SAGf;IAEQ,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CA+DjD;CACF"}
1
+ {"version":3,"file":"layer-pass.d.ts","sourceRoot":"","sources":["../../src/lib/layer-pass.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAiB,QAAQ,EAAE,KAAK,KAAK,EAAW,MAAM,OAAO,CAAA;AACjF,OAAO,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAYvD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAEzD;AAkBD,qBAAa,cAAc;IAKvB,QAAQ,CAAC,MAAM,EAAE,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,YACW,MAAM,EAAE,KAAK,EACtB,MAAM,EAAE,MAAM,EAAE,EAUjB;IAED,QAAQ,CAAC,OAAO,EAAE,QAAQ,QAQzB;IAED,OAAO,CAAC,MAAM,CA8Cb;IAED,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;;;MAkCvC;IAED,OAAO,SAIN;CACF;AAiBD,qBAAa,aAAc,SAAQ,QAAQ;IAMvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAO;IAEzB,YACmB,KAAK,EAAE,cAAc,EACtC,MAAM,EAAE,MAAM,EACG,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,EAYpC;IAEQ,OAAO,SAGf;IAEQ,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CA+DjD;CACF"}
@@ -5,6 +5,19 @@
5
5
  import { Object3D, Vector2 } from 'three';
6
6
  import { PassNode } from 'three/webgpu';
7
7
  const maskObserver = Symbol('LayerPassIndex.maskObserver');
8
+ /**
9
+ * Bumped on every observed mask change and child insertion or removal, so a per-frame walk can
10
+ * tell when what is drawable may have changed (scene-matrices.ts). Only meaningful for scenes
11
+ * with a live index ({@link isLayoutObserved}).
12
+ */
13
+ let layoutRevision = 0;
14
+ const observedScenes = new WeakSet();
15
+ export function getLayoutRevision() {
16
+ return layoutRevision;
17
+ }
18
+ export function isLayoutObserved(scene) {
19
+ return observedScenes.has(scene);
20
+ }
8
21
  function maskOwner(object) {
9
22
  const get = Object.getOwnPropertyDescriptor(object.layers, 'mask')?.get;
10
23
  return get?.[maskObserver];
@@ -22,6 +35,7 @@ export class LayerPassIndex {
22
35
  this.members.set(1 << layer, new Set());
23
36
  try {
24
37
  this.attach(source);
38
+ observedScenes.add(source);
25
39
  }
26
40
  catch (error) {
27
41
  this.dispose();
@@ -45,7 +59,11 @@ export class LayerPassIndex {
45
59
  throw new Error('LayerPassIndex requires one index per scene and unshared Layers');
46
60
  }
47
61
  let mask = layers.mask;
62
+ // Passes switch the camera's layers every frame; that changes nothing in the scene.
63
+ const isCamera = object.isCamera === true;
48
64
  const sync = () => {
65
+ if (!isCamera)
66
+ layoutRevision++;
49
67
  for (const [bit, members] of this.members) {
50
68
  if ((mask & bit) !== 0 && object !== this.source)
51
69
  members.add(object);
@@ -88,6 +106,7 @@ export class LayerPassIndex {
88
106
  this.attach(child);
89
107
  };
90
108
  detach(object) {
109
+ layoutRevision++;
91
110
  for (const child of object.children)
92
111
  this.detach(child);
93
112
  this.cleanups.get(object)?.();
@@ -136,6 +155,7 @@ export class LayerPassIndex {
136
155
  return { drawable, shadowLight };
137
156
  }
138
157
  dispose() {
158
+ observedScenes.delete(this.source);
139
159
  for (const cleanup of this.cleanups.values())
140
160
  cleanup();
141
161
  this.cleanups.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { getMaterialPresetByRef, materialColorPaint, parseMaterialColor, parseMaterialRef, resolveMaterial, } from '@pascal-app/core';
2
2
  import { addAfterEffect, invalidate } from '@react-three/fiber';
3
3
  import * as THREE from 'three';
4
- import { float, mix, positionViewDirection, transformedNormalView } from 'three/tsl';
4
+ import { float, mix, normalView, positionViewDirection } from 'three/tsl';
5
5
  import { MeshLambertNodeMaterial, MeshStandardNodeMaterial } from 'three/webgpu';
6
6
  import { resolveCdnUrl } from './asset-url';
7
7
  import { isKtx2Url, ktx2Loader, whenKtx2Ready } from './ktx2-loader';
@@ -162,35 +162,41 @@ export function resolveTextureRepeat(repeat, scale) {
162
162
  }
163
163
  return [fallback, fallback];
164
164
  }
165
+ function textureOffset(texture) {
166
+ return texture.offset ?? [0, 0];
167
+ }
168
+ function getPlacementKey(texture) {
169
+ const [repeatX, repeatY] = resolveTextureRepeat(texture.repeat, texture.scale);
170
+ const [offsetX, offsetY] = textureOffset(texture);
171
+ return `${repeatX}x${repeatY}+${offsetX},${offsetY}`;
172
+ }
165
173
  export function getTextureKey(material) {
166
174
  const texture = material?.texture;
167
175
  if (!texture)
168
176
  return 'none';
169
- const [repeatX, repeatY] = resolveTextureRepeat(texture.repeat, texture.scale);
170
- return `${texture.url}-${repeatX}x${repeatY}`;
177
+ const normal = texture.normalMap ? `-n:${texture.normalMap}*${texture.normalScale ?? 1}` : '';
178
+ const bump = texture.bumpMap ? `-b:${texture.bumpMap}*${texture.bumpScale ?? 1}` : '';
179
+ return `${texture.url}-${getPlacementKey(texture)}${normal}${bump}`;
171
180
  }
172
- function getTexture(material) {
173
- const textureConfig = material?.texture;
174
- if (!textureConfig?.url)
175
- return undefined;
176
- const cacheKey = getTextureKey(material);
181
+ /** One map of a native material's texture; every map shares the albedo's repeat and offset. */
182
+ function getTexture(textureConfig, url, slot) {
183
+ const cacheKey = `${url}-${getPlacementKey(textureConfig)}-${slot}`;
177
184
  const cached = textureCache.get(cacheKey);
178
185
  if (cached)
179
186
  return cached;
180
- const resolvedUrl = /^(?:asset|blob|data):/.test(textureConfig.url)
181
- ? textureConfig.url
182
- : (resolveCdnUrl(textureConfig.url) ?? textureConfig.url);
187
+ const resolvedUrl = /^(?:asset|blob|data):/.test(url) ? url : (resolveCdnUrl(url) ?? url);
183
188
  const texture = loadTexture(resolvedUrl, cacheKey);
184
189
  texture.wrapS = THREE.RepeatWrapping;
185
190
  texture.wrapT = THREE.RepeatWrapping;
186
191
  const [repeatX, repeatY] = resolveTextureRepeat(textureConfig.repeat, textureConfig.scale);
187
192
  texture.repeat.set(repeatX, repeatY);
193
+ texture.offset.set(...textureOffset(textureConfig));
188
194
  texture.updateMatrix();
189
- texture.colorSpace = THREE.SRGBColorSpace;
195
+ texture.colorSpace = slot === 'map' ? THREE.SRGBColorSpace : THREE.NoColorSpace;
190
196
  stampPascalTextureRef(texture, {
191
197
  kind: 'project-asset',
192
198
  src: resolvedUrl,
193
- slot: 'map',
199
+ slot,
194
200
  });
195
201
  textureCache.set(cacheKey, texture);
196
202
  return texture;
@@ -272,9 +278,14 @@ async function loadPresetTexture(path, props, slot) {
272
278
  // materials can be created while a capture canvas's renderer is still
273
279
  // initializing, and failing here would cache the material permanently
274
280
  // texture-less (white).
275
- const load = isKtx2Url(resolvedPath)
276
- ? whenKtx2Ready().then(() => ktx2Loader.loadAsync(resolvedPath))
277
- : textureLoader.loadAsync(resolvedPath);
281
+ const loadFrom = (url) => isKtx2Url(url)
282
+ ? whenKtx2Ready().then(() => ktx2Loader.loadAsync(url))
283
+ : textureLoader.loadAsync(url);
284
+ // A catalog map ships in the app's public folder before the asset CDN has it
285
+ // (a branch, a deploy ahead of the CDN): a CDN miss retries the app's own copy.
286
+ const load = resolvedPath !== path && path.startsWith('/')
287
+ ? loadFrom(resolvedPath).catch(() => loadFrom(path))
288
+ : loadFrom(resolvedPath);
278
289
  const promise = load
279
290
  .then((texture) => {
280
291
  applyTextureProperties(texture, props, slot);
@@ -383,7 +394,9 @@ export function materialCastsShadow(material) {
383
394
  * This is what makes glass read as a surface instead of a flat blue tint.
384
395
  */
385
396
  function applyGlassFresnel(material) {
386
- const facing = transformedNormalView.dot(positionViewDirection).clamp(0, 1);
397
+ // The daylight look swaps in its tuned glass for flagged materials (lib/daylight/material-hooks).
398
+ material.userData.isGlass = true;
399
+ const facing = normalView.dot(positionViewDirection).clamp(0, 1);
387
400
  const fresnel = facing.oneMinus().pow(3);
388
401
  material.opacityNode = mix(float(material.opacity), float(0.92), fresnel);
389
402
  material.envMapIntensity = 1.4;
@@ -449,22 +462,36 @@ export function createMaterial(material, shading = 'rendered') {
449
462
  if (materialCache.has(cacheKey)) {
450
463
  return materialCache.get(cacheKey);
451
464
  }
452
- const map = getTexture(material);
465
+ const texture = material?.texture?.url ? material.texture : undefined;
453
466
  const materialParams = {
454
467
  color: props.color,
455
468
  opacity: props.opacity,
456
469
  transparent: props.transparent,
457
470
  side: sideMap[props.side],
458
471
  };
459
- if (map)
460
- materialParams.map = map;
461
- const threeMaterial = shading === 'solid'
462
- ? new MeshLambertNodeMaterial(materialParams)
463
- : new MeshStandardNodeMaterial({
472
+ if (texture)
473
+ materialParams.map = getTexture(texture, texture.url, 'map');
474
+ let threeMaterial;
475
+ if (shading === 'solid') {
476
+ threeMaterial = new MeshLambertNodeMaterial(materialParams);
477
+ }
478
+ else {
479
+ const standard = new MeshStandardNodeMaterial({
464
480
  ...materialParams,
465
481
  roughness: props.roughness,
466
482
  metalness: props.metalness,
467
483
  });
484
+ if (texture?.normalMap) {
485
+ standard.normalMap = getTexture(texture, texture.normalMap, 'normalMap');
486
+ const normalScale = texture.normalScale ?? 1;
487
+ standard.normalScale.set(normalScale, normalScale);
488
+ }
489
+ if (texture?.bumpMap) {
490
+ standard.bumpMap = getTexture(texture, texture.bumpMap, 'bumpMap');
491
+ standard.bumpScale = texture.bumpScale ?? 1;
492
+ }
493
+ threeMaterial = standard;
494
+ }
468
495
  // Explicit source transparency keeps its opacity; the glass preset owns this styling.
469
496
  if (glassPreset)
470
497
  maybeApplyGlassFresnel(threeMaterial);
@@ -0,0 +1,4 @@
1
+ import { type MeasurementPoint } from '@pascal-app/core';
2
+ export declare function triangulateMeasurementPolygon(points: readonly MeasurementPoint[]): number[][];
3
+ export declare function measurementPolygonLabelAnchor(points: readonly MeasurementPoint[]): MeasurementPoint | null;
4
+ //# sourceMappingURL=measurement-label.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measurement-label.d.ts","sourceRoot":"","sources":["../../src/lib/measurement-label.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAA0C,MAAM,kBAAkB,CAAA;AA4BhG,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,EAAE,CAE7F;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAClC,gBAAgB,GAAG,IAAI,CAiCzB"}
@@ -0,0 +1,54 @@
1
+ import { measurementCentroid, measurementNormal } from '@pascal-app/core';
2
+ import { ShapeUtils, Vector2, Vector3 } from 'three';
3
+ function projectMeasurementPolygon(points) {
4
+ const normalValue = measurementNormal(points);
5
+ const originValue = points[0];
6
+ if (!(normalValue && originValue))
7
+ return null;
8
+ const normal = new Vector3(...normalValue);
9
+ const reference = Math.abs(normal.y) < 0.9 ? new Vector3(0, 1, 0) : new Vector3(1, 0, 0);
10
+ const tangent = new Vector3().crossVectors(reference, normal).normalize();
11
+ const bitangent = new Vector3().crossVectors(normal, tangent).normalize();
12
+ const origin = new Vector3(...originValue);
13
+ const contour = points.map((point) => {
14
+ const relative = new Vector3(...point).sub(origin);
15
+ return new Vector2(relative.dot(tangent), relative.dot(bitangent));
16
+ });
17
+ return { contour, triangles: ShapeUtils.triangulateShape(contour, []) };
18
+ }
19
+ export function triangulateMeasurementPolygon(points) {
20
+ return projectMeasurementPolygon(points)?.triangles ?? [];
21
+ }
22
+ export function measurementPolygonLabelAnchor(points) {
23
+ const projection = projectMeasurementPolygon(points);
24
+ if (!projection || projection.triangles.length === 0)
25
+ return measurementCentroid(points);
26
+ let largestTriangle = null;
27
+ let largestArea = Number.NEGATIVE_INFINITY;
28
+ for (const triangle of projection.triangles) {
29
+ const [firstIndex, secondIndex, thirdIndex] = triangle;
30
+ const first = firstIndex === undefined ? null : projection.contour[firstIndex];
31
+ const second = secondIndex === undefined ? null : projection.contour[secondIndex];
32
+ const third = thirdIndex === undefined ? null : projection.contour[thirdIndex];
33
+ if (!(first && second && third))
34
+ continue;
35
+ const area = Math.abs((second.x - first.x) * (third.y - first.y) - (second.y - first.y) * (third.x - first.x));
36
+ if (area > largestArea) {
37
+ largestArea = area;
38
+ largestTriangle = triangle;
39
+ }
40
+ }
41
+ if (!largestTriangle)
42
+ return measurementCentroid(points);
43
+ const [firstIndex, secondIndex, thirdIndex] = largestTriangle;
44
+ const first = firstIndex === undefined ? null : points[firstIndex];
45
+ const second = secondIndex === undefined ? null : points[secondIndex];
46
+ const third = thirdIndex === undefined ? null : points[thirdIndex];
47
+ if (!(first && second && third))
48
+ return measurementCentroid(points);
49
+ return [
50
+ (first[0] + second[0] + third[0]) / 3,
51
+ (first[1] + second[1] + third[1]) / 3,
52
+ (first[2] + second[2] + third[2]) / 3,
53
+ ];
54
+ }
@@ -0,0 +1,5 @@
1
+ export declare const MEASUREMENT_ACTIVE_COLOR = "#6366f1";
2
+ export declare const MEASUREMENT_DANGLING_COLOR = "#dc2626";
3
+ export declare const MEASUREMENT_PERSISTENT_COLOR = "#111827";
4
+ export declare function measurementPresentationColor(dangling: boolean, active: boolean): string;
5
+ //# sourceMappingURL=measurement-presentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measurement-presentation.d.ts","sourceRoot":"","sources":["../../src/lib/measurement-presentation.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,YAAY,CAAA;AACjD,eAAO,MAAM,0BAA0B,YAAY,CAAA;AAEnD,eAAO,MAAM,4BAA4B,YAAY,CAAA;AAErD,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAGvF"}
@@ -0,0 +1,8 @@
1
+ export const MEASUREMENT_ACTIVE_COLOR = '#6366f1';
2
+ export const MEASUREMENT_DANGLING_COLOR = '#dc2626';
3
+ export const MEASUREMENT_PERSISTENT_COLOR = '#111827';
4
+ export function measurementPresentationColor(dangling, active) {
5
+ if (dangling)
6
+ return MEASUREMENT_DANGLING_COLOR;
7
+ return active ? MEASUREMENT_ACTIVE_COLOR : MEASUREMENT_PERSISTENT_COLOR;
8
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"merged-outline-node.d.ts","sourceRoot":"","sources":["../../src/lib/merged-outline-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merged-outline-node.d.ts","sourceRoot":"","sources":["../../src/lib/merged-outline-node.ts"],"names":[],"mappings":"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"}