u-space 0.0.2 → 0.0.3

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.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
- import { Raycaster as me, Vector2 as P, RenderPipeline as Be, Sphere as ge, Box3 as we, Spherical as C, Matrix4 as Re, Quaternion as _e, Vector4 as Ne, Vector3 as J, MathUtils as Ae, PMREMGenerator as Ue, OrthographicCamera as F, TimestampQuery as De, Cache as je, EventDispatcher as ke, Timer as Ge, PerspectiveCamera as W, WebGPURenderer as Fe, PCFShadowMap as He, AgXToneMapping as ze, Scene as $e, Color as Z, MeshStandardNodeMaterial as I, Loader as We, LoaderUtils as L, FileLoader as fe, TextureLoader as ye, Group as z, SRGBColorSpace as ve, RepeatWrapping as ne, BufferGeometry as Qe, BufferAttribute as ie, Mesh as j, FrontSide as Ke, BackSide as Xe, DoubleSide as qe, REVISION as re, CubeTextureLoader as Ye, EquirectangularReflectionMapping as Je, Sprite as Ze, SphereGeometry as Ve, TubeGeometry as et, LineCurve3 as tt, CatmullRomCurve3 as st, SpriteNodeMaterial as nt, CanvasTexture as it, ShapeGeometry as rt, Shape as be, ExtrudeGeometry as at, PlaneGeometry as ot, CircleGeometry as ct } from "three/webgpu";
2
- import { pass as q, blendColor as ht, color as N, uv as ae, time as Q, pow as K, sin as oe, mix as X, mx_noise_float as ce, Fn as Te, userData as D, materialColor as he, select as Y, materialOpacity as lt, vec3 as dt } from "three/tsl";
3
- import Ce from "camera-controls";
4
- import { RoomEnvironment as pt } from "three/addons/environments/RoomEnvironment.js";
5
- import { ViewHelper as ut } from "three/addons/helpers/ViewHelper.js";
6
- import { GLTFLoader as xe } from "three/addons/loaders/GLTFLoader.js";
7
- import { FBXLoader as mt } from "three/addons/loaders/FBXLoader.js";
8
- import { OBJLoader as gt } from "three/addons/loaders/OBJLoader.js";
9
- import { STLLoader as wt } from "three/addons/loaders/STLLoader.js";
10
- import { DRACOLoader as ft } from "three/addons/loaders/DRACOLoader.js";
11
- import { KTX2Loader as yt } from "three/addons/loaders/KTX2Loader.js";
12
- import { MeshoptDecoder as le } from "three/addons/libs/meshopt_decoder.module.js";
13
- import { HDRLoader as vt } from "three/addons/loaders/HDRLoader.js";
14
- import { clone as bt } from "three/addons/utils/SkeletonUtils.js";
15
- import { Color as A } from "three";
16
- import { Easing as d, Tween as Tt } from "three/addons/libs/tween.module.js";
17
- class Ct {
1
+ import { Raycaster, Vector2, RenderPipeline as RenderPipeline$1, Sphere, Box3, Spherical, Matrix4, Quaternion, Vector4, Vector3, MathUtils, PMREMGenerator, OrthographicCamera, TimestampQuery, Cache, EventDispatcher, Timer, PerspectiveCamera, WebGPURenderer, PCFShadowMap, AgXToneMapping, Scene, Color, MeshStandardNodeMaterial, Loader, LoaderUtils, FileLoader, TextureLoader, Group, SRGBColorSpace, RepeatWrapping, BufferGeometry, BufferAttribute, Mesh, FrontSide, BackSide, DoubleSide, REVISION, CubeTextureLoader, EquirectangularReflectionMapping, Sprite, SphereGeometry, TubeGeometry, LineCurve3, CatmullRomCurve3, SpriteNodeMaterial, CanvasTexture, ShapeGeometry, Shape, ExtrudeGeometry, PlaneGeometry, CircleGeometry } from "three/webgpu";
2
+ import { pass, blendColor, color, uv, time, pow, sin, mix, mx_noise_float, Fn, userData, materialColor, select, materialOpacity, vec3 } from "three/tsl";
3
+ import CameraControlsBase from "camera-controls";
4
+ import { RoomEnvironment as RoomEnvironment$1 } from "three/addons/environments/RoomEnvironment.js";
5
+ import { ViewHelper } from "three/addons/helpers/ViewHelper.js";
6
+ import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
7
+ import { FBXLoader } from "three/addons/loaders/FBXLoader.js";
8
+ import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
9
+ import { STLLoader } from "three/addons/loaders/STLLoader.js";
10
+ import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
11
+ import { KTX2Loader } from "three/addons/loaders/KTX2Loader.js";
12
+ import { MeshoptDecoder } from "three/addons/libs/meshopt_decoder.module.js";
13
+ import { HDRLoader } from "three/addons/loaders/HDRLoader.js";
14
+ import { clone } from "three/addons/utils/SkeletonUtils.js";
15
+ import { Color as Color$1 } from "three";
16
+ import { Easing, Tween as Tween$1 } from "three/addons/libs/tween.module.js";
17
+ class InteractionEvent {
18
18
  /** The type of event (e.g., 'click', 'pointerdown'). */
19
19
  type;
20
20
  /** The original 3D object that triggered the event. */
@@ -25,15 +25,19 @@ class Ct {
25
25
  intersect;
26
26
  /** The original DOM event, or undefined if not applicable. */
27
27
  originalEvent;
28
- _propagationStopped = !1;
29
- constructor(e) {
30
- this.type = e.type, this.target = e.target, this.currentTarget = e.target, this.intersect = e.intersect, this.originalEvent = e.originalEvent;
28
+ _propagationStopped = false;
29
+ constructor(init) {
30
+ this.type = init.type;
31
+ this.target = init.target;
32
+ this.currentTarget = init.target;
33
+ this.intersect = init.intersect;
34
+ this.originalEvent = init.originalEvent;
31
35
  }
32
36
  /**
33
37
  * Stops the event from bubbling up the parent chain.
34
38
  */
35
39
  stopPropagation() {
36
- this._propagationStopped = !0;
40
+ this._propagationStopped = true;
37
41
  }
38
42
  /**
39
43
  * Returns true if `stopPropagation()` has been called.
@@ -42,15 +46,15 @@ class Ct {
42
46
  return this._propagationStopped;
43
47
  }
44
48
  }
45
- class xt {
49
+ class InteractionManager {
46
50
  domElement;
47
51
  scene;
48
52
  camera;
49
- raycaster = new me();
50
- pointer = new P();
53
+ raycaster = new Raycaster();
54
+ pointer = new Vector2();
51
55
  hoveredObject = null;
52
56
  pointerDownTime = 0;
53
- pointerDownPos = new P();
57
+ pointerDownPos = new Vector2();
54
58
  clickTimer = null;
55
59
  longPressThreshold = 500;
56
60
  moveThreshold = 0.01;
@@ -62,92 +66,142 @@ class xt {
62
66
  * Whether to enable pointer move events (pointermove, pointerenter, pointerleave).
63
67
  * Disabled by default for performance optimization.
64
68
  */
65
- pointerMoveEventsEnabled = !1;
66
- constructor(e, t, s) {
67
- 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();
69
+ pointerMoveEventsEnabled = false;
70
+ constructor(domElement, scene, camera) {
71
+ this.domElement = domElement;
72
+ this.scene = scene;
73
+ this.camera = camera;
74
+ this.raycaster.params.Points.threshold = 0.1;
75
+ this.raycaster.params.Line.threshold = 0.1;
76
+ this.targetObjects = this.scene.children;
77
+ this._bindEvents();
68
78
  }
69
79
  /**
70
80
  * Updates the camera reference (useful when switching cameras).
71
81
  */
72
- setCamera(e) {
73
- this.camera = e;
82
+ setCamera(camera) {
83
+ this.camera = camera;
74
84
  }
75
85
  _bindEvents() {
76
- 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);
77
- }
78
- _updatePointer(e) {
79
- const t = this.domElement.getBoundingClientRect();
80
- this.pointer.x = (e.clientX - t.left) / t.width * 2 - 1, this.pointer.y = -((e.clientY - t.top) / t.height) * 2 + 1;
86
+ this.domElement.addEventListener("click", this._onClick);
87
+ this.domElement.addEventListener("dblclick", this._onDblClick);
88
+ this.domElement.addEventListener("contextmenu", this._onContextMenu);
89
+ this.domElement.addEventListener("pointerdown", this._onPointerDown);
90
+ this.domElement.addEventListener("pointerup", this._onPointerUp);
91
+ this.domElement.addEventListener("pointermove", this._onPointerMove);
92
+ }
93
+ _updatePointer(event) {
94
+ const rect = this.domElement.getBoundingClientRect();
95
+ this.pointer.x = (event.clientX - rect.left) / rect.width * 2 - 1;
96
+ this.pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
81
97
  }
82
98
  _getIntersects() {
83
- return this.raycaster.setFromCamera(this.pointer, this.camera), this.raycaster.intersectObjects(this.targetObjects, !0);
99
+ this.raycaster.setFromCamera(this.pointer, this.camera);
100
+ return this.raycaster.intersectObjects(this.targetObjects, true);
84
101
  }
85
102
  /**
86
103
  * Dispatches an event to the target object and bubbles up the parent chain.
87
104
  */
88
- _dispatchToTarget(e, t, s, n) {
89
- const i = new Ct({
90
- type: e,
91
- target: t,
92
- intersect: s,
93
- originalEvent: n
105
+ _dispatchToTarget(type, target, intersect, originalEvent) {
106
+ const event3d = new InteractionEvent({
107
+ type,
108
+ target,
109
+ intersect,
110
+ originalEvent
94
111
  });
95
- let a = t;
96
- for (; a && !i.propagationStopped; )
97
- i.currentTarget = a, a.dispatchEvent({ type: e, event: i }), a = a.parent;
112
+ let current = target;
113
+ while (current && !event3d.propagationStopped) {
114
+ event3d.currentTarget = current;
115
+ current.dispatchEvent({ type, event: event3d });
116
+ current = current.parent;
117
+ }
98
118
  }
99
119
  /**
100
120
  * Handles a DOM event by raycasting and dispatching to the first intersected object.
101
121
  */
102
- _handleEvent(e, t) {
103
- this._updatePointer(t);
104
- const s = this._getIntersects();
105
- if (s.length === 0) return;
106
- const n = s[0];
107
- this._dispatchToTarget(e, n.object, n, t);
122
+ _handleEvent(type, originalEvent) {
123
+ this._updatePointer(originalEvent);
124
+ const intersects = this._getIntersects();
125
+ if (intersects.length === 0) return;
126
+ const hit = intersects[0];
127
+ this._dispatchToTarget(type, hit.object, hit, originalEvent);
108
128
  }
109
129
  _onClick = (e) => {
110
- const t = Date.now() - this.pointerDownTime, s = this.pointer.distanceTo(this.pointerDownPos);
111
- if (!(t > this.longPressThreshold || s > this.moveThreshold)) {
112
- if (this.clickTimer) {
113
- clearTimeout(this.clickTimer), this.clickTimer = null;
114
- return;
115
- }
116
- this.clickTimer = setTimeout(() => {
117
- this._handleEvent("click", e), this.clickTimer = null;
118
- }, 200);
130
+ const duration = Date.now() - this.pointerDownTime;
131
+ const moveDistance = this.pointer.distanceTo(this.pointerDownPos);
132
+ if (duration > this.longPressThreshold || moveDistance > this.moveThreshold) {
133
+ return;
119
134
  }
135
+ if (this.clickTimer) {
136
+ clearTimeout(this.clickTimer);
137
+ this.clickTimer = null;
138
+ return;
139
+ }
140
+ this.clickTimer = setTimeout(() => {
141
+ this._handleEvent("click", e);
142
+ this.clickTimer = null;
143
+ }, 200);
120
144
  };
121
145
  _onDblClick = (e) => {
122
- this.clickTimer && (clearTimeout(this.clickTimer), this.clickTimer = null), this._handleEvent("dblclick", e);
146
+ if (this.clickTimer) {
147
+ clearTimeout(this.clickTimer);
148
+ this.clickTimer = null;
149
+ }
150
+ this._handleEvent("dblclick", e);
123
151
  };
124
152
  _onContextMenu = (e) => {
125
153
  e.preventDefault();
126
154
  };
127
155
  _onPointerDown = (e) => {
128
- this.pointerDownTime = Date.now(), this._updatePointer(e), this.pointerDownPos.copy(this.pointer), this._handleEvent("pointerdown", e);
156
+ this.pointerDownTime = Date.now();
157
+ this._updatePointer(e);
158
+ this.pointerDownPos.copy(this.pointer);
159
+ this._handleEvent("pointerdown", e);
129
160
  };
130
161
  _onPointerUp = (e) => {
131
- if (this._updatePointer(e), e.button === 2) {
132
- const t = Date.now() - this.pointerDownTime, s = this.pointer.distanceTo(this.pointerDownPos);
133
- t <= this.longPressThreshold && s <= this.moveThreshold && this._handleEvent("rightclick", e);
162
+ this._updatePointer(e);
163
+ if (e.button === 2) {
164
+ const duration = Date.now() - this.pointerDownTime;
165
+ const moveDistance = this.pointer.distanceTo(this.pointerDownPos);
166
+ if (duration <= this.longPressThreshold && moveDistance <= this.moveThreshold) {
167
+ this._handleEvent("rightclick", e);
168
+ }
134
169
  }
135
170
  this._handleEvent("pointerup", e);
136
171
  };
137
172
  _onPointerMove = (e) => {
138
173
  if (!this.pointerMoveEventsEnabled) return;
139
174
  this._updatePointer(e);
140
- const t = this._getIntersects(), s = t.length > 0 ? t[0].object : null, n = t.length > 0 ? t[0] : null;
141
- 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);
175
+ const intersects = this._getIntersects();
176
+ const hitObject = intersects.length > 0 ? intersects[0].object : null;
177
+ const intersect = intersects.length > 0 ? intersects[0] : null;
178
+ if (this.hoveredObject !== hitObject) {
179
+ if (this.hoveredObject) {
180
+ this._dispatchToTarget("pointerleave", this.hoveredObject, null, e);
181
+ }
182
+ this.hoveredObject = hitObject;
183
+ if (hitObject && intersect) {
184
+ this._dispatchToTarget("pointerenter", hitObject, intersect, e);
185
+ }
186
+ }
187
+ if (hitObject && intersect) {
188
+ this._dispatchToTarget("pointermove", hitObject, intersect, e);
189
+ }
142
190
  };
143
191
  /**
144
192
  * Cleans up event listeners.
145
193
  */
146
194
  dispose() {
147
- 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;
195
+ this.domElement.removeEventListener("click", this._onClick);
196
+ this.domElement.removeEventListener("dblclick", this._onDblClick);
197
+ this.domElement.removeEventListener("contextmenu", this._onContextMenu);
198
+ this.domElement.removeEventListener("pointerdown", this._onPointerDown);
199
+ this.domElement.removeEventListener("pointerup", this._onPointerUp);
200
+ this.domElement.removeEventListener("pointermove", this._onPointerMove);
201
+ this.hoveredObject = null;
148
202
  }
149
203
  }
150
- class Mt {
204
+ class ObjectManager {
151
205
  idMap = /* @__PURE__ */ new Map();
152
206
  nameMap = /* @__PURE__ */ new Map();
153
207
  typeMap = /* @__PURE__ */ new Map();
@@ -157,85 +211,117 @@ class Mt {
157
211
  * Add an object with a custom id.
158
212
  * One object can have multiple ids.
159
213
  */
160
- add(e, t) {
161
- if (this.idMap.has(e)) {
162
- console.warn(`ObjectManager: Object with id ${e} already exists.`);
214
+ add(id, object) {
215
+ if (this.idMap.has(id)) {
216
+ console.warn(`ObjectManager: Object with id ${id} already exists.`);
163
217
  return;
164
218
  }
165
- this.idMap.set(e, t), this.allObjects.add(t), this.objectIds.has(t) || this.objectIds.set(t, /* @__PURE__ */ new Set()), this.objectIds.get(t).add(e), t.name && (this.nameMap.has(t.name) || this.nameMap.set(t.name, /* @__PURE__ */ new Set()), this.nameMap.get(t.name).add(t)), t.type && (this.typeMap.has(t.type) || this.typeMap.set(t.type, /* @__PURE__ */ new Set()), this.typeMap.get(t.type).add(t));
219
+ this.idMap.set(id, object);
220
+ this.allObjects.add(object);
221
+ if (!this.objectIds.has(object)) {
222
+ this.objectIds.set(object, /* @__PURE__ */ new Set());
223
+ }
224
+ this.objectIds.get(object).add(id);
225
+ if (object.name) {
226
+ if (!this.nameMap.has(object.name)) {
227
+ this.nameMap.set(object.name, /* @__PURE__ */ new Set());
228
+ }
229
+ this.nameMap.get(object.name).add(object);
230
+ }
231
+ if (object.type) {
232
+ if (!this.typeMap.has(object.type)) {
233
+ this.typeMap.set(object.type, /* @__PURE__ */ new Set());
234
+ }
235
+ this.typeMap.get(object.type).add(object);
236
+ }
166
237
  }
167
238
  /**
168
239
  * Get an object by its custom id.
169
240
  */
170
- getById(e) {
171
- return this.idMap.get(e);
241
+ getById(id) {
242
+ return this.idMap.get(id);
172
243
  }
173
244
  /**
174
245
  * Get all objects with a given name.
175
246
  */
176
- getByName(e) {
177
- return this.nameMap.get(e) || /* @__PURE__ */ new Set();
247
+ getByName(name) {
248
+ return this.nameMap.get(name) || /* @__PURE__ */ new Set();
178
249
  }
179
250
  /**
180
251
  * Get all objects with a given type.
181
252
  */
182
- getByType(e) {
183
- return this.typeMap.get(e) || /* @__PURE__ */ new Set();
253
+ getByType(type) {
254
+ return this.typeMap.get(type) || /* @__PURE__ */ new Set();
184
255
  }
185
256
  /**
186
257
  * Get all ids associated with an object.
187
258
  */
188
- getObjectIds(e) {
189
- return this.objectIds.get(e) || /* @__PURE__ */ new Set();
259
+ getObjectIds(object) {
260
+ return this.objectIds.get(object) || /* @__PURE__ */ new Set();
190
261
  }
191
262
  /**
192
263
  * Remove an object and all its associated ids.
193
264
  */
194
- remove(e) {
195
- const t = this.objectIds.get(e);
196
- if (t) {
197
- for (const s of t)
198
- this.idMap.delete(s);
199
- this.objectIds.delete(e);
265
+ remove(object) {
266
+ const ids = this.objectIds.get(object);
267
+ if (ids) {
268
+ for (const id of ids) {
269
+ this.idMap.delete(id);
270
+ }
271
+ this.objectIds.delete(object);
200
272
  }
201
- if (e.name && this.nameMap.has(e.name)) {
202
- const s = this.nameMap.get(e.name);
203
- s.delete(e), s.size === 0 && this.nameMap.delete(e.name);
273
+ if (object.name && this.nameMap.has(object.name)) {
274
+ const set = this.nameMap.get(object.name);
275
+ set.delete(object);
276
+ if (set.size === 0) {
277
+ this.nameMap.delete(object.name);
278
+ }
204
279
  }
205
- if (e.type && this.typeMap.has(e.type)) {
206
- const s = this.typeMap.get(e.type);
207
- s.delete(e), s.size === 0 && this.typeMap.delete(e.type);
280
+ if (object.type && this.typeMap.has(object.type)) {
281
+ const set = this.typeMap.get(object.type);
282
+ set.delete(object);
283
+ if (set.size === 0) {
284
+ this.typeMap.delete(object.type);
285
+ }
208
286
  }
209
- this.allObjects.delete(e);
287
+ this.allObjects.delete(object);
210
288
  }
211
289
  /**
212
290
  * Remove an object by its id.
213
291
  */
214
- removeById(e) {
215
- const t = this.idMap.get(e);
216
- t && this.remove(t);
292
+ removeById(id) {
293
+ const object = this.idMap.get(id);
294
+ if (object) {
295
+ this.remove(object);
296
+ }
217
297
  }
218
298
  /**
219
299
  * Remove all objects with a given name.
220
300
  */
221
- removeByName(e) {
222
- const t = this.getByName(e);
223
- for (const s of t)
224
- this.remove(s);
301
+ removeByName(name) {
302
+ const objects = this.getByName(name);
303
+ for (const object of objects) {
304
+ this.remove(object);
305
+ }
225
306
  }
226
307
  /**
227
308
  * Remove all objects with a given type.
228
309
  */
229
- removeByType(e) {
230
- const t = this.getByType(e);
231
- for (const s of t)
232
- this.remove(s);
310
+ removeByType(type) {
311
+ const objects = this.getByType(type);
312
+ for (const object of objects) {
313
+ this.remove(object);
314
+ }
233
315
  }
234
316
  /**
235
317
  * Clear all cached objects.
236
318
  */
237
319
  clear() {
238
- this.idMap.clear(), this.nameMap.clear(), this.typeMap.clear(), this.objectIds.clear(), this.allObjects.clear();
320
+ this.idMap.clear();
321
+ this.nameMap.clear();
322
+ this.typeMap.clear();
323
+ this.objectIds.clear();
324
+ this.allObjects.clear();
239
325
  }
240
326
  /**
241
327
  * Get all cached objects as a Set.
@@ -250,148 +336,202 @@ class Mt {
250
336
  return this.allObjects.size;
251
337
  }
252
338
  }
253
- class Et extends Be {
339
+ class RenderPipeline extends RenderPipeline$1 {
254
340
  scene;
255
341
  camera;
256
342
  currentOutputNode;
257
343
  needsUpdateOutputNode;
258
- #e;
259
- constructor(...e) {
260
- const [t, s, n] = e;
261
- super(t), this.scene = s, this.camera = n, this.currentOutputNode = q(s, n), this.needsUpdateOutputNode = !0, this.#e = /* @__PURE__ */ new Set();
262
- }
263
- addOverlayPass(e) {
264
- this.#e.add(e), this.needsUpdateOutputNode = !0;
265
- }
266
- removeOverlayPass(e) {
267
- this.#e.delete(e), this.needsUpdateOutputNode = !0;
268
- }
269
- setCamera(e) {
270
- this.camera = e, this.needsUpdateOutputNode = !0;
271
- }
272
- setCurrentOutputNode(e) {
273
- this.currentOutputNode.dispose(), this.currentOutputNode = e, this.needsUpdateOutputNode = !0;
344
+ #overlayPasses;
345
+ constructor(...args) {
346
+ const [renderer, scene, camera] = args;
347
+ super(renderer);
348
+ this.scene = scene;
349
+ this.camera = camera;
350
+ this.currentOutputNode = pass(scene, camera);
351
+ this.needsUpdateOutputNode = true;
352
+ this.#overlayPasses = /* @__PURE__ */ new Set();
353
+ }
354
+ addOverlayPass(pass2) {
355
+ this.#overlayPasses.add(pass2);
356
+ this.needsUpdateOutputNode = true;
357
+ }
358
+ removeOverlayPass(pass2) {
359
+ this.#overlayPasses.delete(pass2);
360
+ this.needsUpdateOutputNode = true;
361
+ }
362
+ setCamera(camera) {
363
+ this.camera = camera;
364
+ this.needsUpdateOutputNode = true;
365
+ }
366
+ setCurrentOutputNode(node) {
367
+ this.currentOutputNode.dispose();
368
+ this.currentOutputNode = node;
369
+ this.needsUpdateOutputNode = true;
274
370
  }
275
371
  resetCurrentOutputNode() {
276
- this.currentOutputNode.dispose(), this.currentOutputNode = q(this.scene, this.camera), this.needsUpdateOutputNode = !0;
277
- }
278
- #t() {
279
- let e = this.currentOutputNode;
280
- this.#e.size > 0 && this.#e.forEach((t) => {
281
- e = ht(e, t);
282
- }), this.outputNode = e, this.needsUpdate = !0;
372
+ this.currentOutputNode.dispose();
373
+ this.currentOutputNode = pass(this.scene, this.camera);
374
+ this.needsUpdateOutputNode = true;
375
+ }
376
+ #updateOutputNode() {
377
+ let currentNode = this.currentOutputNode;
378
+ if (this.#overlayPasses.size > 0) {
379
+ this.#overlayPasses.forEach((overlayPass) => {
380
+ currentNode = blendColor(currentNode, overlayPass);
381
+ });
382
+ }
383
+ this.outputNode = currentNode;
384
+ this.needsUpdate = true;
283
385
  }
284
386
  render() {
285
- this.needsUpdateOutputNode && (this.#t(), this.needsUpdateOutputNode = !1), super.render();
387
+ if (this.needsUpdateOutputNode) {
388
+ this.#updateOutputNode();
389
+ this.needsUpdateOutputNode = false;
390
+ }
391
+ super.render();
286
392
  }
287
393
  }
288
- const Ot = {
289
- Vector2: P,
290
- Vector3: J,
291
- Vector4: Ne,
292
- Quaternion: _e,
293
- Matrix4: Re,
294
- Spherical: C,
295
- Box3: we,
296
- Sphere: ge,
297
- Raycaster: me
394
+ const subsetOfTHREE = {
395
+ Vector2,
396
+ Vector3,
397
+ Vector4,
398
+ Quaternion,
399
+ Matrix4,
400
+ Spherical,
401
+ Box3,
402
+ Sphere,
403
+ Raycaster
298
404
  };
299
- Ce.install({ THREE: Ot });
300
- class Pt extends Ce {
301
- constructor(...e) {
302
- super(...e), this.minDistance = 0.2, this.smoothTime = 0.2, this.dollySpeed = 0.2;
405
+ CameraControlsBase.install({ THREE: subsetOfTHREE });
406
+ class CameraControls extends CameraControlsBase {
407
+ constructor(...args) {
408
+ super(...args);
409
+ this.minDistance = 0.2;
410
+ this.smoothTime = 0.2;
411
+ this.dollySpeed = 0.2;
303
412
  }
304
413
  /**
305
414
  * Set absolute angle for azimuth to avoid spinning
306
415
  */
307
416
  absoluteRotations() {
308
- this.azimuthAngle = St(this.azimuthAngle, 0);
417
+ this.azimuthAngle = absoluteAngle(this.azimuthAngle, 0);
309
418
  }
310
- async flyToBox(e, t = {}) {
311
- if (e.isEmpty())
312
- return console.warn("CameraControls.flyToBox: The provided Box3 is empty."), !1;
419
+ async flyToBox(box, options = {}) {
420
+ if (box.isEmpty()) {
421
+ console.warn("CameraControls.flyToBox: The provided Box3 is empty.");
422
+ return false;
423
+ }
313
424
  this.absoluteRotations();
314
- const { viewpoint: s = "frontTop", enableTransition: n = !0, padding: i = 0.1, cover: a = !1 } = t, c = [];
315
- if (s !== "current") {
316
- const r = de[s.toUpperCase()] ?? de.FRONTTOP, h = r.theta, l = r.phi;
317
- c.push(
318
- this.fitToBox(e, n, {
319
- paddingLeft: i,
320
- paddingRight: i,
321
- paddingTop: i,
322
- paddingBottom: i,
323
- cover: a
425
+ const { viewpoint = "frontTop", enableTransition = true, padding = 0.1, cover = false } = options;
426
+ const promises = [];
427
+ if (viewpoint !== "current") {
428
+ const spherical = viewpointsSpherical[viewpoint.toUpperCase()] ?? viewpointsSpherical.FRONTTOP;
429
+ const azimuthAngle = spherical.theta, polarAngle = spherical.phi;
430
+ promises.push(
431
+ this.fitToBox(box, enableTransition, {
432
+ paddingLeft: padding,
433
+ paddingRight: padding,
434
+ paddingTop: padding,
435
+ paddingBottom: padding,
436
+ cover
324
437
  })
325
- ), c.push(this.rotateTo(h, l, n));
438
+ );
439
+ promises.push(this.rotateTo(azimuthAngle, polarAngle, enableTransition));
326
440
  } else {
327
- const r = new ge();
328
- e.getBoundingSphere(r), r.radius += i, c.push(this.fitToSphere(r, n));
441
+ const sphere = new Sphere();
442
+ box.getBoundingSphere(sphere);
443
+ sphere.radius += padding;
444
+ promises.push(this.fitToSphere(sphere, enableTransition));
329
445
  }
330
- return await Promise.all(c), !0;
446
+ await Promise.all(promises);
447
+ return true;
331
448
  }
332
- async flyToObject(e, t = {}) {
333
- const s = new we().setFromObject(e);
334
- return this.flyToBox(s, t);
449
+ async flyToObject(object, options = {}) {
450
+ const box = new Box3().setFromObject(object);
451
+ return this.flyToBox(box, options);
335
452
  }
336
453
  }
337
- const de = {
338
- LEFT: new C(0, Math.PI / 2, -Math.PI / 2),
339
- RIGHT: new C(0, Math.PI / 2, Math.PI / 2),
340
- FRONT: new C(0, Math.PI / 2, 0),
341
- BACK: new C(0, Math.PI / 2, Math.PI),
342
- TOP: new C(0, 0, 0),
343
- BOTTOM: new C(0, Math.PI, 0),
344
- FRONTTOP: new C(0, Math.PI / 4, 0),
345
- BACKTOP: new C(0, Math.PI / 4, Math.PI),
346
- LEFTTOP: new C(0, Math.PI / 4, -Math.PI / 2),
347
- RIGHTTOP: new C(0, Math.PI / 4, Math.PI / 2),
348
- LEFTFRONTTOP: new C(0, Math.PI / 4, -Math.PI / 4),
349
- RIGHTFRONTTOP: new C(0, Math.PI / 4, Math.PI / 4),
350
- LEFTBACKTOP: new C(0, Math.PI / 4, -Math.PI / 4 * 3),
351
- RIGHTBACKTOP: new C(0, Math.PI / 4, Math.PI / 4 * 3)
454
+ const viewpointsSpherical = {
455
+ LEFT: new Spherical(0, Math.PI / 2, -Math.PI / 2),
456
+ RIGHT: new Spherical(0, Math.PI / 2, Math.PI / 2),
457
+ FRONT: new Spherical(0, Math.PI / 2, 0),
458
+ BACK: new Spherical(0, Math.PI / 2, Math.PI),
459
+ TOP: new Spherical(0, 0, 0),
460
+ BOTTOM: new Spherical(0, Math.PI, 0),
461
+ FRONTTOP: new Spherical(0, Math.PI / 4, 0),
462
+ BACKTOP: new Spherical(0, Math.PI / 4, Math.PI),
463
+ LEFTTOP: new Spherical(0, Math.PI / 4, -Math.PI / 2),
464
+ RIGHTTOP: new Spherical(0, Math.PI / 4, Math.PI / 2),
465
+ LEFTFRONTTOP: new Spherical(0, Math.PI / 4, -Math.PI / 4),
466
+ RIGHTFRONTTOP: new Spherical(0, Math.PI / 4, Math.PI / 4),
467
+ LEFTBACKTOP: new Spherical(0, Math.PI / 4, -Math.PI / 4 * 3),
468
+ RIGHTBACKTOP: new Spherical(0, Math.PI / 4, Math.PI / 4 * 3)
352
469
  };
353
- function St(o, e) {
354
- const t = o - e;
355
- return Ae.euclideanModulo(t + Math.PI, Math.PI * 2) - Math.PI;
470
+ function absoluteAngle(targetAngle, sourceAngle) {
471
+ const angle = targetAngle - sourceAngle;
472
+ return MathUtils.euclideanModulo(angle + Math.PI, Math.PI * 2) - Math.PI;
356
473
  }
357
- class Lt {
358
- environment = new pt();
474
+ class RoomEnvironment {
475
+ environment = new RoomEnvironment$1();
359
476
  renderer;
360
477
  pmremGenerator;
361
478
  envMap = null;
362
- constructor(e) {
363
- this.renderer = e, this.pmremGenerator = new Ue(e);
479
+ constructor(renderer) {
480
+ this.renderer = renderer;
481
+ this.pmremGenerator = new PMREMGenerator(renderer);
364
482
  }
365
483
  update() {
366
- this.envMap || (this.envMap = this.pmremGenerator.fromScene(this.environment).texture);
484
+ if (!this.envMap) {
485
+ this.envMap = this.pmremGenerator.fromScene(this.environment).texture;
486
+ }
367
487
  }
368
488
  dispose() {
369
- this.pmremGenerator.dispose(), this.envMap?.dispose();
489
+ this.pmremGenerator.dispose();
490
+ this.envMap?.dispose();
370
491
  }
371
492
  }
372
- const G = 128;
373
- class It extends ut {
493
+ const dim = 128;
494
+ class ViewerHelper extends ViewHelper {
374
495
  viewer;
375
496
  overlayPass;
376
- constructor(e) {
377
- super(e.camera, e.el), this.viewer = e;
378
- const t = new F(-2, 2, 2, -2, 0, 4);
379
- t.position.set(0, 0, 2), this.overlayPass = q(this, t), this.setLabels("x", "y", "z");
497
+ constructor(viewer) {
498
+ super(viewer.camera, viewer.el);
499
+ this.viewer = viewer;
500
+ const orthoCamera = new OrthographicCamera(-2, 2, 2, -2, 0, 4);
501
+ orthoCamera.position.set(0, 0, 2);
502
+ this.overlayPass = pass(this, orthoCamera);
503
+ this.setLabels("x", "y", "z");
380
504
  }
381
505
  _update = () => {
382
506
  this.quaternion.copy(this.viewer.camera.quaternion).invert();
383
- const e = this.location;
384
- let t, s;
385
- e.left !== null ? t = e.left : t = this.viewer.el.offsetWidth - G - e.right, e.top !== null ? s = e.top : s = this.viewer.el.offsetHeight - G - e.bottom, this.overlayPass.setViewport(t, s, G, G);
507
+ const location = this.location;
508
+ let x, y;
509
+ if (location.left !== null) {
510
+ x = location.left;
511
+ } else {
512
+ x = this.viewer.el.offsetWidth - dim - location.right;
513
+ }
514
+ if (location.top !== null) {
515
+ y = location.top;
516
+ } else {
517
+ y = this.viewer.el.offsetHeight - dim - location.bottom;
518
+ }
519
+ this.overlayPass.setViewport(x, y, dim, dim);
386
520
  };
387
521
  enable() {
388
- return this.viewer.renderPipeline.addOverlayPass(this.overlayPass), this.viewer.addEventListener("beforeRender", this._update), this.viewer.render(), this;
522
+ this.viewer.renderPipeline.addOverlayPass(this.overlayPass);
523
+ this.viewer.addEventListener("beforeRender", this._update);
524
+ this.viewer.render();
525
+ return this;
389
526
  }
390
527
  disable() {
391
- return this.viewer.renderPipeline.removeOverlayPass(this.overlayPass), this.viewer.removeEventListener("beforeRender", this._update), this.viewer.render(), this;
528
+ this.viewer.renderPipeline.removeOverlayPass(this.overlayPass);
529
+ this.viewer.removeEventListener("beforeRender", this._update);
530
+ this.viewer.render();
531
+ return this;
392
532
  }
393
533
  }
394
- class Bt {
534
+ class Info {
395
535
  el;
396
536
  renderer;
397
537
  container;
@@ -401,40 +541,79 @@ class Bt {
401
541
  pointsText;
402
542
  linesText;
403
543
  timestampText;
404
- _enabled = !1;
405
- constructor(e, t) {
406
- this.el = e, this.renderer = t;
407
- const s = document.createElement("div");
408
- 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;
409
- function n(a, c = !0) {
410
- const r = document.createElement("span");
411
- return c && (r.style.marginLeft = "6px"), r.innerText = a, r;
412
- }
413
- function i() {
544
+ _enabled = false;
545
+ constructor(el, renderer) {
546
+ this.el = el;
547
+ this.renderer = renderer;
548
+ const container = document.createElement("div");
549
+ container.style.position = "absolute";
550
+ container.style.left = "12px";
551
+ container.style.bottom = "12px";
552
+ container.style.fontSize = "12px";
553
+ container.style.color = "#fff";
554
+ container.style.pointerEvents = "none";
555
+ this.container = container;
556
+ function createTextEl(text, isMarginLeft = true) {
557
+ const el2 = document.createElement("span");
558
+ if (isMarginLeft) el2.style.marginLeft = "6px";
559
+ el2.innerText = text;
560
+ return el2;
561
+ }
562
+ function createBr() {
414
563
  return document.createElement("br");
415
564
  }
416
- 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());
565
+ this.drawCallsText = createTextEl("0");
566
+ this.frameCallsText = createTextEl("0");
567
+ this.trianglesText = createTextEl("0");
568
+ this.linesText = createTextEl("0");
569
+ this.pointsText = createTextEl("0");
570
+ this.timestampText = createTextEl("0");
571
+ this.container.appendChild(createTextEl("draw calls", false));
572
+ this.container.appendChild(this.drawCallsText);
573
+ this.container.appendChild(createBr());
574
+ this.container.appendChild(createTextEl("frame calls", false));
575
+ this.container.appendChild(this.frameCallsText);
576
+ this.container.appendChild(createBr());
577
+ this.container.appendChild(createTextEl("triangles", false));
578
+ this.container.appendChild(this.trianglesText);
579
+ this.container.appendChild(createBr());
580
+ this.container.appendChild(createTextEl("points", false));
581
+ this.container.appendChild(this.pointsText);
582
+ this.container.appendChild(createBr());
583
+ this.container.appendChild(createTextEl("lines", false));
584
+ this.container.appendChild(this.linesText);
585
+ this.container.appendChild(createBr());
586
+ this.container.appendChild(createTextEl("timestamp", false));
587
+ this.container.appendChild(this.timestampText);
588
+ this.container.appendChild(createBr());
417
589
  }
418
590
  update() {
419
591
  if (this._enabled) {
420
- const { render: e } = this.renderer.info;
421
- 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(De.RENDER).then((t) => {
422
- this.timestampText.innerText = t?.toFixed(2) ?? "0";
592
+ const { render } = this.renderer.info;
593
+ this.drawCallsText.innerText = render.drawCalls.toString();
594
+ this.frameCallsText.innerText = render.frameCalls.toString();
595
+ this.trianglesText.innerText = render.triangles.toString();
596
+ this.pointsText.innerText = render.points.toString();
597
+ this.linesText.innerText = render.lines.toString();
598
+ this.renderer.resolveTimestampsAsync(TimestampQuery.RENDER).then((timestamps) => {
599
+ this.timestampText.innerText = timestamps?.toFixed(2) ?? "0";
423
600
  });
424
601
  }
425
602
  }
426
603
  enable() {
427
- this._enabled = !0, this.el.appendChild(this.container);
604
+ this._enabled = true;
605
+ this.el.appendChild(this.container);
428
606
  }
429
607
  disable() {
430
- this._enabled = !1, this.container.remove();
608
+ this._enabled = false;
609
+ this.container.remove();
431
610
  }
432
611
  dispose() {
433
612
  this.disable();
434
613
  }
435
614
  }
436
- je.enabled = !0;
437
- class ys extends ke {
615
+ Cache.enabled = true;
616
+ class Viewer extends EventDispatcher {
438
617
  el;
439
618
  renderer;
440
619
  scene;
@@ -449,55 +628,119 @@ class ys extends ke {
449
628
  viewerHelper;
450
629
  frameCount = 1;
451
630
  frameloop = "demand";
452
- constructor({ el: e, rendererOptions: t }) {
453
- super(), this.el = e, this.renderer = this._initRenderer(t), this.scene = this.createScene(), this.camera = this.createPerspectiveCamera(), this.info = new Bt(this.el, this.renderer), this.controls = new Pt(this.camera, this.renderer.domElement), this.renderPipeline = new Et(this.renderer, this.scene, this.camera), this.timer = new Ge(), this.roomEnvironment = new Lt(this.renderer), this.interactionManager = new xt(this.renderer.domElement, this.scene, this.camera), this.objectManager = new Mt(), this.viewerHelper = new It(this), window.addEventListener("resize", this.onWindowResize);
631
+ constructor({ el, rendererOptions }) {
632
+ super();
633
+ this.el = el;
634
+ this.renderer = this._initRenderer(rendererOptions);
635
+ this.scene = this.createScene();
636
+ this.camera = this.createPerspectiveCamera();
637
+ this.info = new Info(this.el, this.renderer);
638
+ this.controls = new CameraControls(this.camera, this.renderer.domElement);
639
+ this.renderPipeline = new RenderPipeline(this.renderer, this.scene, this.camera);
640
+ this.timer = new Timer();
641
+ this.roomEnvironment = new RoomEnvironment(this.renderer);
642
+ this.interactionManager = new InteractionManager(this.renderer.domElement, this.scene, this.camera);
643
+ this.objectManager = new ObjectManager();
644
+ this.viewerHelper = new ViewerHelper(this);
645
+ window.addEventListener("resize", this.onWindowResize);
454
646
  }
455
647
  onWindowResize = () => {
456
- const e = this.el.clientWidth, t = this.el.clientHeight;
457
- this.camera instanceof W ? (this.camera.aspect = e / t, this.camera.updateProjectionMatrix()) : this.camera instanceof F && (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.render();
648
+ const width = this.el.clientWidth;
649
+ const height = this.el.clientHeight;
650
+ if (this.camera instanceof PerspectiveCamera) {
651
+ this.camera.aspect = width / height;
652
+ this.camera.updateProjectionMatrix();
653
+ } else if (this.camera instanceof OrthographicCamera) {
654
+ this.camera.left = -width / 2;
655
+ this.camera.right = width / 2;
656
+ this.camera.top = height / 2;
657
+ this.camera.bottom = -height / 2;
658
+ this.camera.updateProjectionMatrix();
659
+ }
660
+ this.renderer.setSize(width, height);
661
+ this.render();
458
662
  };
459
663
  async init() {
460
- await this.renderer.init(), this.roomEnvironment.update(), this.scene.environment = this.roomEnvironment.envMap;
461
- }
462
- setCamera(e) {
463
- this.camera = e, this.controls.camera = e, this.interactionManager.setCamera(e), this.renderPipeline.setCamera(e), this.onWindowResize(), this.dispatchEvent({ type: "cameraChange", camera: e });
464
- }
465
- setCameraByType(e) {
466
- e === "perspective" && !(this.camera instanceof W) ? this.setCamera(this.createPerspectiveCamera()) : e === "orthographic" && !(this.camera instanceof F) && this.setCamera(this.createOrthographicCamera());
664
+ await this.renderer.init();
665
+ this.roomEnvironment.update();
666
+ this.scene.environment = this.roomEnvironment.envMap;
667
+ }
668
+ setCamera(camera) {
669
+ this.camera = camera;
670
+ this.controls.camera = camera;
671
+ this.interactionManager.setCamera(camera);
672
+ this.renderPipeline.setCamera(camera);
673
+ this.onWindowResize();
674
+ this.dispatchEvent({ type: "cameraChange", camera });
675
+ }
676
+ setCameraByType(type) {
677
+ if (type === "perspective" && !(this.camera instanceof PerspectiveCamera)) {
678
+ this.setCamera(this.createPerspectiveCamera());
679
+ } else if (type === "orthographic" && !(this.camera instanceof OrthographicCamera)) {
680
+ this.setCamera(this.createOrthographicCamera());
681
+ }
467
682
  }
468
- render(e = 1) {
469
- return this.frameCount += e, new Promise((t) => {
470
- const s = () => {
471
- this.removeEventListener("afterRender", s), t();
683
+ render(frame = 1) {
684
+ this.frameCount += frame;
685
+ return new Promise((resolve) => {
686
+ const fn = () => {
687
+ this.removeEventListener("afterRender", fn);
688
+ resolve();
472
689
  };
473
- this.addEventListener("afterRender", s);
690
+ this.addEventListener("afterRender", fn);
474
691
  });
475
692
  }
476
- animate = (e) => {
477
- this.timer.update(e), this.dispatchEvent({ type: "beforeControlsUpdate", time: e });
478
- let t = this.controls.update(this.timer.getDelta());
479
- this.dispatchEvent({ type: "afterControlsUpdate", time: e }), this.frameCount > 0 && (this.frameCount--, t = !0), this.frameloop === "always" && (t = !0), t && (this.dispatchEvent({ type: "beforeRender", time: e }), this.renderer.info.reset(), this.renderPipeline.render(), this.info.update(), this.dispatchEvent({ type: "afterRender", time: e }));
693
+ animate = (time2) => {
694
+ this.timer.update(time2);
695
+ this.dispatchEvent({ type: "beforeControlsUpdate", time: time2 });
696
+ let needsRender = this.controls.update(this.timer.getDelta());
697
+ this.dispatchEvent({ type: "afterControlsUpdate", time: time2 });
698
+ if (this.frameCount > 0) {
699
+ this.frameCount--;
700
+ needsRender = true;
701
+ }
702
+ if (this.frameloop === "always") {
703
+ needsRender = true;
704
+ }
705
+ if (needsRender) {
706
+ this.dispatchEvent({ type: "beforeRender", time: time2 });
707
+ this.renderer.info.reset();
708
+ this.renderPipeline.render();
709
+ this.info.update();
710
+ this.dispatchEvent({ type: "afterRender", time: time2 });
711
+ }
480
712
  };
481
- _initRenderer(e) {
482
- const t = new Fe({
483
- logarithmicDepthBuffer: !0,
484
- antialias: !1,
485
- depth: !1,
486
- trackTimestamp: !0,
487
- ...e
713
+ _initRenderer(rendererOptions) {
714
+ const renderer = new WebGPURenderer({
715
+ logarithmicDepthBuffer: true,
716
+ antialias: false,
717
+ depth: false,
718
+ trackTimestamp: true,
719
+ ...rendererOptions
488
720
  });
489
- return t.setSize(this.el.clientWidth, this.el.clientHeight), t.shadowMap.enabled = !0, t.shadowMap.type = He, t.toneMapping = ze, t.toneMappingExposure = 1, t.info.autoReset = !1, t.setPixelRatio(window.devicePixelRatio), t.setAnimationLoop(this.animate), this.el.appendChild(t.domElement), t;
721
+ renderer.setSize(this.el.clientWidth, this.el.clientHeight);
722
+ renderer.shadowMap.enabled = true;
723
+ renderer.shadowMap.type = PCFShadowMap;
724
+ renderer.toneMapping = AgXToneMapping;
725
+ renderer.toneMappingExposure = 1;
726
+ renderer.info.autoReset = false;
727
+ renderer.setPixelRatio(window.devicePixelRatio);
728
+ renderer.setAnimationLoop(this.animate);
729
+ this.el.appendChild(renderer.domElement);
730
+ return renderer;
490
731
  }
491
732
  createScene() {
492
- const e = new $e();
493
- return e.background = new Z(0), e;
733
+ const scene = new Scene();
734
+ scene.background = new Color(0);
735
+ return scene;
494
736
  }
495
737
  createPerspectiveCamera() {
496
- const e = new W(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);
497
- return e.position.setScalar(5), e;
738
+ const camera = new PerspectiveCamera(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);
739
+ camera.position.setScalar(5);
740
+ return camera;
498
741
  }
499
742
  createOrthographicCamera() {
500
- const e = new F(
743
+ const camera = new OrthographicCamera(
501
744
  -this.el.clientWidth / 2,
502
745
  this.el.clientWidth / 2,
503
746
  this.el.clientHeight / 2,
@@ -505,415 +748,621 @@ class ys extends ke {
505
748
  0.1,
506
749
  1e5
507
750
  );
508
- return e.position.setScalar(5), e;
751
+ camera.position.setScalar(5);
752
+ return camera;
509
753
  }
510
754
  dispose() {
511
- this.el.removeChild(this.renderer.domElement), window.removeEventListener("resize", this.onWindowResize), this.info.dispose(), this.interactionManager.dispose(), this.roomEnvironment.dispose(), this.renderPipeline.dispose(), this.renderer.dispose();
755
+ this.el.removeChild(this.renderer.domElement);
756
+ window.removeEventListener("resize", this.onWindowResize);
757
+ this.info.dispose();
758
+ this.interactionManager.dispose();
759
+ this.roomEnvironment.dispose();
760
+ this.renderPipeline.dispose();
761
+ this.renderer.dispose();
512
762
  }
513
763
  }
514
- class Rt extends xe {
515
- constructor(e) {
516
- super(e);
517
- }
518
- parse(e, t, s, n) {
519
- if (_t(e.slice(0, 8)) === "SBMG----") {
520
- const a = Nt(e.slice(8));
521
- return super.parse(a, t, s, n);
522
- } else
523
- return super.parse(e, t, s, n);
764
+ class SBMXLoader extends GLTFLoader {
765
+ constructor(manager) {
766
+ super(manager);
767
+ }
768
+ parse(data, path, onLoad, onError) {
769
+ const formatName = getAsciiString(data.slice(0, 8));
770
+ switch (formatName) {
771
+ case "SBMG----": {
772
+ const swappedBuffer = swapBytes(data.slice(8));
773
+ return super.parse(swappedBuffer, path, onLoad, onError);
774
+ }
775
+ default: {
776
+ return super.parse(data, path, onLoad, onError);
777
+ }
778
+ }
524
779
  }
525
780
  }
526
- function _t(o) {
527
- return new TextDecoder().decode(new Uint8Array(o));
781
+ function getAsciiString(buf) {
782
+ const decoder = new TextDecoder();
783
+ return decoder.decode(new Uint8Array(buf));
528
784
  }
529
- function Nt(o) {
530
- const e = new DataView(o);
531
- for (let t = 0; t < e.byteLength; t++) {
532
- const s = e.getUint8(t), n = (s >> 4 & 15) + (s << 4 & 240);
533
- e.setUint8(t, n);
534
- }
535
- return e.buffer;
785
+ function swapBytes(buffer) {
786
+ const view = new DataView(buffer);
787
+ for (let i = 0; i < view.byteLength; i++) {
788
+ const byte = view.getUint8(i);
789
+ const swappedByte = (byte >> 4 & 15) + (byte << 4 & 240);
790
+ view.setUint8(i, swappedByte);
791
+ }
792
+ return view.buffer;
536
793
  }
537
- const At = 8, Ut = 130, pe = 66, Dt = "SBK-----", jt = "SBM-----", Me = new TextDecoder(), kt = new TextEncoder();
538
- function Gt(o) {
539
- let e = At;
540
- const t = new Uint8Array(o, 0, e);
541
- if (Me.decode(t) !== Dt)
542
- return o;
543
- e += Ut;
544
- const n = new Uint8Array(o, 0, e);
545
- if (n[40] === 1) {
546
- const a = kt.encode(jt), c = new Uint8Array([n[41]]), r = Ft(n), h = Ht(r);
547
- let l = pe % h.length;
548
- const u = e + pe, f = new Uint8Array(o, u), p = new Uint8Array(f.length);
549
- for (let w = 0; w < f.length; w++)
550
- p[w] = f[w] ^ h[l], l = (l + 1) % h.length;
551
- const g = new Uint8Array(a.length + c.length + p.length);
552
- return g.set(a), g.set(c, a.length), g.set(p, a.length + c.length), g.buffer;
794
+ const BYTE_LENGTH_MAGIC = 8;
795
+ const BYTE_LENGTH_HEAD = 130;
796
+ const BYTE_LENGTH_ATTACH = 66;
797
+ const MAGIC_SBK = "SBK-----";
798
+ const MAGIC_SBM = "SBM-----";
799
+ const textDecoder = new TextDecoder();
800
+ const textEncoder = new TextEncoder();
801
+ function decodeSbk(buffer) {
802
+ let read = BYTE_LENGTH_MAGIC;
803
+ const magicBytes = new Uint8Array(buffer, 0, read);
804
+ const magic = textDecoder.decode(magicBytes);
805
+ if (magic !== MAGIC_SBK) {
806
+ return buffer;
807
+ }
808
+ read += BYTE_LENGTH_HEAD;
809
+ const headBytes = new Uint8Array(buffer, 0, read);
810
+ const version = headBytes[40];
811
+ if (version === 1) {
812
+ const magicBuf = textEncoder.encode(MAGIC_SBM);
813
+ const versionBuf = new Uint8Array([headBytes[41]]);
814
+ const sbmKey = getSbmKey(headBytes);
815
+ const encodeKey = getLeftKey(sbmKey);
816
+ let j = BYTE_LENGTH_ATTACH % encodeKey.length;
817
+ const offset = read + BYTE_LENGTH_ATTACH;
818
+ const bodyBytes = new Uint8Array(buffer, offset);
819
+ const bodyBuf = new Uint8Array(bodyBytes.length);
820
+ for (let i = 0; i < bodyBytes.length; i++) {
821
+ bodyBuf[i] = bodyBytes[i] ^ encodeKey[j];
822
+ j = (j + 1) % encodeKey.length;
823
+ }
824
+ const buf = new Uint8Array(magicBuf.length + versionBuf.length + bodyBuf.length);
825
+ buf.set(magicBuf);
826
+ buf.set(versionBuf, magicBuf.length);
827
+ buf.set(bodyBuf, magicBuf.length + versionBuf.length);
828
+ return buf.buffer;
553
829
  }
554
830
  }
555
- function Ft(o) {
556
- const e = new Uint8Array(128);
557
- return e.set(o.slice(42, 74), 0), e.set(o.slice(74, 138), 32), e.set(o.slice(8, 40), 96), e;
831
+ function getSbmKey(headBuffer) {
832
+ const bytes = new Uint8Array(128);
833
+ bytes.set(headBuffer.slice(42, 42 + 32), 0);
834
+ bytes.set(headBuffer.slice(74, 74 + 64), 32);
835
+ bytes.set(headBuffer.slice(8, 8 + 32), 96);
836
+ return bytes;
558
837
  }
559
- function Ht(o) {
560
- const e = new Uint8Array(64);
561
- return e.set(o.slice(0, 8), 0), e.set(o.slice(24, 32), 8), e.set(o.slice(40, 56), 16), e.set(o.slice(64, 88), 32), e.set(o.slice(96, 104), 56), e;
838
+ function getLeftKey(sbmKey) {
839
+ const bytes = new Uint8Array(64);
840
+ bytes.set(sbmKey.slice(0, 8), 0);
841
+ bytes.set(sbmKey.slice(24, 24 + 8), 8);
842
+ bytes.set(sbmKey.slice(40, 40 + 16), 16);
843
+ bytes.set(sbmKey.slice(64, 64 + 24), 32);
844
+ bytes.set(sbmKey.slice(96, 96 + 8), 56);
845
+ return bytes;
562
846
  }
563
- const zt = (o, e, t) => {
564
- const s = o.buffer.slice(t, t + e);
565
- let n = Me.decode(s);
566
- return n = n.replace("\\", "/"), n.startsWith("Maps/") || (n = `Maps/${n}`), n;
567
- }, $t = (o, e, t) => {
568
- const [s, n, i, a, c] = e, r = t || a < 1;
569
- return new I({
570
- name: o,
571
- color: new Z(s, n, i),
572
- opacity: a,
573
- transparent: r,
847
+ const getTextureName = (dataView, texnamelen, offset) => {
848
+ const temp = dataView.buffer.slice(offset, offset + texnamelen);
849
+ let textureName = textDecoder.decode(temp);
850
+ textureName = textureName.replace("\\", "/");
851
+ if (!textureName.startsWith("Maps/")) {
852
+ textureName = `Maps/${textureName}`;
853
+ }
854
+ return textureName;
855
+ };
856
+ const generateSbmMaterial = (materialId, arr, png) => {
857
+ const [d0, d1, d2, d3, side] = arr;
858
+ const trans = png || d3 < 1;
859
+ const material = new MeshStandardNodeMaterial({
860
+ name: materialId,
861
+ color: new Color(d0, d1, d2),
862
+ opacity: d3,
863
+ transparent: trans,
574
864
  alphaTest: 0.01,
575
- side: c
865
+ side
576
866
  });
577
- }, Wt = (o) => o?.toLowerCase().endsWith(".png") ?? !1;
578
- class Qt {
867
+ return material;
868
+ };
869
+ const isPNG = (textureUrl) => {
870
+ return textureUrl?.toLowerCase().endsWith(".png") ?? false;
871
+ };
872
+ class SBMParser {
579
873
  data;
580
874
  options;
581
875
  textureLoader;
582
- littleEndian = !0;
876
+ littleEndian = true;
583
877
  materials = /* @__PURE__ */ new Map();
584
- constructor(e, t) {
585
- this.data = e, this.options = t, this.textureLoader = new ye(t.manager), this.textureLoader.setCrossOrigin(t.crossOrigin), this.textureLoader.setRequestHeader(t.requestHeader);
586
- }
587
- parse(e, t) {
588
- let s = this.data;
589
- const n = Gt(this.data);
590
- n && (s = n);
591
- const i = new DataView(s);
592
- let a = 8;
593
- const c = i.getUint8(a);
594
- a += 1, c === 1 ? this._parseV2(i, a, e) : c === 2 ? this._parseV2(i, a, e) : c === 3 ? this._parseV3(i, a, e) : t?.(new Error(`SBMLoader: Unsupported SBM version: ${c}`));
595
- }
596
- _parseV2(e, t, s) {
597
- const n = new z(), i = e.getUint16(t, this.littleEndian);
598
- t += 2;
599
- const a = e.getUint16(t, this.littleEndian);
600
- t += 2;
601
- for (let c = 0; c < i; ++c) {
602
- const r = e.getUint16(t, this.littleEndian).toString();
603
- t += 2, t += 4, t += 4, t += 4, t += 4;
604
- const h = e.getFloat32(t, this.littleEndian);
605
- t += 4;
606
- const l = e.getFloat32(t, this.littleEndian);
607
- t += 4;
608
- const u = e.getFloat32(t, this.littleEndian);
609
- t += 4;
610
- const f = e.getFloat32(t, this.littleEndian);
611
- t += 4, t += 4, t += 4, t += 4, t += 4;
612
- let p = e.getUint8(t);
613
- t += 1, p === 0 ? p = Ke : p === 1 ? p = Xe : p === 2 && (p = qe);
614
- const g = e.getUint16(t, this.littleEndian);
615
- t += 2;
616
- const w = g > 0 ? zt(e, g, t) : "";
617
- if (t += g, !this.materials.has(r)) {
618
- const v = $t(r, [h, l, u, f, p], Wt(w));
619
- this.materials.set(r, v), w && this.options.path && this.textureLoader.load(L.resolveURL(w, this.options.path), (b) => {
620
- b.colorSpace = ve, b.wrapS = ne, b.wrapT = ne, b.flipY = !1, b.anisotropy = 16, v.map = b;
621
- });
878
+ constructor(data, options) {
879
+ this.data = data;
880
+ this.options = options;
881
+ this.textureLoader = new TextureLoader(options.manager);
882
+ this.textureLoader.setCrossOrigin(options.crossOrigin);
883
+ this.textureLoader.setRequestHeader(options.requestHeader);
884
+ }
885
+ parse(onLoad, onError) {
886
+ let buffer = this.data;
887
+ const decodeBuffer = decodeSbk(this.data);
888
+ if (decodeBuffer) {
889
+ buffer = decodeBuffer;
890
+ }
891
+ const dataView = new DataView(buffer);
892
+ let offset = 8;
893
+ const version = dataView.getUint8(offset);
894
+ offset += 1;
895
+ if (version === 1) {
896
+ this._parseV2(dataView, offset, onLoad);
897
+ } else if (version === 2) {
898
+ this._parseV2(dataView, offset, onLoad);
899
+ } else if (version === 3) {
900
+ this._parseV3(dataView, offset, onLoad);
901
+ } else {
902
+ onError?.(new Error(`SBMLoader: Unsupported SBM version: ${version}`));
903
+ }
904
+ }
905
+ _parseV2(dataView, offset, onLoad) {
906
+ const sbm = new Group();
907
+ const materialCount = dataView.getUint16(offset, this.littleEndian);
908
+ offset += 2;
909
+ const meshCount = dataView.getUint16(offset, this.littleEndian);
910
+ offset += 2;
911
+ for (let i = 0; i < materialCount; ++i) {
912
+ const materialId = dataView.getUint16(offset, this.littleEndian).toString();
913
+ offset += 2;
914
+ offset += 4;
915
+ offset += 4;
916
+ offset += 4;
917
+ offset += 4;
918
+ const d0 = dataView.getFloat32(offset, this.littleEndian);
919
+ offset += 4;
920
+ const d1 = dataView.getFloat32(offset, this.littleEndian);
921
+ offset += 4;
922
+ const d2 = dataView.getFloat32(offset, this.littleEndian);
923
+ offset += 4;
924
+ const d3 = dataView.getFloat32(offset, this.littleEndian);
925
+ offset += 4;
926
+ offset += 4;
927
+ offset += 4;
928
+ offset += 4;
929
+ offset += 4;
930
+ let side = dataView.getUint8(offset);
931
+ offset += 1;
932
+ if (side === 0) side = FrontSide;
933
+ else if (side === 1) side = BackSide;
934
+ else if (side === 2) side = DoubleSide;
935
+ const textureNameLength = dataView.getUint16(offset, this.littleEndian);
936
+ offset += 2;
937
+ const textureName = textureNameLength > 0 ? getTextureName(dataView, textureNameLength, offset) : "";
938
+ offset += textureNameLength;
939
+ if (!this.materials.has(materialId)) {
940
+ const materialInfo = [d0, d1, d2, d3, side];
941
+ const material = generateSbmMaterial(materialId, materialInfo, isPNG(textureName));
942
+ this.materials.set(materialId, material);
943
+ if (textureName && this.options.path) {
944
+ this.textureLoader.load(LoaderUtils.resolveURL(textureName, this.options.path), (texture) => {
945
+ texture.colorSpace = SRGBColorSpace;
946
+ texture.wrapS = RepeatWrapping;
947
+ texture.wrapT = RepeatWrapping;
948
+ texture.flipY = false;
949
+ texture.anisotropy = 16;
950
+ material.map = texture;
951
+ });
952
+ }
622
953
  }
623
954
  }
624
- for (let c = 0; c < a; ++c) {
625
- const r = e.getUint16(t, this.littleEndian).toString();
626
- t += 2;
627
- const h = e.getUint16(t, this.littleEndian).toString();
628
- t += 2;
629
- const l = [], u = [], f = [], p = [], g = e.getUint16(t, this.littleEndian);
630
- if (t += 2, g > 0)
631
- for (let m = 0; m < g; m++) {
632
- const y = new J();
633
- y.setX(e.getFloat32(t, this.littleEndian)), t += 4, y.setY(e.getFloat32(t, this.littleEndian)), t += 4, y.setZ(e.getFloat32(t, this.littleEndian)), t += 4, l.push(y);
955
+ for (let i = 0; i < meshCount; ++i) {
956
+ const meshId = dataView.getUint16(offset, this.littleEndian).toString();
957
+ offset += 2;
958
+ const materialId = dataView.getUint16(offset, this.littleEndian).toString();
959
+ offset += 2;
960
+ const vertices = [];
961
+ const texcoords = [];
962
+ const faces = [];
963
+ const faceVertexUvs = [];
964
+ const verticesCount = dataView.getUint16(offset, this.littleEndian);
965
+ offset += 2;
966
+ if (verticesCount > 0) {
967
+ for (let j = 0; j < verticesCount; j++) {
968
+ const vector3 = new Vector3();
969
+ vector3.setX(dataView.getFloat32(offset, this.littleEndian));
970
+ offset += 4;
971
+ vector3.setY(dataView.getFloat32(offset, this.littleEndian));
972
+ offset += 4;
973
+ vector3.setZ(dataView.getFloat32(offset, this.littleEndian));
974
+ offset += 4;
975
+ vertices.push(vector3);
976
+ }
977
+ }
978
+ const normalsCount = dataView.getUint16(offset, this.littleEndian);
979
+ offset += 2;
980
+ if (normalsCount > 0) {
981
+ for (let j = 0; j < normalsCount; j++) {
982
+ offset += 4;
983
+ offset += 4;
984
+ offset += 4;
985
+ }
986
+ }
987
+ const texcoordCount = dataView.getUint16(offset, this.littleEndian);
988
+ offset += 2;
989
+ if (texcoordCount > 0) {
990
+ for (let j = 0; j < texcoordCount; j++) {
991
+ const texcoord = new Vector2();
992
+ texcoord.setX(dataView.getFloat32(offset, this.littleEndian));
993
+ offset += 4;
994
+ texcoord.setY(dataView.getFloat32(offset, this.littleEndian));
995
+ offset += 4;
996
+ texcoords.push(texcoord);
634
997
  }
635
- const w = e.getUint16(t, this.littleEndian);
636
- if (t += 2, w > 0)
637
- for (let m = 0; m < w; m++)
638
- t += 4, t += 4, t += 4;
639
- const T = e.getUint16(t, this.littleEndian);
640
- if (t += 2, T > 0)
641
- for (let m = 0; m < T; m++) {
642
- const y = new P();
643
- y.setX(e.getFloat32(t, this.littleEndian)), t += 4, y.setY(e.getFloat32(t, this.littleEndian)), t += 4, u.push(y);
998
+ }
999
+ const idxCount = dataView.getUint16(offset, this.littleEndian);
1000
+ offset += 2;
1001
+ if (idxCount > 0) {
1002
+ for (let j = 0; j < idxCount; j++) {
1003
+ const a = dataView.getUint16(offset, this.littleEndian);
1004
+ offset += 2;
1005
+ const b = dataView.getUint16(offset, this.littleEndian);
1006
+ offset += 2;
1007
+ const c = dataView.getUint16(offset, this.littleEndian);
1008
+ offset += 2;
1009
+ const face = [a, b, c];
1010
+ faces.push(face);
1011
+ if (texcoords.length > 0) {
1012
+ faceVertexUvs.push([texcoords[face[0]], texcoords[face[1]], texcoords[face[2]]]);
1013
+ }
644
1014
  }
645
- const v = e.getUint16(t, this.littleEndian);
646
- if (t += 2, v > 0)
647
- for (let m = 0; m < v; m++) {
648
- const y = e.getUint16(t, this.littleEndian);
649
- t += 2;
650
- const B = e.getUint16(t, this.littleEndian);
651
- t += 2;
652
- const _ = e.getUint16(t, this.littleEndian);
653
- t += 2;
654
- const O = [y, B, _];
655
- f.push(O), u.length > 0 && p.push([u[O[0]], u[O[1]], u[O[2]]]);
1015
+ }
1016
+ const positions = [], uvs = [];
1017
+ for (let i2 = 0; i2 < faces.length; i2++) {
1018
+ const face = faces[i2];
1019
+ const vertex = vertices[face[0]], vertex2 = vertices[face[1]], vertex3 = vertices[face[2]];
1020
+ positions.push(...vertex.toArray(), ...vertex2.toArray(), ...vertex3.toArray());
1021
+ let uv2 = new Vector2(), uv22 = new Vector2(), uv3 = new Vector2();
1022
+ const vertexUvs = faceVertexUvs[i2];
1023
+ if (vertexUvs !== void 0) {
1024
+ uv2 = vertexUvs[0];
1025
+ uv22 = vertexUvs[1];
1026
+ uv3 = vertexUvs[2];
656
1027
  }
657
- const b = [], x = [];
658
- for (let m = 0; m < f.length; m++) {
659
- const y = f[m], B = l[y[0]], _ = l[y[1]], O = l[y[2]];
660
- b.push(...B.toArray(), ..._.toArray(), ...O.toArray());
661
- let ee = new P(), te = new P(), se = new P();
662
- const k = p[m];
663
- k !== void 0 && (ee = k[0], te = k[1], se = k[2]), x.push(...ee.toArray(), ...te.toArray(), ...se.toArray());
1028
+ uvs.push(...uv2.toArray(), ...uv22.toArray(), ...uv3.toArray());
1029
+ }
1030
+ const positionArray = new Float32Array(positions), uvArray = new Float32Array(uvs);
1031
+ const bufferGeometry = new BufferGeometry();
1032
+ if (positionArray.length > 0) {
1033
+ bufferGeometry.setAttribute("position", new BufferAttribute(positionArray, 3));
664
1034
  }
665
- const M = new Float32Array(b), E = new Float32Array(x), S = new Qe();
666
- if (M.length > 0 && S.setAttribute("position", new ie(M, 3)), E.length > 0 && S.setAttribute("uv", new ie(E, 2)), S.computeVertexNormals(), this.materials.has(h)) {
667
- const m = new j(S, this.materials.get(h));
668
- m.name = r, m.castShadow = !0, m.receiveShadow = !0, n.add(m);
1035
+ if (uvArray.length > 0) {
1036
+ bufferGeometry.setAttribute("uv", new BufferAttribute(uvArray, 2));
1037
+ }
1038
+ bufferGeometry.computeVertexNormals();
1039
+ if (this.materials.has(materialId)) {
1040
+ const sbmChild = new Mesh(bufferGeometry, this.materials.get(materialId));
1041
+ sbmChild.name = meshId;
1042
+ sbmChild.castShadow = true;
1043
+ sbmChild.receiveShadow = true;
1044
+ sbm.add(sbmChild);
669
1045
  }
670
1046
  }
671
- s(n);
1047
+ onLoad(sbm);
672
1048
  }
673
- _parseV3(e, t, s) {
674
- const n = new z();
675
- console.warn("SBMLoader: SBM version 3 is not supported yet."), s(n);
1049
+ _parseV3(_dataView, _offset, onLoad) {
1050
+ const sbm = new Group();
1051
+ console.warn("SBMLoader: SBM version 3 is not supported yet.");
1052
+ onLoad(sbm);
676
1053
  }
677
1054
  }
678
- class Kt extends We {
679
- load(e, t, s, n) {
680
- let i;
681
- if (this.resourcePath !== "")
682
- i = this.resourcePath;
683
- else if (this.path !== "") {
684
- const r = L.extractUrlBase(e);
685
- i = L.resolveURL(r, this.path);
686
- } else
687
- i = L.extractUrlBase(e);
688
- this.manager.itemStart(e);
689
- const a = (r) => {
690
- n ? n(r) : console.error(r), this.manager.itemError(e), this.manager.itemEnd(e);
691
- }, c = new fe(this.manager);
692
- c.setPath(this.path), c.setResponseType("arraybuffer"), c.setRequestHeader(this.requestHeader), c.setWithCredentials(this.withCredentials), c.load(
693
- e,
694
- (r) => {
1055
+ class SBMLoader extends Loader {
1056
+ load(url, onLoad, onProgress, onError) {
1057
+ let resourcePath;
1058
+ if (this.resourcePath !== "") {
1059
+ resourcePath = this.resourcePath;
1060
+ } else if (this.path !== "") {
1061
+ const relativeUrl = LoaderUtils.extractUrlBase(url);
1062
+ resourcePath = LoaderUtils.resolveURL(relativeUrl, this.path);
1063
+ } else {
1064
+ resourcePath = LoaderUtils.extractUrlBase(url);
1065
+ }
1066
+ this.manager.itemStart(url);
1067
+ const _onError = (e) => {
1068
+ if (onError) {
1069
+ onError(e);
1070
+ } else {
1071
+ console.error(e);
1072
+ }
1073
+ this.manager.itemError(url);
1074
+ this.manager.itemEnd(url);
1075
+ };
1076
+ const loader = new FileLoader(this.manager);
1077
+ loader.setPath(this.path);
1078
+ loader.setResponseType("arraybuffer");
1079
+ loader.setRequestHeader(this.requestHeader);
1080
+ loader.setWithCredentials(this.withCredentials);
1081
+ loader.load(
1082
+ url,
1083
+ (data) => {
695
1084
  try {
696
1085
  this.parse(
697
- r,
698
- i,
699
- (h) => {
700
- t(h), this.manager.itemEnd(e);
1086
+ data,
1087
+ resourcePath,
1088
+ (sbm) => {
1089
+ onLoad(sbm);
1090
+ this.manager.itemEnd(url);
701
1091
  },
702
- a
1092
+ _onError
703
1093
  );
704
- } catch (h) {
705
- a(h);
1094
+ } catch (e) {
1095
+ _onError(e);
706
1096
  }
707
1097
  },
708
- s,
709
- a
1098
+ onProgress,
1099
+ _onError
710
1100
  );
711
1101
  }
712
- parse(e, t, s, n) {
713
- const i = new TextDecoder().decode(e.slice(0, 8));
714
- if (i !== "SBK-----" && i !== "SBM-----") {
715
- n?.(new Error(`SBMLoader: Invalid SBM format: ${i}`));
1102
+ parse(data, path, onLoad, onError) {
1103
+ const formatName = new TextDecoder().decode(data.slice(0, 8));
1104
+ if (formatName !== "SBK-----" && formatName !== "SBM-----") {
1105
+ onError?.(new Error(`SBMLoader: Invalid SBM format: ${formatName}`));
716
1106
  return;
717
1107
  }
718
- new Qt(e, {
719
- path: t,
1108
+ const parser = new SBMParser(data, {
1109
+ path,
720
1110
  crossOrigin: this.crossOrigin,
721
1111
  requestHeader: this.requestHeader,
722
1112
  manager: this.manager
723
- }).parse(s, n);
1113
+ });
1114
+ parser.parse(onLoad, onError);
724
1115
  }
725
- parseAsync(e, t) {
726
- return new Promise((s, n) => {
1116
+ parseAsync(data, path) {
1117
+ return new Promise((resolve, reject) => {
727
1118
  this.parse(
728
- e,
729
- t,
730
- (i) => {
731
- s(i);
1119
+ data,
1120
+ path,
1121
+ (sbm) => {
1122
+ resolve(sbm);
732
1123
  },
733
- (i) => {
734
- n(i);
1124
+ (err) => {
1125
+ reject(err);
735
1126
  }
736
1127
  );
737
1128
  });
738
1129
  }
739
1130
  }
740
- class R {
1131
+ class ModelLoaderManager {
741
1132
  static CACHE_NAME = "u-space-model-loader-cache";
742
- static fileLoader = new fe().setResponseType("arraybuffer");
743
- static dracoLoader = new ft().setDecoderPath(
744
- `https://cdn.jsdelivr.net/npm/three@0.${re}.0/examples/jsm/libs/draco/`
1133
+ static fileLoader = new FileLoader().setResponseType("arraybuffer");
1134
+ static dracoLoader = new DRACOLoader().setDecoderPath(
1135
+ `https://cdn.jsdelivr.net/npm/three@0.${REVISION}.0/examples/jsm/libs/draco/`
745
1136
  );
746
- static ktx2Loader = new yt().setTranscoderPath(
747
- `https://cdn.jsdelivr.net/npm/three@0.${re}.0/examples/jsm/libs/basis/`
1137
+ static ktx2Loader = new KTX2Loader().setTranscoderPath(
1138
+ `https://cdn.jsdelivr.net/npm/three@0.${REVISION}.0/examples/jsm/libs/basis/`
748
1139
  );
749
- static gltfLoader = new xe().setDRACOLoader(R.dracoLoader).setKTX2Loader(R.ktx2Loader).setMeshoptDecoder(le);
750
- static sbmxLoader = new Rt().setDRACOLoader(R.dracoLoader).setKTX2Loader(R.ktx2Loader).setMeshoptDecoder(le);
751
- static sbmLoader = new Kt();
752
- static fbxLoader = new mt();
753
- static objLoader = new gt();
754
- static stlLoader = new wt();
755
- static setLoadingManager(e) {
756
- 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;
1140
+ static gltfLoader = new GLTFLoader().setDRACOLoader(ModelLoaderManager.dracoLoader).setKTX2Loader(ModelLoaderManager.ktx2Loader).setMeshoptDecoder(MeshoptDecoder);
1141
+ static sbmxLoader = new SBMXLoader().setDRACOLoader(ModelLoaderManager.dracoLoader).setKTX2Loader(ModelLoaderManager.ktx2Loader).setMeshoptDecoder(MeshoptDecoder);
1142
+ static sbmLoader = new SBMLoader();
1143
+ static fbxLoader = new FBXLoader();
1144
+ static objLoader = new OBJLoader();
1145
+ static stlLoader = new STLLoader();
1146
+ static setLoadingManager(loadingManager) {
1147
+ this.fileLoader.manager = loadingManager;
1148
+ this.dracoLoader.manager = loadingManager;
1149
+ this.ktx2Loader.manager = loadingManager;
1150
+ this.gltfLoader.manager = loadingManager;
1151
+ this.sbmxLoader.manager = loadingManager;
1152
+ this.sbmLoader.manager = loadingManager;
1153
+ this.fbxLoader.manager = loadingManager;
1154
+ this.objLoader.manager = loadingManager;
1155
+ this.stlLoader.manager = loadingManager;
757
1156
  }
758
1157
  /**
759
1158
  * Set the renderer to enable KTX2 support and other renderer-dependent features.
760
1159
  */
761
- static async setRenderer(e) {
762
- await e.init(), this.ktx2Loader.detectSupport(e);
1160
+ static async setRenderer(renderer) {
1161
+ await renderer.init();
1162
+ this.ktx2Loader.detectSupport(renderer);
763
1163
  }
764
1164
  /**
765
1165
  * Configure Draco decoder path.
766
1166
  */
767
- static setDracoPath(e) {
768
- this.dracoLoader.setDecoderPath(e);
1167
+ static setDracoPath(path) {
1168
+ this.dracoLoader.setDecoderPath(path);
769
1169
  }
770
1170
  /**
771
1171
  * Configure KTX2 transcoder path.
772
1172
  */
773
- static setKTX2Path(e) {
774
- this.ktx2Loader.setTranscoderPath(e);
775
- }
776
- static async loadAsync(e, t = { persistent: !0 }) {
777
- const s = e.split(".").pop()?.split("?")[0].toLowerCase();
778
- let n;
779
- switch (t.persistent && typeof caches < "u" ? n = await this.getPersistentData(e) : n = await this.fileLoader.loadAsync(e), s) {
1173
+ static setKTX2Path(path) {
1174
+ this.ktx2Loader.setTranscoderPath(path);
1175
+ }
1176
+ static async loadAsync(url, parameters = { persistent: true }) {
1177
+ const extension = url.split(".").pop()?.split("?")[0].toLowerCase();
1178
+ let buffer;
1179
+ if (parameters.persistent && typeof caches !== "undefined") {
1180
+ buffer = await this.getPersistentData(url);
1181
+ } else {
1182
+ buffer = await this.fileLoader.loadAsync(url);
1183
+ }
1184
+ switch (extension) {
780
1185
  case "gltf":
781
1186
  case "glb":
782
- return (await this.gltfLoader.parseAsync(n, L.extractUrlBase(e))).scene;
1187
+ const gltf = await this.gltfLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));
1188
+ return gltf.scene;
783
1189
  case "sbmx":
784
- return (await this.sbmxLoader.parseAsync(n, L.extractUrlBase(e))).scene;
1190
+ const sbmx = await this.sbmxLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));
1191
+ return sbmx.scene;
785
1192
  case "sbm":
786
- return await this.sbmLoader.parseAsync(n, L.extractUrlBase(e));
1193
+ const sbm = await this.sbmLoader.parseAsync(buffer, LoaderUtils.extractUrlBase(url));
1194
+ return sbm;
787
1195
  case "fbx":
788
- return this.fbxLoader.parse(n, L.extractUrlBase(e));
1196
+ const fbx = this.fbxLoader.parse(buffer, LoaderUtils.extractUrlBase(url));
1197
+ return fbx;
789
1198
  case "obj":
790
- const h = new TextDecoder().decode(n);
791
- return this.objLoader.parse(h);
1199
+ const text = new TextDecoder().decode(buffer);
1200
+ const obj = this.objLoader.parse(text);
1201
+ return obj;
792
1202
  case "stl":
793
- const u = this.stlLoader.parse(n);
794
- return new j(u, new I());
1203
+ const geometry = this.stlLoader.parse(buffer);
1204
+ const mesh = new Mesh(geometry, new MeshStandardNodeMaterial());
1205
+ return mesh;
795
1206
  default:
796
- throw new Error(`Unsupported model format: ${s}`);
1207
+ throw new Error(`Unsupported model format: ${extension}`);
797
1208
  }
798
1209
  }
799
- static async getPersistentData(e) {
1210
+ static async getPersistentData(url) {
800
1211
  try {
801
- const t = await caches.open(this.CACHE_NAME), s = await t.match(e);
802
- if (s)
803
- return await s.arrayBuffer();
804
- const n = await this.fileLoader.loadAsync(e), i = new Response(n);
805
- return await t.put(e, i), n;
806
- } catch (t) {
807
- return console.warn(`[LoaderManager] Failed to use Cache API for ${e}:`, t), await this.fileLoader.loadAsync(e);
1212
+ const cache = await caches.open(this.CACHE_NAME);
1213
+ const cachedResponse = await cache.match(url);
1214
+ if (cachedResponse) {
1215
+ return await cachedResponse.arrayBuffer();
1216
+ }
1217
+ const buffer = await this.fileLoader.loadAsync(url);
1218
+ const response = new Response(buffer);
1219
+ await cache.put(url, response);
1220
+ return buffer;
1221
+ } catch (error) {
1222
+ console.warn(`[LoaderManager] Failed to use Cache API for ${url}:`, error);
1223
+ return await this.fileLoader.loadAsync(url);
808
1224
  }
809
1225
  }
810
1226
  }
811
- class vs {
812
- static textureLoader = new ye();
813
- static hdrLoader = new vt();
814
- static cubeTextureLoader = new Ye();
815
- static setLoadingManager(e) {
816
- this.textureLoader.manager = e, this.hdrLoader.manager = e, this.cubeTextureLoader.manager = e;
817
- }
818
- static async loadAsyncTexture(e) {
819
- return await this.textureLoader.loadAsync(e);
820
- }
821
- static async loadAsyncHDR(e) {
822
- const t = await this.hdrLoader.loadAsync(e);
823
- return t.mapping = Je, t;
824
- }
825
- static async loadAsyncCubeTexture(e, t) {
826
- return this.cubeTextureLoader.setPath(e), await this.cubeTextureLoader.loadAsync(t);
1227
+ class TextureLoaderManager {
1228
+ static textureLoader = new TextureLoader();
1229
+ static hdrLoader = new HDRLoader();
1230
+ static cubeTextureLoader = new CubeTextureLoader();
1231
+ static setLoadingManager(loadingManager) {
1232
+ this.textureLoader.manager = loadingManager;
1233
+ this.hdrLoader.manager = loadingManager;
1234
+ this.cubeTextureLoader.manager = loadingManager;
1235
+ }
1236
+ static async loadAsyncTexture(url) {
1237
+ const texture = await this.textureLoader.loadAsync(url);
1238
+ return texture;
1239
+ }
1240
+ static async loadAsyncHDR(url) {
1241
+ const dataTexture = await this.hdrLoader.loadAsync(url);
1242
+ dataTexture.mapping = EquirectangularReflectionMapping;
1243
+ return dataTexture;
1244
+ }
1245
+ static async loadAsyncCubeTexture(path, urls) {
1246
+ this.cubeTextureLoader.setPath(path);
1247
+ const cubeTexture = await this.cubeTextureLoader.loadAsync(urls);
1248
+ return cubeTexture;
827
1249
  }
828
1250
  }
829
- class U extends j {
830
- isBaseMesh = !0;
1251
+ class BaseMesh extends Mesh {
1252
+ isBaseMesh = true;
831
1253
  type = "BaseMesh";
832
- ignoreInvisibleWhenRaycast = !0;
833
- constructor(...e) {
834
- super(...e);
1254
+ ignoreInvisibleWhenRaycast = true;
1255
+ constructor(...args) {
1256
+ super(...args);
835
1257
  }
836
- raycast(e, t) {
837
- return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
1258
+ raycast(raycaster, intersects) {
1259
+ if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {
1260
+ return false;
1261
+ }
1262
+ return super.raycast(raycaster, intersects);
838
1263
  }
839
1264
  }
840
- class Ee extends z {
841
- isBaseGroup = !0;
1265
+ class BaseGroup extends Group {
1266
+ isBaseGroup = true;
842
1267
  type = "BaseGroup";
843
- ignoreInvisibleWhenRaycast = !0;
844
- constructor(...e) {
845
- super(...e);
1268
+ ignoreInvisibleWhenRaycast = true;
1269
+ constructor(...args) {
1270
+ super(...args);
846
1271
  }
847
- raycast(e, t) {
848
- return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
1272
+ raycast(raycaster, intersects) {
1273
+ if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {
1274
+ return false;
1275
+ }
1276
+ return super.raycast(raycaster, intersects);
849
1277
  }
850
1278
  }
851
- class Xt extends Ze {
852
- isBaseSprite = !0;
1279
+ class BaseSprite extends Sprite {
1280
+ isBaseSprite = true;
853
1281
  type = "BaseSprite";
854
- ignoreInvisibleWhenRaycast = !0;
855
- constructor(...e) {
856
- super(...e);
1282
+ ignoreInvisibleWhenRaycast = true;
1283
+ constructor(...args) {
1284
+ super(...args);
857
1285
  }
858
- raycast(e, t) {
859
- return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
1286
+ raycast(raycaster, intersects) {
1287
+ if (this.visible === false && this.ignoreInvisibleWhenRaycast === true) {
1288
+ return false;
1289
+ }
1290
+ return super.raycast(raycaster, intersects);
860
1291
  }
861
1292
  }
862
- class H extends Ee {
863
- isModel = !0;
1293
+ class Model extends BaseGroup {
1294
+ isModel = true;
864
1295
  type = "Model";
865
1296
  static memoryCache = /* @__PURE__ */ new Map();
866
1297
  constructor() {
867
1298
  super();
868
1299
  }
869
- async loadAsync(e) {
870
- const { url: t, cache: s = !0, persistent: n = !0 } = e;
1300
+ async loadAsync(parameters) {
1301
+ const { url, cache = true, persistent = true } = parameters;
871
1302
  try {
872
- let i;
873
- s ? H.memoryCache.has(t) ? i = H.memoryCache.get(t) : (i = R.loadAsync(t, { persistent: n }), H.memoryCache.set(t, i)) : i = R.loadAsync(t, { persistent: n });
874
- const a = await i, c = bt(a);
875
- return this.add(c), c;
876
- } catch (i) {
877
- return console.error(`[Model] Failed to load model from ${t}:`, i), null;
1303
+ let objectPromise;
1304
+ if (cache) {
1305
+ if (Model.memoryCache.has(url)) {
1306
+ objectPromise = Model.memoryCache.get(url);
1307
+ } else {
1308
+ objectPromise = ModelLoaderManager.loadAsync(url, { persistent });
1309
+ Model.memoryCache.set(url, objectPromise);
1310
+ }
1311
+ } else {
1312
+ objectPromise = ModelLoaderManager.loadAsync(url, { persistent });
1313
+ }
1314
+ const object = await objectPromise;
1315
+ const clonedObject = clone(object);
1316
+ this.add(clonedObject);
1317
+ return clonedObject;
1318
+ } catch (error) {
1319
+ console.error(`[Model] Failed to load model from ${url}:`, error);
1320
+ return null;
878
1321
  }
879
1322
  }
880
1323
  static clearMemoryCache() {
881
1324
  this.memoryCache.clear();
882
1325
  }
883
1326
  static async clearPersistentCache() {
884
- typeof caches < "u" && await caches.delete("u-space-loader-cache");
1327
+ if (typeof caches !== "undefined") {
1328
+ await caches.delete("u-space-loader-cache");
1329
+ }
885
1330
  }
886
1331
  }
887
- class qt extends U {
888
- isSphereMesh = !0;
1332
+ class SphereMesh extends BaseMesh {
1333
+ isSphereMesh = true;
889
1334
  type = "SphereMesh";
890
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
891
- super(), this.geometry = new Ve(
892
- e?.radius,
893
- e?.widthSegments,
894
- e?.heightSegments,
895
- e?.phiStart,
896
- e?.phiLength,
897
- e?.thetaStart,
898
- e?.thetaLength
899
- ), this.material = new I(t);
1335
+ constructor({ geometryParameters, materialParameters } = {}) {
1336
+ super();
1337
+ this.geometry = new SphereGeometry(
1338
+ geometryParameters?.radius,
1339
+ geometryParameters?.widthSegments,
1340
+ geometryParameters?.heightSegments,
1341
+ geometryParameters?.phiStart,
1342
+ geometryParameters?.phiLength,
1343
+ geometryParameters?.thetaStart,
1344
+ geometryParameters?.thetaLength
1345
+ );
1346
+ this.material = new MeshStandardNodeMaterial(materialParameters);
900
1347
  }
901
1348
  }
902
- class ue extends U {
903
- isTubeMesh = !0;
1349
+ class TubeMesh extends BaseMesh {
1350
+ isTubeMesh = true;
904
1351
  type = "TubeMesh";
905
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
906
- super(), this.geometry = new et(
907
- e?.path,
908
- e?.tubularSegments,
909
- e?.radius,
910
- e?.radialSegments,
911
- e?.closed
912
- ), this.material = new I(t);
1352
+ constructor({ geometryParameters, materialParameters } = {}) {
1353
+ super();
1354
+ this.geometry = new TubeGeometry(
1355
+ geometryParameters?.path,
1356
+ geometryParameters?.tubularSegments,
1357
+ geometryParameters?.radius,
1358
+ geometryParameters?.radialSegments,
1359
+ geometryParameters?.closed
1360
+ );
1361
+ this.material = new MeshStandardNodeMaterial(materialParameters);
913
1362
  }
914
1363
  }
915
- class bs extends Ee {
916
- isTopology = !0;
1364
+ class Topology extends BaseGroup {
1365
+ isTopology = true;
917
1366
  type = "Topology";
918
1367
  // Visuals
919
1368
  parameters = {
@@ -928,27 +1377,37 @@ class bs extends Ee {
928
1377
  adjacencyMap = /* @__PURE__ */ new Map();
929
1378
  graphGroup = null;
930
1379
  pathMeshes = [];
931
- constructor(e) {
932
- super(), e && Object.assign(this.parameters, e);
1380
+ constructor(parameters) {
1381
+ super();
1382
+ if (parameters) {
1383
+ Object.assign(this.parameters, parameters);
1384
+ }
933
1385
  }
934
1386
  /**
935
1387
  * Add a node to the topology graph.
936
1388
  * @param id Unique identifier for the node
937
1389
  * @param position 3D position of the node
938
1390
  */
939
- addNode(e, t) {
940
- this.nodes.has(e) && console.warn(`[Topology] Node ${e} already exists. Overwriting.`), this.nodes.set(e, t), this.adjacencyMap.has(e) || this.adjacencyMap.set(e, /* @__PURE__ */ new Map());
1391
+ addNode(id, position) {
1392
+ if (this.nodes.has(id)) {
1393
+ console.warn(`[Topology] Node ${id} already exists. Overwriting.`);
1394
+ }
1395
+ this.nodes.set(id, position);
1396
+ if (!this.adjacencyMap.has(id)) {
1397
+ this.adjacencyMap.set(id, /* @__PURE__ */ new Map());
1398
+ }
941
1399
  }
942
1400
  /**
943
1401
  * Remove a node from the topology graph.
944
1402
  * @param id Unique identifier for the node
945
1403
  */
946
- removeNode(e) {
947
- if (!this.nodes.has(e)) {
948
- console.warn(`[Topology] Node ${e} does not exist.`);
1404
+ removeNode(id) {
1405
+ if (!this.nodes.has(id)) {
1406
+ console.warn(`[Topology] Node ${id} does not exist.`);
949
1407
  return;
950
1408
  }
951
- this.nodes.delete(e), this.adjacencyMap.delete(e);
1409
+ this.nodes.delete(id);
1410
+ this.adjacencyMap.delete(id);
952
1411
  }
953
1412
  /**
954
1413
  * Add an edge between two nodes.
@@ -957,14 +1416,18 @@ class bs extends Ee {
957
1416
  * @param weight Cost of the edge. Defaults to Euclidean distance.
958
1417
  * @param bidirectional If true, adds the reverse edge as well. Default true.
959
1418
  */
960
- addEdge(e, t, s, n = !0) {
961
- const i = this.nodes.get(e), a = this.nodes.get(t);
962
- if (!i || !a) {
963
- console.error(`[Topology] Cannot add edge. One or both nodes not found: ${e}, ${t}`);
1419
+ addEdge(from, to, weight, bidirectional = true) {
1420
+ const fromPos = this.nodes.get(from);
1421
+ const toPos = this.nodes.get(to);
1422
+ if (!fromPos || !toPos) {
1423
+ console.error(`[Topology] Cannot add edge. One or both nodes not found: ${from}, ${to}`);
964
1424
  return;
965
1425
  }
966
- const c = s ?? i.distanceTo(a);
967
- this.getNeighbors(e)?.set(t, c), n && this.getNeighbors(t)?.set(e, c);
1426
+ const dist = weight ?? fromPos.distanceTo(toPos);
1427
+ this.getNeighbors(from)?.set(to, dist);
1428
+ if (bidirectional) {
1429
+ this.getNeighbors(to)?.set(from, dist);
1430
+ }
968
1431
  }
969
1432
  /**
970
1433
  * Remove an edge between two nodes.
@@ -972,51 +1435,80 @@ class bs extends Ee {
972
1435
  * @param to Node ID
973
1436
  * @param bidirectional If true, removes the reverse edge as well. Default true.
974
1437
  */
975
- removeEdge(e, t, s = !0) {
976
- this.getNeighbors(e)?.delete(t), s && this.getNeighbors(t)?.delete(e);
1438
+ removeEdge(from, to, bidirectional = true) {
1439
+ const fromNeighbors = this.getNeighbors(from);
1440
+ fromNeighbors?.delete(to);
1441
+ if (bidirectional) {
1442
+ const toNeighbors = this.getNeighbors(to);
1443
+ toNeighbors?.delete(from);
1444
+ }
977
1445
  }
978
1446
  /**
979
1447
  * Find the shortest path between start and end nodes using Dijkstra's algorithm.
980
1448
  */
981
- getShortestPath(e, t) {
982
- if (!this.nodes.has(e) || !this.nodes.has(t))
983
- return console.warn("[Topology] Start or End node not found."), [];
984
- const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set();
985
- for (const [r] of this.nodes)
986
- s.set(r, 1 / 0), n.set(r, null), i.add(r);
987
- for (s.set(e, 0); i.size > 0; ) {
988
- let r = null, h = 1 / 0;
989
- for (const u of i) {
990
- const f = s.get(u);
991
- f < h && (h = f, r = u);
1449
+ getShortestPath(startId, endId) {
1450
+ if (!this.nodes.has(startId) || !this.nodes.has(endId)) {
1451
+ console.warn(`[Topology] Start or End node not found.`);
1452
+ return [];
1453
+ }
1454
+ const distances = /* @__PURE__ */ new Map();
1455
+ const previous = /* @__PURE__ */ new Map();
1456
+ const unvisited = /* @__PURE__ */ new Set();
1457
+ for (const [id] of this.nodes) {
1458
+ distances.set(id, Infinity);
1459
+ previous.set(id, null);
1460
+ unvisited.add(id);
1461
+ }
1462
+ distances.set(startId, 0);
1463
+ while (unvisited.size > 0) {
1464
+ let currentId = null;
1465
+ let minDist = Infinity;
1466
+ for (const id of unvisited) {
1467
+ const d = distances.get(id);
1468
+ if (d < minDist) {
1469
+ minDist = d;
1470
+ currentId = id;
1471
+ }
1472
+ }
1473
+ if (currentId === null || currentId === endId) {
1474
+ break;
992
1475
  }
993
- if (r === null || r === t || h === 1 / 0)
1476
+ if (minDist === Infinity) {
994
1477
  break;
995
- i.delete(r);
996
- const l = this.adjacencyMap?.get(r);
997
- if (l)
998
- for (const [u, f] of l) {
999
- if (!i.has(u)) continue;
1000
- const p = s.get(r) + f;
1001
- p < s.get(u) && (s.set(u, p), n.set(u, r));
1478
+ }
1479
+ unvisited.delete(currentId);
1480
+ const neighbors = this.adjacencyMap?.get(currentId);
1481
+ if (!neighbors) {
1482
+ continue;
1483
+ }
1484
+ for (const [to, weight] of neighbors) {
1485
+ if (!unvisited.has(to)) continue;
1486
+ const alt = distances.get(currentId) + weight;
1487
+ if (alt < distances.get(to)) {
1488
+ distances.set(to, alt);
1489
+ previous.set(to, currentId);
1002
1490
  }
1491
+ }
1003
1492
  }
1004
- const a = [];
1005
- let c = t;
1006
- if (n.get(t) === null && e !== t)
1493
+ const path = [];
1494
+ let curr = endId;
1495
+ if (previous.get(endId) === null && startId !== endId) {
1007
1496
  return [];
1008
- for (; c !== null; ) {
1009
- const r = this.nodes.get(c);
1010
- r && a.unshift(r), c = n.get(c) || null;
1011
1497
  }
1012
- return a;
1498
+ while (curr !== null) {
1499
+ const pos = this.nodes.get(curr);
1500
+ if (pos) path.unshift(pos);
1501
+ curr = previous.get(curr) || null;
1502
+ }
1503
+ return path;
1013
1504
  }
1014
1505
  /**
1015
1506
  * Renders the entire topology graph structure using TubeGeometry and Spheres.
1016
1507
  */
1017
1508
  renderGraph() {
1018
- this.clearGraph(), this.graphGroup = new z();
1019
- const e = new qt({
1509
+ this.clearGraph();
1510
+ this.graphGroup = new Group();
1511
+ const _dummySphere = new SphereMesh({
1020
1512
  geometryParameters: {
1021
1513
  radius: this.parameters.nodeRadius,
1022
1514
  widthSegments: 16,
@@ -1026,97 +1518,128 @@ class bs extends Ee {
1026
1518
  color: this.parameters.nodeColor
1027
1519
  }
1028
1520
  });
1029
- this.nodes.forEach((s, n) => {
1030
- const i = e.clone();
1031
- i.position.copy(s), Object.assign(i.userData, { id: n, type: "node" }), this.graphGroup.add(i);
1521
+ this.nodes.forEach((pos, id) => {
1522
+ const nodeMesh = _dummySphere.clone();
1523
+ nodeMesh.position.copy(pos);
1524
+ Object.assign(nodeMesh.userData, { id, type: "node" });
1525
+ this.graphGroup.add(nodeMesh);
1032
1526
  });
1033
- const t = /* @__PURE__ */ new Set();
1034
- this.adjacencyMap.forEach((s, n) => {
1035
- s.forEach((i, a) => {
1036
- const c = [n, a].sort().join("-");
1037
- if (t.has(c)) return;
1038
- t.add(c);
1039
- const r = this.nodes.get(n), h = this.nodes.get(a);
1040
- if (r && h) {
1041
- const l = new tt(r, h), u = new ue({
1527
+ const processedEdges = /* @__PURE__ */ new Set();
1528
+ this.adjacencyMap.forEach((edges, from) => {
1529
+ edges.forEach((weight, to) => {
1530
+ const key = [from, to].sort().join("-");
1531
+ if (processedEdges.has(key)) return;
1532
+ processedEdges.add(key);
1533
+ const p1 = this.nodes.get(from);
1534
+ const p2 = this.nodes.get(to);
1535
+ if (p1 && p2) {
1536
+ const path = new LineCurve3(p1, p2);
1537
+ const tubeMesh = new TubeMesh({
1042
1538
  geometryParameters: {
1043
- path: l,
1539
+ path,
1044
1540
  tubularSegments: 1,
1045
1541
  radius: this.parameters.edgeRadius,
1046
1542
  radialSegments: 8,
1047
- closed: !1
1543
+ closed: false
1048
1544
  },
1049
1545
  materialParameters: {
1050
1546
  color: this.parameters.edgeColor
1051
1547
  }
1052
1548
  });
1053
- Object.assign(u.userData, { from: n, to: a, weight: i, type: "edge" }), this.graphGroup.add(u);
1549
+ Object.assign(tubeMesh.userData, { from, to, weight, type: "edge" });
1550
+ this.graphGroup.add(tubeMesh);
1054
1551
  }
1055
1552
  });
1056
- }), this.add(this.graphGroup);
1553
+ });
1554
+ this.add(this.graphGroup);
1057
1555
  }
1058
1556
  clearGraph() {
1059
- this.graphGroup && (this.remove(this.graphGroup), this.graphGroup.traverse((e) => {
1060
- e instanceof j && (e.geometry.dispose(), e.material.dispose());
1061
- }), this.graphGroup = null);
1557
+ if (this.graphGroup) {
1558
+ this.remove(this.graphGroup);
1559
+ this.graphGroup.traverse((child) => {
1560
+ if (child instanceof Mesh) {
1561
+ child.geometry.dispose();
1562
+ child.material.dispose();
1563
+ }
1564
+ });
1565
+ this.graphGroup = null;
1566
+ }
1062
1567
  }
1063
1568
  /**
1064
1569
  * Visualizes a path using TubeGeometry (CatmullRomCurve3).
1065
1570
  */
1066
- renderPath(e, t = this.parameters.pathColor) {
1067
- if (e.length < 2) return;
1068
- const s = new st(e, !1, "catmullrom", 0), n = new ue({
1571
+ renderPath(points, color2 = this.parameters.pathColor) {
1572
+ if (points.length < 2) return;
1573
+ const curve = new CatmullRomCurve3(points, false, "catmullrom", 0);
1574
+ const mesh = new TubeMesh({
1069
1575
  geometryParameters: {
1070
- path: s,
1071
- tubularSegments: e.length * 10,
1576
+ path: curve,
1577
+ tubularSegments: points.length * 10,
1072
1578
  radius: this.parameters.pathRadius,
1073
- closed: !1
1579
+ closed: false
1074
1580
  },
1075
1581
  materialParameters: {
1076
- color: t
1582
+ color: color2
1077
1583
  }
1078
1584
  });
1079
- return this.add(n), this.pathMeshes.push(n), n;
1585
+ this.add(mesh);
1586
+ this.pathMeshes.push(mesh);
1587
+ return mesh;
1080
1588
  }
1081
1589
  clearPaths() {
1082
- this.pathMeshes.forEach((e) => {
1083
- this.remove(e), e.geometry.dispose(), e.material.dispose();
1084
- }), this.pathMeshes = [];
1590
+ this.pathMeshes.forEach((m) => {
1591
+ this.remove(m);
1592
+ m.geometry.dispose();
1593
+ m.material.dispose();
1594
+ });
1595
+ this.pathMeshes = [];
1085
1596
  }
1086
1597
  /** Export nodes and edges as a JSON-serializable object. */
1087
1598
  exportData() {
1088
- const e = {};
1089
- this.nodes.forEach((n, i) => {
1090
- e[i] = { x: n.x, y: n.y, z: n.z };
1599
+ const nodes = {};
1600
+ this.nodes.forEach((pos, id) => {
1601
+ nodes[id] = { x: pos.x, y: pos.y, z: pos.z };
1091
1602
  });
1092
- const t = [], s = /* @__PURE__ */ new Set();
1093
- return this.adjacencyMap.forEach((n, i) => {
1094
- n.forEach((a, c) => {
1095
- const r = [i, c].sort().join("-");
1096
- s.has(r) || (s.add(r), t.push({ from: i, to: c, weight: a }));
1603
+ const edges = [];
1604
+ const processed = /* @__PURE__ */ new Set();
1605
+ this.adjacencyMap.forEach((neighbors, from) => {
1606
+ neighbors.forEach((weight, to) => {
1607
+ const key = [from, to].sort().join("-");
1608
+ if (!processed.has(key)) {
1609
+ processed.add(key);
1610
+ edges.push({ from, to, weight });
1611
+ }
1097
1612
  });
1098
- }), { nodes: e, edges: t };
1613
+ });
1614
+ return { nodes, edges };
1099
1615
  }
1100
1616
  /**
1101
1617
  * Load topology from a previously exported data object.
1102
1618
  * Replaces all current nodes, edges, and path meshes, then re-renders the graph.
1103
1619
  */
1104
- importData(e) {
1105
- this.clearGraph(), this.clearPaths(), this.nodes.clear(), this.adjacencyMap.clear(), Object.entries(e.nodes).forEach(([t, s]) => {
1106
- this.addNode(t, new J(s.x, s.y, s.z));
1107
- }), e.edges.forEach(({ from: t, to: s, weight: n }) => {
1108
- this.addEdge(t, s, n);
1109
- }), this.renderGraph();
1620
+ importData(data) {
1621
+ this.clearGraph();
1622
+ this.clearPaths();
1623
+ this.nodes.clear();
1624
+ this.adjacencyMap.clear();
1625
+ Object.entries(data.nodes).forEach(([id, pos]) => {
1626
+ this.addNode(id, new Vector3(pos.x, pos.y, pos.z));
1627
+ });
1628
+ data.edges.forEach(({ from, to, weight }) => {
1629
+ this.addEdge(from, to, weight);
1630
+ });
1631
+ this.renderGraph();
1110
1632
  }
1111
1633
  dispose() {
1112
- this.clearGraph(), this.clearPaths();
1634
+ this.clearGraph();
1635
+ this.clearPaths();
1113
1636
  }
1114
- getNeighbors(e) {
1115
- return this.adjacencyMap.get(e);
1637
+ getNeighbors(id) {
1638
+ return this.adjacencyMap.get(id);
1116
1639
  }
1117
1640
  }
1118
- class Ts extends Xt {
1119
- isPoi = !0;
1641
+ class Poi extends BaseSprite {
1642
+ isPoi = true;
1120
1643
  type = "Poi";
1121
1644
  parameters = {
1122
1645
  img: "",
@@ -1126,277 +1649,426 @@ class Ts extends Xt {
1126
1649
  color: "#ffffff",
1127
1650
  iconSize: 64,
1128
1651
  padding: 10,
1129
- backgroundColor: "rgba(0, 0, 0, 0.5)",
1652
+ backgroundColor: "rgba(0, 0, 0, 0)",
1130
1653
  borderRadius: 8,
1131
- textPosition: "right"
1654
+ textPosition: "right",
1655
+ scaleFactor: 0.01
1132
1656
  };
1133
- constructor(e = {}) {
1134
- super(new nt()), Object.assign(this.parameters, e);
1657
+ _canvas = document.createElement("canvas");
1658
+ _lastParametersJSON = "";
1659
+ constructor(parameters = {}) {
1660
+ super(new SpriteNodeMaterial());
1661
+ Object.assign(this.parameters, parameters);
1662
+ this.updateAsync();
1135
1663
  }
1136
1664
  /**
1137
1665
  * Update the POI with new parameters
1138
1666
  * @param parameters Partial POI parameters
1139
1667
  */
1140
- async updateAsync(e = {}) {
1141
- Object.assign(this.parameters, e);
1142
- const t = document.createElement("canvas"), s = t.getContext("2d");
1143
- if (!s) return;
1144
- s.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;
1145
- let n = null;
1146
- this.parameters.img && (n = await this._loadImage(this.parameters.img));
1147
- const { text: i, fontSize: a, color: c, iconSize: r, padding: h, backgroundColor: l, borderRadius: u, textPosition: f } = this.parameters, p = s.measureText(i), g = i ? p.width : 0, w = i ? a : 0;
1148
- let T = 0, v = 0, b = 0, x = 0, M = 0, E = 0;
1149
- const S = !!n, m = !!i;
1150
- if (S && m)
1151
- switch (f) {
1668
+ async updateAsync(parameters = {}) {
1669
+ Object.assign(this.parameters, parameters);
1670
+ const json = JSON.stringify(this.parameters);
1671
+ if (json === this._lastParametersJSON) return;
1672
+ this._lastParametersJSON = json;
1673
+ const canvas = this._canvas;
1674
+ const ctx = canvas.getContext("2d");
1675
+ if (!ctx) return;
1676
+ ctx.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;
1677
+ let image = null;
1678
+ if (this.parameters.img) {
1679
+ image = await this._loadImage(this.parameters.img);
1680
+ }
1681
+ const { text, fontSize, color: color2, iconSize, padding, backgroundColor, borderRadius, textPosition, scaleFactor } = this.parameters;
1682
+ const textMetrics = ctx.measureText(text);
1683
+ const textWidth = text ? textMetrics.width : 0;
1684
+ const textHeight = text ? fontSize : 0;
1685
+ let contentWidth = 0;
1686
+ let contentHeight = 0;
1687
+ let iconX = 0, iconY = 0;
1688
+ let textX = 0, textY = 0;
1689
+ const hasImage = !!image;
1690
+ const hasText = !!text;
1691
+ if (hasImage && hasText) {
1692
+ switch (textPosition) {
1152
1693
  case "top":
1153
- T = Math.max(r, g), v = r + h + w, M = (T - g) / 2, E = w / 2, b = (T - r) / 2, x = w + h;
1694
+ contentWidth = Math.max(iconSize, textWidth);
1695
+ contentHeight = iconSize + padding + textHeight;
1696
+ textX = (contentWidth - textWidth) / 2;
1697
+ textY = textHeight / 2;
1698
+ iconX = (contentWidth - iconSize) / 2;
1699
+ iconY = textHeight + padding;
1154
1700
  break;
1155
1701
  case "bottom":
1156
- T = Math.max(r, g), v = r + h + w, b = (T - r) / 2, x = 0, M = (T - g) / 2, E = r + h + w / 2;
1702
+ contentWidth = Math.max(iconSize, textWidth);
1703
+ contentHeight = iconSize + padding + textHeight;
1704
+ iconX = (contentWidth - iconSize) / 2;
1705
+ iconY = 0;
1706
+ textX = (contentWidth - textWidth) / 2;
1707
+ textY = iconSize + padding + textHeight / 2;
1157
1708
  break;
1158
1709
  case "left":
1159
- T = r + h + g, v = Math.max(r, w), M = 0, E = v / 2, b = g + h, x = (v - r) / 2;
1710
+ contentWidth = iconSize + padding + textWidth;
1711
+ contentHeight = Math.max(iconSize, textHeight);
1712
+ textX = 0;
1713
+ textY = contentHeight / 2;
1714
+ iconX = textWidth + padding;
1715
+ iconY = (contentHeight - iconSize) / 2;
1160
1716
  break;
1717
+ case "right":
1161
1718
  default:
1162
- T = r + h + g, v = Math.max(r, w), b = 0, x = (v - r) / 2, M = r + h, E = v / 2;
1719
+ contentWidth = iconSize + padding + textWidth;
1720
+ contentHeight = Math.max(iconSize, textHeight);
1721
+ iconX = 0;
1722
+ iconY = (contentHeight - iconSize) / 2;
1723
+ textX = iconSize + padding;
1724
+ textY = contentHeight / 2;
1163
1725
  break;
1164
1726
  }
1165
- else S ? (T = r, v = r, b = 0, x = 0) : m && (T = g, v = w, M = 0, E = w / 2);
1166
- const y = T + h * 2, B = v + h * 2;
1167
- t.width = y, t.height = B, s.font = `${a}px ${this.parameters.fontFamily}`, s.textBaseline = "middle", l && (s.fillStyle = l, this._drawRoundedRect(s, 0, 0, y, B, u), s.fill()), S && s.drawImage(n, b + h, x + h, r, r), m && (s.fillStyle = c, s.fillText(i, M + h, E + h)), this.material.map?.dispose();
1168
- const _ = new it(t);
1169
- _.colorSpace = ve, this.material.map = _;
1170
- const O = 0.01;
1171
- this.scale.set(y * O, B * O, 1);
1172
- }
1173
- _loadImage(e) {
1174
- return new Promise((t, s) => {
1175
- if (typeof e == "string") {
1176
- const n = new Image();
1177
- n.crossOrigin = "Anonymous", n.onload = () => t(n), n.onerror = (i) => s(i), n.src = e;
1178
- } else
1179
- t(e);
1727
+ } else if (hasImage) {
1728
+ contentWidth = iconSize;
1729
+ contentHeight = iconSize;
1730
+ iconX = 0;
1731
+ iconY = 0;
1732
+ } else if (hasText) {
1733
+ contentWidth = textWidth;
1734
+ contentHeight = textHeight;
1735
+ textX = 0;
1736
+ textY = textHeight / 2;
1737
+ }
1738
+ const canvasWidth = contentWidth + padding * 2;
1739
+ const canvasHeight = contentHeight + padding * 2;
1740
+ canvas.width = canvasWidth;
1741
+ canvas.height = canvasHeight;
1742
+ ctx.font = `${fontSize}px ${this.parameters.fontFamily}`;
1743
+ if (backgroundColor) {
1744
+ ctx.fillStyle = backgroundColor;
1745
+ this._drawRoundedRect(ctx, 0, 0, canvasWidth, canvasHeight, borderRadius);
1746
+ ctx.fill();
1747
+ }
1748
+ if (hasImage) {
1749
+ ctx.drawImage(image, iconX + padding, iconY + padding, iconSize, iconSize);
1750
+ }
1751
+ if (hasText) {
1752
+ ctx.fillStyle = color2;
1753
+ const metrics = ctx.measureText(text);
1754
+ const actualTextHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
1755
+ const baselineOffset = metrics.actualBoundingBoxAscent - actualTextHeight / 2;
1756
+ ctx.textBaseline = "alphabetic";
1757
+ ctx.fillText(text, textX + padding, textY + padding + baselineOffset);
1758
+ }
1759
+ const oldTexture = this.material.map;
1760
+ const texture = new CanvasTexture(canvas);
1761
+ texture.colorSpace = SRGBColorSpace;
1762
+ this.material.map = texture;
1763
+ oldTexture?.dispose();
1764
+ this.scale.set(canvasWidth * scaleFactor, canvasHeight * scaleFactor, 1);
1765
+ }
1766
+ _loadImage(img) {
1767
+ return new Promise((resolve, reject) => {
1768
+ if (typeof img === "string") {
1769
+ const _img = new Image();
1770
+ _img.crossOrigin = "Anonymous";
1771
+ _img.onload = () => resolve(_img);
1772
+ _img.onerror = () => reject(new Error(`Failed to load image: ${img}`));
1773
+ _img.src = img;
1774
+ } else {
1775
+ resolve(img);
1776
+ }
1180
1777
  });
1181
1778
  }
1182
- _drawRoundedRect(e, t, s, n, i, a) {
1183
- e.beginPath(), e.moveTo(t + a, s), e.lineTo(t + n - a, s), e.quadraticCurveTo(t + n, s, t + n, s + a), e.lineTo(t + n, s + i - a), e.quadraticCurveTo(t + n, s + i, t + n - a, s + i), e.lineTo(t + a, s + i), e.quadraticCurveTo(t, s + i, t, s + i - a), e.lineTo(t, s + a), e.quadraticCurveTo(t, s, t + a, s), e.closePath();
1779
+ _drawRoundedRect(ctx, x, y, width, height, radius) {
1780
+ ctx.beginPath();
1781
+ ctx.moveTo(x + radius, y);
1782
+ ctx.lineTo(x + width - radius, y);
1783
+ ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
1784
+ ctx.lineTo(x + width, y + height - radius);
1785
+ ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
1786
+ ctx.lineTo(x + radius, y + height);
1787
+ ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
1788
+ ctx.lineTo(x, y + radius);
1789
+ ctx.quadraticCurveTo(x, y, x + radius, y);
1790
+ ctx.closePath();
1184
1791
  }
1185
1792
  dispose() {
1186
- this.material.map?.dispose(), this.material.dispose();
1793
+ this.material.map?.dispose();
1794
+ this.material.dispose();
1187
1795
  }
1188
1796
  }
1189
- class Oe extends U {
1190
- isShapeMesh = !0;
1797
+ class ShapeMesh extends BaseMesh {
1798
+ isShapeMesh = true;
1191
1799
  type = "ShapeMesh";
1192
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
1193
- super(), this.geometry = new rt(e?.shape, e?.curveSegments), this.material = new I(t), this.geometry.rotateX(-Math.PI / 2);
1800
+ constructor({ geometryParameters, materialParameters } = {}) {
1801
+ super();
1802
+ this.geometry = new ShapeGeometry(geometryParameters?.shape, geometryParameters?.curveSegments);
1803
+ this.material = new MeshStandardNodeMaterial(materialParameters);
1804
+ this.geometry.rotateX(-Math.PI / 2);
1194
1805
  }
1195
- static createFromPoints(e, t = {}) {
1196
- return new Oe({
1197
- ...t,
1806
+ static createFromPoints(points, parameters = {}) {
1807
+ return new ShapeMesh({
1808
+ ...parameters,
1198
1809
  geometryParameters: {
1199
- ...t.geometryParameters,
1200
- shape: new be(e.map((s) => new P(s.x, -s.z)))
1810
+ ...parameters.geometryParameters,
1811
+ shape: new Shape(points.map((point) => new Vector2(point.x, -point.z)))
1201
1812
  }
1202
1813
  });
1203
1814
  }
1204
1815
  }
1205
- class Pe extends U {
1206
- isExtrudeMesh = !0;
1816
+ class ExtrudeMesh extends BaseMesh {
1817
+ isExtrudeMesh = true;
1207
1818
  type = "ExtrudeMesh";
1208
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
1209
- super(), this.geometry = new at(e?.shape, e?.options), this.material = new I(t), this.geometry.rotateX(-Math.PI / 2);
1819
+ constructor({ geometryParameters, materialParameters } = {}) {
1820
+ super();
1821
+ this.geometry = new ExtrudeGeometry(geometryParameters?.shape, geometryParameters?.options);
1822
+ this.material = new MeshStandardNodeMaterial(materialParameters);
1823
+ this.geometry.rotateX(-Math.PI / 2);
1210
1824
  }
1211
- static createFromPoints(e, t = {}) {
1212
- return new Pe({
1213
- ...t,
1825
+ static createFromPoints(points, parameters = {}) {
1826
+ return new ExtrudeMesh({
1827
+ ...parameters,
1214
1828
  geometryParameters: {
1215
- ...t.geometryParameters,
1216
- shape: new be(e.map((s) => new P(s.x, -s.z)))
1829
+ ...parameters.geometryParameters,
1830
+ shape: new Shape(points.map((point) => new Vector2(point.x, -point.z)))
1217
1831
  }
1218
1832
  });
1219
1833
  }
1220
1834
  }
1221
- class Cs extends U {
1222
- isPlaneMesh = !0;
1835
+ class PlaneMesh extends BaseMesh {
1836
+ isPlaneMesh = true;
1223
1837
  type = "PlaneMesh";
1224
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
1225
- super(), this.geometry = new ot(
1226
- e?.width,
1227
- e?.height,
1228
- e?.widthSegments,
1229
- e?.heightSegments
1230
- ), this.material = new I(t);
1838
+ constructor({ geometryParameters, materialParameters } = {}) {
1839
+ super();
1840
+ this.geometry = new PlaneGeometry(
1841
+ geometryParameters?.width,
1842
+ geometryParameters?.height,
1843
+ geometryParameters?.widthSegments,
1844
+ geometryParameters?.heightSegments
1845
+ );
1846
+ this.material = new MeshStandardNodeMaterial(materialParameters);
1231
1847
  }
1232
1848
  }
1233
- class xs extends U {
1234
- isCircleMesh = !0;
1849
+ class CircleMesh extends BaseMesh {
1850
+ isCircleMesh = true;
1235
1851
  type = "CircleMesh";
1236
- constructor({ geometryParameters: e, materialParameters: t } = {}) {
1852
+ constructor({ geometryParameters, materialParameters } = {}) {
1237
1853
  super(
1238
- new ct(
1239
- e?.radius,
1240
- e?.segments,
1241
- e?.thetaStart,
1242
- e?.thetaLength
1854
+ new CircleGeometry(
1855
+ geometryParameters?.radius,
1856
+ geometryParameters?.segments,
1857
+ geometryParameters?.thetaStart,
1858
+ geometryParameters?.thetaLength
1243
1859
  ),
1244
- new I(t)
1245
- ), this.geometry.rotateX(-Math.PI / 2);
1860
+ new MeshStandardNodeMaterial(materialParameters)
1861
+ );
1862
+ this.geometry.rotateX(-Math.PI / 2);
1246
1863
  }
1247
1864
  }
1248
- class Yt {
1249
- static traverseMeshes(e, t) {
1250
- e.traverse((s) => {
1251
- s instanceof j && t(s);
1865
+ class ObjectUtils {
1866
+ static traverseMeshes(object, callback) {
1867
+ object.traverse((child) => {
1868
+ if (child instanceof Mesh) {
1869
+ callback(child);
1870
+ }
1252
1871
  });
1253
1872
  }
1254
1873
  }
1255
- class Ms {
1256
- static flow(e = {}) {
1257
- const { baseColor: t = 16777215, flowColor: s = 65280, speed: n = 1, scale: i = 3, intensity: a = 4 } = e, c = N(new A(t)), r = N(new A(s)), h = ae().x.mul(i).sub(Q.mul(n)), l = K(oe(h).add(1).mul(0.5), a);
1258
- return X(c, r, l);
1259
- }
1260
- static breathe(e = {}) {
1261
- const { baseColor: t = 16777215, breathColor: s = 65280, speed: n = 1, intensity: i = 2 } = e, a = N(new A(t)), c = N(new A(s)), r = oe(Q.mul(n)).add(1).mul(0.5), h = K(r, i);
1262
- return X(a, c, h);
1263
- }
1264
- static fluid(e = {}) {
1874
+ class TSLEffects {
1875
+ static flow(parameters = {}) {
1876
+ const { baseColor = 16777215, flowColor = 65280, speed = 1, scale = 3, intensity = 4 } = parameters;
1877
+ const baseColorNode = color(new Color$1(baseColor));
1878
+ const flowColorNode = color(new Color$1(flowColor));
1879
+ const flow = uv().x.mul(scale).sub(time.mul(speed));
1880
+ const pattern = pow(sin(flow).add(1).mul(0.5), intensity);
1881
+ return mix(baseColorNode, flowColorNode, pattern);
1882
+ }
1883
+ static breathe(parameters = {}) {
1884
+ const { baseColor = 16777215, breathColor = 65280, speed = 1, intensity = 2 } = parameters;
1885
+ const baseColorNode = color(new Color$1(baseColor));
1886
+ const breathColorNode = color(new Color$1(breathColor));
1887
+ const osc = sin(time.mul(speed)).add(1).mul(0.5);
1888
+ const pattern = pow(osc, intensity);
1889
+ return mix(baseColorNode, breathColorNode, pattern);
1890
+ }
1891
+ static fluid(parameters = {}) {
1265
1892
  const {
1266
- baseColor: t = 16777215,
1267
- flowColor: s = 255,
1268
- speed: n = 1,
1269
- scale: i = 1,
1270
- intensity: a = 1,
1271
- distortion: c = 0.5
1272
- } = e, r = N(new A(t)), h = N(new A(s)), l = ae().mul(i), u = Q.mul(n), f = ce(l.add(u), 1, 0), p = l.add(f.mul(c)), g = ce(p, 1, 0).add(1).mul(0.5), w = K(g, a);
1273
- return X(r, h, w);
1893
+ baseColor = 16777215,
1894
+ flowColor = 255,
1895
+ speed = 1,
1896
+ scale = 1,
1897
+ intensity = 1,
1898
+ distortion = 0.5
1899
+ } = parameters;
1900
+ const baseColorNode = color(new Color$1(baseColor));
1901
+ const flowColorNode = color(new Color$1(flowColor));
1902
+ const uvNode = uv().mul(scale);
1903
+ const timeNode = time.mul(speed);
1904
+ const noiseNode = mx_noise_float(uvNode.add(timeNode), 1, 0);
1905
+ const distortedUV = uvNode.add(noiseNode.mul(distortion));
1906
+ const pattern = mx_noise_float(distortedUV, 1, 0).add(1).mul(0.5);
1907
+ const fluidPattern = pow(pattern, intensity);
1908
+ return mix(baseColorNode, flowColorNode, fluidPattern);
1274
1909
  }
1275
1910
  }
1276
- function Es(o) {
1911
+ function reinterpretType(_value) {
1277
1912
  }
1278
- const $ = "uSpaceHighlight", V = `${$}/enabled`, Se = `${$}/opacity`, Le = `${$}/color`, Ie = `${$}/overwrite`, Jt = Te(() => {
1279
- const o = D(V, "uint"), e = D(Le, "uint"), t = D(Ie, "uint"), s = Vt(e), n = he.mul(s), i = Y(t.greaterThan(0), s, n);
1280
- return Y(o.greaterThan(0), i, he);
1281
- })(), Zt = Te(() => {
1282
- const o = D(V, "uint"), e = D(Se, "float");
1283
- return Y(o.greaterThan(0), e, lt);
1913
+ const _highlightKey = "uSpaceHighlight";
1914
+ const _highlightEnabledKey = `${_highlightKey}/enabled`;
1915
+ const _highlightOpacityKey = `${_highlightKey}/opacity`;
1916
+ const _highlightColorKey = `${_highlightKey}/color`;
1917
+ const _highlightOverwriteKey = `${_highlightKey}/overwrite`;
1918
+ const _highlightColorNode = Fn(() => {
1919
+ const enabled = userData(_highlightEnabledKey, "uint");
1920
+ const colorUint = userData(_highlightColorKey, "uint");
1921
+ const overwrite = userData(_highlightOverwriteKey, "uint");
1922
+ const hlColorRaw = uintToColor(colorUint);
1923
+ const tintedColor = materialColor.mul(hlColorRaw);
1924
+ const finalHlColor = select(overwrite.greaterThan(0), hlColorRaw, tintedColor);
1925
+ const hlColor = select(enabled.greaterThan(0), finalHlColor, materialColor);
1926
+ return hlColor;
1284
1927
  })();
1285
- class Os {
1286
- static highlight(e, t = {}) {
1287
- const s = Object.assign(
1928
+ const _highlightOpacityNode = Fn(() => {
1929
+ const enabled = userData(_highlightEnabledKey, "uint");
1930
+ const opacity = userData(_highlightOpacityKey, "float");
1931
+ const hlOpacity = select(enabled.greaterThan(0), opacity, materialOpacity);
1932
+ return hlOpacity;
1933
+ })();
1934
+ class MaterialEffects {
1935
+ static highlight(object, options = {}) {
1936
+ const highlightOptions = Object.assign(
1288
1937
  {
1289
- enabled: !0,
1938
+ enabled: true,
1290
1939
  opacity: 0.5,
1291
1940
  color: 16711680,
1292
- overwrite: !1
1941
+ overwrite: false
1293
1942
  },
1294
- t
1943
+ options
1295
1944
  );
1296
- s.color = new Z(s.color).getHex(), Yt.traverseMeshes(e, (n) => {
1297
- n.userData[V] = s.enabled ? 1 : 0, n.userData[Se] = s.opacity, n.userData[Le] = s.color, n.userData[Ie] = s.overwrite ? 1 : 0;
1298
- const i = n.material;
1299
- i && !Array.isArray(i) && (i.transparent = !0, i.colorNode = Jt, i.opacityNode = Zt, i.needsUpdate = !0);
1945
+ highlightOptions.color = new Color(highlightOptions.color).getHex();
1946
+ ObjectUtils.traverseMeshes(object, (mesh) => {
1947
+ mesh.userData[_highlightEnabledKey] = highlightOptions.enabled ? 1 : 0;
1948
+ mesh.userData[_highlightOpacityKey] = highlightOptions.opacity;
1949
+ mesh.userData[_highlightColorKey] = highlightOptions.color;
1950
+ mesh.userData[_highlightOverwriteKey] = highlightOptions.overwrite ? 1 : 0;
1951
+ const material = mesh.material;
1952
+ if (material && !Array.isArray(material)) {
1953
+ material.transparent = true;
1954
+ material.colorNode = _highlightColorNode;
1955
+ material.opacityNode = _highlightOpacityNode;
1956
+ material.needsUpdate = true;
1957
+ }
1300
1958
  });
1301
1959
  }
1302
1960
  }
1303
- const Vt = (o) => {
1304
- const e = o.shiftRight(16).bitAnd(255).toFloat().div(255), t = o.shiftRight(8).bitAnd(255).toFloat().div(255), s = o.bitAnd(255).toFloat().div(255);
1305
- return dt(e, t, s);
1961
+ const uintToColor = (colorUint) => {
1962
+ const r = colorUint.shiftRight(16).bitAnd(255).toFloat().div(255);
1963
+ const g = colorUint.shiftRight(8).bitAnd(255).toFloat().div(255);
1964
+ const b = colorUint.bitAnd(255).toFloat().div(255);
1965
+ return vec3(r, g, b);
1306
1966
  };
1307
- class es extends Tt {
1967
+ class Tween extends Tween$1 {
1308
1968
  viewer;
1309
- constructor(e, t) {
1310
- super(t), this.viewer = e;
1311
- }
1312
- _update = ({ time: e }) => {
1313
- this.update(e) && this.viewer.render();
1969
+ constructor(viewer, source) {
1970
+ super(source);
1971
+ this.viewer = viewer;
1972
+ }
1973
+ _update = ({ time: time2 }) => {
1974
+ const needsRender = this.update(time2);
1975
+ if (needsRender) {
1976
+ this.viewer.render();
1977
+ }
1314
1978
  };
1315
- easingByMode(e) {
1316
- const t = ts[e];
1317
- return super.easing(t);
1979
+ easingByMode(mode) {
1980
+ const tweenModeFunc = animationModeEnum[mode];
1981
+ return super.easing(tweenModeFunc);
1318
1982
  }
1319
- start(e, t) {
1320
- return this.viewer.addEventListener("afterControlsUpdate", this._update), super.start(e, t);
1983
+ start(time2, overrideStartingValues) {
1984
+ this.viewer.addEventListener("afterControlsUpdate", this._update);
1985
+ return super.start(time2, overrideStartingValues);
1321
1986
  }
1322
1987
  stop() {
1323
- return this.viewer.removeEventListener("afterControlsUpdate", this._update), super.stop();
1988
+ this.viewer.removeEventListener("afterControlsUpdate", this._update);
1989
+ return super.stop();
1324
1990
  }
1325
1991
  }
1326
- function Ps(o, e, t, s = {}, n, i) {
1327
- return new Promise((a, c) => {
1328
- const { duration: r = 1e3, delay: h = 0, repeat: l = !1, mode: u = "Linear.None", yoyo: f = !1 } = s, p = new es(o, e).to(t, r).easingByMode(u).delay(h).onUpdate((g) => {
1329
- n?.(g, p);
1992
+ function tweenAnimation(viewer, source, target, options = {}, onUpdate, onStart) {
1993
+ return new Promise((resolve, reject) => {
1994
+ const { duration = 1e3, delay = 0, repeat = false, mode = "Linear.None", yoyo = false } = options;
1995
+ const tween = new Tween(viewer, source).to(target, duration).easingByMode(mode).delay(delay).onUpdate((e) => {
1996
+ onUpdate?.(e, tween);
1330
1997
  }).onComplete(() => {
1331
- a();
1998
+ resolve();
1332
1999
  }).onStop(() => {
1333
- c("animation stop");
2000
+ reject("animation stop");
1334
2001
  }).onStart(() => {
1335
- i?.(p);
2002
+ onStart?.(tween);
1336
2003
  });
1337
- typeof l == "number" ? p.repeat(l) : typeof l == "boolean" && l && p.repeat(1 / 0), f && p.repeatDelay(20), p.yoyo(f), p.start();
2004
+ if (typeof repeat === "number") tween.repeat(repeat);
2005
+ else if (typeof repeat === "boolean" && repeat) tween.repeat(Infinity);
2006
+ if (yoyo) tween.repeatDelay(20);
2007
+ tween.yoyo(yoyo);
2008
+ tween.start();
1338
2009
  });
1339
2010
  }
1340
- const ts = {
1341
- "Linear.None": d.Linear.None,
1342
- "Quadratic.In": d.Quadratic.In,
1343
- "Quadratic.Out": d.Quadratic.Out,
1344
- "Quadratic.InOut": d.Quadratic.InOut,
1345
- "Cubic.In": d.Cubic.In,
1346
- "Cubic.Out": d.Cubic.Out,
1347
- "Cubic.InOut": d.Cubic.InOut,
1348
- "Quartic.In": d.Quartic.In,
1349
- "Quartic.Out": d.Quartic.Out,
1350
- "Quartic.InOut": d.Quartic.InOut,
1351
- "Quintic.In": d.Quintic.In,
1352
- "Quintic.Out": d.Quintic.Out,
1353
- "Quintic.InOut": d.Quintic.InOut,
1354
- "Sinusoidal.In": d.Sinusoidal.In,
1355
- "Sinusoidal.Out": d.Sinusoidal.Out,
1356
- "Sinusoidal.InOut": d.Sinusoidal.InOut,
1357
- "Exponential.In": d.Exponential.In,
1358
- "Exponential.Out": d.Exponential.Out,
1359
- "Exponential.InOut": d.Exponential.InOut,
1360
- "Circular.In": d.Circular.In,
1361
- "Circular.Out": d.Circular.Out,
1362
- "Circular.InOut": d.Circular.InOut,
1363
- "Elastic.In": d.Elastic.In,
1364
- "Elastic.Out": d.Elastic.Out,
1365
- "Elastic.InOut": d.Elastic.InOut,
1366
- "Back.In": d.Back.In,
1367
- "Back.Out": d.Back.Out,
1368
- "Back.InOut": d.Back.InOut,
1369
- "Bounce.In": d.Bounce.In,
1370
- "Bounce.Out": d.Bounce.Out,
1371
- "Bounce.InOut": d.Bounce.InOut
2011
+ const animationModeEnum = {
2012
+ "Linear.None": Easing.Linear.None,
2013
+ "Quadratic.In": Easing.Quadratic.In,
2014
+ "Quadratic.Out": Easing.Quadratic.Out,
2015
+ "Quadratic.InOut": Easing.Quadratic.InOut,
2016
+ "Cubic.In": Easing.Cubic.In,
2017
+ "Cubic.Out": Easing.Cubic.Out,
2018
+ "Cubic.InOut": Easing.Cubic.InOut,
2019
+ "Quartic.In": Easing.Quartic.In,
2020
+ "Quartic.Out": Easing.Quartic.Out,
2021
+ "Quartic.InOut": Easing.Quartic.InOut,
2022
+ "Quintic.In": Easing.Quintic.In,
2023
+ "Quintic.Out": Easing.Quintic.Out,
2024
+ "Quintic.InOut": Easing.Quintic.InOut,
2025
+ "Sinusoidal.In": Easing.Sinusoidal.In,
2026
+ "Sinusoidal.Out": Easing.Sinusoidal.Out,
2027
+ "Sinusoidal.InOut": Easing.Sinusoidal.InOut,
2028
+ "Exponential.In": Easing.Exponential.In,
2029
+ "Exponential.Out": Easing.Exponential.Out,
2030
+ "Exponential.InOut": Easing.Exponential.InOut,
2031
+ "Circular.In": Easing.Circular.In,
2032
+ "Circular.Out": Easing.Circular.Out,
2033
+ "Circular.InOut": Easing.Circular.InOut,
2034
+ "Elastic.In": Easing.Elastic.In,
2035
+ "Elastic.Out": Easing.Elastic.Out,
2036
+ "Elastic.InOut": Easing.Elastic.InOut,
2037
+ "Back.In": Easing.Back.In,
2038
+ "Back.Out": Easing.Back.Out,
2039
+ "Back.InOut": Easing.Back.InOut,
2040
+ "Bounce.In": Easing.Bounce.In,
2041
+ "Bounce.Out": Easing.Bounce.Out,
2042
+ "Bounce.InOut": Easing.Bounce.InOut
1372
2043
  };
1373
2044
  export {
1374
- Ee as BaseGroup,
1375
- U as BaseMesh,
1376
- Xt as BaseSprite,
1377
- Pt as CameraControls,
1378
- xs as CircleMesh,
1379
- Pe as ExtrudeMesh,
1380
- Ct as InteractionEvent,
1381
- xt as InteractionManager,
1382
- Os as MaterialEffects,
1383
- H as Model,
1384
- R as ModelLoaderManager,
1385
- Mt as ObjectManager,
1386
- Yt as ObjectUtils,
1387
- Cs as PlaneMesh,
1388
- Ts as Poi,
1389
- Lt as RoomEnvironment,
1390
- Kt as SBMLoader,
1391
- Rt as SBMXLoader,
1392
- Oe as ShapeMesh,
1393
- qt as SphereMesh,
1394
- Ms as TSLEffects,
1395
- vs as TextureLoaderManager,
1396
- bs as Topology,
1397
- ue as TubeMesh,
1398
- es as Tween,
1399
- ys as Viewer,
1400
- Es as reinterpretType,
1401
- Ps as tweenAnimation
2045
+ BaseGroup,
2046
+ BaseMesh,
2047
+ BaseSprite,
2048
+ CameraControls,
2049
+ CircleMesh,
2050
+ ExtrudeMesh,
2051
+ InteractionEvent,
2052
+ InteractionManager,
2053
+ MaterialEffects,
2054
+ Model,
2055
+ ModelLoaderManager,
2056
+ ObjectManager,
2057
+ ObjectUtils,
2058
+ PlaneMesh,
2059
+ Poi,
2060
+ RoomEnvironment,
2061
+ SBMLoader,
2062
+ SBMXLoader,
2063
+ ShapeMesh,
2064
+ SphereMesh,
2065
+ TSLEffects,
2066
+ TextureLoaderManager,
2067
+ Topology,
2068
+ TubeMesh,
2069
+ Tween,
2070
+ Viewer,
2071
+ reinterpretType,
2072
+ tweenAnimation
1402
2073
  };
2074
+ //# sourceMappingURL=index.js.map