u-space 0.0.7 → 0.0.9

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 (40) hide show
  1. package/dist/index.cjs +16 -1
  2. package/dist/index.js +1578 -534
  3. package/dist/src/effects/MaterialEffects.d.ts +23 -0
  4. package/dist/src/index.d.ts +1 -0
  5. package/dist/src/interactions/InteractionManager.d.ts +31 -0
  6. package/dist/src/interactions/Selection.d.ts +77 -0
  7. package/dist/src/interactions/index.d.ts +1 -0
  8. package/dist/src/managers/LightManager.d.ts +101 -0
  9. package/dist/src/managers/ObjectManager.d.ts +33 -1
  10. package/dist/src/managers/SceneManager.d.ts +57 -0
  11. package/dist/src/managers/index.d.ts +2 -0
  12. package/dist/src/objects/Model.d.ts +13 -1
  13. package/dist/src/tools/AnnotationManager.d.ts +104 -0
  14. package/dist/src/tools/ClippingTool.d.ts +96 -0
  15. package/dist/src/tools/MeasureTool.d.ts +80 -0
  16. package/dist/src/tools/index.d.ts +3 -0
  17. package/dist/src/viewers/CameraControls.d.ts +23 -0
  18. package/dist/src/viewers/Viewer.d.ts +52 -1
  19. package/docs/api-camera-controls.md +146 -0
  20. package/docs/api-effects.md +47 -5
  21. package/docs/api-interactions.md +107 -7
  22. package/docs/api-managers.md +181 -0
  23. package/docs/api-objects.md +46 -13
  24. package/docs/api-plugin-atmosphere.md +10 -0
  25. package/docs/api-plugin-curve-movement.md +38 -0
  26. package/docs/api-plugin-keyboard-controls.md +40 -0
  27. package/docs/api-plugin-minimap.md +36 -0
  28. package/docs/api-plugin-object-controls.md +67 -0
  29. package/docs/api-plugin-tiles.md +26 -0
  30. package/docs/api-plugin-topology-drawer.md +74 -0
  31. package/docs/api-plugin-tracking-controls.md +23 -0
  32. package/docs/api-plugin-u-manager.md +123 -0
  33. package/docs/api-tools.md +254 -0
  34. package/docs/api-viewer.md +85 -19
  35. package/docs/changelog.md +105 -0
  36. package/docs/examples-guide.md +104 -0
  37. package/docs/getting-started.md +1 -1
  38. package/docs/index.md +14 -12
  39. package/package.json +1 -1
  40. package/docs/api-plugins.md +0 -449
package/dist/index.js CHANGED
@@ -1,27 +1,27 @@
1
- import { Raycaster as Te, Vector2 as R, RenderPipeline as $e, PerspectiveCamera as K, Sphere as Se, Box3 as xe, Spherical as C, Matrix4 as We, Quaternion as Ke, Vector4 as Qe, Vector3 as oe, MathUtils as Xe, PMREMGenerator as qe, OrthographicCamera as Q, TimestampQuery as Ye, Cache as Je, EventDispatcher as Ze, Timer as Ve, WebGPURenderer as et, PCFShadowMap as tt, AgXToneMapping as st, Scene as it, Color as V, MeshStandardNodeMaterial as L, Loader as nt, LoaderUtils as I, FileLoader as Ee, TextureLoader as Me, Group as ee, SRGBColorSpace as Pe, RepeatWrapping as ce, BufferGeometry as rt, BufferAttribute as he, Mesh as z, FrontSide as at, BackSide as ot, DoubleSide as ct, REVISION as le, CubeTextureLoader as ht, EquirectangularReflectionMapping as lt, Sprite as dt, AnimationMixer as pt, LoopRepeat as ut, LoopOnce as mt, SphereGeometry as gt, TubeGeometry as ft, LineCurve3 as yt, CatmullRomCurve3 as wt, SpriteNodeMaterial as vt, CanvasTexture as bt, ShapeGeometry as Ct, Shape as Oe, ExtrudeGeometry as Tt, PlaneGeometry as St, CircleGeometry as xt } from "three/webgpu";
2
- import { pass as re, mrt as Et, output as Mt, add as de, blendColor as Pt, emissive as Ot, normalView as Rt, velocity as It, color as j, uv as pe, time as X, pow as q, sin as ae, mix as Y, mx_noise_float as ue, Fn as Re, userData as O, materialColor as me, select as J, materialOpacity as Lt, vec3 as At } from "three/tsl";
3
- import { bloom as Nt } from "three/addons/tsl/display/BloomNode.js";
4
- import { ssgi as Bt } from "three/addons/tsl/display/SSGINode.js";
5
- import { traa as _t } from "three/addons/tsl/display/TRAANode.js";
6
- import Ie from "camera-controls";
7
- import { RoomEnvironment as Dt } from "three/addons/environments/RoomEnvironment.js";
8
- import { ViewHelper as jt } from "three/addons/helpers/ViewHelper.js";
9
- import { CSS2DRenderer as Ut, CSS2DObject as kt } from "three/addons/renderers/CSS2DRenderer.js";
10
- import { CSS2DObject as pi } from "three/addons/renderers/CSS2DRenderer.js";
11
- import { CSS3DRenderer as Gt, CSS3DSprite as Ft, CSS3DObject as zt } from "three/addons/renderers/CSS3DRenderer.js";
12
- import { CSS3DObject as mi, CSS3DSprite as gi } from "three/addons/renderers/CSS3DRenderer.js";
13
- import { GLTFLoader as Le } from "three/addons/loaders/GLTFLoader.js";
14
- import { FBXLoader as Ht } from "three/addons/loaders/FBXLoader.js";
15
- import { OBJLoader as $t } from "three/addons/loaders/OBJLoader.js";
16
- import { STLLoader as Wt } from "three/addons/loaders/STLLoader.js";
17
- import { DRACOLoader as Kt } from "three/addons/loaders/DRACOLoader.js";
18
- import { KTX2Loader as Qt } from "three/addons/loaders/KTX2Loader.js";
19
- import { MeshoptDecoder as ge } from "three/addons/libs/meshopt_decoder.module.js";
20
- import { HDRLoader as Xt } from "three/addons/loaders/HDRLoader.js";
21
- import { clone as qt } from "three/addons/utils/SkeletonUtils.js";
1
+ import { Raycaster as Be, Vector2 as S, EventDispatcher as Le, Box2 as tt, Matrix4 as Ie, Vector3 as w, Box3 as q, Scene as Re, Color as B, AmbientLight as st, DirectionalLight as ue, PointLight as me, SpotLight as ge, HemisphereLight as fe, DirectionalLightHelper as nt, PointLightHelper as it, SpotLightHelper as rt, HemisphereLightHelper as ot, RenderPipeline as at, PerspectiveCamera as J, Sphere as ze, Spherical as C, Quaternion as ct, Vector4 as ht, MathUtils as lt, PMREMGenerator as dt, OrthographicCamera as V, TimestampQuery as pt, Cache as ut, Timer as mt, WebGPURenderer as gt, PCFShadowMap as ft, AgXToneMapping as yt, Fog as wt, FogExp2 as bt, MeshStandardNodeMaterial as R, Loader as vt, LoaderUtils as L, FileLoader as Ne, TextureLoader as je, Group as I, SRGBColorSpace as De, RepeatWrapping as ye, BufferGeometry as K, BufferAttribute as we, Mesh as G, FrontSide as xt, BackSide as St, DoubleSide as Ct, REVISION as be, CubeTextureLoader as _t, EquirectangularReflectionMapping as Mt, Sprite as Tt, AnimationMixer as Pt, LoopRepeat as Et, LoopOnce as Ot, SphereGeometry as At, TubeGeometry as Bt, LineCurve3 as Lt, CatmullRomCurve3 as It, SpriteNodeMaterial as Rt, CanvasTexture as zt, ShapeGeometry as Nt, Shape as ke, ExtrudeGeometry as jt, PlaneGeometry as Dt, CircleGeometry as kt, ClippingGroup as Ht, Plane as Ut, PlaneHelper as Ft, LineBasicMaterial as Z, Line as ee } from "three/webgpu";
2
+ import { pass as de, mrt as Gt, output as $t, add as ve, blendColor as Wt, emissive as Kt, normalView as Qt, velocity as qt, color as H, uv as xe, time as te, pow as se, sin as pe, mix as ne, mx_noise_float as Se, Fn as He, userData as A, materialColor as Ce, select as ie, materialOpacity as Xt, vec3 as Yt } from "three/tsl";
3
+ import { bloom as Jt } from "three/addons/tsl/display/BloomNode.js";
4
+ import { ssgi as Vt } from "three/addons/tsl/display/SSGINode.js";
5
+ import { traa as Zt } from "three/addons/tsl/display/TRAANode.js";
6
+ import Ue from "camera-controls";
7
+ import { RoomEnvironment as es } from "three/addons/environments/RoomEnvironment.js";
8
+ import { ViewHelper as ts } from "three/addons/helpers/ViewHelper.js";
9
+ import { CSS2DRenderer as ss, CSS2DObject as ns } from "three/addons/renderers/CSS2DRenderer.js";
10
+ import { CSS2DObject as Nn } from "three/addons/renderers/CSS2DRenderer.js";
11
+ import { CSS3DRenderer as is, CSS3DSprite as rs, CSS3DObject as os } from "three/addons/renderers/CSS3DRenderer.js";
12
+ import { CSS3DObject as Dn, CSS3DSprite as kn } from "three/addons/renderers/CSS3DRenderer.js";
13
+ import { GLTFLoader as Fe } from "three/addons/loaders/GLTFLoader.js";
14
+ import { FBXLoader as as } from "three/addons/loaders/FBXLoader.js";
15
+ import { OBJLoader as cs } from "three/addons/loaders/OBJLoader.js";
16
+ import { STLLoader as hs } from "three/addons/loaders/STLLoader.js";
17
+ import { DRACOLoader as ls } from "three/addons/loaders/DRACOLoader.js";
18
+ import { KTX2Loader as ds } from "three/addons/loaders/KTX2Loader.js";
19
+ import { MeshoptDecoder as _e } from "three/addons/libs/meshopt_decoder.module.js";
20
+ import { HDRLoader as ps } from "three/addons/loaders/HDRLoader.js";
21
+ import { clone as us } from "three/addons/utils/SkeletonUtils.js";
22
22
  import { Color as U } from "three";
