abstract-3d 3.1.1 → 4.0.0-beta.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 (229) hide show
  1. package/README.md +21 -1
  2. package/lib/renderers/dxf/dxf-encoding/dxf-build.d.ts.map +1 -1
  3. package/lib/renderers/dxf/dxf-encoding/dxf-build.js +1 -2
  4. package/lib/renderers/dxf/dxf-encoding/dxf-build.js.map +1 -1
  5. package/lib/renderers/ifc/ifc.test.d.ts +2 -0
  6. package/lib/renderers/ifc/ifc.test.d.ts.map +1 -0
  7. package/lib/renderers/ifc/ifc.test.js +380 -0
  8. package/lib/renderers/ifc/ifc.test.js.map +1 -0
  9. package/lib/renderers/index.d.ts +1 -0
  10. package/lib/renderers/index.d.ts.map +1 -1
  11. package/lib/renderers/index.js +1 -0
  12. package/lib/renderers/index.js.map +1 -1
  13. package/lib/renderers/react/index.d.ts +2 -5
  14. package/lib/renderers/react/index.d.ts.map +1 -1
  15. package/lib/renderers/react/index.js +1 -2
  16. package/lib/renderers/react/index.js.map +1 -1
  17. package/lib/renderers/react/react.d.ts +16 -42
  18. package/lib/renderers/react/react.d.ts.map +1 -1
  19. package/lib/renderers/react/react.js +49 -32
  20. package/lib/renderers/react/react.js.map +1 -1
  21. package/lib/renderers/three/appearance/appearance.d.ts +41 -0
  22. package/lib/renderers/three/appearance/appearance.d.ts.map +1 -0
  23. package/lib/renderers/three/appearance/appearance.js +89 -0
  24. package/lib/renderers/three/appearance/appearance.js.map +1 -0
  25. package/lib/renderers/three/appearance/appearance.test.d.ts +2 -0
  26. package/lib/renderers/three/appearance/appearance.test.d.ts.map +1 -0
  27. package/lib/renderers/three/appearance/appearance.test.js +97 -0
  28. package/lib/renderers/three/appearance/appearance.test.js.map +1 -0
  29. package/lib/renderers/three/appearance.d.ts +41 -0
  30. package/lib/renderers/three/appearance.d.ts.map +1 -0
  31. package/lib/renderers/three/appearance.js +100 -0
  32. package/lib/renderers/three/appearance.js.map +1 -0
  33. package/lib/renderers/three/build/build.d.ts +51 -0
  34. package/lib/renderers/three/build/build.d.ts.map +1 -0
  35. package/lib/renderers/three/build/build.js +174 -0
  36. package/lib/renderers/three/build/build.js.map +1 -0
  37. package/lib/renderers/three/build/build.test.d.ts +2 -0
  38. package/lib/renderers/three/build/build.test.d.ts.map +1 -0
  39. package/lib/renderers/three/build/build.test.js +120 -0
  40. package/lib/renderers/three/build/build.test.js.map +1 -0
  41. package/lib/renderers/three/build/materials.d.ts +12 -0
  42. package/lib/renderers/three/build/materials.d.ts.map +1 -0
  43. package/lib/renderers/three/build/materials.js +55 -0
  44. package/lib/renderers/three/build/materials.js.map +1 -0
  45. package/lib/renderers/three/build/parts.d.ts +65 -0
  46. package/lib/renderers/three/build/parts.d.ts.map +1 -0
  47. package/lib/renderers/three/build/parts.js +203 -0
  48. package/lib/renderers/three/build/parts.js.map +1 -0
  49. package/lib/renderers/three/build.d.ts +50 -0
  50. package/lib/renderers/three/build.d.ts.map +1 -0
  51. package/lib/renderers/three/build.js +210 -0
  52. package/lib/renderers/three/build.js.map +1 -0
  53. package/lib/renderers/three/camera/camera.d.ts +40 -0
  54. package/lib/renderers/three/camera/camera.d.ts.map +1 -0
  55. package/lib/renderers/three/camera/camera.js +51 -0
  56. package/lib/renderers/three/camera/camera.js.map +1 -0
  57. package/lib/renderers/three/camera/camera.test.d.ts +2 -0
  58. package/lib/renderers/three/camera/camera.test.d.ts.map +1 -0
  59. package/lib/renderers/three/camera/camera.test.js +46 -0
  60. package/lib/renderers/three/camera/camera.test.js.map +1 -0
  61. package/lib/renderers/three/camera/controls.d.ts +24 -0
  62. package/lib/renderers/three/camera/controls.d.ts.map +1 -0
  63. package/lib/renderers/three/camera/controls.js +39 -0
  64. package/lib/renderers/three/camera/controls.js.map +1 -0
  65. package/lib/renderers/three/camera/gizmo.d.ts +44 -0
  66. package/lib/renderers/three/camera/gizmo.d.ts.map +1 -0
  67. package/lib/renderers/three/camera/gizmo.js +42 -0
  68. package/lib/renderers/three/camera/gizmo.js.map +1 -0
  69. package/lib/renderers/three/camera.d.ts +63 -0
  70. package/lib/renderers/three/camera.d.ts.map +1 -0
  71. package/lib/renderers/three/camera.js +85 -0
  72. package/lib/renderers/three/camera.js.map +1 -0
  73. package/lib/renderers/three/compile/compile.d.ts +59 -0
  74. package/lib/renderers/three/compile/compile.d.ts.map +1 -0
  75. package/lib/renderers/three/compile/compile.js +88 -0
  76. package/lib/renderers/three/compile/compile.js.map +1 -0
  77. package/lib/renderers/three/compile/compile.test.d.ts +2 -0
  78. package/lib/renderers/three/compile/compile.test.d.ts.map +1 -0
  79. package/lib/renderers/three/compile/compile.test.js +93 -0
  80. package/lib/renderers/three/compile/compile.test.js.map +1 -0
  81. package/lib/renderers/three/compile.d.ts +58 -0
  82. package/lib/renderers/three/compile.d.ts.map +1 -0
  83. package/lib/renderers/three/compile.js +89 -0
  84. package/lib/renderers/three/compile.js.map +1 -0
  85. package/lib/renderers/three/controls.d.ts +27 -0
  86. package/lib/renderers/three/controls.d.ts.map +1 -0
  87. package/lib/renderers/three/controls.js +115 -0
  88. package/lib/renderers/three/controls.js.map +1 -0
  89. package/lib/renderers/three/geometry/geometry.d.ts +21 -0
  90. package/lib/renderers/three/geometry/geometry.d.ts.map +1 -0
  91. package/lib/renderers/three/geometry/geometry.js +132 -0
  92. package/lib/renderers/three/geometry/geometry.js.map +1 -0
  93. package/lib/renderers/three/geometry/geometry.test.d.ts +2 -0
  94. package/lib/renderers/three/geometry/geometry.test.d.ts.map +1 -0
  95. package/lib/renderers/three/geometry/geometry.test.js +80 -0
  96. package/lib/renderers/three/geometry/geometry.test.js.map +1 -0
  97. package/lib/renderers/three/geometry.d.ts +20 -0
  98. package/lib/renderers/three/geometry.d.ts.map +1 -0
  99. package/lib/renderers/three/geometry.js +164 -0
  100. package/lib/renderers/three/geometry.js.map +1 -0
  101. package/lib/renderers/three/gizmo.d.ts +49 -0
  102. package/lib/renderers/three/gizmo.d.ts.map +1 -0
  103. package/lib/renderers/three/gizmo.js +172 -0
  104. package/lib/renderers/three/gizmo.js.map +1 -0
  105. package/lib/renderers/three/index.d.ts +16 -0
  106. package/lib/renderers/three/index.d.ts.map +1 -0
  107. package/lib/renderers/three/index.js +6 -0
  108. package/lib/renderers/three/index.js.map +1 -0
  109. package/lib/renderers/three/input.d.ts +25 -0
  110. package/lib/renderers/three/input.d.ts.map +1 -0
  111. package/lib/renderers/three/input.js +71 -0
  112. package/lib/renderers/three/input.js.map +1 -0
  113. package/lib/renderers/three/lines.d.ts +16 -0
  114. package/lib/renderers/three/lines.d.ts.map +1 -0
  115. package/lib/renderers/three/lines.js +63 -0
  116. package/lib/renderers/three/lines.js.map +1 -0
  117. package/lib/renderers/three/materials.d.ts +15 -0
  118. package/lib/renderers/three/materials.d.ts.map +1 -0
  119. package/lib/renderers/three/materials.js +70 -0
  120. package/lib/renderers/three/materials.js.map +1 -0
  121. package/lib/renderers/three/options.d.ts +68 -0
  122. package/lib/renderers/three/options.d.ts.map +1 -0
  123. package/lib/renderers/three/options.js +64 -0
  124. package/lib/renderers/three/options.js.map +1 -0
  125. package/lib/renderers/three/overlays.d.ts +25 -0
  126. package/lib/renderers/three/overlays.d.ts.map +1 -0
  127. package/lib/renderers/three/overlays.js +57 -0
  128. package/lib/renderers/three/overlays.js.map +1 -0
  129. package/lib/renderers/three/quality/quality.d.ts +37 -0
  130. package/lib/renderers/three/quality/quality.d.ts.map +1 -0
  131. package/lib/renderers/three/quality/quality.js +64 -0
  132. package/lib/renderers/three/quality/quality.js.map +1 -0
  133. package/lib/renderers/three/quality/quality.test.d.ts +2 -0
  134. package/lib/renderers/three/quality/quality.test.d.ts.map +1 -0
  135. package/lib/renderers/three/quality/quality.test.js +23 -0
  136. package/lib/renderers/three/quality/quality.test.js.map +1 -0
  137. package/lib/renderers/three/quality.d.ts +24 -0
  138. package/lib/renderers/three/quality.d.ts.map +1 -0
  139. package/lib/renderers/three/quality.js +67 -0
  140. package/lib/renderers/three/quality.js.map +1 -0
  141. package/lib/renderers/three/text/text.d.ts +55 -0
  142. package/lib/renderers/three/text/text.d.ts.map +1 -0
  143. package/lib/renderers/three/text/text.js +90 -0
  144. package/lib/renderers/three/text/text.js.map +1 -0
  145. package/lib/renderers/three/text/text.test.d.ts +2 -0
  146. package/lib/renderers/three/text/text.test.d.ts.map +1 -0
  147. package/lib/renderers/three/text/text.test.js +70 -0
  148. package/lib/renderers/three/text/text.test.js.map +1 -0
  149. package/lib/renderers/three/text.d.ts +53 -0
  150. package/lib/renderers/three/text.d.ts.map +1 -0
  151. package/lib/renderers/three/text.js +151 -0
  152. package/lib/renderers/three/text.js.map +1 -0
  153. package/lib/renderers/three/viewer/options.d.ts +71 -0
  154. package/lib/renderers/three/viewer/options.d.ts.map +1 -0
  155. package/lib/renderers/three/viewer/options.js +31 -0
  156. package/lib/renderers/three/viewer/options.js.map +1 -0
  157. package/lib/renderers/three/viewer/options.test.d.ts +2 -0
  158. package/lib/renderers/three/viewer/options.test.d.ts.map +1 -0
  159. package/lib/renderers/three/viewer/options.test.js +38 -0
  160. package/lib/renderers/three/viewer/options.test.js.map +1 -0
  161. package/lib/renderers/three/viewer/overlays.d.ts +31 -0
  162. package/lib/renderers/three/viewer/overlays.d.ts.map +1 -0
  163. package/lib/renderers/three/viewer/overlays.js +43 -0
  164. package/lib/renderers/three/viewer/overlays.js.map +1 -0
  165. package/lib/renderers/three/viewer/viewer.d.ts +90 -0
  166. package/lib/renderers/three/viewer/viewer.d.ts.map +1 -0
  167. package/lib/renderers/three/viewer/viewer.js +432 -0
  168. package/lib/renderers/three/viewer/viewer.js.map +1 -0
  169. package/lib/renderers/three/viewer.d.ts +38 -0
  170. package/lib/renderers/three/viewer.d.ts.map +1 -0
  171. package/lib/renderers/three/viewer.js +435 -0
  172. package/lib/renderers/three/viewer.js.map +1 -0
  173. package/package.json +26 -9
  174. package/src/abstract-3d.ts +1 -1
  175. package/src/custom_typings/n8ao.d.ts +11 -0
  176. package/src/renderers/dxf/dxf-encoding/dxf-build.ts +1 -2
  177. package/src/renderers/index.ts +1 -0
  178. package/src/renderers/react/index.ts +2 -5
  179. package/src/renderers/react/react.tsx +96 -181
  180. package/src/renderers/three/appearance/appearance.test.ts +116 -0
  181. package/src/renderers/three/appearance/appearance.ts +132 -0
  182. package/src/renderers/three/build/build.test.ts +141 -0
  183. package/src/renderers/three/build/build.ts +270 -0
  184. package/src/renderers/three/build/materials.ts +85 -0
  185. package/src/renderers/three/build/parts.ts +277 -0
  186. package/src/renderers/three/camera/camera.test.ts +53 -0
  187. package/src/renderers/three/camera/camera.ts +82 -0
  188. package/src/renderers/three/camera/controls.ts +65 -0
  189. package/src/renderers/three/camera/gizmo.ts +93 -0
  190. package/src/renderers/three/compile/compile.test.ts +113 -0
  191. package/src/renderers/three/compile/compile.ts +151 -0
  192. package/src/renderers/three/geometry/geometry.test.ts +95 -0
  193. package/src/renderers/three/geometry/geometry.ts +179 -0
  194. package/src/renderers/three/index.ts +15 -0
  195. package/src/renderers/three/quality/quality.test.ts +30 -0
  196. package/src/renderers/three/quality/quality.ts +95 -0
  197. package/src/renderers/three/text/text.test.ts +79 -0
  198. package/src/renderers/three/text/text.ts +128 -0
  199. package/src/renderers/three/viewer/options.ts +98 -0
  200. package/src/renderers/three/viewer/overlays.ts +71 -0
  201. package/src/renderers/three/viewer/viewer.ts +540 -0
  202. package/lib/renderers/dxf/color.d.ts +0 -7
  203. package/lib/renderers/dxf/color.d.ts.map +0 -1
  204. package/lib/renderers/dxf/color.js +0 -311
  205. package/lib/renderers/dxf/color.js.map +0 -1
  206. package/lib/renderers/dxf/dxf-encoding.d.ts +0 -17
  207. package/lib/renderers/dxf/dxf-encoding.d.ts.map +0 -1
  208. package/lib/renderers/dxf/dxf-encoding.js +0 -18467
  209. package/lib/renderers/dxf/dxf-encoding.js.map +0 -1
  210. package/lib/renderers/react/react-hotspot.d.ts +0 -27
  211. package/lib/renderers/react/react-hotspot.d.ts.map +0 -1
  212. package/lib/renderers/react/react-hotspot.js +0 -37
  213. package/lib/renderers/react/react-hotspot.js.map +0 -1
  214. package/lib/renderers/shared.d.ts +0 -30
  215. package/lib/renderers/shared.d.ts.map +0 -1
  216. package/lib/renderers/shared.js +0 -164
  217. package/lib/renderers/shared.js.map +0 -1
  218. package/src/custom_typings/react-three-fiber.d.ts +0 -9
  219. package/src/custom_typings/react-three-postprocessing.d.ts +0 -1
  220. package/src/renderers/react/react-camera.tsx +0 -391
  221. package/src/renderers/react/react-dimension.tsx +0 -122
  222. package/src/renderers/react/react-group.test.ts +0 -56
  223. package/src/renderers/react/react-group.tsx +0 -202
  224. package/src/renderers/react/react-image-material.tsx +0 -139
  225. package/src/renderers/react/react-material.tsx +0 -91
  226. package/src/renderers/react/react-mesh.tsx +0 -512
  227. package/src/renderers/react/react-relation.tsx +0 -86
  228. package/src/renderers/react/react-scene.tsx +0 -111
  229. package/src/renderers/react/react-types.ts +0 -9