23
- import { Easing as u, Tween as Yt } from "three/addons/libs/tween.module.js";
24
- class Jt {
23
+ import { Easing as m, Tween as ms } from "three/addons/libs/tween.module.js";
24
+ class gs {
25
25
  /** The type of event (e.g., 'click', 'pointerdown'). */
26
26
  type;
27
27
  /** The original 3D object that triggered the event. */
@@ -49,15 +49,15 @@ class Jt {
49
49
  return this._propagationStopped;
50
50
  }
51
51
  }
52
- class Zt {
52
+ class fs {
53
53
  domElement;
54
54
  scene;
55
55
  camera;
56
- raycaster = new Te();
57
- pointer = new R();
56
+ raycaster = new Be();
57
+ pointer = new S();
58
58
  hoveredObject = null;
59
59
  pointerDownTime = 0;
60
- pointerDownPos = new R();
60
+ pointerDownPos = new S();
61
61
  clickTimer = null;
62
62
  longPressThreshold = 500;
63
63
  moveThreshold = 0.01;
@@ -70,6 +70,14 @@ class Zt {
70
70
  * Disabled by default for performance optimization.
71
71
  */
72
72
  pointerMoveEventsEnabled = !1;
73
+ /**
74
+ * Whether interaction is enabled globally.
75
+ */
76
+ _enabled = !0;
77
+ /**
78
+ * Objects excluded from raycasting (via addIgnore or setInteractable(false)).
79
+ */
80
+ _excludeSet = /* @__PURE__ */ new Set();
73
81
  constructor(e, t, s) {
74
82
  this.domElement = e, this.scene = t, this.camera = s, this.raycaster.params.Points.threshold = 0.1, this.raycaster.params.Line.threshold = 0.1, this.targetObjects = this.scene.children, this._bindEvents();
75
83
  }
@@ -79,6 +87,39 @@ class Zt {
79
87
  setCamera(e) {
80
88
  this.camera = e;
81
89
  }
90
+ /**
91
+ * Enable all interactions.
92
+ */
93
+ enable() {
94
+ this._enabled = !0;
95
+ }
96
+ /**
97
+ * Disable all interactions.
98
+ */
99
+ disable() {
100
+ this._enabled = !1;
101
+ }
102
+ /**
103
+ * Set whether a specific object is interactable.
104
+ * When set to false, the object and its children are excluded from raycasting.
105
+ */
106
+ setInteractable(e, t) {
107
+ t ? this._excludeSet.delete(e) : this._excludeSet.add(e);
108
+ }
109
+ /**
110
+ * Add an object to the exclude list (will not receive any events).
111
+ * Alias for `setInteractable(object, false)`.
112
+ */
113
+ addIgnore(e) {
114
+ this._excludeSet.add(e);
115
+ }
116
+ /**
117
+ * Remove an object from the exclude list.
118
+ * Alias for `setInteractable(object, true)`.
119
+ */
120
+ removeIgnore(e) {
121
+ this._excludeSet.delete(e);
122
+ }
82
123
  _bindEvents() {
83
124
  this.domElement.addEventListener("click", this._onClick), this.domElement.addEventListener("dblclick", this._onDblClick), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointerup", this._onPointerUp), this.domElement.addEventListener("pointermove", this._onPointerMove);
84
125
  }
@@ -87,31 +128,42 @@ class Zt {
87
128
  this.pointer.x = (e.clientX - t.left) / t.width * 2 - 1, this.pointer.y = -((e.clientY - t.top) / t.height) * 2 + 1;
88
129
  }
89
130
  _getIntersects() {
90
- return this.raycaster.setFromCamera(this.pointer, this.camera), this.raycaster.intersectObjects(this.targetObjects, !0);
131
+ this.raycaster.setFromCamera(this.pointer, this.camera);
132
+ const e = this.raycaster.intersectObjects(this.targetObjects, !0);
133
+ return this._excludeSet.size > 0 ? e.filter((t) => {
134
+ let s = t.object;
135
+ for (; s; ) {
136
+ if (this._excludeSet.has(s))
137
+ return !1;
138
+ s = s.parent;
139
+ }
140
+ return !0;
141
+ }) : e;
91
142
  }
92
143
  /**
93
144
  * Dispatches an event to the target object and bubbles up the parent chain.
94
145
  */
95
- _dispatchToTarget(e, t, s, i) {
96
- const n = new Jt({
146
+ _dispatchToTarget(e, t, s, n) {
147
+ const i = new gs({
97
148
  type: e,
98
149
  target: t,
99
150
  intersect: s,
100
- originalEvent: i
151
+ originalEvent: n
101
152
  });
102
153
  let r = t;
103
- for (; r && !n.propagationStopped; )
104
- n.currentTarget = r, r.dispatchEvent({ type: e, event: n }), r = r.parent;
154
+ for (; r && !i.propagationStopped; )
155
+ i.currentTarget = r, r.dispatchEvent({ type: e, event: i }), r = r.parent;
105
156
  }
106
157
  /**
107
158
  * Handles a DOM event by raycasting and dispatching to the first intersected object.
108
159
  */
109
160
  _handleEvent(e, t) {
161
+ if (!this._enabled) return;
110
162
  this._updatePointer(t);
111
163
  const s = this._getIntersects();
112
164
  if (s.length === 0) return;
113
- const i = s[0];
114
- this._dispatchToTarget(e, i.object, i, t);
165
+ const n = s[0];
166
+ this._dispatchToTarget(e, n.object, n, t);
115
167
  }
116
168
  _onClick = (e) => {
117
169
  const t = Date.now() - this.pointerDownTime, s = this.pointer.distanceTo(this.pointerDownPos);
@@ -142,19 +194,155 @@ class Zt {
142
194
  this._handleEvent("pointerup", e);
143
195
  };
144
196
  _onPointerMove = (e) => {
145
- if (!this.pointerMoveEventsEnabled) return;
197
+ if (!this._enabled || !this.pointerMoveEventsEnabled) return;
146
198
  this._updatePointer(e);
147
- const t = this._getIntersects(), s = t.length > 0 ? t[0].object : null, i = t.length > 0 ? t[0] : null;
148
- this.hoveredObject !== s && (this.hoveredObject && this._dispatchToTarget("pointerleave", this.hoveredObject, null, e), this.hoveredObject = s, s && i && this._dispatchToTarget("pointerenter", s, i, e)), s && i && this._dispatchToTarget("pointermove", s, i, e);
199
+ const t = this._getIntersects(), s = t.length > 0 ? t[0].object : null, n = t.length > 0 ? t[0] : null;
200
+ this.hoveredObject !== s && (this.hoveredObject && this._dispatchToTarget("pointerleave", this.hoveredObject, null, e), this.hoveredObject = s, s && n && this._dispatchToTarget("pointerenter", s, n, e)), s && n && this._dispatchToTarget("pointermove", s, n, e);
149
201
  };
150
202
  /**
151
203
  * Cleans up event listeners.
152
204
  */
153
205
  dispose() {
154
- this.domElement.removeEventListener("click", this._onClick), this.domElement.removeEventListener("dblclick", this._onDblClick), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.hoveredObject = null;
206
+ this.domElement.removeEventListener("click", this._onClick), this.domElement.removeEventListener("dblclick", this._onDblClick), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.clickTimer && (clearTimeout(this.clickTimer), this.clickTimer = null), this.hoveredObject = null, this._excludeSet.clear();
155
207
  }
156
208
  }
157
- class Vt {
209
+ class bn extends Le {
210
+ scene;
211
+ camera;
212
+ domElement;
213
+ /** The container element for the selection box overlay (domElement's parent). */
214
+ _container;
215
+ _selected = /* @__PURE__ */ new Set();
216
+ // Box selection state
217
+ _boxSelectionEnabled = !1;
218
+ _isSelecting = !1;
219
+ _startPoint = new S();
220
+ _endPoint = new S();
221
+ _selectionBox = null;
222
+ _deep = !0;
223
+ /**
224
+ * Objects available for selection (defaults to scene.children).
225
+ */
226
+ targetObjects = null;
227
+ constructor(e, t, s) {
228
+ super(), this.domElement = e, this._container = e.parentElement ?? e, this.scene = t, this.camera = s;
229
+ }
230
+ get selected() {
231
+ return this._selected;
232
+ }
233
+ get selectedArray() {
234
+ return Array.from(this._selected);
235
+ }
236
+ /**
237
+ * Select one or more objects.
238
+ */
239
+ select(e) {
240
+ const t = Array.isArray(e) ? e : [e], s = [];
241
+ for (const n of t)
242
+ this._selected.has(n) || (this._selected.add(n), s.push(n));
243
+ s.length > 0 && (this.dispatchEvent({ type: "select", objects: s }), this.dispatchEvent({ type: "change", selected: this._selected }));
244
+ }
245
+ /**
246
+ * Deselect one or more objects.
247
+ */
248
+ deselect(e) {
249
+ const t = Array.isArray(e) ? e : [e], s = [];
250
+ for (const n of t)
251
+ this._selected.delete(n) && s.push(n);
252
+ s.length > 0 && (this.dispatchEvent({ type: "deselect", objects: s }), this.dispatchEvent({ type: "change", selected: this._selected }));
253
+ }
254
+ /**
255
+ * Toggle selection of an object.
256
+ */
257
+ toggle(e) {
258
+ this._selected.has(e) ? this.deselect(e) : this.select(e);
259
+ }
260
+ /**
261
+ * Clear all selections.
262
+ */
263
+ clear() {
264
+ if (this._selected.size === 0) return;
265
+ const e = Array.from(this._selected);
266
+ this._selected.clear(), this.dispatchEvent({ type: "deselect", objects: e }), this.dispatchEvent({ type: "change", selected: this._selected });
267
+ }
268
+ /**
269
+ * Check if an object is selected.
270
+ */
271
+ isSelected(e) {
272
+ return this._selected.has(e);
273
+ }
274
+ /**
275
+ * Enable rubber-band box selection mode.
276
+ */
277
+ enableBoxSelection(e = {}) {
278
+ this._boxSelectionEnabled || (this._boxSelectionEnabled = !0, this._deep = e.deep ?? !0, this._selectionBox = document.createElement("div"), this._selectionBox.style.cssText = `
279
+ position: absolute;
280
+ border: 1px dashed #55aaff;
281
+ background: rgba(75, 160, 255, 0.15);
282
+ pointer-events: none;
283
+ display: none;
284
+ z-index: 9999;
285
+ `, e.className && (this._selectionBox.className = e.className), this._container.style.position = this._container.style.position || "relative", this._container.appendChild(this._selectionBox), this.domElement.addEventListener("pointerdown", this._onBoxPointerDown), this.domElement.addEventListener("pointermove", this._onBoxPointerMove), this.domElement.addEventListener("pointerup", this._onBoxPointerUp));
286
+ }
287
+ /**
288
+ * Disable box selection mode.
289
+ */
290
+ disableBoxSelection() {
291
+ this._boxSelectionEnabled && (this._boxSelectionEnabled = !1, this.domElement.removeEventListener("pointerdown", this._onBoxPointerDown), this.domElement.removeEventListener("pointermove", this._onBoxPointerMove), this.domElement.removeEventListener("pointerup", this._onBoxPointerUp), this._selectionBox && (this._selectionBox.remove(), this._selectionBox = null));
292
+ }
293
+ setCamera(e) {
294
+ this.camera = e;
295
+ }
296
+ _onBoxPointerDown = (e) => {
297
+ if (e.button !== 0) return;
298
+ this._isSelecting = !0;
299
+ const t = this._container.getBoundingClientRect();
300
+ this._startPoint.set(e.clientX - t.left, e.clientY - t.top), this._endPoint.copy(this._startPoint), this._selectionBox && (this._selectionBox.style.display = "block", this._updateBoxElement());
301
+ };
302
+ _onBoxPointerMove = (e) => {
303
+ if (!this._isSelecting) return;
304
+ const t = this._container.getBoundingClientRect();
305
+ this._endPoint.set(e.clientX - t.left, e.clientY - t.top), this._updateBoxElement();
306
+ };
307
+ _onBoxPointerUp = () => {
308
+ if (!this._isSelecting) return;
309
+ this._isSelecting = !1, this._selectionBox && (this._selectionBox.style.display = "none");
310
+ const e = this._getObjectsInBox();
311
+ this.clear(), e.length > 0 && this.select(e);
312
+ };
313
+ _updateBoxElement() {
314
+ if (!this._selectionBox) return;
315
+ const e = Math.min(this._startPoint.x, this._endPoint.x), t = Math.min(this._startPoint.y, this._endPoint.y), s = Math.abs(this._endPoint.x - this._startPoint.x), n = Math.abs(this._endPoint.y - this._startPoint.y);
316
+ this._selectionBox.style.left = `${e}px`, this._selectionBox.style.top = `${t}px`, this._selectionBox.style.width = `${s}px`, this._selectionBox.style.height = `${n}px`;
317
+ }
318
+ _getObjectsInBox() {
319
+ const e = this._container.getBoundingClientRect(), t = e.width, s = e.height, n = new S(
320
+ this._startPoint.x / t * 2 - 1,
321
+ -(this._startPoint.y / s) * 2 + 1
322
+ ), i = new S(
323
+ this._endPoint.x / t * 2 - 1,
324
+ -(this._endPoint.y / s) * 2 + 1
325
+ ), r = new tt(
326
+ new S(Math.min(n.x, i.x), Math.min(n.y, i.y)),
327
+ new S(Math.max(n.x, i.x), Math.max(n.y, i.y))
328
+ ), o = this.targetObjects || this.scene.children, a = [], c = new Ie();
329
+ c.multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse);
330
+ const h = (d) => {
331
+ if (!d.visible) return;
332
+ const p = new w();
333
+ if (p.setFromMatrixPosition(d.matrixWorld), p.applyMatrix4(c), p.z > -1 && p.z < 1 && r.containsPoint(new S(p.x, p.y)) && a.push(d), this._deep)
334
+ for (const u of d.children)
335
+ h(u);
336
+ };
337
+ for (const d of o)
338
+ h(d);
339
+ return a;
340
+ }
341
+ dispose() {
342
+ this.disableBoxSelection(), this._selected.clear();
343
+ }
344
+ }
345
+ class ys {
158
346
  idMap = /* @__PURE__ */ new Map();
159
347
  nameMap = /* @__PURE__ */ new Map();
160
348
  typeMap = /* @__PURE__ */ new Map();
@@ -256,8 +444,272 @@ class Vt {
256
444
  get size() {
257
445
  return this.allObjects.size;
258
446
  }
447
+ /**
448
+ * Show an object by id.
449
+ */
450
+ show(e) {
451
+ const t = this.idMap.get(e);
452
+ t && (t.visible = !0);
453
+ }
454
+ /**
455
+ * Hide an object by id.
456
+ */
457
+ hide(e) {
458
+ const t = this.idMap.get(e);
459
+ t && (t.visible = !1);
460
+ }
461
+ /**
462
+ * Show only the specified objects, hide all others.
463
+ */
464
+ isolate(e) {
465
+ const t = new Set(e);
466
+ for (const [s, n] of this.idMap)
467
+ n.visible = t.has(s);
468
+ }
469
+ /**
470
+ * Set the opacity of an object's materials.
471
+ */
472
+ setOpacity(e, t) {
473
+ const s = this.idMap.get(e);
474
+ s && s.traverse((n) => {
475
+ if (!n.isMesh) return;
476
+ const i = n.material;
477
+ if (!i) return;
478
+ const r = Array.isArray(i) ? i : [i];
479
+ for (const o of r)
480
+ o.transparent = t < 1, o.opacity = t, o.needsUpdate = !0;
481
+ });
482
+ }
483
+ /**
484
+ * Get the bounding box of an object by id, or all objects if no id provided.
485
+ */
486
+ getBoundingBox(e) {
487
+ const t = new q();
488
+ if (e) {
489
+ const s = this.idMap.get(e);
490
+ s && t.setFromObject(s);
491
+ } else
492
+ for (const s of this.allObjects)
493
+ t.expandByObject(s);
494
+ return t;
495
+ }
496
+ /**
497
+ * Iterate over all managed objects.
498
+ */
499
+ forEach(e) {
500
+ for (const t of this.allObjects) {
501
+ const s = this.objectIds.get(t) || /* @__PURE__ */ new Set();
502
+ e(t, s);
503
+ }
504
+ }
505
+ /**
506
+ * Filter objects by a predicate.
507
+ */
508
+ filter(e) {
509
+ const t = [];
510
+ for (const s of this.allObjects)
511
+ e(s) && t.push(s);
512
+ return t;
513
+ }
514
+ /**
515
+ * Show all managed objects.
516
+ */
517
+ showAll() {
518
+ for (const e of this.allObjects)
519
+ e.visible = !0;
520
+ }
259
521
  }
260
- class es extends $e {
522
+ class vn {
523
+ scenes = /* @__PURE__ */ new Map();
524
+ _activeSceneKey = null;
525
+ /**
526
+ * Add a scene with a key.
527
+ */
528
+ add(e, t) {
529
+ this.scenes.set(e, t);
530
+ }
531
+ /**
532
+ * Create and register a new scene.
533
+ */
534
+ create(e, t = {}) {
535
+ const s = new Re();
536
+ return t.background !== void 0 && (s.background = new B(t.background)), this.scenes.set(e, s), s;
537
+ }
538
+ /**
539
+ * Get a scene by key.
540
+ */
541
+ get(e) {
542
+ return this.scenes.get(e);
543
+ }
544
+ /**
545
+ * Remove a scene by key.
546
+ */
547
+ remove(e) {
548
+ this.scenes.delete(e), this._activeSceneKey === e && (this._activeSceneKey = null);
549
+ }
550
+ /**
551
+ * Get the currently active scene key.
552
+ */
553
+ get activeKey() {
554
+ return this._activeSceneKey;
555
+ }
556
+ /**
557
+ * Set the active scene key (for external use to track which scene is active).
558
+ */
559
+ set activeKey(e) {
560
+ this._activeSceneKey = e;
561
+ }
562
+ /**
563
+ * List all registered scene keys.
564
+ */
565
+ keys() {
566
+ return Array.from(this.scenes.keys());
567
+ }
568
+ /**
569
+ * Serialize scene metadata to JSON (children names/ids, background, etc.).
570
+ */
571
+ serialize(e) {
572
+ const t = this.scenes.get(e);
573
+ if (!t) return null;
574
+ let s = null;
575
+ return t.background instanceof B && (s = `#${t.background.getHexString()}`), {
576
+ name: t.name || e,
577
+ background: s,
578
+ environmentRotation: {
579
+ x: t.environmentRotation?.x ?? 0,
580
+ y: t.environmentRotation?.y ?? 0,
581
+ z: t.environmentRotation?.z ?? 0
582
+ },
583
+ children: t.children.map((n) => n.name || n.uuid)
584
+ };
585
+ }
586
+ /**
587
+ * Clear all scenes.
588
+ */
589
+ clear() {
590
+ this.scenes.clear(), this._activeSceneKey = null;
591
+ }
592
+ get size() {
593
+ return this.scenes.size;
594
+ }
595
+ }
596
+ class xn {
597
+ scene;
598
+ lights = /* @__PURE__ */ new Map();
599
+ helpers = /* @__PURE__ */ new Map();
600
+ constructor(e) {
601
+ this.scene = e;
602
+ }
603
+ addAmbient(e, t = {}) {
604
+ const { color: s = 16777215, intensity: n = 0.5 } = t, i = new st(s, n);
605
+ return i.name = e, this._register(e, i), i;
606
+ }
607
+ addDirectional(e, t = {}) {
608
+ const { color: s = 16777215, intensity: n = 1, position: i = { x: 5, y: 10, z: 5 }, castShadow: r = !1, shadowMapSize: o = 1024 } = t, a = new ue(s, n);
609
+ return a.position.set(i.x, i.y, i.z), a.castShadow = r, r && a.shadow.mapSize.setScalar(o), a.name = e, this._register(e, a), a;
610
+ }
611
+ addPoint(e, t = {}) {
612
+ const { color: s = 16777215, intensity: n = 1, distance: i = 0, decay: r = 2, position: o = { x: 0, y: 5, z: 0 }, castShadow: a = !1 } = t, c = new me(s, n, i, r);
613
+ return c.position.set(o.x, o.y, o.z), c.castShadow = a, c.name = e, this._register(e, c), c;
614
+ }
615
+ addSpot(e, t = {}) {
616
+ const {
617
+ color: s = 16777215,
618
+ intensity: n = 1,
619
+ distance: i = 0,
620
+ angle: r = Math.PI / 6,
621
+ penumbra: o = 0.1,
622
+ decay: a = 2,
623
+ position: c = { x: 0, y: 10, z: 0 },
624
+ target: h,
625
+ castShadow: d = !1
626
+ } = t, p = new ge(s, n, i, r, o, a);
627
+ return p.position.set(c.x, c.y, c.z), h && p.target.position.set(h.x, h.y, h.z), p.castShadow = d, p.name = e, this._register(e, p), p;
628
+ }
629
+ addHemisphere(e, t = {}) {
630
+ const { skyColor: s = 8900331, groundColor: n = 3549447, intensity: i = 0.6 } = t, r = new fe(s, n, i);
631
+ return r.name = e, this._register(e, r), r;
632
+ }
633
+ /**
634
+ * Apply a lighting preset to the scene.
635
+ */
636
+ applyPreset(e) {
637
+ switch (this.removeAll(), e) {
638
+ case "indoor":
639
+ this.addAmbient("preset_ambient", { intensity: 0.4 }), this.addPoint("preset_point1", { position: { x: 0, y: 3, z: 0 }, intensity: 1, castShadow: !0 }), this.addPoint("preset_point2", { position: { x: 3, y: 2, z: -3 }, intensity: 0.5 });
640
+ break;
641
+ case "outdoor":
642
+ this.addHemisphere("preset_hemi", { skyColor: 8900331, groundColor: 3549447, intensity: 0.6 }), this.addDirectional("preset_sun", { position: { x: 10, y: 20, z: 10 }, intensity: 1.5, castShadow: !0, shadowMapSize: 2048 });
643
+ break;
644
+ case "studio":
645
+ this.addAmbient("preset_ambient", { intensity: 0.3 }), this.addDirectional("preset_key", { position: { x: 5, y: 8, z: 5 }, intensity: 1.2, castShadow: !0 }), this.addDirectional("preset_fill", { position: { x: -5, y: 5, z: -2 }, intensity: 0.6 }), this.addDirectional("preset_back", { position: { x: 0, y: 5, z: -8 }, intensity: 0.4 });
646
+ break;
647
+ case "warehouse":
648
+ this.addAmbient("preset_ambient", { intensity: 0.2 }), this.addPoint("preset_light1", { position: { x: -5, y: 6, z: -5 }, intensity: 2, distance: 20 }), this.addPoint("preset_light2", { position: { x: 5, y: 6, z: -5 }, intensity: 2, distance: 20 }), this.addPoint("preset_light3", { position: { x: -5, y: 6, z: 5 }, intensity: 2, distance: 20 }), this.addPoint("preset_light4", { position: { x: 5, y: 6, z: 5 }, intensity: 2, distance: 20 });
649
+ break;
650
+ }
651
+ }
652
+ /**
653
+ * Get a light by id.
654
+ */
655
+ get(e) {
656
+ return this.lights.get(e);
657
+ }
658
+ /**
659
+ * Remove a light by id.
660
+ */
661
+ remove(e) {
662
+ const t = this.lights.get(e);
663
+ t && (this.scene.remove(t), this.lights.delete(e)), this.hideHelper(e);
664
+ }
665
+ /**
666
+ * Remove all lights managed by this manager.
667
+ */
668
+ removeAll() {
669
+ const e = Array.from(this.lights.keys());
670
+ for (const t of e)
671
+ this.remove(t);
672
+ }
673
+ /**
674
+ * Show a visual helper for a light.
675
+ */
676
+ showHelper(e) {
677
+ if (this.helpers.has(e)) return;
678
+ const t = this.lights.get(e);
679
+ if (!t) return;
680
+ let s = null;
681
+ t instanceof ue ? s = new nt(t, 1) : t instanceof me ? s = new it(t, 0.5) : t instanceof ge ? s = new rt(t) : t instanceof fe && (s = new ot(t, 1)), s && (this.scene.add(s), this.helpers.set(e, s));
682
+ }
683
+ /**
684
+ * Hide (remove) the helper for a light.
685
+ */
686
+ hideHelper(e) {
687
+ const t = this.helpers.get(e);
688
+ t && (this.scene.remove(t), this.helpers.delete(e));
689
+ }
690
+ /**
691
+ * Show helpers for all lights.
692
+ */
693
+ showAllHelpers() {
694
+ for (const [e] of this.lights)
695
+ this.showHelper(e);
696
+ }
697
+ /**
698
+ * Hide all helpers.
699
+ */
700
+ hideAllHelpers() {
701
+ const e = Array.from(this.helpers.keys());
702
+ for (const t of e)
703
+ this.hideHelper(t);
704
+ }
705
+ _register(e, t) {
706
+ this.lights.has(e) && this.remove(e), this.lights.set(e, t), this.scene.add(t);
707
+ }
708
+ dispose() {
709
+ this.removeAll(), this.hideAllHelpers();
710
+ }
711
+ }
712
+ class ws extends at {
261
713
  scene;
262
714
  camera;
263
715
  scenePass;
@@ -265,9 +717,9 @@ class es extends $e {
265
717
  #r;
266
718
  #t;
267
719
  #s = !1;
268
- #a = { strength: 1, radius: 0, threshold: 0 };
720
+ #o = { strength: 1, radius: 0, threshold: 0 };
269
721
  #c = null;
270
- #n = !1;
722
+ #i = !1;
271
723
  #e = {
272
724
  sliceCount: 1,
273
725
  stepCount: 12,
@@ -277,12 +729,12 @@ class es extends $e {
277
729
  thickness: 1
278
730
  };
279
731
  #h = null;
280
- #o = !1;
732
+ #a = !1;
281
733
  #l = null;
282
734
  #d = null;
283
735
  constructor(...e) {
284
- const [t, s, i] = e;
285
- super(t), this.scene = s, this.camera = i, this.scenePass = re(s, i), this.needsUpdateOutputNode = !0, this.#r = /* @__PURE__ */ new Set(), this.#t = [], this.#p();
736
+ const [t, s, n] = e;
737
+ super(t), this.scene = s, this.camera = n, this.scenePass = de(s, n), this.needsUpdateOutputNode = !0, this.#r = /* @__PURE__ */ new Set(), this.#t = [], this.#p();
286
738
  }
287
739
  /** @deprecated Use `scenePass` instead */
288
740
  get currentOutputNode() {
@@ -295,7 +747,7 @@ class es extends $e {
295
747
  this.#r.delete(e), this.needsUpdateOutputNode = !0;
296
748
  }
297
749
  setCamera(e) {
298
- this.camera = e, this.#i();
750
+ this.camera = e, this.#n();
299
751
  }
300
752
  /** @deprecated Use `setOutputComposer` instead */
301
753
  setCurrentOutputNode(e) {
@@ -309,19 +761,19 @@ class es extends $e {
309
761
  this.#d = e, this.needsUpdateOutputNode = !0;
310
762
  }
311
763
  enableBloom(e) {
312
- e && Object.assign(this.#a, e), this.#s = !0, this.#i();
764
+ e && Object.assign(this.#o, e), this.#s = !0, this.#n();
313
765
  }
314
766
  disableBloom() {
315
- this.#s = !1, this.#c = null, this.#i();
767
+ this.#s = !1, this.#c = null, this.#n();
316
768
  }
317
769
  updateBloom(e) {
318
- Object.assign(this.#a, e), this.#s && (this.needsUpdateOutputNode = !0);
770
+ Object.assign(this.#o, e), this.#s && (this.needsUpdateOutputNode = !0);
319
771
  }
320
772
  enableSSGI(e) {
321
- e && Object.assign(this.#e, e), this.#n = !0, this.#i();
773
+ e && Object.assign(this.#e, e), this.#i = !0, this.#n();
322
774
  }
323
775
  disableSSGI() {
324
- this.#n = !1, this.#h = null, this.#i();
776
+ this.#i = !1, this.#h = null, this.#n();
325
777
  }
326
778
  updateSSGI(e) {
327
779
  if (Object.assign(this.#e, e), this.#h) {
@@ -330,19 +782,19 @@ class es extends $e {
330
782
  }
331
783
  }
332
784
  enableTRAA() {
333
- this.#o = !0, this.#i();
785
+ this.#a = !0, this.#n();
334
786
  }
335
787
  disableTRAA() {
336
- this.#o = !1, this.#l = null, this.#i();
788
+ this.#a = !1, this.#l = null, this.#n();
337
789
  }
338
- #i() {
790
+ #n() {
339
791
  const e = this.scenePass;
340
- this.scenePass = re(this.scene, this.camera), this.#p(), this.needsUpdateOutputNode = !0, e.dispose();
792
+ this.scenePass = de(this.scene, this.camera), this.#p(), this.needsUpdateOutputNode = !0, e.dispose();
341
793
  }
342
794
  #p() {
343
- if (this.#s || this.#n || this.#o) {
344
- const t = { output: Mt };
345
- this.#s && (t.emissive = Ot), this.#n && (t.normal = Rt), this.#o && (t.velocity = It), this.scenePass.setMRT(Et(t));
795
+ if (this.#s || this.#i || this.#a) {
796
+ const t = { output: $t };
797
+ this.#s && (t.emissive = Kt), this.#i && (t.normal = Qt), this.#a && (t.velocity = qt), this.scenePass.setMRT(Gt(t));
346
798
  }
347
799
  }
348
800
  #u() {
@@ -352,33 +804,33 @@ class es extends $e {
352
804
  }
353
805
  #m() {
354
806
  let e = this.scenePass.getTextureNode();
355
- if (this.#n)
356
- if (!(this.camera instanceof K))
807
+ if (this.#i)
808
+ if (!(this.camera instanceof J))
357
809
  console.warn("RenderPipeline: SSGI requires a PerspectiveCamera, skipping.");
358
810
  else {
359
- const t = this.scenePass.getTextureNode(), s = this.scenePass.getTextureNode("depth"), i = this.scenePass.getTextureNode("normal"), n = Bt(t, s, i, this.camera);
360
- n.sliceCount.value = this.#e.sliceCount, n.stepCount.value = this.#e.stepCount, n.aoIntensity.value = this.#e.aoIntensity, n.giIntensity.value = this.#e.giIntensity, n.radius.value = this.#e.radius, n.thickness.value = this.#e.thickness, this.#h = n, e = de(e, n), this.#t.push(n);
811
+ const t = this.scenePass.getTextureNode(), s = this.scenePass.getTextureNode("depth"), n = this.scenePass.getTextureNode("normal"), i = Vt(t, s, n, this.camera);
812
+ i.sliceCount.value = this.#e.sliceCount, i.stepCount.value = this.#e.stepCount, i.aoIntensity.value = this.#e.aoIntensity, i.giIntensity.value = this.#e.giIntensity, i.radius.value = this.#e.radius, i.thickness.value = this.#e.thickness, this.#h = i, e = ve(e, i), this.#t.push(i);
361
813
  }
362
814
  if (this.#s) {
363
815
  const t = this.scenePass.getTextureNode("emissive");
364
- this.#c = Nt(
816
+ this.#c = Jt(
365
817
  t,
366
- this.#a.strength,
367
- this.#a.radius,
368
- this.#a.threshold
369
- ), e = de(e, this.#c), this.#t.push(this.#c);
818
+ this.#o.strength,
819
+ this.#o.radius,
820
+ this.#o.threshold
821
+ ), e = ve(e, this.#c), this.#t.push(this.#c);
370
822
  }
371
823
  return e;
372
824
  }
373
825
  #g() {
374
826
  this.#u();
375
827
  let e;
376
- if (this.#d ? e = this.#d(this.scenePass) : this.#s || this.#n ? e = this.#m() : e = this.scenePass, this.#o) {
828
+ if (this.#d ? e = this.#d(this.scenePass) : this.#s || this.#i ? e = this.#m() : e = this.scenePass, this.#a) {
377
829
  const t = this.scenePass.getTextureNode("depth"), s = this.scenePass.getTextureNode("velocity");
378
- this.#l = _t(e, t, s, this.camera), this.#t.push(this.#l), e = this.#l;
830
+ this.#l = Zt(e, t, s, this.camera), this.#t.push(this.#l), e = this.#l;
379
831
  }
380
832
  this.#r.size > 0 && this.#r.forEach((t) => {
381
- const s = Pt(e, t);
833
+ const s = Wt(e, t);
382
834
  this.#t.push(s), e = s;
383
835
  }), this.outputNode = e, this.needsUpdate = !0;
384
836
  }
@@ -389,19 +841,19 @@ class es extends $e {
389
841
  this.#u(), this.scenePass.dispose(), super.dispose();
390
842
  }
391
843
  }
392
- const ts = {
393
- Vector2: R,
394
- Vector3: oe,
395
- Vector4: Qe,
396
- Quaternion: Ke,
397
- Matrix4: We,
844
+ const bs = {
845
+ Vector2: S,
846
+ Vector3: w,
847
+ Vector4: ht,
848
+ Quaternion: ct,
849
+ Matrix4: Ie,
398
850
  Spherical: C,
399
- Box3: xe,
400
- Sphere: Se,
401
- Raycaster: Te
851
+ Box3: q,
852
+ Sphere: ze,
853
+ Raycaster: Be
402
854
  };
403
- Ie.install({ THREE: ts });
404
- class ss extends Ie {
855
+ Ue.install({ THREE: bs });
856
+ class vs extends Ue {
405
857
  constructor(...e) {
406
858
  super(...e), this.minDistance = 0.2, this.smoothTime = 0.2, this.dollySpeed = 0.2;
407
859
  }
@@ -409,43 +861,83 @@ class ss extends Ie {
409
861
  * Set absolute angle for azimuth to avoid spinning
410
862
  */
411
863
  absoluteRotations() {
412
- this.azimuthAngle = is(this.azimuthAngle, 0);
864
+ this.azimuthAngle = xs(this.azimuthAngle, 0);
413
865
  }
414
866
  async flyToBox(e, t = {}) {
415
867
  if (e.isEmpty())
416
868
  return console.warn("CameraControls.flyToBox: The provided Box3 is empty."), !1;
417
869
  this.absoluteRotations();
418
- const { viewpoint: s = "frontTop", enableTransition: i = !0, padding: n = 0.1, cover: r = !1 } = t, o = [];
870
+ const { viewpoint: s = "frontTop", enableTransition: n = !0, padding: i = 0.1, cover: r = !1 } = t, o = [];
419
871
  if (s !== "current") {
420
- const c = fe[s.toUpperCase()] ?? fe.FRONTTOP, h = c.theta, l = c.phi;
872
+ const a = Me[s.toUpperCase()] ?? Me.FRONTTOP, c = a.theta, h = a.phi;
421
873
  o.push(
422
- this.fitToBox(e, i, {
423
- paddingLeft: n,
424
- paddingRight: n,
425
- paddingTop: n,
426
- paddingBottom: n,
874
+ this.fitToBox(e, n, {
875
+ paddingLeft: i,
876
+ paddingRight: i,
877
+ paddingTop: i,
878
+ paddingBottom: i,
427
879
  cover: r
428
880
  })
429
- ), o.push(this.rotateTo(h, l, i));
881
+ ), o.push(this.rotateTo(c, h, n));
430
882
  } else {
431
- const c = new Se();
432
- e.getBoundingSphere(c), c.radius += n, o.push(this.fitToSphere(c, i));
883
+ const a = new ze();
884
+ e.getBoundingSphere(a), a.radius += i, o.push(this.fitToSphere(a, n));
433
885
  }
434
886
  return await Promise.all(o), !0;
435
887
  }
436
888
  async flyToObject(e, t = {}) {
437
- const s = new xe().setFromObject(e);
889
+ const s = new q().setFromObject(e);
438
890
  return this.flyToBox(s, t);
439
891
  }
892
+ /**
893
+ * Fly camera to a specific position and look-at target.
894
+ */
895
+ async flyTo(e, t, s = {}) {
896
+ const { enableTransition: n = !0 } = s;
897
+ return this.absoluteRotations(), this.setLookAt(e.x, e.y, e.z, t.x, t.y, t.z, n);
898
+ }
899
+ /**
900
+ * Get the current camera viewpoint data (position, target, zoom).
901
+ */
902
+ getCameraViewpoint() {
903
+ const e = new w(), t = new w();
904
+ return this.getPosition(e), this.getTarget(t), {
905
+ position: { x: e.x, y: e.y, z: e.z },
906
+ target: { x: t.x, y: t.y, z: t.z },
907
+ zoom: this.camera.zoom
908
+ };
909
+ }
910
+ /**
911
+ * Lock camera controls (disable all user interaction).
912
+ */
913
+ lock() {
914
+ this.enabled = !1;
915
+ }
916
+ /**
917
+ * Unlock camera controls (re-enable user interaction).
918
+ */
919
+ unlock() {
920
+ this.enabled = !0;
921
+ }
922
+ /**
923
+ * Switch between 2D top-down and 3D perspective views.
924
+ */
925
+ async setViewMode(e, t = !0) {
926
+ if (e === "2d") {
927
+ const s = new w();
928
+ this.getTarget(s), await this.rotateTo(0, 0, t), this.minPolarAngle = 0, this.maxPolarAngle = 0;
929
+ } else
930
+ this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, await this.rotateTo(0, Math.PI / 4, t);
931
+ }
440
932
  async setCameraViewpoint(e, t = !0) {
441
- const { position: s, target: i, zoom: n = this.camera.zoom } = e;
933
+ const { position: s, target: n, zoom: i = this.camera.zoom } = e;
442
934
  return Promise.all([
443
- this.zoomTo(n, t),
444
- this.setLookAt(s.x, s.y, s.z, i.x, i.y, i.z, t)
935
+ this.zoomTo(i, t),
936
+ this.setLookAt(s.x, s.y, s.z, n.x, n.y, n.z, t)
445
937
  ]);
446
938
  }
447
939
  }
448
- const fe = {
940
+ const Me = {
449
941
  LEFT: new C(0, Math.PI / 2, -Math.PI / 2),
450
942
  RIGHT: new C(0, Math.PI / 2, Math.PI / 2),
451
943
  FRONT: new C(0, Math.PI / 2, 0),
@@ -461,17 +953,17 @@ const fe = {
461
953
  LEFTBACKTOP: new C(0, Math.PI / 4, -Math.PI / 4 * 3),
462
954
  RIGHTBACKTOP: new C(0, Math.PI / 4, Math.PI / 4 * 3)
463
955
  };
464
- function is(a, e) {
465
- const t = a - e;
466
- return Xe.euclideanModulo(t + Math.PI, Math.PI * 2) - Math.PI;
956
+ function xs(l, e) {
957
+ const t = l - e;
958
+ return lt.euclideanModulo(t + Math.PI, Math.PI * 2) - Math.PI;
467
959
  }
468
- class ns {
469
- environment = new Dt();
960
+ class Ss {
961
+ environment = new es();
470
962
  renderer;
471
963
  pmremGenerator;
472
964
  envMap = null;
473
965
  constructor(e) {
474
- this.renderer = e, this.pmremGenerator = new qe(e);
966
+ this.renderer = e, this.pmremGenerator = new dt(e);
475
967
  }
476
968
  update() {
477
969
  this.envMap || (this.envMap = this.pmremGenerator.fromScene(this.environment).texture);
@@ -480,20 +972,20 @@ class ns {
480
972
  this.pmremGenerator.dispose(), this.envMap?.dispose();
481
973
  }
482
974
  }
483
- const $ = 128;
484
- class rs extends jt {
975
+ const Y = 128;
976
+ class Cs extends ts {
485
977
  viewer;
486
978
  overlayPass;
487
979
  constructor(e) {
488
980
  super(e.camera, e.el), this.viewer = e;
489
- const t = new Q(-2, 2, 2, -2, 0, 4);
490
- t.position.set(0, 0, 2), this.overlayPass = re(this, t), this.setLabels("x", "y", "z");
981
+ const t = new V(-2, 2, 2, -2, 0, 4);
982
+ t.position.set(0, 0, 2), this.overlayPass = de(this, t), this.setLabels("x", "y", "z");
491
983
  }
492
984
  _update = () => {
493
985
  this.quaternion.copy(this.viewer.camera.quaternion).invert();
494
986
  const e = this.location;
495
987
  let t, s;
496
- e.left !== null ? t = e.left : t = this.viewer.el.offsetWidth - $ - e.right, e.top !== null ? s = e.top : s = this.viewer.el.offsetHeight - $ - e.bottom, this.overlayPass.setViewport(t, s, $, $);
988
+ e.left !== null ? t = e.left : t = this.viewer.el.offsetWidth - Y - e.right, e.top !== null ? s = e.top : s = this.viewer.el.offsetHeight - Y - e.bottom, this.overlayPass.setViewport(t, s, Y, Y);
497
989
  };
498
990
  enable() {
499
991
  return this.viewer.renderPipeline.addOverlayPass(this.overlayPass), this.viewer.addEventListener("beforeRender", this._update), this.viewer.render(), this;
@@ -502,8 +994,8 @@ class rs extends jt {
502
994
  return this.viewer.renderPipeline.removeOverlayPass(this.overlayPass), this.viewer.removeEventListener("beforeRender", this._update), this.viewer.render(), this;
503
995
  }
504
996
  }
505
- const Ae = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;overflow:hidden;", as = Ae + "z-index:0;", os = Ae + "z-index:1;";
506
- class cs {
997
+ const Ge = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;overflow:hidden;", _s = Ge + "z-index:0;", Ms = Ge + "z-index:1;";
998
+ class Ts {
507
999
  el;
508
1000
  css2dRenderer = null;
509
1001
  css3dRenderer = null;
@@ -511,21 +1003,21 @@ class cs {
511
1003
  this.el = e, getComputedStyle(e).position === "static" && (e.style.position = "relative");
512
1004
  }
513
1005
  initCSS2DRenderer() {
514
- const e = new Ut();
515
- return e.setSize(this.el.clientWidth, this.el.clientHeight), e.domElement.style.cssText = os, this.el.appendChild(e.domElement), this.css2dRenderer = e, e;
1006
+ const e = new ss();
1007
+ return e.setSize(this.el.clientWidth, this.el.clientHeight), e.domElement.style.cssText = Ms, this.el.appendChild(e.domElement), this.css2dRenderer = e, e;
516
1008
  }
517
1009
  initCSS3DRenderer() {
518
- const e = new Gt();
519
- return e.setSize(this.el.clientWidth, this.el.clientHeight), e.domElement.style.cssText = as, this.el.appendChild(e.domElement), this.css3dRenderer = e, e;
1010
+ const e = new is();
1011
+ return e.setSize(this.el.clientWidth, this.el.clientHeight), e.domElement.style.cssText = _s, this.el.appendChild(e.domElement), this.css3dRenderer = e, e;
520
1012
  }
521
1013
  createCSS2DObject(e) {
522
- return this.css2dRenderer || this.initCSS2DRenderer(), new kt(e);
1014
+ return this.css2dRenderer || this.initCSS2DRenderer(), new ns(e);
523
1015
  }
524
1016
  createCSS25DObject(e) {
525
- return this.css3dRenderer || this.initCSS3DRenderer(), new Ft(e);
1017
+ return this.css3dRenderer || this.initCSS3DRenderer(), new rs(e);
526
1018
  }
527
1019
  createCSS3DObject(e) {
528
- return this.css3dRenderer || this.initCSS3DRenderer(), new zt(e);
1020
+ return this.css3dRenderer || this.initCSS3DRenderer(), new os(e);
529
1021
  }
530
1022
  render(e, t) {
531
1023
  this.css2dRenderer && this.css2dRenderer.render(e, t), this.css3dRenderer && this.css3dRenderer.render(e, t);
@@ -537,7 +1029,7 @@ class cs {
537
1029
  this.css2dRenderer && (this.el.removeChild(this.css2dRenderer.domElement), this.css2dRenderer = null), this.css3dRenderer && (this.el.removeChild(this.css3dRenderer.domElement), this.css3dRenderer = null);
538
1030
  }
539
1031
  }
540
- class hs {
1032
+ class Ps {
541
1033
  el;
542
1034
  renderer;
543
1035
  container;
@@ -552,19 +1044,19 @@ class hs {
552
1044
  this.el = e, this.renderer = t;
553
1045
  const s = document.createElement("div");
554
1046
  s.style.position = "absolute", s.style.left = "12px", s.style.bottom = "12px", s.style.fontSize = "12px", s.style.color = "#fff", s.style.pointerEvents = "none", this.container = s;
555
- function i(r, o = !0) {
556
- const c = document.createElement("span");
557
- return o && (c.style.marginLeft = "6px"), c.innerText = r, c;
1047
+ function n(r, o = !0) {
1048
+ const a = document.createElement("span");
1049
+ return o && (a.style.marginLeft = "6px"), a.innerText = r, a;
558
1050
  }
559
- function n() {
1051
+ function i() {
560
1052
  return document.createElement("br");
561
1053
  }
562
- this.drawCallsText = i("0"), this.frameCallsText = i("0"), this.trianglesText = i("0"), this.linesText = i("0"), this.pointsText = i("0"), this.timestampText = i("0"), this.container.appendChild(i("draw calls", !1)), this.container.appendChild(this.drawCallsText), this.container.appendChild(n()), this.container.appendChild(i("frame calls", !1)), this.container.appendChild(this.frameCallsText), this.container.appendChild(n()), this.container.appendChild(i("triangles", !1)), this.container.appendChild(this.trianglesText), this.container.appendChild(n()), this.container.appendChild(i("points", !1)), this.container.appendChild(this.pointsText), this.container.appendChild(n()), this.container.appendChild(i("lines", !1)), this.container.appendChild(this.linesText), this.container.appendChild(n()), this.container.appendChild(i("timestamp", !1)), this.container.appendChild(this.timestampText), this.container.appendChild(n());
1054
+ this.drawCallsText = n("0"), this.frameCallsText = n("0"), this.trianglesText = n("0"), this.linesText = n("0"), this.pointsText = n("0"), this.timestampText = n("0"), this.container.appendChild(n("draw calls", !1)), this.container.appendChild(this.drawCallsText), this.container.appendChild(i()), this.container.appendChild(n("frame calls", !1)), this.container.appendChild(this.frameCallsText), this.container.appendChild(i()), this.container.appendChild(n("triangles", !1)), this.container.appendChild(this.trianglesText), this.container.appendChild(i()), this.container.appendChild(n("points", !1)), this.container.appendChild(this.pointsText), this.container.appendChild(i()), this.container.appendChild(n("lines", !1)), this.container.appendChild(this.linesText), this.container.appendChild(i()), this.container.appendChild(n("timestamp", !1)), this.container.appendChild(this.timestampText), this.container.appendChild(i());
563
1055
  }
564
1056
  update() {
565
1057
  if (this._enabled) {
566
1058
  const { render: e } = this.renderer.info;
567
- this.drawCallsText.innerText = e.drawCalls.toString(), this.frameCallsText.innerText = e.frameCalls.toString(), this.trianglesText.innerText = e.triangles.toString(), this.pointsText.innerText = e.points.toString(), this.linesText.innerText = e.lines.toString(), this.renderer.resolveTimestampsAsync(Ye.RENDER).then((t) => {
1059
+ this.drawCallsText.innerText = e.drawCalls.toString(), this.frameCallsText.innerText = e.frameCalls.toString(), this.trianglesText.innerText = e.triangles.toString(), this.pointsText.innerText = e.points.toString(), this.linesText.innerText = e.lines.toString(), this.renderer.resolveTimestampsAsync(pt.RENDER).then((t) => {
568
1060
  this.timestampText.innerText = t?.toFixed(2) ?? "0";
569
1061
  });
570
1062
  }
@@ -579,8 +1071,8 @@ class hs {
579
1071
  this.disable();
580
1072
  }
581
1073
  }
582
- Je.enabled = !0;
583
- class ei extends Ze {
1074
+ ut.enabled = !0;
1075
+ class Sn extends Le {
584
1076
  el;
585
1077
  renderer;
586
1078
  scene;
@@ -597,11 +1089,11 @@ class ei extends Ze {
597
1089
  frameCount = 1;
598
1090
  frameloop = "demand";
599
1091
  constructor({ el: e, rendererOptions: t }) {
600
- super(), this.el = e, this.renderer = this._initRenderer(t), this.scene = this.createScene(), this.camera = this.createPerspectiveCamera(), this.info = new hs(this.el, this.renderer), this.controls = new ss(this.camera, this.renderer.domElement), this.renderPipeline = new es(this.renderer, this.scene, this.camera), this.timer = new Ve(), this.roomEnvironment = new ns(this.renderer), this.interactionManager = new Zt(this.renderer.domElement, this.scene, this.camera), this.objectManager = new Vt(), this.viewerHelper = new rs(this), this.cssRenderer = new cs(this.el), window.addEventListener("resize", this.onWindowResize);
1092
+ super(), this.el = e, this.renderer = this._initRenderer(t), this.scene = this.createScene(), this.camera = this.createPerspectiveCamera(), this.info = new Ps(this.el, this.renderer), this.controls = new vs(this.camera, this.renderer.domElement), this.renderPipeline = new ws(this.renderer, this.scene, this.camera), this.timer = new mt(), this.roomEnvironment = new Ss(this.renderer), this.interactionManager = new fs(this.renderer.domElement, this.scene, this.camera), this.objectManager = new ys(), this.viewerHelper = new Cs(this), this.cssRenderer = new Ts(this.el), window.addEventListener("resize", this.onWindowResize);
601
1093
  }
602
1094
  onWindowResize = () => {
603
1095
  const e = this.el.clientWidth, t = this.el.clientHeight;
604
- this.camera instanceof K ? (this.camera.aspect = e / t, this.camera.updateProjectionMatrix()) : this.camera instanceof Q && (this.camera.left = -e / 2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = -t / 2, this.camera.updateProjectionMatrix()), this.renderer.setSize(e, t), this.cssRenderer.resize(e, t), this.render();
1096
+ this.camera instanceof J ? (this.camera.aspect = e / t, this.camera.updateProjectionMatrix()) : this.camera instanceof V && (this.camera.left = -e / 2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = -t / 2, this.camera.updateProjectionMatrix()), this.renderer.setSize(e, t), this.cssRenderer.resize(e, t), this.render();
605
1097
  };
606
1098
  async init() {
607
1099
  await this.renderer.init(), this.roomEnvironment.update(), this.scene.environment = this.roomEnvironment.envMap;
@@ -610,7 +1102,7 @@ class ei extends Ze {
610
1102
  this.camera = e, this.controls.camera = e, this.interactionManager.setCamera(e), this.renderPipeline.setCamera(e), this.onWindowResize(), this.dispatchEvent({ type: "cameraChange", camera: e });
611
1103
  }
612
1104
  setCameraByType(e) {
613
- e === "perspective" && !(this.camera instanceof K) ? this.setCamera(this.createPerspectiveCamera()) : e === "orthographic" && !(this.camera instanceof Q) && this.setCamera(this.createOrthographicCamera());
1105
+ e === "perspective" && !(this.camera instanceof J) ? this.setCamera(this.createPerspectiveCamera()) : e === "orthographic" && !(this.camera instanceof V) && this.setCamera(this.createOrthographicCamera());
614
1106
  }
615
1107
  render(e = 1) {
616
1108
  return this.frameCount += e, new Promise((t) => {
@@ -628,25 +1120,25 @@ class ei extends Ze {
628
1120
  this.dispatchEvent({ type: "afterControlsUpdate", time: e, delta: t }), this.frameCount > 0 && (this.frameCount--, s = !0), this.frameloop === "always" && (s = !0), s && (this.dispatchEvent({ type: "beforeRender", time: e, delta: t }), this.renderer.info.reset(), this.renderPipeline.render(), this.cssRenderer.render(this.scene, this.camera), this.info.update(), this.dispatchEvent({ type: "afterRender", time: e, delta: t }));
629
1121
  };
630
1122
  _initRenderer(e) {
631
- const t = new et({
1123
+ const t = new gt({
632
1124
  logarithmicDepthBuffer: !0,
633
1125
  antialias: !1,
634
1126
  depth: !1,
635
1127
  trackTimestamp: !0,
636
1128
  ...e
637
1129
  });
638
- return t.setSize(this.el.clientWidth, this.el.clientHeight), t.shadowMap.enabled = !0, t.shadowMap.type = tt, t.toneMapping = st, t.toneMappingExposure = 1, t.info.autoReset = !1, t.setPixelRatio(window.devicePixelRatio), t.setAnimationLoop(this.animate), this.el.appendChild(t.domElement), t;
1130
+ return t.setSize(this.el.clientWidth, this.el.clientHeight), t.shadowMap.enabled = !0, t.shadowMap.type = ft, t.toneMapping = yt, t.toneMappingExposure = 1, t.info.autoReset = !1, t.setPixelRatio(window.devicePixelRatio), t.setAnimationLoop(this.animate), this.el.appendChild(t.domElement), t;
639
1131
  }
640
1132
  createScene() {
641
- const e = new it();
642
- return e.background = new V(0), e;
1133
+ const e = new Re();
1134
+ return e.background = new B(0), e;
643
1135
  }
644
1136
  createPerspectiveCamera() {
645
- const e = new K(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);
1137
+ const e = new J(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);
646
1138
  return e.position.setScalar(5), e;
647
1139
  }
648
1140
  createOrthographicCamera() {
649
- const e = new Q(
1141
+ const e = new V(
650
1142
  -this.el.clientWidth / 2,
651
1143
  this.el.clientWidth / 2,
652
1144
  this.el.clientHeight / 2,
@@ -656,251 +1148,310 @@ class ei extends Ze {
656
1148
  );
657
1149
  return e.position.setScalar(5), e;
658
1150
  }
1151
+ /**
1152
+ * Manually trigger a resize update.
1153
+ */
1154
+ resize(e, t) {
1155
+ e !== void 0 && t !== void 0 && (this.el.style.width = `${e}px`, this.el.style.height = `${t}px`), this.onWindowResize();
1156
+ }
1157
+ /**
1158
+ * Capture a screenshot of the current render.
1159
+ */
1160
+ async screenshot(e = {}) {
1161
+ const { type: t = "image/png", quality: s = 1 } = e, n = this.el.clientWidth, i = this.el.clientHeight, r = e.width && e.height;
1162
+ r && this.renderer.setSize(e.width, e.height), await this.render();
1163
+ const o = this.renderer.domElement.toDataURL(t, s);
1164
+ return r && (this.renderer.setSize(n, i), this.onWindowResize()), o;
1165
+ }
1166
+ /**
1167
+ * Set the scene background color, texture, or null.
1168
+ */
1169
+ setBackground(e) {
1170
+ e === null ? this.scene.background = null : e instanceof B || typeof e == "number" || typeof e == "string" ? this.scene.background = new B(e) : this.scene.background = e, this.render();
1171
+ }
1172
+ /**
1173
+ * Set the scene environment map for reflections / IBL.
1174
+ */
1175
+ setEnvironment(e) {
1176
+ this.scene.environment = e, this.render();
1177
+ }
1178
+ /**
1179
+ * Enable shadow rendering.
1180
+ */
1181
+ enableShadow() {
1182
+ this.renderer.shadowMap.enabled = !0, this.render();
1183
+ }
1184
+ /**
1185
+ * Disable shadow rendering.
1186
+ */
1187
+ disableShadow() {
1188
+ this.renderer.shadowMap.enabled = !1, this.render();
1189
+ }
1190
+ /**
1191
+ * Enable linear fog.
1192
+ */
1193
+ enableFog(e = {}) {
1194
+ const { color: t = 13421772, near: s = 10, far: n = 100 } = e;
1195
+ this.scene.fog = new wt(t, s, n), this.render();
1196
+ }
1197
+ /**
1198
+ * Enable exponential fog.
1199
+ */
1200
+ enableFogExp2(e = {}) {
1201
+ const { color: t = 13421772, density: s = 0.01 } = e;
1202
+ this.scene.fog = new bt(t, s), this.render();
1203
+ }
1204
+ /**
1205
+ * Disable fog.
1206
+ */
1207
+ disableFog() {
1208
+ this.scene.fog = null, this.render();
1209
+ }
659
1210
  dispose() {
660
1211
  this.el.removeChild(this.renderer.domElement), window.removeEventListener("resize", this.onWindowResize), this.info.dispose(), this.interactionManager.dispose(), this.roomEnvironment.dispose(), this.cssRenderer.dispose(), this.renderPipeline.dispose(), this.renderer.dispose();
661
1212
  }
662
1213
  }
663
- class ls extends Le {
1214
+ class Es extends Fe {
664
1215
  constructor(e) {
665
1216
  super(e);
666
1217
  }
667
- parse(e, t, s, i) {
668
- if (ds(e.slice(0, 8)) === "SBMG----") {
669
- const r = ps(e.slice(8));
670
- return super.parse(r, t, s, i);
1218
+ parse(e, t, s, n) {
1219
+ if (Os(e.slice(0, 8)) === "SBMG----") {
1220
+ const r = As(e.slice(8));
1221
+ return super.parse(r, t, s, n);
671
1222
  } else
672
- return super.parse(e, t, s, i);
1223
+ return super.parse(e, t, s, n);
673
1224
  }
674
1225
  }
675
- function ds(a) {
676
- return new TextDecoder().decode(new Uint8Array(a));
1226
+ function Os(l) {
1227
+ return new TextDecoder().decode(new Uint8Array(l));
677
1228
  }
678
- function ps(a) {
679
- const e = new DataView(a);
1229
+ function As(l) {
1230
+ const e = new DataView(l);
680
1231
  for (let t = 0; t < e.byteLength; t++) {
681
- const s = e.getUint8(t), i = (s >> 4 & 15) + (s << 4 & 240);
682
- e.setUint8(t, i);
1232
+ const s = e.getUint8(t), n = (s >> 4 & 15) + (s << 4 & 240);
1233
+ e.setUint8(t, n);
683
1234
  }
684
1235
  return e.buffer;
685
1236
  }
686
- const us = 8, ms = 130, ye = 66, gs = "SBK-----", fs = "SBM-----", Ne = new TextDecoder(), ys = new TextEncoder();
687
- function ws(a) {
688
- let e = us;
689
- const t = new Uint8Array(a, 0, e);
690
- if (Ne.decode(t) !== gs)
691
- return a;
692
- e += ms;
693
- const i = new Uint8Array(a, 0, e);
694
- if (i[40] === 1) {
695
- const r = ys.encode(fs), o = new Uint8Array([i[41]]), c = vs(i), h = bs(c);
696
- let l = ye % h.length;
697
- const d = e + ye, g = new Uint8Array(a, d), p = new Uint8Array(g.length);
698
- for (let v = 0; v < g.length; v++)
699
- p[v] = g[v] ^ h[l], l = (l + 1) % h.length;
700
- const y = new Uint8Array(r.length + o.length + p.length);
701
- return y.set(r), y.set(o, r.length), y.set(p, r.length + o.length), y.buffer;
1237
+ const Bs = 8, Ls = 130, Te = 66, Is = "SBK-----", Rs = "SBM-----", $e = new TextDecoder(), zs = new TextEncoder();
1238
+ function Ns(l) {
1239
+ let e = Bs;
1240
+ const t = new Uint8Array(l, 0, e);
1241
+ if ($e.decode(t) !== Is)
1242
+ return l;
1243
+ e += Ls;
1244
+ const n = new Uint8Array(l, 0, e);
1245
+ if (n[40] === 1) {
1246
+ const r = zs.encode(Rs), o = new Uint8Array([n[41]]), a = js(n), c = Ds(a);
1247
+ let h = Te % c.length;
1248
+ const d = e + Te, p = new Uint8Array(l, d), u = new Uint8Array(p.length);
1249
+ for (let b = 0; b < p.length; b++)
1250
+ u[b] = p[b] ^ c[h], h = (h + 1) % c.length;
1251
+ const g = new Uint8Array(r.length + o.length + u.length);
1252
+ return g.set(r), g.set(o, r.length), g.set(u, r.length + o.length), g.buffer;
702
1253
  }
703
1254
  }
704
- function vs(a) {
1255
+ function js(l) {
705
1256
  const e = new Uint8Array(128);
706
- return e.set(a.slice(42, 74), 0), e.set(a.slice(74, 138), 32), e.set(a.slice(8, 40), 96), e;
1257
+ return e.set(l.slice(42, 74), 0), e.set(l.slice(74, 138), 32), e.set(l.slice(8, 40), 96), e;
707
1258
  }
708
- function bs(a) {
1259
+ function Ds(l) {
709
1260
  const e = new Uint8Array(64);
710
- return e.set(a.slice(0, 8), 0), e.set(a.slice(24, 32), 8), e.set(a.slice(40, 56), 16), e.set(a.slice(64, 88), 32), e.set(a.slice(96, 104), 56), e;
1261
+ return e.set(l.slice(0, 8), 0), e.set(l.slice(24, 32), 8), e.set(l.slice(40, 56), 16), e.set(l.slice(64, 88), 32), e.set(l.slice(96, 104), 56), e;
711
1262
  }
712
- const Cs = (a, e, t) => {
713
- const s = a.buffer.slice(t, t + e);
714
- let i = Ne.decode(s);
715
- return i = i.replace("\\", "/"), i.startsWith("Maps/") || (i = `Maps/${i}`), i;
716
- }, Ts = (a, e, t) => {
717
- const [s, i, n, r, o] = e, c = t || r < 1;
718
- return new L({
719
- name: a,
720
- color: new V(s, i, n),
1263
+ const ks = (l, e, t) => {
1264
+ const s = l.buffer.slice(t, t + e);
1265
+ let n = $e.decode(s);
1266
+ return n = n.replace("\\", "/"), n.startsWith("Maps/") || (n = `Maps/${n}`), n;
1267
+ }, Hs = (l, e, t) => {
1268
+ const [s, n, i, r, o] = e, a = t || r < 1;
1269
+ return new R({
1270
+ name: l,
1271
+ color: new B(s, n, i),
721
1272
  opacity: r,
722
- transparent: c,
1273
+ transparent: a,
723
1274
  alphaTest: 0.01,
724
1275
  side: o
725
1276
  });
726
- }, Ss = (a) => a?.toLowerCase().endsWith(".png") ?? !1;
727
- class xs {
1277
+ }, Us = (l) => l?.toLowerCase().endsWith(".png") ?? !1;
1278
+ class Fs {
728
1279
  data;
729
1280
  options;
730
1281
  textureLoader;
731
1282
  littleEndian = !0;
732
1283
  materials = /* @__PURE__ */ new Map();
733
1284
  constructor(e, t) {
734
- this.data = e, this.options = t, this.textureLoader = new Me(t.manager), this.textureLoader.setCrossOrigin(t.crossOrigin), this.textureLoader.setRequestHeader(t.requestHeader);
1285
+ this.data = e, this.options = t, this.textureLoader = new je(t.manager), this.textureLoader.setCrossOrigin(t.crossOrigin), this.textureLoader.setRequestHeader(t.requestHeader);
735
1286
  }
736
1287
  parse(e, t) {
737
1288
  let s = this.data;
738
- const i = ws(this.data);
739
- i && (s = i);
740
- const n = new DataView(s);
1289
+ const n = Ns(this.data);
1290
+ n && (s = n);
1291
+ const i = new DataView(s);
741
1292
  let r = 8;
742
- const o = n.getUint8(r);
743
- r += 1, o === 1 ? this._parseV2(n, r, e) : o === 2 ? this._parseV2(n, r, e) : o === 3 ? this._parseV3(n, r, e) : t?.(new Error(`SBMLoader: Unsupported SBM version: ${o}`));
1293
+ const o = i.getUint8(r);
1294
+ r += 1, o === 1 ? this._parseV2(i, r, e) : o === 2 ? this._parseV2(i, r, e) : o === 3 ? this._parseV3(i, r, e) : t?.(new Error(`SBMLoader: Unsupported SBM version: ${o}`));
744
1295
  }
745
1296
  _parseV2(e, t, s) {
746
- const i = new ee(), n = e.getUint16(t, this.littleEndian);
1297
+ const n = new I(), i = e.getUint16(t, this.littleEndian);
747
1298
  t += 2;
748
1299
  const r = e.getUint16(t, this.littleEndian);
749
1300
  t += 2;
750
- for (let o = 0; o < n; ++o) {
751
- const c = e.getUint16(t, this.littleEndian).toString();
1301
+ for (let o = 0; o < i; ++o) {
1302
+ const a = e.getUint16(t, this.littleEndian).toString();
752
1303
  t += 2, t += 4, t += 4, t += 4, t += 4;
753
- const h = e.getFloat32(t, this.littleEndian);
1304
+ const c = e.getFloat32(t, this.littleEndian);
754
1305
  t += 4;
755
- const l = e.getFloat32(t, this.littleEndian);
1306
+ const h = e.getFloat32(t, this.littleEndian);
756
1307
  t += 4;
757
1308
  const d = e.getFloat32(t, this.littleEndian);
758
1309
  t += 4;
759
- const g = e.getFloat32(t, this.littleEndian);
1310
+ const p = e.getFloat32(t, this.littleEndian);
760
1311
  t += 4, t += 4, t += 4, t += 4, t += 4;
761
- let p = e.getUint8(t);
762
- t += 1, p === 0 ? p = at : p === 1 ? p = ot : p === 2 && (p = ct);
763
- const y = e.getUint16(t, this.littleEndian);
1312
+ let u = e.getUint8(t);
1313
+ t += 1, u === 0 ? u = xt : u === 1 ? u = St : u === 2 && (u = Ct);
1314
+ const g = e.getUint16(t, this.littleEndian);
764
1315
  t += 2;
765
- const v = y > 0 ? Cs(e, y, t) : "";
766
- if (t += y, !this.materials.has(c)) {
767
- const b = Ts(c, [h, l, d, g, p], Ss(v));
768
- this.materials.set(c, b), v && this.options.path && this.textureLoader.load(I.resolveURL(v, this.options.path), (f) => {
769
- f.colorSpace = Pe, f.wrapS = ce, f.wrapT = ce, f.flipY = !1, f.anisotropy = 16, b.map = f;
1316
+ const b = g > 0 ? ks(e, g, t) : "";
1317
+ if (t += g, !this.materials.has(a)) {
1318
+ const x = Hs(a, [c, h, d, p, u], Us(b));
1319
+ this.materials.set(a, x), b && this.options.path && this.textureLoader.load(L.resolveURL(b, this.options.path), (y) => {
1320
+ y.colorSpace = De, y.wrapS = ye, y.wrapT = ye, y.flipY = !1, y.anisotropy = 16, x.map = y;
770
1321
  });
771
1322
  }
772
1323
  }
773
1324
  for (let o = 0; o < r; ++o) {
774
- const c = e.getUint16(t, this.littleEndian).toString();
1325
+ const a = e.getUint16(t, this.littleEndian).toString();
775
1326
  t += 2;
776
- const h = e.getUint16(t, this.littleEndian).toString();
1327
+ const c = e.getUint16(t, this.littleEndian).toString();
777
1328
  t += 2;
778
- const l = [], d = [], g = [], p = [], y = e.getUint16(t, this.littleEndian);
779
- if (t += 2, y > 0)
780
- for (let m = 0; m < y; m++) {
781
- const w = new oe();
782
- w.setX(e.getFloat32(t, this.littleEndian)), t += 4, w.setY(e.getFloat32(t, this.littleEndian)), t += 4, w.setZ(e.getFloat32(t, this.littleEndian)), t += 4, l.push(w);
783
- }
784
- const v = e.getUint16(t, this.littleEndian);
785
- if (t += 2, v > 0)
786
- for (let m = 0; m < v; m++)
787
- t += 4, t += 4, t += 4;
788
- const S = e.getUint16(t, this.littleEndian);
789
- if (t += 2, S > 0)
790
- for (let m = 0; m < S; m++) {
791
- const w = new R();
792
- w.setX(e.getFloat32(t, this.littleEndian)), t += 4, w.setY(e.getFloat32(t, this.littleEndian)), t += 4, d.push(w);
1329
+ const h = [], d = [], p = [], u = [], g = e.getUint16(t, this.littleEndian);
1330
+ if (t += 2, g > 0)
1331
+ for (let f = 0; f < g; f++) {
1332
+ const v = new w();
1333
+ v.setX(e.getFloat32(t, this.littleEndian)), t += 4, v.setY(e.getFloat32(t, this.littleEndian)), t += 4, v.setZ(e.getFloat32(t, this.littleEndian)), t += 4, h.push(v);
793
1334
  }
794
1335
  const b = e.getUint16(t, this.littleEndian);
795
1336
  if (t += 2, b > 0)
796
- for (let m = 0; m < b; m++) {
797
- const w = e.getUint16(t, this.littleEndian);
1337
+ for (let f = 0; f < b; f++)
1338
+ t += 4, t += 4, t += 4;
1339
+ const _ = e.getUint16(t, this.littleEndian);
1340
+ if (t += 2, _ > 0)
1341
+ for (let f = 0; f < _; f++) {
1342
+ const v = new S();
1343
+ v.setX(e.getFloat32(t, this.littleEndian)), t += 4, v.setY(e.getFloat32(t, this.littleEndian)), t += 4, d.push(v);
1344
+ }
1345
+ const x = e.getUint16(t, this.littleEndian);
1346
+ if (t += 2, x > 0)
1347
+ for (let f = 0; f < x; f++) {
1348
+ const v = e.getUint16(t, this.littleEndian);
798
1349
  t += 2;
799
- const A = e.getUint16(t, this.littleEndian);
1350
+ const z = e.getUint16(t, this.littleEndian);
800
1351
  t += 2;
801
1352
  const N = e.getUint16(t, this.littleEndian);
802
1353
  t += 2;
803
- const E = [w, A, N];
804
- g.push(E), d.length > 0 && p.push([d[E[0]], d[E[1]], d[E[2]]]);
1354
+ const P = [v, z, N];
1355
+ p.push(P), d.length > 0 && u.push([d[P[0]], d[P[1]], d[P[2]]]);
805
1356
  }
806
- const f = [], T = [];
807
- for (let m = 0; m < g.length; m++) {
808
- const w = g[m], A = l[w[0]], N = l[w[1]], E = l[w[2]];
809
- f.push(...A.toArray(), ...N.toArray(), ...E.toArray());
810
- let H = new R(), G = new R(), _ = new R();
811
- const D = p[m];
812
- D !== void 0 && (H = D[0], G = D[1], _ = D[2]), T.push(...H.toArray(), ...G.toArray(), ..._.toArray());
1357
+ const y = [], M = [];
1358
+ for (let f = 0; f < p.length; f++) {
1359
+ const v = p[f], z = h[v[0]], N = h[v[1]], P = h[v[2]];
1360
+ y.push(...z.toArray(), ...N.toArray(), ...P.toArray());
1361
+ let X = new S(), W = new S(), D = new S();
1362
+ const k = u[f];
1363
+ k !== void 0 && (X = k[0], W = k[1], D = k[2]), M.push(...X.toArray(), ...W.toArray(), ...D.toArray());
813
1364
  }
814
- const M = new Float32Array(f), P = new Float32Array(T), x = new rt();
815
- if (M.length > 0 && x.setAttribute("position", new he(M, 3)), P.length > 0 && x.setAttribute("uv", new he(P, 2)), x.computeVertexNormals(), this.materials.has(h)) {
816
- const m = new z(x, this.materials.get(h));
817
- m.name = c, m.castShadow = !0, m.receiveShadow = !0, i.add(m);
1365
+ const E = new Float32Array(y), O = new Float32Array(M), T = new K();
1366
+ if (E.length > 0 && T.setAttribute("position", new we(E, 3)), O.length > 0 && T.setAttribute("uv", new we(O, 2)), T.computeVertexNormals(), this.materials.has(c)) {
1367
+ const f = new G(T, this.materials.get(c));
1368
+ f.name = a, f.castShadow = !0, f.receiveShadow = !0, n.add(f);
818
1369
  }
819
1370
  }
820
- s(i);
1371
+ s(n);
821
1372
  }
822
1373
  _parseV3(e, t, s) {
823
- const i = new ee();
824
- console.warn("SBMLoader: SBM version 3 is not supported yet."), s(i);
1374
+ const n = new I();
1375
+ console.warn("SBMLoader: SBM version 3 is not supported yet."), s(n);
825
1376
  }
826
1377
  }
827
- class Es extends nt {
828
- load(e, t, s, i) {
829
- let n;
1378
+ class Gs extends vt {
1379
+ load(e, t, s, n) {
1380
+ let i;
830
1381
  if (this.resourcePath !== "")
831
- n = this.resourcePath;
1382
+ i = this.resourcePath;
832
1383
  else if (this.path !== "") {
833
- const c = I.extractUrlBase(e);
834
- n = I.resolveURL(c, this.path);
1384
+ const a = L.extractUrlBase(e);
1385
+ i = L.resolveURL(a, this.path);
835
1386
  } else
836
- n = I.extractUrlBase(e);
1387
+ i = L.extractUrlBase(e);
837
1388
  this.manager.itemStart(e);
838
- const r = (c) => {
839
- i ? i(c) : console.error(c), this.manager.itemError(e), this.manager.itemEnd(e);
840
- }, o = new Ee(this.manager);
1389
+ const r = (a) => {
1390
+ n ? n(a) : console.error(a), this.manager.itemError(e), this.manager.itemEnd(e);
1391
+ }, o = new Ne(this.manager);
841
1392
  o.setPath(this.path), o.setResponseType("arraybuffer"), o.setRequestHeader(this.requestHeader), o.setWithCredentials(this.withCredentials), o.load(
842
1393
  e,
843
- (c) => {
1394
+ (a) => {
844
1395
  try {
845
1396
  this.parse(
846
- c,
847
- n,
848
- (h) => {
849
- t(h), this.manager.itemEnd(e);
1397
+ a,
1398
+ i,
1399
+ (c) => {
1400
+ t(c), this.manager.itemEnd(e);
850
1401
  },
851
1402
  r
852
1403
  );
853
- } catch (h) {
854
- r(h);
1404
+ } catch (c) {
1405
+ r(c);
855
1406
  }
856
1407
  },
857
1408
  s,
858
1409
  r
859
1410
  );
860
1411
  }
861
- parse(e, t, s, i) {
862
- const n = new TextDecoder().decode(e.slice(0, 8));
863
- if (n !== "SBK-----" && n !== "SBM-----") {
864
- i?.(new Error(`SBMLoader: Invalid SBM format: ${n}`));
1412
+ parse(e, t, s, n) {
1413
+ const i = new TextDecoder().decode(e.slice(0, 8));
1414
+ if (i !== "SBK-----" && i !== "SBM-----") {
1415
+ n?.(new Error(`SBMLoader: Invalid SBM format: ${i}`));
865
1416
  return;
866
1417
  }
867
- new xs(e, {
1418
+ new Fs(e, {
868
1419
  path: t,
869
1420
  crossOrigin: this.crossOrigin,
870
1421
  requestHeader: this.requestHeader,
871
1422
  manager: this.manager
872
- }).parse(s, i);
1423
+ }).parse(s, n);
873
1424
  }
874
1425
  parseAsync(e, t) {
875
- return new Promise((s, i) => {
1426
+ return new Promise((s, n) => {
876
1427
  this.parse(
877
1428
  e,
878
1429
  t,
879
- (n) => {
880
- s(n);
1430
+ (i) => {
1431
+ s(i);
881
1432
  },
882
- (n) => {
883
- i(n);
1433
+ (i) => {
1434
+ n(i);
884
1435
  }
885
1436
  );
886
1437
  });
887
1438
  }
888
1439
  }
889
- class B {
1440
+ class j {
890
1441
  static CACHE_NAME = "u-space-model-loader-cache";
891
- static fileLoader = new Ee().setResponseType("arraybuffer");
892
- static dracoLoader = new Kt().setDecoderPath(
893
- `https://cdn.jsdelivr.net/npm/three@0.${le}.0/examples/jsm/libs/draco/`
1442
+ static fileLoader = new Ne().setResponseType("arraybuffer");
1443
+ static dracoLoader = new ls().setDecoderPath(
1444
+ `https://cdn.jsdelivr.net/npm/three@0.${be}.0/examples/jsm/libs/draco/`
894
1445
  );
895
- static ktx2Loader = new Qt().setTranscoderPath(
896
- `https://cdn.jsdelivr.net/npm/three@0.${le}.0/examples/jsm/libs/basis/`
1446
+ static ktx2Loader = new ds().setTranscoderPath(
1447
+ `https://cdn.jsdelivr.net/npm/three@0.${be}.0/examples/jsm/libs/basis/`
897
1448
  );
898
- static gltfLoader = new Le().setDRACOLoader(B.dracoLoader).setKTX2Loader(B.ktx2Loader).setMeshoptDecoder(ge);
899
- static sbmxLoader = new ls().setDRACOLoader(B.dracoLoader).setKTX2Loader(B.ktx2Loader).setMeshoptDecoder(ge);
900
- static sbmLoader = new Es();
901
- static fbxLoader = new Ht();
902
- static objLoader = new $t();
903
- static stlLoader = new Wt();
1449
+ static gltfLoader = new Fe().setDRACOLoader(j.dracoLoader).setKTX2Loader(j.ktx2Loader).setMeshoptDecoder(_e);
1450
+ static sbmxLoader = new Es().setDRACOLoader(j.dracoLoader).setKTX2Loader(j.ktx2Loader).setMeshoptDecoder(_e);
1451
+ static sbmLoader = new Gs();
1452
+ static fbxLoader = new as();
1453
+ static objLoader = new cs();
1454
+ static stlLoader = new hs();
904
1455
  static setLoadingManager(e) {
905
1456
  this.fileLoader.manager = e, this.dracoLoader.manager = e, this.ktx2Loader.manager = e, this.gltfLoader.manager = e, this.sbmxLoader.manager = e, this.sbmLoader.manager = e, this.fbxLoader.manager = e, this.objLoader.manager = e, this.stlLoader.manager = e;
906
1457
  }
@@ -924,25 +1475,25 @@ class B {
924
1475
  }
925
1476
  static async loadAsync(e, t = { persistent: !0 }) {
926
1477
  const s = e.split(".").pop()?.split("?")[0].toLowerCase();
927
- let i;
928
- switch (t.persistent && typeof caches < "u" ? i = await this.getPersistentData(e) : i = await this.fileLoader.loadAsync(e), s) {
1478
+ let n;
1479
+ switch (t.persistent && typeof caches < "u" ? n = await this.getPersistentData(e) : n = await this.fileLoader.loadAsync(e), s) {
929
1480
  case "gltf":
930
1481
  case "glb":
931
- const n = await this.gltfLoader.parseAsync(i, I.extractUrlBase(e));
932
- return n.scene.animations = n.animations, n.scene;
1482
+ const i = await this.gltfLoader.parseAsync(n, L.extractUrlBase(e));
1483
+ return i.scene.animations = i.animations, i.scene;
933
1484
  case "sbmx":
934
- const r = await this.sbmxLoader.parseAsync(i, I.extractUrlBase(e));
1485
+ const r = await this.sbmxLoader.parseAsync(n, L.extractUrlBase(e));
935
1486
  return r.scene.animations = r.animations, r.scene;
936
1487
  case "sbm":
937
- return await this.sbmLoader.parseAsync(i, I.extractUrlBase(e));
1488
+ return await this.sbmLoader.parseAsync(n, L.extractUrlBase(e));
938
1489
  case "fbx":
939
- return this.fbxLoader.parse(i, I.extractUrlBase(e));
1490
+ return this.fbxLoader.parse(n, L.extractUrlBase(e));
940
1491
  case "obj":
941
- const h = new TextDecoder().decode(i);
942
- return this.objLoader.parse(h);
1492
+ const c = new TextDecoder().decode(n);
1493
+ return this.objLoader.parse(c);
943
1494
  case "stl":
944
- const d = this.stlLoader.parse(i);
945
- return new z(d, new L());
1495
+ const d = this.stlLoader.parse(n);
1496
+ return new G(d, new R());
946
1497
  default:
947
1498
  throw new Error(`Unsupported model format: ${s}`);
948
1499
  }
@@ -952,17 +1503,17 @@ class B {
952
1503
  const t = await caches.open(this.CACHE_NAME), s = await t.match(e);
953
1504
  if (s)
954
1505
  return await s.arrayBuffer();
955
- const i = await this.fileLoader.loadAsync(e), n = new Response(i);
956
- return await t.put(e, n), i;
1506
+ const n = await this.fileLoader.loadAsync(e), i = new Response(n);
1507
+ return await t.put(e, i), n;
957
1508
  } catch (t) {
958
1509
  return console.warn(`[LoaderManager] Failed to use Cache API for ${e}:`, t), await this.fileLoader.loadAsync(e);
959
1510
  }
960
1511
  }
961
1512
  }
962
- class ti {
963
- static textureLoader = new Me();
964
- static hdrLoader = new Xt();
965
- static cubeTextureLoader = new ht();
1513
+ class Cn {
1514
+ static textureLoader = new je();
1515
+ static hdrLoader = new ps();
1516
+ static cubeTextureLoader = new _t();
966
1517
  static setLoadingManager(e) {
967
1518
  this.textureLoader.manager = e, this.hdrLoader.manager = e, this.cubeTextureLoader.manager = e;
968
1519
  }
@@ -971,13 +1522,13 @@ class ti {
971
1522
  }
972
1523
  static async loadAsyncHDR(e) {
973
1524
  const t = await this.hdrLoader.loadAsync(e);
974
- return t.mapping = lt, t;
1525
+ return t.mapping = Mt, t;
975
1526
  }
976
1527
  static async loadAsyncCubeTexture(e, t) {
977
1528
  return this.cubeTextureLoader.setPath(e), await this.cubeTextureLoader.loadAsync(t);
978
1529
  }
979
1530
  }
980
- class k extends z {
1531
+ class $ extends G {
981
1532
  isBaseMesh = !0;
982
1533
  type = "BaseMesh";
983
1534
  ignoreInvisibleWhenRaycast = !0;
@@ -988,7 +1539,7 @@ class k extends z {
988
1539
  return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
989
1540
  }
990
1541
  }
991
- class Be extends ee {
1542
+ class We extends I {
992
1543
  isBaseGroup = !0;
993
1544
  type = "BaseGroup";
994
1545
  ignoreInvisibleWhenRaycast = !0;
@@ -999,7 +1550,7 @@ class Be extends ee {
999
1550
  return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
1000
1551
  }
1001
1552
  }
1002
- class Ms extends dt {
1553
+ class $s extends Tt {
1003
1554
  isBaseSprite = !0;
1004
1555
  type = "BaseSprite";
1005
1556
  ignoreInvisibleWhenRaycast = !0;
@@ -1010,7 +1561,7 @@ class Ms extends dt {
1010
1561
  return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
1011
1562
  }
1012
1563
  }
1013
- class Z extends Be {
1564
+ class re extends We {
1014
1565
  isModel = !0;
1015
1566
  type = "Model";
1016
1567
  static memoryCache = /* @__PURE__ */ new Map();
@@ -1021,24 +1572,24 @@ class Z extends Be {
1021
1572
  super();
1022
1573
  }
1023
1574
  async loadAsync(e) {
1024
- const { url: t, cache: s = !0, persistent: i = !0 } = e;
1575
+ const { url: t, cache: s = !0, persistent: n = !0 } = e;
1025
1576
  try {
1026
- let n;
1027
- s ? Z.memoryCache.has(t) ? n = Z.memoryCache.get(t) : (n = B.loadAsync(t, { persistent: i }), Z.memoryCache.set(t, n)) : n = B.loadAsync(t, { persistent: i });
1028
- const r = await n, o = qt(r);
1029
- return this.add(o), o.animations && o.animations.length > 0 && (this.animations = o.animations, this.mixer = new pt(o)), o;
1030
- } catch (n) {
1031
- return console.error(`[Model] Failed to load model from ${t}:`, n), null;
1577
+ let i;
1578
+ s ? re.memoryCache.has(t) ? i = re.memoryCache.get(t) : (i = j.loadAsync(t, { persistent: n }), re.memoryCache.set(t, i)) : i = j.loadAsync(t, { persistent: n });
1579
+ const r = await i, o = us(r);
1580
+ return this.add(o), o.animations && o.animations.length > 0 && (this.animations = o.animations, this.mixer = new Pt(o)), o;
1581
+ } catch (i) {
1582
+ return console.error(`[Model] Failed to load model from ${t}:`, i), null;
1032
1583
  }
1033
1584
  }
1034
1585
  playAnimation(e, t = {}) {
1035
1586
  if (!this.mixer || this.animations.length === 0) return null;
1036
- const { loop: s = !0, repetitions: i = 1 / 0, timeScale: n = 1, clampWhenFinished: r = !1 } = t;
1587
+ const { loop: s = !0, repetitions: n = 1 / 0, timeScale: i = 1, clampWhenFinished: r = !1 } = t;
1037
1588
  let o;
1038
- if (e === void 0 ? o = this.animations[0] : typeof e == "number" ? o = this.animations[e] : o = this.animations.find((h) => h.name === e), !o)
1589
+ if (e === void 0 ? o = this.animations[0] : typeof e == "number" ? o = this.animations[e] : o = this.animations.find((c) => c.name === e), !o)
1039
1590
  return console.warn(`[Model] Animation not found: ${e}`), null;
1040
- let c = this.actions.get(o.name);
1041
- return c || (c = this.mixer.clipAction(o), this.actions.set(o.name, c)), c.setLoop(s ? ut : mt, i), c.clampWhenFinished = r, c.timeScale = n, c.reset().play(), c;
1591
+ let a = this.actions.get(o.name);
1592
+ return a || (a = this.mixer.clipAction(o), this.actions.set(o.name, a)), a.setLoop(s ? Et : Ot, n), a.clampWhenFinished = r, a.timeScale = i, a.reset().play(), a;
1042
1593
  }
1043
1594
  playAllAnimations(e = {}) {
1044
1595
  return this.animations.map((t, s) => this.playAnimation(s, e)).filter((t) => t !== null);
@@ -1055,6 +1606,27 @@ class Z extends Be {
1055
1606
  updateAnimation(e) {
1056
1607
  this.mixer?.update(e);
1057
1608
  }
1609
+ /**
1610
+ * Get the axis-aligned bounding box of this model.
1611
+ */
1612
+ getBoundingBox() {
1613
+ return new q().setFromObject(this);
1614
+ }
1615
+ /**
1616
+ * Get the center point of this model's bounding box.
1617
+ */
1618
+ getCenter() {
1619
+ const e = new w();
1620
+ return this.getBoundingBox().getCenter(e), e;
1621
+ }
1622
+ /**
1623
+ * Set the material for all meshes in this model.
1624
+ */
1625
+ setMaterial(e) {
1626
+ this.traverse((t) => {
1627
+ t instanceof G && (t.material = e);
1628
+ });
1629
+ }
1058
1630
  static clearMemoryCache() {
1059
1631
  this.memoryCache.clear();
1060
1632
  }
@@ -1062,11 +1634,11 @@ class Z extends Be {
1062
1634
  typeof caches < "u" && await caches.delete("u-space-loader-cache");
1063
1635
  }
1064
1636
  }
1065
- class Ps extends k {
1637
+ class Ws extends $ {
1066
1638
  isSphereMesh = !0;
1067
1639
  type = "SphereMesh";
1068
1640
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1069
- super(), this.geometry = new gt(
1641
+ super(), this.geometry = new At(
1070
1642
  e?.radius,
1071
1643
  e?.widthSegments,
1072
1644
  e?.heightSegments,
@@ -1074,23 +1646,23 @@ class Ps extends k {
1074
1646
  e?.phiLength,
1075
1647
  e?.thetaStart,
1076
1648
  e?.thetaLength
1077
- ), this.material = new L(t);
1649
+ ), this.material = new R(t);
1078
1650
  }
1079
1651
  }
1080
- class we extends k {
1652
+ class Pe extends $ {
1081
1653
  isTubeMesh = !0;
1082
1654
  type = "TubeMesh";
1083
1655
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1084
- super(), this.geometry = new ft(
1656
+ super(), this.geometry = new Bt(
1085
1657
  e?.path,
1086
1658
  e?.tubularSegments,
1087
1659
  e?.radius,
1088
1660
  e?.radialSegments,
1089
1661
  e?.closed
1090
- ), this.material = new L(t);
1662
+ ), this.material = new R(t);
1091
1663
  }
1092
1664
  }
1093
- class si extends Be {
1665
+ class _n extends We {
1094
1666
  isTopology = !0;
1095
1667
  type = "Topology";
1096
1668
  // Visuals
@@ -1135,14 +1707,14 @@ class si extends Be {
1135
1707
  * @param weight Cost of the edge. Defaults to Euclidean distance.
1136
1708
  * @param bidirectional If true, adds the reverse edge as well. Default true.
1137
1709
  */
1138
- addEdge(e, t, s, i = !0) {
1139
- const n = this.nodes.get(e), r = this.nodes.get(t);
1140
- if (!n || !r) {
1710
+ addEdge(e, t, s, n = !0) {
1711
+ const i = this.nodes.get(e), r = this.nodes.get(t);
1712
+ if (!i || !r) {
1141
1713
  console.error(`[Topology] Cannot add edge. One or both nodes not found: ${e}, ${t}`);
1142
1714
  return;
1143
1715
  }
1144
- const o = s ?? n.distanceTo(r);
1145
- this.getNeighbors(e)?.set(t, o), i && this.getNeighbors(t)?.set(e, o);
1716
+ const o = s ?? i.distanceTo(r);
1717
+ this.getNeighbors(e)?.set(t, o), n && this.getNeighbors(t)?.set(e, o);
1146
1718
  }
1147
1719
  /**
1148
1720
  * Remove an edge between two nodes.
@@ -1159,33 +1731,33 @@ class si extends Be {
1159
1731
  getShortestPath(e, t) {
1160
1732
  if (!this.nodes.has(e) || !this.nodes.has(t))
1161
1733
  return console.warn("[Topology] Start or End node not found."), [];
1162
- const s = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set();
1163
- for (const [c] of this.nodes)
1164
- s.set(c, 1 / 0), i.set(c, null), n.add(c);
1165
- for (s.set(e, 0); n.size > 0; ) {
1166
- let c = null, h = 1 / 0;
1167
- for (const d of n) {
1168
- const g = s.get(d);
1169
- g < h && (h = g, c = d);
1734
+ const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set();
1735
+ for (const [a] of this.nodes)
1736
+ s.set(a, 1 / 0), n.set(a, null), i.add(a);
1737
+ for (s.set(e, 0); i.size > 0; ) {
1738
+ let a = null, c = 1 / 0;
1739
+ for (const d of i) {
1740
+ const p = s.get(d);
1741
+ p < c && (c = p, a = d);
1170
1742
  }
1171
- if (c === null || c === t || h === 1 / 0)
1743
+ if (a === null || a === t || c === 1 / 0)
1172
1744
  break;
1173
- n.delete(c);
1174
- const l = this.adjacencyMap?.get(c);
1175
- if (l)
1176
- for (const [d, g] of l) {
1177
- if (!n.has(d)) continue;
1178
- const p = s.get(c) + g;
1179
- p < s.get(d) && (s.set(d, p), i.set(d, c));
1745
+ i.delete(a);
1746
+ const h = this.adjacencyMap?.get(a);
1747
+ if (h)
1748
+ for (const [d, p] of h) {
1749
+ if (!i.has(d)) continue;
1750
+ const u = s.get(a) + p;
1751
+ u < s.get(d) && (s.set(d, u), n.set(d, a));
1180
1752
  }
1181
1753
  }
1182
1754
  const r = [];
1183
1755
  let o = t;
1184
- if (i.get(t) === null && e !== t)
1756
+ if (n.get(t) === null && e !== t)
1185
1757
  return [];
1186
1758
  for (; o !== null; ) {
1187
- const c = this.nodes.get(o);
1188
- c && r.unshift(c), o = i.get(o) || null;
1759
+ const a = this.nodes.get(o);
1760
+ a && r.unshift(a), o = n.get(o) || null;
1189
1761
  }
1190
1762
  return r;
1191
1763
  }
@@ -1193,8 +1765,8 @@ class si extends Be {
1193
1765
  * Renders the entire topology graph structure using TubeGeometry and Spheres.
1194
1766
  */
1195
1767
  renderGraph() {
1196
- this.clearGraph(), this.graphGroup = new ee();
1197
- const e = new Ps({
1768
+ this.clearGraph(), this.graphGroup = new I();
1769
+ const e = new Ws({
1198
1770
  geometryParameters: {
1199
1771
  radius: this.parameters.nodeRadius,
1200
1772
  widthSegments: 16,
@@ -1204,21 +1776,21 @@ class si extends Be {
1204
1776
  color: this.parameters.nodeColor
1205
1777
  }
1206
1778
  });
1207
- this.nodes.forEach((s, i) => {
1208
- const n = e.clone();
1209
- n.position.copy(s), Object.assign(n.userData, { id: i, type: "node" }), this.graphGroup.add(n);
1779
+ this.nodes.forEach((s, n) => {
1780
+ const i = e.clone();
1781
+ i.position.copy(s), Object.assign(i.userData, { id: n, type: "node" }), this.graphGroup.add(i);
1210
1782
  });
1211
1783
  const t = /* @__PURE__ */ new Set();
1212
- this.adjacencyMap.forEach((s, i) => {
1213
- s.forEach((n, r) => {
1214
- const o = [i, r].sort().join("-");
1784
+ this.adjacencyMap.forEach((s, n) => {
1785
+ s.forEach((i, r) => {
1786
+ const o = [n, r].sort().join("-");
1215
1787
  if (t.has(o)) return;
1216
1788
  t.add(o);
1217
- const c = this.nodes.get(i), h = this.nodes.get(r);
1218
- if (c && h) {
1219
- const l = new yt(c, h), d = new we({
1789
+ const a = this.nodes.get(n), c = this.nodes.get(r);
1790
+ if (a && c) {
1791
+ const h = new Lt(a, c), d = new Pe({
1220
1792
  geometryParameters: {
1221
- path: l,
1793
+ path: h,
1222
1794
  tubularSegments: 1,
1223
1795
  radius: this.parameters.edgeRadius,
1224
1796
  radialSegments: 8,
@@ -1228,14 +1800,14 @@ class si extends Be {
1228
1800
  color: this.parameters.edgeColor
1229
1801
  }
1230
1802
  });
1231
- Object.assign(d.userData, { from: i, to: r, weight: n, type: "edge" }), this.graphGroup.add(d);
1803
+ Object.assign(d.userData, { from: n, to: r, weight: i, type: "edge" }), this.graphGroup.add(d);
1232
1804
  }
1233
1805
  });
1234
1806
  }), this.add(this.graphGroup);
1235
1807
  }
1236
1808
  clearGraph() {
1237
1809
  this.graphGroup && (this.remove(this.graphGroup), this.graphGroup.traverse((e) => {
1238
- e instanceof z && (e.geometry.dispose(), e.material.dispose());
1810
+ e instanceof G && (e.geometry.dispose(), e.material.dispose());
1239
1811
  }), this.graphGroup = null);
1240
1812
  }
1241
1813
  /**
@@ -1243,7 +1815,7 @@ class si extends Be {
1243
1815
  */
1244
1816
  renderPath(e, t = this.parameters.pathColor) {
1245
1817
  if (e.length < 2) return;
1246
- const s = new wt(e, !1, "catmullrom", 0), i = new we({
1818
+ const s = new It(e, !1, "catmullrom", 0), n = new Pe({
1247
1819
  geometryParameters: {
1248
1820
  path: s,
1249
1821
  tubularSegments: e.length * 10,
@@ -1254,7 +1826,7 @@ class si extends Be {
1254
1826
  color: t
1255
1827
  }
1256
1828
  });
1257
- return this.add(i), this.pathMeshes.push(i), i;
1829
+ return this.add(n), this.pathMeshes.push(n), n;
1258
1830
  }
1259
1831
  clearPaths() {
1260
1832
  this.pathMeshes.forEach((e) => {
@@ -1264,14 +1836,14 @@ class si extends Be {
1264
1836
  /** Export nodes and edges as a JSON-serializable object. */
1265
1837
  exportData() {
1266
1838
  const e = {};
1267
- this.nodes.forEach((i, n) => {
1268
- e[n] = { x: i.x, y: i.y, z: i.z };
1839
+ this.nodes.forEach((n, i) => {
1840
+ e[i] = { x: n.x, y: n.y, z: n.z };
1269
1841
  });
1270
1842
  const t = [], s = /* @__PURE__ */ new Set();
1271
- return this.adjacencyMap.forEach((i, n) => {
1272
- i.forEach((r, o) => {
1273
- const c = [n, o].sort().join("-");
1274
- s.has(c) || (s.add(c), t.push({ from: n, to: o, weight: r }));
1843
+ return this.adjacencyMap.forEach((n, i) => {
1844
+ n.forEach((r, o) => {
1845
+ const a = [i, o].sort().join("-");
1846
+ s.has(a) || (s.add(a), t.push({ from: i, to: o, weight: r }));
1275
1847
  });
1276
1848
  }), { nodes: e, edges: t };
1277
1849
  }
@@ -1281,9 +1853,9 @@ class si extends Be {
1281
1853
  */
1282
1854
  importData(e) {
1283
1855
  this.clearGraph(), this.clearPaths(), this.nodes.clear(), this.adjacencyMap.clear(), Object.entries(e.nodes).forEach(([t, s]) => {
1284
- this.addNode(t, new oe(s.x, s.y, s.z));
1285
- }), e.edges.forEach(({ from: t, to: s, weight: i }) => {
1286
- this.addEdge(t, s, i);
1856
+ this.addNode(t, new w(s.x, s.y, s.z));
1857
+ }), e.edges.forEach(({ from: t, to: s, weight: n }) => {
1858
+ this.addEdge(t, s, n);
1287
1859
  }), this.renderGraph();
1288
1860
  }
1289
1861
  dispose() {
@@ -1293,7 +1865,7 @@ class si extends Be {
1293
1865
  return this.adjacencyMap.get(e);
1294
1866
  }
1295
1867
  }
1296
- class ii extends Ms {
1868
+ class Mn extends $s {
1297
1869
  isPoi = !0;
1298
1870
  type = "Poi";
1299
1871
  parameters = {
@@ -1312,7 +1884,7 @@ class ii extends Ms {
1312
1884
  _canvas = document.createElement("canvas");
1313
1885
  _lastParametersJSON = "";
1314
1886
  constructor(e = {}) {
1315
- super(new vt()), Object.assign(this.parameters, e), this.updateAsync();
1887
+ super(new Rt()), Object.assign(this.parameters, e), this.updateAsync();
1316
1888
  }
1317
1889
  /**
1318
1890
  * Update the POI with new parameters
@@ -1323,195 +1895,191 @@ class ii extends Ms {
1323
1895
  const t = JSON.stringify(this.parameters);
1324
1896
  if (t === this._lastParametersJSON) return;
1325
1897
  this._lastParametersJSON = t;
1326
- const s = this._canvas, i = s.getContext("2d");
1327
- if (!i) return;
1328
- i.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;
1329
- let n = null;
1330
- this.parameters.img && (n = await this._loadImage(this.parameters.img));
1331
- const { text: r, fontSize: o, color: c, iconSize: h, padding: l, backgroundColor: d, borderRadius: g, textPosition: p, scaleFactor: y } = this.parameters, v = i.measureText(r), S = r ? v.width : 0, b = r ? o : 0;
1332
- let f = 0, T = 0, M = 0, P = 0, x = 0, m = 0;
1333
- const w = !!n, A = !!r;
1334
- if (w && A)
1335
- switch (p) {
1898
+ const s = this._canvas, n = s.getContext("2d");
1899
+ if (!n) return;
1900
+ n.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;
1901
+ let i = null;
1902
+ this.parameters.img && (i = await this._loadImage(this.parameters.img));
1903
+ const { text: r, fontSize: o, color: a, iconSize: c, padding: h, backgroundColor: d, borderRadius: p, textPosition: u, scaleFactor: g } = this.parameters, b = n.measureText(r), _ = r ? b.width : 0, x = r ? o : 0;
1904
+ let y = 0, M = 0, E = 0, O = 0, T = 0, f = 0;
1905
+ const v = !!i, z = !!r;
1906
+ if (v && z)
1907
+ switch (u) {
1336
1908
  case "top":
1337
- f = Math.max(h, S), T = h + l + b, x = (f - S) / 2, m = b / 2, M = (f - h) / 2, P = b + l;
1909
+ y = Math.max(c, _), M = c + h + x, T = (y - _) / 2, f = x / 2, E = (y - c) / 2, O = x + h;
1338
1910
  break;
1339
1911
  case "bottom":
1340
- f = Math.max(h, S), T = h + l + b, M = (f - h) / 2, P = 0, x = (f - S) / 2, m = h + l + b / 2;
1912
+ y = Math.max(c, _), M = c + h + x, E = (y - c) / 2, O = 0, T = (y - _) / 2, f = c + h + x / 2;
1341
1913
  break;
1342
1914
  case "left":
1343
- f = h + l + S, T = Math.max(h, b), x = 0, m = T / 2, M = S + l, P = (T - h) / 2;
1915
+ y = c + h + _, M = Math.max(c, x), T = 0, f = M / 2, E = _ + h, O = (M - c) / 2;
1344
1916
  break;
1345
1917
  default:
1346
- f = h + l + S, T = Math.max(h, b), M = 0, P = (T - h) / 2, x = h + l, m = T / 2;
1918
+ y = c + h + _, M = Math.max(c, x), E = 0, O = (M - c) / 2, T = c + h, f = M / 2;
1347
1919
  break;
1348
1920
  }
1349
- else w ? (f = h, T = h, M = 0, P = 0) : A && (f = S, T = b, x = 0, m = b / 2);
1350
- const N = f + l * 2, E = T + l * 2;
1351
- if (s.width = N, s.height = E, i.font = `${o}px ${this.parameters.fontFamily}`, d && (i.fillStyle = d, this._drawRoundedRect(i, 0, 0, N, E, g), i.fill()), w && i.drawImage(n, M + l, P + l, h, h), A) {
1352
- i.fillStyle = c;
1353
- const _ = i.measureText(r), D = _.actualBoundingBoxAscent + _.actualBoundingBoxDescent, He = _.actualBoundingBoxAscent - D / 2;
1354
- i.textBaseline = "alphabetic", i.fillText(r, x + l, m + l + He);
1921
+ else v ? (y = c, M = c, E = 0, O = 0) : z && (y = _, M = x, T = 0, f = x / 2);
1922
+ const N = y + h * 2, P = M + h * 2;
1923
+ if (s.width = N, s.height = P, n.font = `${o}px ${this.parameters.fontFamily}`, d && (n.fillStyle = d, this._drawRoundedRect(n, 0, 0, N, P, p), n.fill()), v && n.drawImage(i, E + h, O + h, c, c), z) {
1924
+ n.fillStyle = a;
1925
+ const D = n.measureText(r), k = D.actualBoundingBoxAscent + D.actualBoundingBoxDescent, et = D.actualBoundingBoxAscent - k / 2;
1926
+ n.textBaseline = "alphabetic", n.fillText(r, T + h, f + h + et);
1355
1927
  }
1356
- const H = this.material.map, G = new bt(s);
1357
- G.colorSpace = Pe, this.material.map = G, H?.dispose(), this.scale.set(N * y, E * y, 1);
1928
+ const X = this.material.map, W = new zt(s);
1929
+ W.colorSpace = De, this.material.map = W, X?.dispose(), this.scale.set(N * g, P * g, 1);
1358
1930
  }
1359
1931
  _loadImage(e) {
1360
1932
  return new Promise((t, s) => {
1361
1933
  if (typeof e == "string") {
1362
- const i = new Image();
1363
- i.crossOrigin = "Anonymous", i.onload = () => t(i), i.onerror = () => s(new Error(`Failed to load image: ${e}`)), i.src = e;
1934
+ const n = new Image();
1935
+ n.crossOrigin = "Anonymous", n.onload = () => t(n), n.onerror = () => s(new Error(`Failed to load image: ${e}`)), n.src = e;
1364
1936
  } else
1365
1937
  t(e);
1366
1938
  });
1367
1939
  }
1368
- _drawRoundedRect(e, t, s, i, n, r) {
1369
- e.beginPath(), e.moveTo(t + r, s), e.lineTo(t + i - r, s), e.quadraticCurveTo(t + i, s, t + i, s + r), e.lineTo(t + i, s + n - r), e.quadraticCurveTo(t + i, s + n, t + i - r, s + n), e.lineTo(t + r, s + n), e.quadraticCurveTo(t, s + n, t, s + n - r), e.lineTo(t, s + r), e.quadraticCurveTo(t, s, t + r, s), e.closePath();
1940
+ _drawRoundedRect(e, t, s, n, i, r) {
1941
+ e.beginPath(), e.moveTo(t + r, s), e.lineTo(t + n - r, s), e.quadraticCurveTo(t + n, s, t + n, s + r), e.lineTo(t + n, s + i - r), e.quadraticCurveTo(t + n, s + i, t + n - r, s + i), e.lineTo(t + r, s + i), e.quadraticCurveTo(t, s + i, t, s + i - r), e.lineTo(t, s + r), e.quadraticCurveTo(t, s, t + r, s), e.closePath();
1370
1942
  }
1371
1943
  dispose() {
1372
1944
  this.material.map?.dispose(), this.material.dispose();
1373
1945
  }
1374
1946
  }
1375
- class _e extends k {
1947
+ class Ke extends $ {
1376
1948
  isShapeMesh = !0;
1377
1949
  type = "ShapeMesh";
1378
1950
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1379
- super(), this.geometry = new Ct(e?.shape, e?.curveSegments), this.material = new L(t), this.geometry.rotateX(-Math.PI / 2);
1951
+ super(), this.geometry = new Nt(e?.shape, e?.curveSegments), this.material = new R(t), this.geometry.rotateX(-Math.PI / 2);
1380
1952
  }
1381
1953
  static createFromPoints(e, t = {}) {
1382
- return new _e({
1954
+ return new Ke({
1383
1955
  ...t,
1384
1956
  geometryParameters: {
1385
1957
  ...t.geometryParameters,
1386
- shape: new Oe(e.map((s) => new R(s.x, -s.z)))
1958
+ shape: new ke(e.map((s) => new S(s.x, -s.z)))
1387
1959
  }
1388
1960
  });
1389
1961
  }
1390
1962
  }
1391
- class De extends k {
1963
+ class Qe extends $ {
1392
1964
  isExtrudeMesh = !0;
1393
1965
  type = "ExtrudeMesh";
1394
1966
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1395
- super(), this.geometry = new Tt(e?.shape, e?.options), this.material = new L(t), this.geometry.rotateX(-Math.PI / 2);
1967
+ super(), this.geometry = new jt(e?.shape, e?.options), this.material = new R(t), this.geometry.rotateX(-Math.PI / 2);
1396
1968
  }
1397
1969
  static createFromPoints(e, t = {}) {
1398
- return new De({
1970
+ return new Qe({
1399
1971
  ...t,
1400
1972
  geometryParameters: {
1401
1973
  ...t.geometryParameters,
1402
- shape: new Oe(e.map((s) => new R(s.x, -s.z)))
1974
+ shape: new ke(e.map((s) => new S(s.x, -s.z)))
1403
1975
  }
1404
1976
  });
1405
1977
  }
1406
1978
  }
1407
- class ni extends k {
1979
+ class Tn extends $ {
1408
1980
  isPlaneMesh = !0;
1409
1981
  type = "PlaneMesh";
1410
1982
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1411
- super(), this.geometry = new St(
1983
+ super(), this.geometry = new Dt(
1412
1984
  e?.width,
1413
1985
  e?.height,
1414
1986
  e?.widthSegments,
1415
1987
  e?.heightSegments
1416
- ), this.material = new L(t);
1988
+ ), this.material = new R(t);
1417
1989
  }
1418
1990
  }
1419
- class ri extends k {
1991
+ class Pn extends $ {
1420
1992
  isCircleMesh = !0;
1421
1993
  type = "CircleMesh";
1422
1994
  constructor({ geometryParameters: e, materialParameters: t } = {}) {
1423
1995
  super(
1424
- new xt(
1996
+ new kt(
1425
1997
  e?.radius,
1426
1998
  e?.segments,
1427
1999
  e?.thetaStart,
1428
2000
  e?.thetaLength
1429
2001
  ),
1430
- new L(t)
2002
+ new R(t)
1431
2003
  ), this.geometry.rotateX(-Math.PI / 2);
1432
2004
  }
1433
2005
  }
1434
- class W {
2006
+ class F {
1435
2007
  static traverseMeshes(e, t) {
1436
2008
  e.traverse((s) => {
1437
- s instanceof z && t(s);
2009
+ s instanceof G && t(s);
1438
2010
  });
1439
2011
  }
1440
2012
  }
1441
- class ai {
2013
+ class En {
1442
2014
  static flow(e = {}) {
1443
- const { baseColor: t = 16777215, flowColor: s = 65280, speed: i = 1, scale: n = 3, intensity: r = 4 } = e, o = j(new U(t)), c = j(new U(s)), h = pe().x.mul(n).sub(X.mul(i)), l = q(ae(h).add(1).mul(0.5), r);
1444
- return Y(o, c, l);
2015
+ const { baseColor: t = 16777215, flowColor: s = 65280, speed: n = 1, scale: i = 3, intensity: r = 4 } = e, o = H(new U(t)), a = H(new U(s)), c = xe().x.mul(i).sub(te.mul(n)), h = se(pe(c).add(1).mul(0.5), r);
2016
+ return ne(o, a, h);
1445
2017
  }
1446
2018
  static breathe(e = {}) {
1447
- const { baseColor: t = 16777215, breathColor: s = 65280, speed: i = 1, intensity: n = 2 } = e, r = j(new U(t)), o = j(new U(s)), c = ae(X.mul(i)).add(1).mul(0.5), h = q(c, n);
1448
- return Y(r, o, h);
2019
+ const { baseColor: t = 16777215, breathColor: s = 65280, speed: n = 1, intensity: i = 2 } = e, r = H(new U(t)), o = H(new U(s)), a = pe(te.mul(n)).add(1).mul(0.5), c = se(a, i);
2020
+ return ne(r, o, c);
1449
2021
  }
1450
2022
  static fluid(e = {}) {
1451
2023
  const {
1452
2024
  baseColor: t = 16777215,
1453
2025
  flowColor: s = 255,
1454
- speed: i = 1,
1455
- scale: n = 1,
2026
+ speed: n = 1,
2027
+ scale: i = 1,
1456
2028
  intensity: r = 1,
1457
2029
  distortion: o = 0.5
1458
- } = e, c = j(new U(t)), h = j(new U(s)), l = pe().mul(n), d = X.mul(i), g = ue(l.add(d), 1, 0), p = l.add(g.mul(o)), y = ue(p, 1, 0).add(1).mul(0.5), v = q(y, r);
1459
- return Y(c, h, v);
2030
+ } = e, a = H(new U(t)), c = H(new U(s)), h = xe().mul(i), d = te.mul(n), p = Se(h.add(d), 1, 0), u = h.add(p.mul(o)), g = Se(u, 1, 0).add(1).mul(0.5), b = se(g, r);
2031
+ return ne(a, c, b);
1460
2032
  }
1461
2033
  }
1462
- function oi(a) {
2034
+ function On(l) {
1463
2035
  }
1464
- const ie = "uSpaceHighlight", F = `${ie}/enabled`, je = `${ie}/opacity`, Ue = `${ie}/color`, ke = `${ie}/overwrite`, ne = "uSpaceBreathe", te = `${ne}/enabled`, Ge = `${ne}/color`, Fe = `${ne}/speed`, ze = `${ne}/intensity`, se = /* @__PURE__ */ new WeakMap(), Os = Re(() => {
1465
- const a = O(F, "uint"), e = O(Ue, "uint"), t = O(ke, "uint"), s = Ce(e), i = me.mul(s), n = J(t.greaterThan(0), s, i), r = J(a.greaterThan(0), n, me), o = O(te, "uint"), c = O(Ge, "uint"), h = O(Fe, "float"), l = O(ze, "float"), d = Ce(c), g = ae(X.mul(h)).add(1).mul(0.5), p = q(g, l), y = Y(r, d, p);
1466
- return J(o.greaterThan(0), y, r);
1467
- })(), Rs = Re(() => {
1468
- const a = O(F, "uint"), e = O(je, "float");
1469
- return J(a.greaterThan(0), e, Lt);
2036
+ const he = "uSpaceHighlight", Q = `${he}/enabled`, qe = `${he}/opacity`, Xe = `${he}/color`, Ye = `${he}/overwrite`, le = "uSpaceBreathe", ae = `${le}/enabled`, Je = `${le}/color`, Ve = `${le}/speed`, Ze = `${le}/intensity`, ce = /* @__PURE__ */ new WeakMap(), Ks = He(() => {
2037
+ const l = A(Q, "uint"), e = A(Xe, "uint"), t = A(Ye, "uint"), s = Ae(e), n = Ce.mul(s), i = ie(t.greaterThan(0), s, n), r = ie(l.greaterThan(0), i, Ce), o = A(ae, "uint"), a = A(Je, "uint"), c = A(Ve, "float"), h = A(Ze, "float"), d = Ae(a), p = pe(te.mul(c)).add(1).mul(0.5), u = se(p, h), g = ne(r, d, u);
2038
+ return ie(o.greaterThan(0), g, r);
2039
+ })(), Qs = He(() => {
2040
+ const l = A(Q, "uint"), e = A(qe, "float");
2041
+ return ie(l.greaterThan(0), e, Xt);
1470
2042
  })();
1471
- function ve(a) {
1472
- const e = a.material;
2043
+ function Ee(l) {
2044
+ const e = l.material;
1473
2045
  if (!e || Array.isArray(e)) return;
1474
- let t = se.get(e);
2046
+ let t = ce.get(e);
1475
2047
  t || (t = {
1476
2048
  colorNode: e.colorNode,
1477
2049
  opacityNode: e.opacityNode,
1478
2050
  transparent: e.transparent,
2051
+ depthWrite: e.depthWrite,
1479
2052
  activeMeshes: /* @__PURE__ */ new Set()
1480
- }, se.set(e, t)), t.activeMeshes.add(a), e.transparent = !0, e.colorNode = Os, e.opacityNode = Rs, e.needsUpdate = !0;
2053
+ }, ce.set(e, t)), t.activeMeshes.add(l), e.transparent = !0, e.colorNode = Ks, e.opacityNode = Qs, e.needsUpdate = !0;
1481
2054
  }
1482
- function be(a) {
1483
- const e = a.userData[F], t = a.userData[te];
2055
+ function Oe(l) {
2056
+ const e = l.userData[Q], t = l.userData[ae];
1484
2057
  if (e || t) return;
1485
- const s = a.material;
2058
+ const s = l.material;
1486
2059
  if (!s || Array.isArray(s)) return;
1487
- const i = se.get(s);
1488
- i && (i.activeMeshes.delete(a), !(i.activeMeshes.size > 0) && (s.colorNode = i.colorNode, s.opacityNode = i.opacityNode, s.transparent = i.transparent, s.needsUpdate = !0, se.delete(s)));
2060
+ const n = ce.get(s);
2061
+ n && (n.activeMeshes.delete(l), !(n.activeMeshes.size > 0) && (s.colorNode = n.colorNode, s.opacityNode = n.opacityNode, s.transparent = n.transparent, s.depthWrite = n.depthWrite, s.needsUpdate = !0, ce.delete(s)));
1489
2062
  }
1490
- class ci {
2063
+ class oe {
1491
2064
  static highlightColor(e, t = {}) {
1492
- const s = Array.isArray(e) ? e : [e], i = Object.assign(
1493
- {
1494
- opacity: 0.5,
1495
- color: 16711680,
1496
- overwrite: !1
1497
- },
1498
- t
1499
- );
1500
- i.color = new V(i.color).getHex();
1501
- for (const n of s)
1502
- W.traverseMeshes(n, (r) => {
1503
- r.userData[F] = 1, r.userData[je] = i.opacity, r.userData[Ue] = i.color, r.userData[ke] = i.overwrite ? 1 : 0, ve(r);
2065
+ const s = Array.isArray(e) ? e : [e], { opacity: n = 0.5, color: i = 16711680, overwrite: r = !1, depthWrite: o } = t, a = new B(i).getHex();
2066
+ for (const c of s)
2067
+ F.traverseMeshes(c, (h) => {
2068
+ if (h.userData[Q] = 1, h.userData[qe] = n, h.userData[Xe] = a, h.userData[Ye] = r ? 1 : 0, Ee(h), o !== void 0) {
2069
+ const d = h.material;
2070
+ d && !Array.isArray(d) && (d.depthWrite = o);
2071
+ }
1504
2072
  });
1505
2073
  }
1506
2074
  static removeHighlightColor(e) {
1507
2075
  const t = Array.isArray(e) ? e : [e];
1508
2076
  for (const s of t)
1509
- W.traverseMeshes(s, (i) => {
1510
- i.userData[F] = 0, be(i);
2077
+ F.traverseMeshes(s, (n) => {
2078
+ n.userData[Q] = 0, Oe(n);
1511
2079
  });
1512
2080
  }
1513
2081
  static breatheColor(e, t = {}) {
1514
- const s = Array.isArray(e) ? e : [e], i = Object.assign(
2082
+ const s = Array.isArray(e) ? e : [e], n = Object.assign(
1515
2083
  {
1516
2084
  color: 65280,
1517
2085
  speed: 1,
@@ -1519,25 +2087,88 @@ class ci {
1519
2087
  },
1520
2088
  t
1521
2089
  );
1522
- i.color = new V(i.color).getHex();
1523
- for (const n of s)
1524
- W.traverseMeshes(n, (r) => {
1525
- r.userData[te] = 1, r.userData[Ge] = i.color, r.userData[Fe] = i.speed, r.userData[ze] = i.intensity, ve(r);
2090
+ n.color = new B(n.color).getHex();
2091
+ for (const i of s)
2092
+ F.traverseMeshes(i, (r) => {
2093
+ r.userData[ae] = 1, r.userData[Je] = n.color, r.userData[Ve] = n.speed, r.userData[Ze] = n.intensity, Ee(r);
1526
2094
  });
1527
2095
  }
1528
2096
  static removeBreatheColor(e) {
1529
2097
  const t = Array.isArray(e) ? e : [e];
1530
2098
  for (const s of t)
1531
- W.traverseMeshes(s, (i) => {
1532
- i.userData[te] = 0, be(i);
2099
+ F.traverseMeshes(s, (n) => {
2100
+ n.userData[ae] = 0, Oe(n);
1533
2101
  });
1534
2102
  }
2103
+ /**
2104
+ * Enable wireframe mode on object(s).
2105
+ */
2106
+ static wireframe(e, t = !0) {
2107
+ const s = Array.isArray(e) ? e : [e];
2108
+ for (const n of s)
2109
+ F.traverseMeshes(n, (i) => {
2110
+ const r = i.material;
2111
+ !r || Array.isArray(r) || (r.wireframe = t, r.needsUpdate = !0);
2112
+ });
2113
+ }
2114
+ /**
2115
+ * Remove wireframe mode.
2116
+ */
2117
+ static removeWireframe(e) {
2118
+ oe.wireframe(e, !1);
2119
+ }
2120
+ /**
2121
+ * Fade in object(s) from fully transparent to original opacity.
2122
+ * Returns a promise that resolves when animation is complete.
2123
+ */
2124
+ static fadeIn(e, t = {}) {
2125
+ const { duration: s = 500 } = t;
2126
+ return oe._fade(e, 0, 1, s);
2127
+ }
2128
+ /**
2129
+ * Fade out object(s) to fully transparent.
2130
+ * Returns a promise that resolves when animation is complete.
2131
+ */
2132
+ static fadeOut(e, t = {}) {
2133
+ const { duration: s = 500 } = t;
2134
+ return oe._fade(e, 1, 0, s);
2135
+ }
2136
+ static _fade(e, t, s, n) {
2137
+ const i = Array.isArray(e) ? e : [e], r = [];
2138
+ for (const o of i)
2139
+ F.traverseMeshes(o, (a) => {
2140
+ const c = a.material;
2141
+ !c || Array.isArray(c) || (c.transparent = !0, c.opacity = t, c.needsUpdate = !0, r.push({ material: c, targetOpacity: s }));
2142
+ });
2143
+ return r.length === 0 ? Promise.resolve() : new Promise((o) => {
2144
+ const a = performance.now();
2145
+ let c = 0;
2146
+ const h = () => {
2147
+ const d = performance.now() - a, p = Math.min(d / n, 1);
2148
+ if (!i[0].parent) {
2149
+ cancelAnimationFrame(c), o();
2150
+ return;
2151
+ }
2152
+ for (const { material: g, targetOpacity: b } of r)
2153
+ g.opacity = t + (b - t) * p, g.needsUpdate = !0;
2154
+ if (p < 1)
2155
+ c = requestAnimationFrame(h);
2156
+ else {
2157
+ if (s >= 1)
2158
+ for (const { material: g } of r)
2159
+ g.transparent = !1;
2160
+ o();
2161
+ }
2162
+ };
2163
+ c = requestAnimationFrame(h);
2164
+ });
2165
+ }
1535
2166
  }
1536
- const Ce = (a) => {
1537
- const e = a.shiftRight(16).bitAnd(255).toFloat().div(255), t = a.shiftRight(8).bitAnd(255).toFloat().div(255), s = a.bitAnd(255).toFloat().div(255);
1538
- return At(e, t, s);
2167
+ const Ae = (l) => {
2168
+ const e = l.shiftRight(16).bitAnd(255).toFloat().div(255), t = l.shiftRight(8).bitAnd(255).toFloat().div(255), s = l.bitAnd(255).toFloat().div(255);
2169
+ return Yt(e, t, s);
1539
2170
  };
1540
- class Is extends Yt {
2171
+ class qs extends ms {
1541
2172
  viewer;
1542
2173
  constructor(e, t) {
1543
2174
  super(t), this.viewer = e;
@@ -1546,7 +2177,7 @@ class Is extends Yt {
1546
2177
  this.update(e) && this.viewer.render();
1547
2178
  };
1548
2179
  easingByMode(e) {
1549
- const t = Ls[e];
2180
+ const t = Xs[e];
1550
2181
  return super.easing(t);
1551
2182
  }
1552
2183
  start(e, t) {
@@ -1556,87 +2187,500 @@ class Is extends Yt {
1556
2187
  return this.viewer.removeEventListener("afterControlsUpdate", this._update), super.stop();
1557
2188
  }
1558
2189
  }
1559
- function hi(a, e, t, s = {}, i, n) {
2190
+ function An(l, e, t, s = {}, n, i) {
1560
2191
  return new Promise((r, o) => {
1561
- const { duration: c = 1e3, delay: h = 0, repeat: l = !1, mode: d = "Linear.None", yoyo: g = !1 } = s, p = new Is(a, e).to(t, c).easingByMode(d).delay(h).onUpdate((y) => {
1562
- i?.(y, p);
2192
+ const { duration: a = 1e3, delay: c = 0, repeat: h = !1, mode: d = "Linear.None", yoyo: p = !1 } = s, u = new qs(l, e).to(t, a).easingByMode(d).delay(c).onUpdate((g) => {
2193
+ n?.(g, u);
1563
2194
  }).onComplete(() => {
1564
2195
  r();
1565
2196
  }).onStop(() => {
1566
2197
  o("animation stop");
1567
2198
  }).onStart(() => {
1568
- n?.(p);
2199
+ i?.(u);
1569
2200
  });
1570
- typeof l == "number" ? p.repeat(l) : typeof l == "boolean" && l && p.repeat(1 / 0), g && p.repeatDelay(20), p.yoyo(g), p.start();
2201
+ typeof h == "number" ? u.repeat(h) : typeof h == "boolean" && h && u.repeat(1 / 0), p && u.repeatDelay(20), u.yoyo(p), u.start();
1571
2202
  });
1572
2203
  }
1573
- const Ls = {
1574
- "Linear.None": u.Linear.None,
1575
- "Quadratic.In": u.Quadratic.In,
1576
- "Quadratic.Out": u.Quadratic.Out,
1577
- "Quadratic.InOut": u.Quadratic.InOut,
1578
- "Cubic.In": u.Cubic.In,
1579
- "Cubic.Out": u.Cubic.Out,
1580
- "Cubic.InOut": u.Cubic.InOut,
1581
- "Quartic.In": u.Quartic.In,
1582
- "Quartic.Out": u.Quartic.Out,
1583
- "Quartic.InOut": u.Quartic.InOut,
1584
- "Quintic.In": u.Quintic.In,
1585
- "Quintic.Out": u.Quintic.Out,
1586
- "Quintic.InOut": u.Quintic.InOut,
1587
- "Sinusoidal.In": u.Sinusoidal.In,
1588
- "Sinusoidal.Out": u.Sinusoidal.Out,
1589
- "Sinusoidal.InOut": u.Sinusoidal.InOut,
1590
- "Exponential.In": u.Exponential.In,
1591
- "Exponential.Out": u.Exponential.Out,
1592
- "Exponential.InOut": u.Exponential.InOut,
1593
- "Circular.In": u.Circular.In,
1594
- "Circular.Out": u.Circular.Out,
1595
- "Circular.InOut": u.Circular.InOut,
1596
- "Elastic.In": u.Elastic.In,
1597
- "Elastic.Out": u.Elastic.Out,
1598
- "Elastic.InOut": u.Elastic.InOut,
1599
- "Back.In": u.Back.In,
1600
- "Back.Out": u.Back.Out,
1601
- "Back.InOut": u.Back.InOut,
1602
- "Bounce.In": u.Bounce.In,
1603
- "Bounce.Out": u.Bounce.Out,
1604
- "Bounce.InOut": u.Bounce.InOut
1605
- }, As = "0.0.5";
1606
- window.__USPACE__ = { version: As };
2204
+ const Xs = {
2205
+ "Linear.None": m.Linear.None,
2206
+ "Quadratic.In": m.Quadratic.In,
2207
+ "Quadratic.Out": m.Quadratic.Out,
2208
+ "Quadratic.InOut": m.Quadratic.InOut,
2209
+ "Cubic.In": m.Cubic.In,
2210
+ "Cubic.Out": m.Cubic.Out,
2211
+ "Cubic.InOut": m.Cubic.InOut,
2212
+ "Quartic.In": m.Quartic.In,
2213
+ "Quartic.Out": m.Quartic.Out,
2214
+ "Quartic.InOut": m.Quartic.InOut,
2215
+ "Quintic.In": m.Quintic.In,
2216
+ "Quintic.Out": m.Quintic.Out,
2217
+ "Quintic.InOut": m.Quintic.InOut,
2218
+ "Sinusoidal.In": m.Sinusoidal.In,
2219
+ "Sinusoidal.Out": m.Sinusoidal.Out,
2220
+ "Sinusoidal.InOut": m.Sinusoidal.InOut,
2221
+ "Exponential.In": m.Exponential.In,
2222
+ "Exponential.Out": m.Exponential.Out,
2223
+ "Exponential.InOut": m.Exponential.InOut,
2224
+ "Circular.In": m.Circular.In,
2225
+ "Circular.Out": m.Circular.Out,
2226
+ "Circular.InOut": m.Circular.InOut,
2227
+ "Elastic.In": m.Elastic.In,
2228
+ "Elastic.Out": m.Elastic.Out,
2229
+ "Elastic.InOut": m.Elastic.InOut,
2230
+ "Back.In": m.Back.In,
2231
+ "Back.Out": m.Back.Out,
2232
+ "Back.InOut": m.Back.InOut,
2233
+ "Bounce.In": m.Bounce.In,
2234
+ "Bounce.Out": m.Bounce.Out,
2235
+ "Bounce.InOut": m.Bounce.InOut
2236
+ };
2237
+ class Bn {
2238
+ scene;
2239
+ planes = /* @__PURE__ */ new Map();
2240
+ helpers = /* @__PURE__ */ new Map();
2241
+ /**
2242
+ * The ClippingGroup node. Objects must be descendants of this group to be clipped.
2243
+ */
2244
+ group;
2245
+ constructor(e) {
2246
+ this.scene = e, this.group = new Ht(), this.group.name = "__clippingToolGroup", this.scene.add(this.group);
2247
+ }
2248
+ /**
2249
+ * Move all current scene children (except the clipping group itself) into the ClippingGroup,
2250
+ * so they are all subject to clipping.
2251
+ */
2252
+ attach() {
2253
+ const e = [...this.scene.children];
2254
+ for (const t of e)
2255
+ t !== this.group && this.group.add(t);
2256
+ }
2257
+ /**
2258
+ * Move all children out of the ClippingGroup back to the scene root.
2259
+ */
2260
+ detach() {
2261
+ const e = [...this.group.children];
2262
+ for (const t of e)
2263
+ this.helpers.has(t.name) || this.scene.add(t);
2264
+ }
2265
+ /**
2266
+ * Enable clipping.
2267
+ */
2268
+ enable() {
2269
+ this.group.enabled = !0;
2270
+ }
2271
+ /**
2272
+ * Disable clipping.
2273
+ */
2274
+ disable() {
2275
+ this.group.enabled = !1;
2276
+ }
2277
+ /**
2278
+ * Add a clipping plane.
2279
+ */
2280
+ addPlane(e, t = {}) {
2281
+ const {
2282
+ normal: s = { x: 0, y: -1, z: 0 },
2283
+ constant: n = 0,
2284
+ showHelper: i = !1,
2285
+ helperSize: r = 5,
2286
+ helperColor: o = 16711680
2287
+ } = t, a = new Ut(new w(s.x, s.y, s.z), n);
2288
+ return this.planes.set(e, a), this._syncPlanes(), i && this.showHelper(e, r, o), a;
2289
+ }
2290
+ /**
2291
+ * Add six clipping planes that form a box around a Box3.
2292
+ * Returns the six plane ids: `${id}_+x`, `${id}_-x`, etc.
2293
+ */
2294
+ addBox(e, t, s = {}) {
2295
+ const { showHelpers: n = !1, helperColor: i = 16711680 } = s, r = t.min, o = t.max, a = [
2296
+ { suffix: "+x", normal: { x: -1, y: 0, z: 0 }, constant: o.x },
2297
+ { suffix: "-x", normal: { x: 1, y: 0, z: 0 }, constant: -r.x },
2298
+ { suffix: "+y", normal: { x: 0, y: -1, z: 0 }, constant: o.y },
2299
+ { suffix: "-y", normal: { x: 0, y: 1, z: 0 }, constant: -r.y },
2300
+ { suffix: "+z", normal: { x: 0, y: 0, z: -1 }, constant: o.z },
2301
+ { suffix: "-z", normal: { x: 0, y: 0, z: 1 }, constant: -r.z }
2302
+ ], c = [];
2303
+ for (const h of a) {
2304
+ const d = `${e}_${h.suffix}`;
2305
+ this.addPlane(d, { normal: h.normal, constant: h.constant, showHelper: n, helperColor: i }), c.push(d);
2306
+ }
2307
+ return c;
2308
+ }
2309
+ /**
2310
+ * Add a clipping box from an object's bounding box with optional padding.
2311
+ */
2312
+ addBoxFromObject(e, t, s = 0, n = {}) {
2313
+ const i = new q().setFromObject(t);
2314
+ return i.expandByScalar(s), this.addBox(e, i, n);
2315
+ }
2316
+ /**
2317
+ * Update a plane's constant (distance from origin).
2318
+ */
2319
+ setPlaneConstant(e, t) {
2320
+ const s = this.planes.get(e);
2321
+ s && (s.constant = t);
2322
+ }
2323
+ /**
2324
+ * Remove a clipping plane.
2325
+ */
2326
+ removePlane(e) {
2327
+ this.planes.delete(e), this.hideHelper(e), this._syncPlanes();
2328
+ }
2329
+ /**
2330
+ * Remove a clipping box (all 6 associated planes).
2331
+ */
2332
+ removeBox(e) {
2333
+ const t = ["+x", "-x", "+y", "-y", "+z", "-z"];
2334
+ for (const s of t)
2335
+ this.removePlane(`${e}_${s}`);
2336
+ }
2337
+ /**
2338
+ * Remove all clipping planes.
2339
+ */
2340
+ removeAll() {
2341
+ const e = Array.from(this.helpers.keys());
2342
+ for (const t of e)
2343
+ this.hideHelper(t);
2344
+ this.planes.clear(), this._syncPlanes();
2345
+ }
2346
+ /**
2347
+ * Show a helper visualization for a clipping plane.
2348
+ */
2349
+ showHelper(e, t = 5, s = 16711680) {
2350
+ this.hideHelper(e);
2351
+ const n = this.planes.get(e);
2352
+ if (!n) return;
2353
+ const i = new Ft(n, t, new B(s).getHex());
2354
+ i.name = e, this.helpers.set(e, i), this.scene.add(i);
2355
+ }
2356
+ /**
2357
+ * Hide a plane helper.
2358
+ */
2359
+ hideHelper(e) {
2360
+ const t = this.helpers.get(e);
2361
+ t && (this.scene.remove(t), t.dispose(), this.helpers.delete(e));
2362
+ }
2363
+ /**
2364
+ * Get a plane by id.
2365
+ */
2366
+ get(e) {
2367
+ return this.planes.get(e);
2368
+ }
2369
+ /**
2370
+ * Sync the planes map into the ClippingGroup's clippingPlanes array.
2371
+ */
2372
+ _syncPlanes() {
2373
+ this.group.clippingPlanes = Array.from(this.planes.values());
2374
+ }
2375
+ dispose() {
2376
+ this.detach(), this.removeAll(), this.scene.remove(this.group);
2377
+ }
2378
+ }
2379
+ class Ln {
2380
+ scene;
2381
+ measurements = /* @__PURE__ */ new Map();
2382
+ _idCounter = 0;
2383
+ constructor(e) {
2384
+ this.scene = e;
2385
+ }
2386
+ /**
2387
+ * Measure distance between two points.
2388
+ */
2389
+ measureDistance(e, t, s = {}) {
2390
+ const { lineColor: n = 16776960 } = s, i = new w(e.x, e.y, e.z), r = new w(t.x, t.y, t.z), o = i.distanceTo(r), a = `measure_dist_${this._idCounter++}`, c = new I();
2391
+ c.name = a;
2392
+ const h = new K().setFromPoints([i, r]), d = new Z({ color: n }), p = new ee(h, d);
2393
+ c.add(p), this.scene.add(c);
2394
+ const u = {
2395
+ id: a,
2396
+ type: "distance",
2397
+ value: o,
2398
+ unit: "m",
2399
+ points: [i, r],
2400
+ object: c
2401
+ };
2402
+ return this.measurements.set(a, u), u;
2403
+ }
2404
+ /**
2405
+ * Measure the area of a polygon defined by 3+ coplanar points.
2406
+ */
2407
+ measureArea(e, t = {}) {
2408
+ const { lineColor: s = 65280 } = t;
2409
+ if (e.length < 3)
2410
+ throw new Error("MeasureTool.measureArea requires at least 3 points");
2411
+ const n = e.map((u) => new w(u.x, u.y, u.z)), i = this._calculatePolygonArea(n), r = `measure_area_${this._idCounter++}`, o = new I();
2412
+ o.name = r;
2413
+ const a = [...n, n[0]], c = new K().setFromPoints(a), h = new Z({ color: s }), d = new ee(c, h);
2414
+ o.add(d), this.scene.add(o);
2415
+ const p = {
2416
+ id: r,
2417
+ type: "area",
2418
+ value: i,
2419
+ unit: "m²",
2420
+ points: n,
2421
+ object: o
2422
+ };
2423
+ return this.measurements.set(r, p), p;
2424
+ }
2425
+ /**
2426
+ * Measure the angle between three points (vertex at the middle point).
2427
+ */
2428
+ measureAngle(e, t, s, n = {}) {
2429
+ const { lineColor: i = 16746496 } = n, r = new w(e.x, e.y, e.z), o = new w(t.x, t.y, t.z), a = new w(s.x, s.y, s.z), c = r.clone().sub(o).normalize(), h = a.clone().sub(o).normalize(), p = Math.acos(Math.max(-1, Math.min(1, c.dot(h)))) * 180 / Math.PI, u = `measure_angle_${this._idCounter++}`, g = new I();
2430
+ g.name = u;
2431
+ const b = new K().setFromPoints([r, o, a]), _ = new Z({ color: i }), x = new ee(b, _);
2432
+ g.add(x), this.scene.add(g);
2433
+ const y = {
2434
+ id: u,
2435
+ type: "angle",
2436
+ value: p,
2437
+ unit: "°",
2438
+ points: [r, o, a],
2439
+ object: g
2440
+ };
2441
+ return this.measurements.set(u, y), y;
2442
+ }
2443
+ /**
2444
+ * Get a measurement result by id.
2445
+ */
2446
+ get(e) {
2447
+ return this.measurements.get(e);
2448
+ }
2449
+ /**
2450
+ * Remove a measurement by id.
2451
+ */
2452
+ remove(e) {
2453
+ const t = this.measurements.get(e);
2454
+ t && (this.scene.remove(t.object), t.object.traverse((s) => {
2455
+ s.geometry?.dispose(), s.material?.dispose();
2456
+ }), this.measurements.delete(e));
2457
+ }
2458
+ /**
2459
+ * Remove all measurements.
2460
+ */
2461
+ removeAll() {
2462
+ const e = Array.from(this.measurements.keys());
2463
+ for (const t of e)
2464
+ this.remove(t);
2465
+ }
2466
+ /**
2467
+ * Get all measurement results.
2468
+ */
2469
+ getAll() {
2470
+ return Array.from(this.measurements.values());
2471
+ }
2472
+ /**
2473
+ * Calculate polygon area using cross product method (Newell's method).
2474
+ */
2475
+ _calculatePolygonArea(e) {
2476
+ const t = e.length, s = new w();
2477
+ for (let i = 0; i < t; i++) {
2478
+ const r = e[i], o = e[(i + 1) % t], a = new w().crossVectors(r, o);
2479
+ s.add(a);
2480
+ }
2481
+ const n = new w();
2482
+ if (t >= 3) {
2483
+ const i = e[1].clone().sub(e[0]), r = e[2].clone().sub(e[0]);
2484
+ n.crossVectors(i, r).normalize();
2485
+ }
2486
+ return Math.abs(s.dot(n)) / 2;
2487
+ }
2488
+ dispose() {
2489
+ this.removeAll();
2490
+ }
2491
+ }
2492
+ class In {
2493
+ scene;
2494
+ annotations = /* @__PURE__ */ new Map();
2495
+ _idCounter = 0;
2496
+ _createCSSObject = null;
2497
+ constructor(e) {
2498
+ this.scene = e;
2499
+ }
2500
+ /**
2501
+ * Set the CSS object factory function (from CSSRenderer).
2502
+ * This allows annotations to be rendered as CSS2D/CSS2.5D objects.
2503
+ */
2504
+ setCSSObjectFactory(e) {
2505
+ this._createCSSObject = e;
2506
+ }
2507
+ /**
2508
+ * Add an annotation.
2509
+ */
2510
+ add(e, t) {
2511
+ this.annotations.has(e) && this.remove(e);
2512
+ const s = new I();
2513
+ s.name = `annotation_${e}`;
2514
+ const n = new w(t.position.x, t.position.y, t.position.z);
2515
+ s.position.copy(n);
2516
+ const i = document.createElement("div");
2517
+ if (i.innerHTML = t.content, i.style.cssText = `
2518
+ padding: 4px 8px;
2519
+ background: rgba(0, 0, 0, 0.75);
2520
+ color: #fff;
2521
+ font-size: 12px;
2522
+ border-radius: 4px;
2523
+ pointer-events: auto;
2524
+ white-space: nowrap;
2525
+ `, t.labelStyle)
2526
+ for (const [c, h] of Object.entries(t.labelStyle))
2527
+ h !== void 0 && (i.style[c] = h);
2528
+ let r = null;
2529
+ const o = t.labelOffset || { x: 0, y: 2, z: 0 };
2530
+ if (t.showLeaderLine !== !1) {
2531
+ const { lineColor: c = 16777215 } = t, h = new K().setFromPoints([
2532
+ new w(0, 0, 0),
2533
+ new w(o.x, o.y, o.z)
2534
+ ]), d = new Z({ color: c });
2535
+ r = new ee(h, d), s.add(r);
2536
+ }
2537
+ if (this._createCSSObject) {
2538
+ const c = this._createCSSObject(i);
2539
+ c.position.set(o.x, o.y, o.z), s.add(c);
2540
+ }
2541
+ this.scene.add(s);
2542
+ const a = {
2543
+ id: e,
2544
+ options: t,
2545
+ group: s,
2546
+ labelElement: i,
2547
+ line: r
2548
+ };
2549
+ return this.annotations.set(e, a), a;
2550
+ }
2551
+ /**
2552
+ * Quick-add a text annotation.
2553
+ */
2554
+ addText(e, t, s = {}) {
2555
+ const n = `annotation_${this._idCounter++}`;
2556
+ return this.add(n, {
2557
+ position: t,
2558
+ content: e,
2559
+ ...s
2560
+ });
2561
+ }
2562
+ /**
2563
+ * Update an annotation's content.
2564
+ */
2565
+ updateContent(e, t) {
2566
+ const s = this.annotations.get(e);
2567
+ s && (s.labelElement.innerHTML = t, s.options.content = t);
2568
+ }
2569
+ /**
2570
+ * Update an annotation's position.
2571
+ */
2572
+ updatePosition(e, t) {
2573
+ const s = this.annotations.get(e);
2574
+ s && (s.group.position.set(t.x, t.y, t.z), s.options.position = t);
2575
+ }
2576
+ /**
2577
+ * Show an annotation.
2578
+ */
2579
+ show(e) {
2580
+ const t = this.annotations.get(e);
2581
+ t && (t.group.visible = !0);
2582
+ }
2583
+ /**
2584
+ * Hide an annotation.
2585
+ */
2586
+ hide(e) {
2587
+ const t = this.annotations.get(e);
2588
+ t && (t.group.visible = !1);
2589
+ }
2590
+ /**
2591
+ * Get an annotation by id.
2592
+ */
2593
+ get(e) {
2594
+ return this.annotations.get(e);
2595
+ }
2596
+ /**
2597
+ * Remove an annotation.
2598
+ */
2599
+ remove(e) {
2600
+ const t = this.annotations.get(e);
2601
+ if (t) {
2602
+ const s = [...t.group.children];
2603
+ for (const n of s)
2604
+ t.group.remove(n), n.geometry?.dispose(), n.material?.dispose();
2605
+ this.scene.remove(t.group), this.annotations.delete(e);
2606
+ }
2607
+ }
2608
+ /**
2609
+ * Remove all annotations.
2610
+ */
2611
+ removeAll() {
2612
+ const e = Array.from(this.annotations.keys());
2613
+ for (const t of e)
2614
+ this.remove(t);
2615
+ }
2616
+ /**
2617
+ * Show all annotations.
2618
+ */
2619
+ showAll() {
2620
+ for (const e of this.annotations.values())
2621
+ e.group.visible = !0;
2622
+ }
2623
+ /**
2624
+ * Hide all annotations.
2625
+ */
2626
+ hideAll() {
2627
+ for (const e of this.annotations.values())
2628
+ e.group.visible = !1;
2629
+ }
2630
+ /**
2631
+ * Get all annotation ids.
2632
+ */
2633
+ keys() {
2634
+ return Array.from(this.annotations.keys());
2635
+ }
2636
+ get size() {
2637
+ return this.annotations.size;
2638
+ }
2639
+ dispose() {
2640
+ this.removeAll();
2641
+ }
2642
+ }
2643
+ const Ys = "0.0.8";
2644
+ window.__USPACE__ = { version: Ys };
1607
2645
  export {
1608
- Be as BaseGroup,
1609
- k as BaseMesh,
1610
- Ms as BaseSprite,
1611
- pi as CSS2DObject,
1612
- mi as CSS3DObject,
1613
- gi as CSS3DSprite,
1614
- cs as CSSRenderer,
1615
- ss as CameraControls,
1616
- ri as CircleMesh,
1617
- De as ExtrudeMesh,
1618
- Jt as InteractionEvent,
1619
- Zt as InteractionManager,
1620
- ci as MaterialEffects,
1621
- Z as Model,
1622
- B as ModelLoaderManager,
1623
- Vt as ObjectManager,
1624
- W as ObjectUtils,
1625
- ni as PlaneMesh,
1626
- ii as Poi,
1627
- es as RenderPipeline,
1628
- ns as RoomEnvironment,
1629
- Es as SBMLoader,
1630
- ls as SBMXLoader,
1631
- _e as ShapeMesh,
1632
- Ps as SphereMesh,
1633
- ai as TSLEffects,
1634
- ti as TextureLoaderManager,
1635
- si as Topology,
1636
- we as TubeMesh,
1637
- Is as Tween,
1638
- ei as Viewer,
1639
- oi as reinterpretType,
1640
- hi as tweenAnimation,
1641
- As as version
2646
+ In as AnnotationManager,
2647
+ We as BaseGroup,
2648
+ $ as BaseMesh,
2649
+ $s as BaseSprite,
2650
+ Nn as CSS2DObject,
2651
+ Dn as CSS3DObject,
2652
+ kn as CSS3DSprite,
2653
+ Ts as CSSRenderer,
2654
+ vs as CameraControls,
2655
+ Pn as CircleMesh,
2656
+ Bn as ClippingTool,
2657
+ Qe as ExtrudeMesh,
2658
+ gs as InteractionEvent,
2659
+ fs as InteractionManager,
2660
+ xn as LightManager,
2661
+ oe as MaterialEffects,
2662
+ Ln as MeasureTool,
2663
+ re as Model,
2664
+ j as ModelLoaderManager,
2665
+ ys as ObjectManager,
2666
+ F as ObjectUtils,
2667
+ Tn as PlaneMesh,
2668
+ Mn as Poi,
2669
+ ws as RenderPipeline,
2670
+ Ss as RoomEnvironment,
2671
+ Gs as SBMLoader,
2672
+ Es as SBMXLoader,
2673
+ vn as SceneManager,
2674
+ bn as Selection,
2675
+ Ke as ShapeMesh,
2676
+ Ws as SphereMesh,
2677
+ En as TSLEffects,
2678
+ Cn as TextureLoaderManager,
2679
+ _n as Topology,
2680
+ Pe as TubeMesh,
2681
+ qs as Tween,
2682
+ Sn as Viewer,
2683
+ On as reinterpretType,
2684
+ An as tweenAnimation,
2685
+ Ys as version
1642
2686
  };