@@ -0,0 +1,51 @@
1
+ import { exhaustiveCheck } from "ts-exhaustive-check";
2
+ import { vec3 } from "../../../abstract-3d.js";
3
+ /** Sets the camera's projection to fit the scene into the usable area of the canvas, and returns where to place it */
4
+ export function fitCamera(camera, { view, size: sceneSize, canvas, bufferZones, fitPadding }) {
5
+ if (canvas.width === 0 || canvas.height === 0) {
6
+ return undefined;
7
+ }
8
+ const [direction, size, sceneAspect] = getViewTransform(view, sceneSize);
9
+ const { left = 0, right = 0, top = 0, bottom = 0 } = bufferZones;
10
+ const usableW = Math.max(1, canvas.width - left - right);
11
+ const usableH = Math.max(1, canvas.height - top - bottom);
12
+ const usableAspect = usableW / usableH;
13
+ camera.zoom = 1;
14
+ if ("isOrthographicCamera" in camera) {
15
+ const pad = 1 + fitPadding;
16
+ // Constrained by the scene's width when it's wider than the usable area, else by its height
17
+ const [halfW, halfH] = sceneAspect > usableAspect
18
+ ? [(size.x / 2) * pad, (size.x / 2 / usableAspect) * pad]
19
+ : [((usableAspect * size.y) / 2) * pad, (size.y / 2) * pad];
20
+ // Extended by the buffer zones, at the world units per CSS pixel of the usable area
21
+ const [wpp, hpp] = [(halfW * 2) / usableW, (halfH * 2) / usableH];
22
+ Object.assign(camera, { left: -halfW - left * wpp, right: halfW + right * wpp, top: halfH + top * hpp, bottom: -halfH - bottom * hpp });
23
+ camera.updateProjectionMatrix();
24
+ const fovTan = Math.tan((45 * Math.PI) / 360);
25
+ return { distance: size.z * 0.5 + Math.max(size.x, size.y) * 2 * fovTan, direction };
26
+ }
27
+ // The field of view describes the usable area; the view offset extends the rendered frustum from it to the full canvas
28
+ const tan = Math.tan((camera.fov * Math.PI) / 360);
29
+ const distance = Math.max(size.y / 2 / tan, size.x / 2 / (tan * usableAspect)) + size.z * 0.5;
30
+ camera.aspect = usableAspect;
31
+ camera.setViewOffset(usableW, usableH, -left, -top, canvas.width, canvas.height);
32
+ camera.updateProjectionMatrix();
33
+ return { distance: distance * (1 + fitPadding), direction };
34
+ }
35
+ /** The direction to look from, the scene's size as seen on screen and its aspect */
36
+ function getViewTransform(view, size) {
37
+ switch (view) {
38
+ case "front":
39
+ case "back":
40
+ return [vec3(0, 0, view === "front" ? 1 : -1), size, size.x / size.y];
41
+ case "top":
42
+ case "bottom":
43
+ return [vec3(0, view === "top" ? 1 : -1, 0), vec3(size.x, size.z, size.y), size.x / size.z];
44
+ case "right":
45
+ case "left":
46
+ return [vec3(view === "right" ? 1 : -1, 0, 0), vec3(size.z, size.y, size.x), size.z / size.y];
47
+ default:
48
+ return exhaustiveCheck(view);
49
+ }
50
+ }
51
+ //# sourceMappingURL=camera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.js","sourceRoot":"","sources":["../../../../src/renderers/three/camera/camera.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=camera.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.test.d.ts","sourceRoot":"","sources":["../../../../src/renderers/three/camera/camera.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { OrthographicCamera, PerspectiveCamera } from "three";
2
+ import { describe, expect, it } from "vitest";
3
+ import { vec3 } from "../../../abstract-3d.js";
4
+ import { fitCamera } from "./camera.js";
5
+ const input = { view: "front", size: vec3(4000, 2000, 1000), canvas: { width: 800, height: 400 }, bufferZones: {}, fitPadding: 0 };
6
+ const tan = Math.tan((45 * Math.PI) / 360);
7
+ const fitPerspective = (partial = {}) => {
8
+ const camera = new PerspectiveCamera(45);
9
+ return [camera, fitCamera(camera, { ...input, ...partial })];
10
+ };
11
+ const fitOrthographic = (partial = {}) => {
12
+ const camera = new OrthographicCamera();
13
+ fitCamera(camera, { ...input, ...partial });
14
+ return [camera.left, camera.right, camera.top, camera.bottom, camera.zoom];
15
+ };
16
+ describe("fitCamera", () => {
17
+ it("fits nothing into an empty canvas", () => {
18
+ expect(fitPerspective({ canvas: { width: 0, height: 400 } })[1]).toBeUndefined();
19
+ });
20
+ it("backs a perspective camera off until the scene's width and height fit, plus half its depth", () => {
21
+ const [camera, placement] = fitPerspective();
22
+ expect(placement.distance).toBeCloseTo(Math.max(1000 / tan, 2000 / (tan * 2)) + 500);
23
+ expect(placement.direction).toEqual(vec3(0, 0, 1));
24
+ expect(camera.aspect).toBe(2);
25
+ });
26
+ it("pads the distance", () => {
27
+ expect(fitPerspective({ fitPadding: 0.1 })[1].distance).toBeCloseTo(fitPerspective()[1].distance * 1.1);
28
+ });
29
+ it("fits into the area inside the buffer zones, and offsets the view to it", () => {
30
+ const [camera] = fitPerspective({ bufferZones: { left: 200, top: 100 } });
31
+ expect(camera.aspect).toBeCloseTo(600 / 300);
32
+ expect(camera.view).toMatchObject({ enabled: true, fullWidth: 600, fullHeight: 300, offsetX: -200, offsetY: -100, width: 800, height: 400 });
33
+ });
34
+ it("looks along each view, with the scene's size seen from it", () => {
35
+ expect(fitPerspective({ view: "top" })[1].direction).toEqual(vec3(0, 1, 0));
36
+ expect(fitPerspective({ view: "left" })[1].direction).toEqual(vec3(-1, 0, 0));
37
+ // From the top, the scene is 4000 wide and 1000 high on screen, and 2000 deep
38
+ expect(fitPerspective({ view: "top" })[1].distance).toBeCloseTo(Math.max(500 / tan, 2000 / (tan * 2)) + 1000);
39
+ });
40
+ it("frames orthographic cameras around the scene, extended by the buffer zones", () => {
41
+ expect(fitOrthographic()).toEqual([-2000, 2000, 1000, -1000, 1]);
42
+ // The usable area is 400 x 400, so the scene's 4000 width sets 10 world units per pixel
43
+ expect(fitOrthographic({ bufferZones: { right: 400 } })).toEqual([-2000, 6000, 2000, -2000, 1]);
44
+ });
45
+ });
46
+ //# sourceMappingURL=camera.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.test.js","sourceRoot":"","sources":["../../../../src/renderers/three/camera/camera.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { OrthographicCamera, PerspectiveCamera, Vector3 } from "three";
2
+ import { OrbitControls } from "three/addons/controls/OrbitControls.js";
3
+ /** The r3f renderer's OrbitControls, with drei's damping default */
4
+ export type ControlsOptions = Partial<Omit<OrbitControls, "object" | "domElement" | "target" | "cursor">> & {
5
+ readonly onStart?: () => void;
6
+ readonly onChange?: () => void;
7
+ readonly onEnd?: () => void;
8
+ };
9
+ export type Controls = {
10
+ readonly orbit: OrbitControls;
11
+ readonly current: {
12
+ options: ControlsOptions;
13
+ };
14
+ /** The user drags the camera, and it moved since the drag started */
15
+ readonly drag: {
16
+ active: boolean;
17
+ moved: boolean;
18
+ };
19
+ };
20
+ export declare function createControls(camera: PerspectiveCamera | OrthographicCamera, element: HTMLElement, options: ControlsOptions, onInput: () => void): Controls;
21
+ /** Sets the options that are defined, so ones left out keep their defaults */
22
+ export declare function configureControls(controls: Controls, options: ControlsOptions): void;
23
+ export declare function setPose(controls: Controls, position: Vector3, target: Vector3): void;
24
+ //# sourceMappingURL=controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../../../src/renderers/three/camera/controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAEvE,oEAAoE;AAEpE,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC,GAAG;IAC1G,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,eAAe,CAAA;KAAE,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CACpD,CAAC;AAEF,wBAAgB,cAAc,CAC5B,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,EAC9C,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,IAAI,GAClB,QAAQ,CAOV;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAQpF;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAIpF"}
@@ -0,0 +1,39 @@
1
+ import { OrbitControls } from "three/addons/controls/OrbitControls.js";
2
+ export function createControls(camera, element, options, onInput) {
3
+ const controls = { orbit: new OrbitControls(camera, element), current: { options }, drag: { active: false, moved: false } };
4
+ configureControls(controls, options);
5
+ controls.orbit.addEventListener("start", () => onDragStart(controls, onInput));
6
+ controls.orbit.addEventListener("change", () => onDragChange(controls, onInput));
7
+ controls.orbit.addEventListener("end", () => onDragEnd(controls));
8
+ return controls;
9
+ }
10
+ /** Sets the options that are defined, so ones left out keep their defaults */
11
+ export function configureControls(controls, options) {
12
+ controls.current.options = options;
13
+ controls.orbit.enableDamping = true;
14
+ Object.entries(options).forEach(([key, value]) => {
15
+ if (value !== undefined && typeof value !== "function") {
16
+ Object.assign(controls.orbit, { [key]: value });
17
+ }
18
+ });
19
+ }
20
+ export function setPose(controls, position, target) {
21
+ controls.orbit.target.copy(target);
22
+ controls.orbit.object.position.copy(position);
23
+ controls.orbit.update();
24
+ }
25
+ function onDragStart(controls, onInput) {
26
+ Object.assign(controls.drag, { active: true, moved: false });
27
+ controls.current.options.onStart?.();
28
+ onInput();
29
+ }
30
+ function onDragChange(controls, onInput) {
31
+ controls.drag.moved = controls.drag.active;
32
+ controls.current.options.onChange?.();
33
+ onInput();
34
+ }
35
+ function onDragEnd(controls) {
36
+ Object.assign(controls.drag, { active: false, moved: false });
37
+ controls.current.options.onEnd?.();
38
+ }
39
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../../src/renderers/three/camera/controls.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAiBvE,MAAM,UAAU,cAAc,CAC5B,MAA8C,EAC9C,OAAoB,EACpB,OAAwB,EACxB,OAAmB;IAEnB,MAAM,QAAQ,GAAa,EAAE,KAAK,EAAE,IAAI,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;IACtI,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/E,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACjF,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAAC,QAAkB,EAAE,OAAwB;IAC5E,QAAQ,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;IACpC,MAAM,CAAC,OAAO,CAAC,OAAkC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC1E,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAkB,EAAE,QAAiB,EAAE,MAAe;IAC5E,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,QAAkB,EAAE,OAAmB;IAC1D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;IACrC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,YAAY,CAAC,QAAkB,EAAE,OAAmB;IAC3D,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;IACtC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,SAAS,CAAC,QAAkB;IACnC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { OrthographicCamera, PerspectiveCamera, WebGLRenderer } from "three";
2
+ import { ViewportGizmo } from "three-viewport-gizmo";
3
+ /**
4
+ * A viewcube or axes in a corner of the canvas that turns with the camera; clicking it turns the camera to look from that side. three-viewport-gizmo,
5
+ * with the options of drei's GizmoViewcube and GizmoViewport that the r3f renderer took
6
+ */
7
+ export type GizmoAlignment = `${"top" | "center" | "bottom"}-${"left" | "center" | "right"}`;
8
+ export type ViewcubeOptions = {
9
+ /** A CSS font; its weight and family are used */
10
+ readonly font?: string;
11
+ readonly opacity?: number;
12
+ readonly color?: string;
13
+ readonly hoverColor?: string;
14
+ readonly textColor?: string;
15
+ readonly strokeColor?: string;
16
+ /** Labels of the +x, -x, +y, -y, +z and -z faces */
17
+ readonly faces?: ReadonlyArray<string>;
18
+ /** Clicking also moves the target back to the scene's center and fits the scene */
19
+ readonly resetZoomAndPanOnClick?: boolean;
20
+ };
21
+ export type AxesOptions = {
22
+ readonly axisColors?: readonly [string, string, string];
23
+ readonly labels?: readonly [string, string, string];
24
+ readonly labelColor?: string;
25
+ readonly hideNegativeAxes?: boolean;
26
+ readonly disabled?: boolean;
27
+ readonly font?: string;
28
+ readonly resetZoomAndPanOnClick?: boolean;
29
+ };
30
+ export type ControlsHelper = ({
31
+ readonly type: "Viewcube";
32
+ readonly viewcubeProps?: ViewcubeOptions;
33
+ } | {
34
+ readonly type: "Viewport";
35
+ readonly viewportProps?: AxesOptions;
36
+ }) & {
37
+ /** The margin is from the canvas' corner to the gizmo's center, in CSS pixels */
38
+ readonly props?: {
39
+ readonly alignment?: GizmoAlignment;
40
+ readonly margin?: readonly [number, number];
41
+ };
42
+ };
43
+ export declare function createGizmo(camera: PerspectiveCamera | OrthographicCamera, renderer: WebGLRenderer, container: HTMLElement, helper: ControlsHelper): ViewportGizmo;
44
+ //# sourceMappingURL=gizmo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gizmo.d.ts","sourceRoot":"","sources":["../../../../src/renderers/three/camera/gizmo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO,EAAE,CAAC;AAE7F,MAAM,MAAM,eAAe,GAAG;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,CAAA;CAAE,CACtE,GAAG;IACF,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CACvG,CAAC;AAKF,wBAAgB,WAAW,CACzB,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,EAC9C,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE,cAAc,GACrB,aAAa,CAef"}
@@ -0,0 +1,42 @@
1
+ import { ViewportGizmo } from "three-viewport-gizmo";
2
+ const size = 110;
3
+ const axes = ["x", "nx", "y", "ny", "z", "nz"];
4
+ export function createGizmo(camera, renderer, container, helper) {
5
+ const [mx, my] = helper.props?.margin ?? [80, 80];
6
+ const options = helper.type === "Viewcube" ? helper.viewcubeProps : helper.viewportProps;
7
+ // "600 24px Helvetica, Arial" is weight 600 of Helvetica, Arial
8
+ const [, weight = 600, family = "Helvetica, Arial, sans-serif"] = /^(?:(\S+)\s+)?[\d.]+px\s+(.+)$/.exec(options?.font ?? "") ?? [];
9
+ const gizmo = new ViewportGizmo(camera, renderer, {
10
+ container,
11
+ size,
12
+ placement: helper.props?.alignment ?? "bottom-right",
13
+ offset: { left: mx - size / 2, right: mx - size / 2, top: my - size / 2, bottom: my - size / 2 },
14
+ font: { family, weight },
15
+ ...(helper.type === "Viewcube" ? getViewcubeOptions(helper.viewcubeProps ?? {}) : getAxesOptions(helper.viewportProps ?? {})),
16
+ });
17
+ gizmo.enabled = !(helper.type === "Viewport" && helper.viewportProps?.disabled);
18
+ return gizmo;
19
+ }
20
+ function getViewcubeOptions(options) {
21
+ const { opacity = 1, color = "#f4f5f7", hoverColor = "#cfe0ff", textColor = "#333", strokeColor = "#9aa0a6" } = options;
22
+ const labels = options.faces ?? ["Right", "Left", "Top", "Bottom", "Front", "Back"];
23
+ const face = { color, opacity, labelColor: textColor, hover: { color: hoverColor, labelColor: textColor, opacity } };
24
+ return {
25
+ type: "cube",
26
+ background: { color: strokeColor, opacity, hover: { color: strokeColor, opacity } },
27
+ corners: { color, hover: { color: hoverColor } },
28
+ edges: { color, hover: { color: hoverColor } },
29
+ ...Object.fromEntries(axes.map((axis, i) => [axis, { ...face, label: (labels[i] ?? "").toUpperCase() }])),
30
+ };
31
+ }
32
+ function getAxesOptions(options) {
33
+ const { axisColors = ["#ff3653", "#8adb00", "#2c8fff"], labels = ["X", "Y", "Z"], labelColor = "#000" } = options;
34
+ return {
35
+ type: "sphere",
36
+ ...Object.fromEntries(axes.map((axis, i) => [
37
+ axis,
38
+ { color: axisColors[Math.floor(i / 2)], labelColor, ...(i % 2 ? { enabled: !options.hideNegativeAxes } : { label: labels[i / 2] }) },
39
+ ])),
40
+ };
41
+ }
42
+ //# sourceMappingURL=gizmo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gizmo.js","sourceRoot":"","sources":["../../../../src/renderers/three/camera/gizmo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { OrthographicCamera, PerspectiveCamera } from "three";
2
+ import type { Vec3, View } from "../../abstract-3d.js";
3
+ /** Fitting the camera to the scene, inside buffer zones of the canvas that UI covers; the math of the r3f renderer's react-camera.tsx */
4
+ export type CameraOptions = {
5
+ readonly type: "Perspective";
6
+ readonly near?: number;
7
+ readonly far?: number;
8
+ readonly fov?: number;
9
+ } | {
10
+ readonly type: "Orthographic";
11
+ readonly near?: number;
12
+ readonly far?: number;
13
+ };
14
+ /** Margins of the canvas, in CSS pixels, that the scene is fitted inside of */
15
+ export type BufferZones = {
16
+ readonly left?: number;
17
+ readonly right?: number;
18
+ readonly top?: number;
19
+ readonly bottom?: number;
20
+ };
21
+ export type FitInput = {
22
+ readonly view: View;
23
+ /** The scene's size */
24
+ readonly size: Vec3;
25
+ readonly camera: CameraOptions;
26
+ /** In CSS pixels */
27
+ readonly canvas: {
28
+ readonly width: number;
29
+ readonly height: number;
30
+ };
31
+ readonly bufferZones: BufferZones;
32
+ readonly fitPadding: number;
33
+ };
34
+ type FitPlacement = {
35
+ /** The camera's distance from the target */
36
+ readonly distance: number;
37
+ /** From the target to the camera */
38
+ readonly direction: Vec3;
39
+ };
40
+ export type Fit = (FitPlacement & {
41
+ readonly type: "Perspective";
42
+ readonly fov: number;
43
+ readonly aspect: number;
44
+ readonly viewOffset: {
45
+ readonly fullWidth: number;
46
+ readonly fullHeight: number;
47
+ readonly x: number;
48
+ readonly y: number;
49
+ readonly width: number;
50
+ readonly height: number;
51
+ };
52
+ }) | (FitPlacement & {
53
+ readonly type: "Orthographic";
54
+ readonly left: number;
55
+ readonly right: number;
56
+ readonly top: number;
57
+ readonly bottom: number;
58
+ });
59
+ export declare function fitCamera({ view, size: sceneSize, camera, canvas, bufferZones, fitPadding }: FitInput): Fit | undefined;
60
+ /** Sets the camera's projection from the fit; the caller places the camera */
61
+ export declare function applyFit(fit: Fit, camera: PerspectiveCamera | OrthographicCamera): void;
62
+ export {};
63
+ //# sourceMappingURL=camera.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../../src/renderers/three/camera.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGvD,yIAAyI;AAEzI,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,oBAAoB;IACpB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,GAAG,GACX,CAAC,YAAY,GAAG;IACd,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC,GACF,CAAC,YAAY,GAAG;IACd,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEP,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,QAAQ,GAAG,GAAG,GAAG,SAAS,CA6CvH;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,IAAI,CAevF"}
@@ -0,0 +1,85 @@
1
+ import { exhaustiveCheck } from "ts-exhaustive-check";
2
+ import { vec3 } from "../../abstract-3d.js";
3
+ export function fitCamera({ view, size: sceneSize, camera, canvas, bufferZones, fitPadding }) {
4
+ if (canvas.width === 0 || canvas.height === 0) {
5
+ return undefined;
6
+ }
7
+ const [direction, size, sceneAspect] = getViewTransform(view, sceneSize);
8
+ const fov = camera.type === "Perspective" ? (camera.fov ?? 45) : 45;
9
+ const { left = 0, right = 0, top = 0, bottom = 0 } = bufferZones;
10
+ const usableW = Math.max(1, canvas.width - left - right);
11
+ const usableH = Math.max(1, canvas.height - top - bottom);
12
+ const usableAspect = usableW / usableH;
13
+ if (camera.type === "Orthographic") {
14
+ const padFactor = 1 + fitPadding;
15
+ // Constrained by the scene's width when it's wider than the usable area, else by its height
16
+ const [halfW, halfH] = sceneAspect > usableAspect
17
+ ? [(size.x / 2) * padFactor, (size.x / 2 / usableAspect) * padFactor]
18
+ : [((usableAspect * size.y) / 2) * padFactor, (size.y / 2) * padFactor];
19
+ // World units per CSS pixel in the usable area
20
+ const wpp = (halfW * 2) / usableW;
21
+ const hpp = (halfH * 2) / usableH;
22
+ return {
23
+ type: "Orthographic",
24
+ distance: cameraDistance(size, fov),
25
+ direction,
26
+ left: -halfW - left * wpp,
27
+ right: halfW + right * wpp,
28
+ top: halfH + top * hpp,
29
+ bottom: -halfH - bottom * hpp,
30
+ };
31
+ }
32
+ // The field of view describes the usable area; the view offset extends the rendered frustum from it to the full canvas
33
+ const fovRad = (fov * Math.PI) / 180;
34
+ const fovHRad = 2 * Math.atan(Math.tan(fovRad / 2) * usableAspect);
35
+ const distForH = size.y / 2 / Math.tan(fovRad / 2) + size.z * 0.5;
36
+ const distForW = size.x / 2 / Math.tan(fovHRad / 2) + size.z * 0.5;
37
+ return {
38
+ type: "Perspective",
39
+ distance: Math.max(distForH, distForW) * (1 + fitPadding),
40
+ direction,
41
+ fov,
42
+ aspect: usableAspect,
43
+ viewOffset: { fullWidth: usableW, fullHeight: usableH, x: -left, y: -top, width: canvas.width, height: canvas.height },
44
+ };
45
+ }
46
+ /** Sets the camera's projection from the fit; the caller places the camera */
47
+ export function applyFit(fit, camera) {
48
+ if (fit.type === "Perspective" && "isPerspectiveCamera" in camera) {
49
+ const { fullWidth, fullHeight, x, y, width, height } = fit.viewOffset;
50
+ camera.fov = fit.fov;
51
+ camera.aspect = fit.aspect;
52
+ camera.zoom = 1;
53
+ camera.setViewOffset(fullWidth, fullHeight, x, y, width, height);
54
+ }
55
+ else if (fit.type === "Orthographic" && "isOrthographicCamera" in camera) {
56
+ camera.left = fit.left;
57
+ camera.right = fit.right;
58
+ camera.top = fit.top;
59
+ camera.bottom = fit.bottom;
60
+ camera.zoom = 1;
61
+ }
62
+ camera.updateProjectionMatrix();
63
+ }
64
+ /** The distance an orthographic camera is placed at, far enough to see the scene's depth */
65
+ const cameraDistance = (size, fov) => size.z * 0.5 + (size.x > size.y ? size.x : size.y) / (1 / 2 / Math.tan((Math.PI * fov) / 180 / 2));
66
+ /** The direction to look from, the scene's size as seen on screen and its aspect */
67
+ function getViewTransform(view, size) {
68
+ switch (view) {
69
+ case "front":
70
+ return [vec3(0, 0, 1), size, size.x / size.y];
71
+ case "back":
72
+ return [vec3(0, 0, -1), size, size.x / size.y];
73
+ case "top":
74
+ return [vec3(0, 1, 0), vec3(size.x, size.z, size.y), size.x / size.z];
75
+ case "bottom":
76
+ return [vec3(0, -1, 0), vec3(size.x, size.z, size.y), size.x / size.z];
77
+ case "right":
78
+ return [vec3(1, 0, 0), vec3(size.z, size.y, size.x), size.z / size.y];
79
+ case "left":
80
+ return [vec3(-1, 0, 0), vec3(size.z, size.y, size.x), size.z / size.y];
81
+ default:
82
+ return exhaustiveCheck(view);
83
+ }
84
+ }
85
+ //# sourceMappingURL=camera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.js","sourceRoot":"","sources":["../../../src/renderers/three/camera.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { Matrix4 } from "three";
2
+ import type { Group, Mesh, Relation, Scene, Vec3 } from "../../../abstract-3d.js";
3
+ /**
4
+ * Scene → flat items with world matrices, with no GPU objects, so everything here is testable in Node; groups transform as the r3f renderer's
5
+ * react-group.tsx
6
+ */
7
+ /** How the item's geometry is drawn */
8
+ export type Role = "solid" | "text" | "line" | "image";
9
+ /** What the item belongs to, which decides its material and whether it's shown */
10
+ export type Style = "group" | "dimension" | "relation" | "outline";
11
+ /** What a pointer event on an item is about, and what hover and selection apply to */
12
+ export type Target = {
13
+ readonly kind: "group";
14
+ readonly id: string;
15
+ readonly root: number;
16
+ readonly rootData: Record<string, string> | undefined;
17
+ } | {
18
+ readonly kind: "dimension";
19
+ readonly id: string | undefined;
20
+ } | {
21
+ readonly kind: "relation";
22
+ readonly relation: Relation;
23
+ };
24
+ export type Item = {
25
+ readonly mesh: Mesh;
26
+ readonly role: Role;
27
+ readonly style: Style;
28
+ /** World matrix, or for an animated item its matrix relative to its animation's group */
29
+ readonly matrix: Matrix4;
30
+ readonly target: number;
31
+ /** The data of the group the mesh is in */
32
+ readonly data: Record<string, string> | undefined;
33
+ readonly animation: number | undefined;
34
+ };
35
+ export type Animation = {
36
+ readonly parent: number | undefined;
37
+ /** The matrix of the group's parent, in world space or relative to the parent animation's group */
38
+ readonly base: Matrix4;
39
+ readonly pos: Vec3;
40
+ readonly rot: Vec3;
41
+ /** Radians per second around x, y and z */
42
+ readonly speed: Vec3;
43
+ };
44
+ export type CompiledScene = {
45
+ readonly items: ReadonlyArray<Item>;
46
+ readonly targets: ReadonlyArray<Target>;
47
+ readonly animations: ReadonlyArray<Animation>;
48
+ /** World matrix of the scene's root, from its deprecated center and rotation */
49
+ readonly matrix: Matrix4;
50
+ /** World matrix of each top-level group */
51
+ readonly roots: ReadonlyArray<Matrix4>;
52
+ };
53
+ /** Targets are the top-level groups, then the dimensions, then the relations */
54
+ export declare function compileScene(scene: Scene, createGroupId?: (g: Group) => string): CompiledScene;
55
+ /** The item's world matrix at `seconds` into its animations, written to `out` */
56
+ export declare function getItemMatrix(compiled: CompiledScene, item: Item, seconds: number, out: Matrix4): Matrix4;
57
+ /** Translation, then XYZ Euler rotation, then scale, as on a three.js Object3D */
58
+ export declare function transform(pos: Vec3, rot: Vec3 | undefined, out?: Matrix4, size?: Vec3): Matrix4;
59
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../../src/renderers/three/compile/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAAuB,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAGlF;;;GAGG;AAEH,uCAAuC;AACvC,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AACvD,kFAAkF;AAClF,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEnE,sFAAsF;AACtF,MAAM,MAAM,MAAM,GACd;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,GAC7H;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE/D,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAOF,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,MAAM,GAAG,aAAa,CAqB9F;AAoBD,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAIzG;AA0CD,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,SAAS,EAAE,GAAG,UAAgB,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAGrG"}
@@ -0,0 +1,88 @@
1
+ import { Euler, Matrix4, Quaternion, Vector3 } from "three";
2
+ import { dimensionConvertToTypeMesh, vec3, vec3Scale, vec3Zero } from "../../../abstract-3d.js";
3
+ const outlineScale = 1.0125;
4
+ /** Targets are the top-level groups, then the dimensions, then the relations */
5
+ export function compileScene(scene, createGroupId) {
6
+ const out = { items: [], animations: [] };
7
+ const center = scene.center_deprecated ?? vec3Zero;
8
+ const matrix = new Matrix4().makeTranslation(-center.x, -center.y, -center.z).multiply(transform(vec3Zero, scene.rotation_deprecated));
9
+ const dimensions = scene.dimensions_deprecated?.dimensions ?? [];
10
+ const relations = scene.relations ?? [];
11
+ const targets = [
12
+ ...scene.groups.map((g, root) => ({ kind: "group", id: createGroupId?.(g) ?? "", root, rootData: g.data })),
13
+ ...dimensions.map((d) => ({ kind: "dimension", id: d.id })),
14
+ ...relations.map((relation) => ({ kind: "relation", relation })),
15
+ ];
16
+ scene.groups.forEach((g, i) => addGroup(out, g, matrix, undefined, "group", i));
17
+ dimensions.forEach((dimension, i) => {
18
+ const mesh = dimensionConvertToTypeMesh(dimension, scene.rotation_deprecated ?? vec3Zero, scene.dimensions_deprecated?.material);
19
+ const base = { style: "dimension", target: scene.groups.length + i, data: undefined, animation: undefined };
20
+ addMeshes(out, mesh.meshes, matrix.clone().multiply(transform(mesh.pos, mesh.rot)), base);
21
+ });
22
+ relations.forEach((relation, i) => relation.groups?.forEach((g) => addGroup(out, g, matrix, undefined, "relation", scene.groups.length + dimensions.length + i)));
23
+ return { ...out, targets, matrix, roots: scene.groups.map((g) => matrix.clone().multiply(transform(g.pos, g.rot))) };
24
+ }
25
+ function addGroup(out, g, parent, parentAnimation, style, target) {
26
+ const animation = g.animation ? out.animations.push(createAnimation(g, parent, parentAnimation)) - 1 : parentAnimation;
27
+ // An animated group's items are relative to it, so its animation can move them
28
+ const matrix = g.animation ? new Matrix4() : parent.clone().multiply(transform(g.pos, g.rot));
29
+ addMeshes(out, g.meshes ?? [], matrix, { style, target, data: g.data, animation });
30
+ g.groups?.forEach((child) => addGroup(out, child, matrix, animation, style, target));
31
+ }
32
+ function addMeshes(out, meshes, matrix, base) {
33
+ meshes.forEach((mesh) => {
34
+ out.items.push({ ...base, mesh, role: getRole(mesh), matrix });
35
+ if (base.style === "relation" && mesh.geometry.type === "Box") {
36
+ const outline = { ...mesh, geometry: { ...mesh.geometry, size: vec3Scale(mesh.geometry.size, outlineScale) } };
37
+ out.items.push({ ...base, style: "outline", mesh: outline, role: "solid", matrix });
38
+ }
39
+ });
40
+ }
41
+ /** The item's world matrix at `seconds` into its animations, written to `out` */
42
+ export function getItemMatrix(compiled, item, seconds, out) {
43
+ return item.animation === undefined
44
+ ? out.copy(item.matrix)
45
+ : getAnimationMatrix(compiled.animations, item.animation, seconds, out).multiply(item.matrix);
46
+ }
47
+ function getAnimationMatrix(animations, index, seconds, out) {
48
+ const a = animations[index];
49
+ const rot = vec3(a.rot.x + a.speed.x * seconds, a.rot.y + a.speed.y * seconds, a.rot.z + a.speed.z * seconds);
50
+ out.copy(a.base).multiply(transform(a.pos, rot, scratch));
51
+ return a.parent === undefined ? out : out.premultiply(getAnimationMatrix(animations, a.parent, seconds, new Matrix4()));
52
+ }
53
+ /** The r3f renderer turned an animated group by its rotation per duration in milliseconds */
54
+ function createAnimation(g, parent, parentAnimation) {
55
+ const { rot } = g.animation.transform;
56
+ const perSecond = 1000 / g.animation.duration;
57
+ return {
58
+ parent: parentAnimation,
59
+ base: parent.clone(),
60
+ pos: g.pos,
61
+ rot: g.rot ?? vec3Zero,
62
+ speed: vec3(rot.x * perSecond, rot.y * perSecond, rot.z * perSecond),
63
+ };
64
+ }
65
+ function getRole(mesh) {
66
+ switch (mesh.geometry.type) {
67
+ case "Text":
68
+ return "text";
69
+ case "Line":
70
+ case "CulledLine":
71
+ return "line";
72
+ case "Image":
73
+ return "image";
74
+ default:
75
+ return "solid";
76
+ }
77
+ }
78
+ const scratch = new Matrix4();
79
+ const euler = new Euler();
80
+ const quaternion = new Quaternion();
81
+ const position = new Vector3();
82
+ const scale = new Vector3();
83
+ /** Translation, then XYZ Euler rotation, then scale, as on a three.js Object3D */
84
+ export function transform(pos, rot, out = new Matrix4(), size) {
85
+ quaternion.setFromEuler(euler.set(rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0));
86
+ return out.compose(position.set(pos.x, pos.y, pos.z), quaternion, scale.set(size?.x ?? 1, size?.y ?? 1, size?.z ?? 1));
87
+ }
88
+ //# sourceMappingURL=compile.js.map