@tonybfox/threejs-tools 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/asset-loader/index.cjs +3 -417
  2. package/dist/asset-loader/index.mjs +1 -6
  3. package/dist/camera/index.cjs +1 -393
  4. package/dist/camera/index.mjs +1 -6
  5. package/dist/chunk-4O4ENFL7.mjs +83 -0
  6. package/dist/chunk-55YVGK52.mjs +1 -0
  7. package/dist/chunk-B75TYEOO.mjs +44 -0
  8. package/dist/chunk-EQRUOKFV.mjs +1 -0
  9. package/dist/chunk-JRJBW66X.mjs +1 -0
  10. package/dist/chunk-OJFYE56U.mjs +1 -0
  11. package/dist/chunk-UJF4S4J3.mjs +1 -0
  12. package/dist/chunk-WZ4X7GQ2.mjs +1 -0
  13. package/dist/chunk-Z5VL3O6M.mjs +43 -0
  14. package/dist/compass/index.cjs +3 -304
  15. package/dist/compass/index.mjs +1 -6
  16. package/dist/grid/index.cjs +3 -159
  17. package/dist/grid/index.mjs +1 -6
  18. package/dist/index.cjs +7 -5406
  19. package/dist/index.mjs +1 -384
  20. package/dist/measurements/index.cjs +1 -1197
  21. package/dist/measurements/index.mjs +1 -8
  22. package/dist/sunlight/index.cjs +1 -440
  23. package/dist/sunlight/index.d.mts +19 -0
  24. package/dist/sunlight/index.d.ts +19 -0
  25. package/dist/sunlight/index.mjs +1 -6
  26. package/dist/terrain/index.cjs +1 -422
  27. package/dist/terrain/index.mjs +1 -6
  28. package/dist/transform-controls/index.cjs +1 -1586
  29. package/dist/transform-controls/index.mjs +1 -12
  30. package/dist/view-helper/index.cjs +1 -435
  31. package/dist/view-helper/index.mjs +1 -6
  32. package/package.json +1 -1
  33. package/dist/chunk-2CDI7ORN.mjs +0 -163
  34. package/dist/chunk-FBTT6MU6.mjs +0 -386
  35. package/dist/chunk-IAZH4OHC.mjs +0 -399
  36. package/dist/chunk-LUE7VHLK.mjs +0 -422
  37. package/dist/chunk-OZKJ3GAD.mjs +0 -1160
  38. package/dist/chunk-W4DAAAW6.mjs +0 -404
  39. package/dist/chunk-XA7OKYSM.mjs +0 -357
  40. package/dist/chunk-YMMLYGHV.mjs +0 -1578
  41. package/dist/chunk-ZNGFST7K.mjs +0 -348
@@ -1,393 +1 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // packages/camera/src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- DualCameraControls: () => DualCameraControls
34
- });
35
- module.exports = __toCommonJS(src_exports);
36
-
37
- // packages/camera/src/DualCameraControls.ts
38
- var THREE = __toESM(require("three"));
39
- var import_camera_controls = __toESM(require("camera-controls"));
40
- var controlsInstalled = false;
41
- var tempVec3A = new THREE.Vector3();
42
- var tempVec3B = new THREE.Vector3();
43
- var tempVec2 = new THREE.Vector2();
44
- function ensureCameraControlsInstalled() {
45
- if (!controlsInstalled) {
46
- import_camera_controls.default.install({ THREE });
47
- controlsInstalled = true;
48
- }
49
- }
50
- function toVector3(value, fallback, target) {
51
- if (!value) {
52
- target.set(fallback[0], fallback[1], fallback[2]);
53
- return target;
54
- }
55
- if (Array.isArray(value)) {
56
- target.set(value[0], value[1], value[2]);
57
- return target;
58
- }
59
- target.copy(value);
60
- return target;
61
- }
62
- var DualCameraControls = class extends import_camera_controls.default {
63
- constructor(renderer, options = {}) {
64
- ensureCameraControlsInstalled();
65
- const { domElement = renderer.domElement } = options;
66
- const aspect = resolveAspect(renderer, domElement);
67
- const perspectiveConfig = options.perspective ?? {};
68
- const orthographicConfig = options.orthographic ?? {};
69
- const perspectiveCamera = new THREE.PerspectiveCamera(
70
- perspectiveConfig.fov ?? 60,
71
- aspect,
72
- perspectiveConfig.near ?? 0.1,
73
- perspectiveConfig.far ?? 2e3
74
- );
75
- perspectiveCamera.position.copy(
76
- toVector3(perspectiveConfig.position, [12, 12, 12], new THREE.Vector3())
77
- );
78
- if (perspectiveConfig.zoom !== void 0) {
79
- perspectiveCamera.zoom = perspectiveConfig.zoom;
80
- perspectiveCamera.updateProjectionMatrix();
81
- }
82
- const orthoHalfHeight = Math.max(orthographicConfig.size ?? 20, 1e-3) * 0.5;
83
- const orthoHalfWidth = orthoHalfHeight * aspect;
84
- const orthographicCamera = new THREE.OrthographicCamera(
85
- -orthoHalfWidth,
86
- orthoHalfWidth,
87
- orthoHalfHeight,
88
- -orthoHalfHeight,
89
- orthographicConfig.near ?? 0.1,
90
- orthographicConfig.far ?? 2e3
91
- );
92
- orthographicCamera.position.copy(
93
- toVector3(orthographicConfig.position, [12, 12, 12], new THREE.Vector3())
94
- );
95
- if (orthographicConfig.zoom !== void 0) {
96
- orthographicCamera.zoom = orthographicConfig.zoom;
97
- orthographicCamera.updateProjectionMatrix();
98
- }
99
- const initialMode = options.initialMode ?? "perspective";
100
- const initialCamera = initialMode === "orthographic" ? orthographicCamera : perspectiveCamera;
101
- super(initialCamera, domElement);
102
- this.updateClock = new THREE.Clock();
103
- this.externalCamera = null;
104
- const initialTarget = toVector3(
105
- options.initialTarget,
106
- [0, 0, 0],
107
- new THREE.Vector3()
108
- );
109
- void this.setLookAt(
110
- initialCamera.position.x,
111
- initialCamera.position.y,
112
- initialCamera.position.z,
113
- initialTarget.x,
114
- initialTarget.y,
115
- initialTarget.z,
116
- false
117
- );
118
- this.renderer = renderer;
119
- this.domElementRef = domElement;
120
- this.perspectiveCamera = perspectiveCamera;
121
- this.orthographicCamera = orthographicCamera;
122
- this.activeMode = initialMode;
123
- this.minOrthoHalfHeight = orthoHalfHeight;
124
- this.updateInputBindingsForMode(initialMode);
125
- }
126
- get mode() {
127
- return this.activeMode;
128
- }
129
- /**
130
- * Returns the currently active camera instance.
131
- */
132
- get activeCamera() {
133
- return this.camera;
134
- }
135
- /**
136
- * Switch to the perspective camera while keeping the current framing.
137
- */
138
- switchToPerspective(enableTransition = false) {
139
- if (this.activeMode === "perspective" && !this.externalCamera) {
140
- return;
141
- }
142
- this.externalCamera = null;
143
- const target = this.getTarget(tempVec3A);
144
- const position = this.getPosition(tempVec3B);
145
- const aspect = resolveAspect(this.renderer, this.domElementRef);
146
- this.perspectiveCamera.aspect = aspect;
147
- this.perspectiveCamera.position.copy(position);
148
- this.perspectiveCamera.quaternion.copy(this.camera.quaternion);
149
- this.perspectiveCamera.up.copy(this.camera.up);
150
- this.perspectiveCamera.updateProjectionMatrix();
151
- this.camera = this.perspectiveCamera;
152
- this.activeMode = "perspective";
153
- this.updateInputBindingsForMode("perspective");
154
- void this.setLookAt(
155
- position.x,
156
- position.y,
157
- position.z,
158
- target.x,
159
- target.y,
160
- target.z,
161
- enableTransition
162
- );
163
- this.dispatchEvent({
164
- type: "modechange",
165
- mode: this.activeMode,
166
- previousMode: "orthographic",
167
- camera: this.perspectiveCamera
168
- });
169
- }
170
- /**
171
- * Switch to the orthographic camera while keeping the current framing.
172
- */
173
- switchToOrthographic(enableTransition = false) {
174
- if (this.activeMode === "orthographic" && !this.externalCamera) {
175
- return;
176
- }
177
- this.externalCamera = null;
178
- const target = this.getTarget(tempVec3A);
179
- const position = this.getPosition(tempVec3B);
180
- const aspect = resolveAspect(this.renderer, this.domElementRef);
181
- this.updateOrthographicFrustum(position, target, aspect);
182
- this.orthographicCamera.position.copy(position);
183
- this.orthographicCamera.quaternion.copy(this.camera.quaternion);
184
- this.orthographicCamera.up.copy(this.camera.up);
185
- this.orthographicCamera.updateProjectionMatrix();
186
- this.camera = this.orthographicCamera;
187
- this.activeMode = "orthographic";
188
- this.updateInputBindingsForMode("orthographic");
189
- void this.setLookAt(
190
- position.x,
191
- position.y,
192
- position.z,
193
- target.x,
194
- target.y,
195
- target.z,
196
- enableTransition
197
- );
198
- this.dispatchEvent({
199
- type: "modechange",
200
- mode: this.activeMode,
201
- previousMode: "perspective",
202
- camera: this.orthographicCamera
203
- });
204
- }
205
- /**
206
- * Toggles between perspective and orthographic camera modes.
207
- */
208
- toggleCameraMode(enableTransition = false) {
209
- if (this.activeMode === "perspective") {
210
- this.switchToOrthographic(enableTransition);
211
- } else {
212
- this.switchToPerspective(enableTransition);
213
- }
214
- }
215
- /**
216
- * Returns true if currently using an external camera.
217
- */
218
- get isUsingExternalCamera() {
219
- return this.externalCamera !== null;
220
- }
221
- /**
222
- * Sets an external camera to use with the controls.
223
- * This allows using a camera created outside of DualCameraControls.
224
- * Call `clearExternalCamera()` to return to the internal cameras.
225
- */
226
- setCamera(camera, target, enableTransition = false) {
227
- const previousCamera = this.camera;
228
- this.externalCamera = camera;
229
- const aspect = resolveAspect(this.renderer, this.domElementRef);
230
- if (camera.type === "PerspectiveCamera") {
231
- ;
232
- camera.aspect = aspect;
233
- camera.updateProjectionMatrix();
234
- } else if (camera.type === "OrthographicCamera") {
235
- const ortho = camera;
236
- const currentHeight = (ortho.top - ortho.bottom) * 0.5;
237
- const newHalfWidth = currentHeight * aspect;
238
- ortho.left = -newHalfWidth;
239
- ortho.right = newHalfWidth;
240
- ortho.updateProjectionMatrix();
241
- }
242
- this.camera = camera;
243
- const mode = camera.type === "PerspectiveCamera" ? "perspective" : "orthographic";
244
- this.activeMode = mode;
245
- this.updateInputBindingsForMode(mode);
246
- const targetVec = toVector3(target, [0, 0, 0], tempVec3A);
247
- void this.setLookAt(
248
- camera.position.x,
249
- camera.position.y,
250
- camera.position.z,
251
- targetVec.x,
252
- targetVec.y,
253
- targetVec.z,
254
- enableTransition
255
- );
256
- this.dispatchEvent({
257
- type: "externalcamerachange",
258
- camera,
259
- previousCamera
260
- });
261
- }
262
- /**
263
- * Clears the external camera and returns to using the internal cameras.
264
- * Will switch to the camera matching the current mode.
265
- */
266
- clearExternalCamera(enableTransition = false) {
267
- if (!this.externalCamera) {
268
- return;
269
- }
270
- const target = this.getTarget(tempVec3A);
271
- const position = this.getPosition(tempVec3B);
272
- this.externalCamera = null;
273
- const internalCamera = this.activeMode === "orthographic" ? this.orthographicCamera : this.perspectiveCamera;
274
- internalCamera.position.copy(position);
275
- internalCamera.quaternion.copy(this.camera.quaternion);
276
- internalCamera.up.copy(this.camera.up);
277
- const aspect = resolveAspect(this.renderer, this.domElementRef);
278
- if (this.activeMode === "orthographic") {
279
- this.updateOrthographicFrustum(position, target, aspect);
280
- } else {
281
- this.perspectiveCamera.aspect = aspect;
282
- this.perspectiveCamera.updateProjectionMatrix();
283
- }
284
- this.camera = internalCamera;
285
- void this.setLookAt(
286
- position.x,
287
- position.y,
288
- position.z,
289
- target.x,
290
- target.y,
291
- target.z,
292
- enableTransition
293
- );
294
- this.dispatchEvent({
295
- type: "modechange",
296
- mode: this.activeMode,
297
- previousMode: this.activeMode,
298
- camera: internalCamera
299
- });
300
- }
301
- /**
302
- * Update camera projection parameters when the viewport size changes.
303
- */
304
- handleResize(width, height) {
305
- const aspect = height === 0 ? 1 : width / height;
306
- this.perspectiveCamera.aspect = aspect;
307
- this.perspectiveCamera.updateProjectionMatrix();
308
- const target = this.getTarget(tempVec3A);
309
- const position = this.getPosition(tempVec3B);
310
- this.updateOrthographicFrustum(position, target, aspect);
311
- if (this.activeMode === "orthographic") {
312
- this.camera = this.orthographicCamera;
313
- void this.setLookAt(
314
- position.x,
315
- position.y,
316
- position.z,
317
- target.x,
318
- target.y,
319
- target.z,
320
- false
321
- );
322
- }
323
- }
324
- /**
325
- * Moves the camera to a new position and target.
326
- */
327
- moveCamera(position, target, enableTransition = true) {
328
- toVector3(position, [0, 0, 0], tempVec3A);
329
- toVector3(target, [0, 0, 0], tempVec3B);
330
- return this.setLookAt(
331
- tempVec3A.x,
332
- tempVec3A.y,
333
- tempVec3A.z,
334
- tempVec3B.x,
335
- tempVec3B.y,
336
- tempVec3B.z,
337
- enableTransition
338
- );
339
- }
340
- /**
341
- * Updates the controls using an internally managed clock.
342
- * Useful when you don't want to pass delta time each frame.
343
- */
344
- updateDelta() {
345
- const delta = this.updateClock.getDelta();
346
- return super.update(delta);
347
- }
348
- updateInputBindingsForMode(mode) {
349
- const { ACTION } = import_camera_controls.default;
350
- if (mode === "orthographic") {
351
- this.mouseButtons.left = ACTION.TRUCK;
352
- this.mouseButtons.right = ACTION.ROTATE;
353
- this.mouseButtons.wheel = ACTION.ZOOM;
354
- this.touches.one = ACTION.TOUCH_TRUCK;
355
- this.touches.two = ACTION.TOUCH_ZOOM_TRUCK;
356
- } else {
357
- this.mouseButtons.left = ACTION.ROTATE;
358
- this.mouseButtons.right = ACTION.TRUCK;
359
- this.mouseButtons.wheel = ACTION.DOLLY;
360
- this.touches.one = ACTION.TOUCH_ROTATE;
361
- this.touches.two = ACTION.TOUCH_DOLLY_TRUCK;
362
- }
363
- }
364
- updateOrthographicFrustum(position, target, aspect) {
365
- const distance = Math.max(position.distanceTo(target), 1e-3);
366
- const fov = this.perspectiveCamera.fov;
367
- const halfHeight = Math.max(
368
- distance * Math.tan(THREE.MathUtils.degToRad(fov * 0.5)),
369
- this.minOrthoHalfHeight
370
- );
371
- const halfWidth = halfHeight * aspect;
372
- this.orthographicCamera.left = -halfWidth;
373
- this.orthographicCamera.right = halfWidth;
374
- this.orthographicCamera.top = halfHeight;
375
- this.orthographicCamera.bottom = -halfHeight;
376
- this.orthographicCamera.updateProjectionMatrix();
377
- }
378
- };
379
- function resolveAspect(renderer, domElement) {
380
- const size = renderer.getSize(tempVec2);
381
- if (size.y > 0) {
382
- return size.x / size.y;
383
- }
384
- const { clientWidth, clientHeight } = domElement;
385
- if (clientHeight > 0) {
386
- return clientWidth / clientHeight;
387
- }
388
- return 1;
389
- }
390
- // Annotate the CommonJS export names for ESM import in node:
391
- 0 && (module.exports = {
392
- DualCameraControls
393
- });
1
+ "use strict";var O=Object.create;var E=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var b=(i,s)=>{for(var e in s)E(i,e,{get:s[e],enumerable:!0})},R=(i,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of z(s))!L.call(i,r)&&r!==e&&E(i,r,{get:()=>s[r],enumerable:!(t=P(s,r))||t.enumerable});return i};var x=(i,s,e)=>(e=i!=null?O(V(i)):{},R(s||!i||!i.__esModule?E(e,"default",{value:i,enumerable:!0}):e,i)),w=i=>R(E({},"__esModule",{value:!0}),i);var B={};b(B,{DualCameraControls:()=>H});module.exports=w(B);var n=x(require("three")),v=x(require("camera-controls")),y=!1,m=new n.Vector3,u=new n.Vector3,k=new n.Vector2;function A(){y||(v.default.install({THREE:n}),y=!0)}function C(i,s,e){return i?Array.isArray(i)?(e.set(i[0],i[1],i[2]),e):(e.copy(i),e):(e.set(s[0],s[1],s[2]),e)}var H=class extends v.default{constructor(e,t={}){A();let{domElement:r=e.domElement}=t,a=g(e,r),o=t.perspective??{},h=t.orthographic??{},c=new n.PerspectiveCamera(o.fov??60,a,o.near??.1,o.far??2e3);c.position.copy(C(o.position,[12,12,12],new n.Vector3)),o.zoom!==void 0&&(c.zoom=o.zoom,c.updateProjectionMatrix());let p=Math.max(h.size??20,.001)*.5,f=p*a,d=new n.OrthographicCamera(-f,f,p,-p,h.near??.1,h.far??2e3);d.position.copy(C(h.position,[12,12,12],new n.Vector3)),h.zoom!==void 0&&(d.zoom=h.zoom,d.updateProjectionMatrix());let T=t.initialMode??"perspective",l=T==="orthographic"?d:c;super(l,r);this.updateClock=new n.Clock;this.externalCamera=null;let M=C(t.initialTarget,[0,0,0],new n.Vector3);this.setLookAt(l.position.x,l.position.y,l.position.z,M.x,M.y,M.z,!1),this.renderer=e,this.domElementRef=r,this.perspectiveCamera=c,this.orthographicCamera=d,this.activeMode=T,this.minOrthoHalfHeight=p,this.updateInputBindingsForMode(T)}get mode(){return this.activeMode}get activeCamera(){return this.camera}switchToPerspective(e=!1){if(this.activeMode==="perspective"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),a=g(this.renderer,this.domElementRef);this.perspectiveCamera.aspect=a,this.perspectiveCamera.position.copy(r),this.perspectiveCamera.quaternion.copy(this.camera.quaternion),this.perspectiveCamera.up.copy(this.camera.up),this.perspectiveCamera.updateProjectionMatrix(),this.camera=this.perspectiveCamera,this.activeMode="perspective",this.updateInputBindingsForMode("perspective"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"orthographic",camera:this.perspectiveCamera})}switchToOrthographic(e=!1){if(this.activeMode==="orthographic"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),a=g(this.renderer,this.domElementRef);this.updateOrthographicFrustum(r,t,a),this.orthographicCamera.position.copy(r),this.orthographicCamera.quaternion.copy(this.camera.quaternion),this.orthographicCamera.up.copy(this.camera.up),this.orthographicCamera.updateProjectionMatrix(),this.camera=this.orthographicCamera,this.activeMode="orthographic",this.updateInputBindingsForMode("orthographic"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"perspective",camera:this.orthographicCamera})}toggleCameraMode(e=!1){this.activeMode==="perspective"?this.switchToOrthographic(e):this.switchToPerspective(e)}get isUsingExternalCamera(){return this.externalCamera!==null}setCamera(e,t,r=!1){let a=this.camera;this.externalCamera=e;let o=g(this.renderer,this.domElementRef);if(e.type==="PerspectiveCamera")e.aspect=o,e.updateProjectionMatrix();else if(e.type==="OrthographicCamera"){let p=e,d=(p.top-p.bottom)*.5*o;p.left=-d,p.right=d,p.updateProjectionMatrix()}this.camera=e;let h=e.type==="PerspectiveCamera"?"perspective":"orthographic";this.activeMode=h,this.updateInputBindingsForMode(h);let c=C(t,[0,0,0],m);this.setLookAt(e.position.x,e.position.y,e.position.z,c.x,c.y,c.z,r),this.dispatchEvent({type:"externalcamerachange",camera:e,previousCamera:a})}clearExternalCamera(e=!1){if(!this.externalCamera)return;let t=this.getTarget(m),r=this.getPosition(u);this.externalCamera=null;let a=this.activeMode==="orthographic"?this.orthographicCamera:this.perspectiveCamera;a.position.copy(r),a.quaternion.copy(this.camera.quaternion),a.up.copy(this.camera.up);let o=g(this.renderer,this.domElementRef);this.activeMode==="orthographic"?this.updateOrthographicFrustum(r,t,o):(this.perspectiveCamera.aspect=o,this.perspectiveCamera.updateProjectionMatrix()),this.camera=a,this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:this.activeMode,camera:a})}handleResize(e,t){let r=t===0?1:e/t;this.perspectiveCamera.aspect=r,this.perspectiveCamera.updateProjectionMatrix();let a=this.getTarget(m),o=this.getPosition(u);this.updateOrthographicFrustum(o,a,r),this.activeMode==="orthographic"&&(this.camera=this.orthographicCamera,this.setLookAt(o.x,o.y,o.z,a.x,a.y,a.z,!1))}moveCamera(e,t,r=!0){return C(e,[0,0,0],m),C(t,[0,0,0],u),this.setLookAt(m.x,m.y,m.z,u.x,u.y,u.z,r)}updateDelta(){let e=this.updateClock.getDelta();return super.update(e)}updateInputBindingsForMode(e){let{ACTION:t}=v.default;e==="orthographic"?(this.mouseButtons.left=t.TRUCK,this.mouseButtons.right=t.ROTATE,this.mouseButtons.wheel=t.ZOOM,this.touches.one=t.TOUCH_TRUCK,this.touches.two=t.TOUCH_ZOOM_TRUCK):(this.mouseButtons.left=t.ROTATE,this.mouseButtons.right=t.TRUCK,this.mouseButtons.wheel=t.DOLLY,this.touches.one=t.TOUCH_ROTATE,this.touches.two=t.TOUCH_DOLLY_TRUCK)}updateOrthographicFrustum(e,t,r){let a=Math.max(e.distanceTo(t),.001),o=this.perspectiveCamera.fov,h=Math.max(a*Math.tan(n.MathUtils.degToRad(o*.5)),this.minOrthoHalfHeight),c=h*r;this.orthographicCamera.left=-c,this.orthographicCamera.right=c,this.orthographicCamera.top=h,this.orthographicCamera.bottom=-h,this.orthographicCamera.updateProjectionMatrix()}};function g(i,s){let e=i.getSize(k);if(e.y>0)return e.x/e.y;let{clientWidth:t,clientHeight:r}=s;return r>0?t/r:1}0&&(module.exports={DualCameraControls});
@@ -1,6 +1 @@
1
- import {
2
- DualCameraControls
3
- } from "../chunk-XA7OKYSM.mjs";
4
- export {
5
- DualCameraControls
6
- };
1
+ import{a}from"../chunk-OJFYE56U.mjs";export{a as DualCameraControls};
@@ -0,0 +1,83 @@
1
+ import*as a from"three";var m=class extends a.EventDispatcher{constructor(t,e={}){super();this.isActive=!1;this.currentRotation=0;this.camera=t,this.options={container:e.container||document.body,size:e.size||100,position:e.position||"bottom-right",offset:e.offset||{x:20,y:20},northDirection:e.northDirection?.clone().normalize()||new a.Vector3(0,0,-1),colors:{background:e.colors?.background||"#1a1a1a",border:e.colors?.border||"#333333",arrow:e.colors?.arrow||"#ff4444",text:e.colors?.text||"#ffffff",ticks:e.colors?.ticks||"#666666",...e.colors}},this.container=this.options.container,this.createCompassElement(),this.setupStyles(),this.start()}createCompassElement(){this.compassElement=document.createElement("div"),this.compassElement.className="threejs-compass-overlay";let t=document.createElement("div");t.className="compass-background";let e=[{label:"N",angle:0},{label:"E",angle:90},{label:"S",angle:180},{label:"W",angle:270}];for(let i=0;i<360;i+=11.25){let o=document.createElement("div");o.className=i%45===0?"compass-tick-major":"compass-tick-minor";let s=i%30===0?8:4;o.style.transform=`rotate(${i}deg) translateY(-${this.options.size/2-s-2}px)`,t.appendChild(o)}e.forEach(({label:i,angle:o})=>{let s=document.createElement("div");s.className="compass-label",s.textContent=i,s.style.transform=`rotate(${o}deg) translateY(-${this.options.size/2-15}px) rotate(-${o}deg)`,t.appendChild(s)}),this.arrowElement=document.createElement("div"),this.arrowElement.className="compass-arrow",this.arrowElement.innerHTML=`
2
+ <svg width="20" height="20" viewBox="0 0 20 20">
3
+ <polygon points="10,2 14,12 10,10 6,12" fill="${this.options.colors.arrow}" stroke="#000" stroke-width="0.5"/>
4
+ </svg>
5
+ `,this.compassElement.appendChild(t),this.compassElement.appendChild(this.arrowElement),this.container.appendChild(this.compassElement),this.setupDoubleClickHandler()}setupStyles(){if(document.getElementById("threejs-compass-styles"))return;let t=document.createElement("style");t.id="threejs-compass-styles",t.textContent=`
6
+ .threejs-compass-overlay {
7
+ position: fixed;
8
+ width: ${this.options.size}px;
9
+ height: ${this.options.size}px;
10
+ background: ${this.options.colors.background};
11
+ border: 2px solid ${this.options.colors.border};
12
+ border-radius: 50%;
13
+ z-index: 1000;
14
+ pointer-events: none;
15
+ user-select: none;
16
+ transition: opacity 0.2s ease;
17
+ ${this.getPositionStyles()};
18
+ }
19
+
20
+ .compass-background {
21
+ position: relative;
22
+ width: 100%;
23
+ height: 100%;
24
+ border-radius: 50%;
25
+ }
26
+
27
+ .compass-label {
28
+ position: absolute;
29
+ top: 50%;
30
+ left: 50%;
31
+ transform-origin: center;
32
+ color: ${this.options.colors.text};
33
+ font-family: Arial, sans-serif;
34
+ font-size: 12px;
35
+ font-weight: bold;
36
+ text-align: center;
37
+ width: 12px;
38
+ height: 12px;
39
+ line-height: 12px;
40
+ margin-left: -6px;
41
+ margin-top: -6px;
42
+ }
43
+
44
+ .compass-tick-major {
45
+ position: absolute;
46
+ top: 50%;
47
+ left: 50%;
48
+ width: 2px;
49
+ height: 8px;
50
+ background: ${this.options.colors.ticks};
51
+ transform-origin: center top;
52
+ margin-left: -1px;
53
+ margin-top: -4px;
54
+ }
55
+
56
+ .compass-tick-minor {
57
+ position: absolute;
58
+ top: 50%;
59
+ left: 50%;
60
+ width: 1px;
61
+ height: 4px;
62
+ background: ${this.options.colors.ticks};
63
+ transform-origin: center top;
64
+ margin-left: -0.5px;
65
+ margin-top: -2px;
66
+ opacity: 0.6;
67
+ }
68
+
69
+ .compass-arrow {
70
+ position: absolute;
71
+ top: 50%;
72
+ left: 50%;
73
+ transform: translate(-50%, -50%);
74
+ transform-origin: center;
75
+ transition: transform 0.1s ease-out;
76
+ z-index: 1;
77
+ }
78
+
79
+ .compass-arrow svg {
80
+ display: block;
81
+ filter: drop-shadow(0 0 2px rgba(0,0,0,0.5));
82
+ }
83
+ `,document.head.appendChild(t)}setupDoubleClickHandler(){this.compassElement.style.pointerEvents="auto",this.compassElement.style.cursor="pointer",this.compassElement.addEventListener("dblclick",t=>{t.preventDefault(),t.stopPropagation(),this.dispatchEvent({type:"resetToNorth"})}),this.compassElement.addEventListener("mouseenter",()=>{this.compassElement.style.opacity="0.8"}),this.compassElement.addEventListener("mouseleave",()=>{this.compassElement.style.opacity="1"})}updateTicksAndLabels(){let t=this.compassElement.querySelectorAll(".compass-tick-major"),e=this.compassElement.querySelectorAll(".compass-tick-minor");t.forEach((o,s)=>{let r=s*30%360,n=8;o.style.transform=`rotate(${r}deg) translateY(-${this.options.size/2-n-2}px)`}),e.forEach((o,s)=>{let r=[];for(let l=0;l<360;l+=10)l%30!==0&&r.push(l);let n=r[s]||0,c=4;o.style.transform=`rotate(${n}deg) translateY(-${this.options.size/2-c-2}px)`}),this.compassElement.querySelectorAll(".compass-label").forEach((o,s)=>{let r=[{label:"N",angle:0},{label:"E",angle:90},{label:"S",angle:180},{label:"W",angle:270}],{angle:n}=r[s];o.style.transform=`rotate(${n}deg) translateY(-${this.options.size/2-15}px) rotate(-${n}deg)`})}getPositionStyles(){let{position:t,offset:e}=this.options;switch(t){case"top-left":return`top: ${e.y}px; left: ${e.x}px;`;case"top-right":return`top: ${e.y}px; right: ${e.x}px;`;case"bottom-left":return`bottom: ${e.y}px; left: ${e.x}px;`;case"bottom-right":default:return`bottom: ${e.y}px; right: ${e.x}px;`}}start(){this.isActive||(this.isActive=!0,this.update())}stop(){this.isActive=!1}update(){if(!this.isActive)return;let t=new a.Matrix4;this.camera.updateMatrixWorld(),t.copy(this.camera.matrixWorld);let e=new a.Vector3(0,0,-1);e.transformDirection(t),e.y=0,e.normalize();let i=this.options.northDirection.clone();i.y=0,i.normalize();let o=Math.atan2(-e.x,-e.z)*(180/Math.PI),s=Math.atan2(-i.x,-i.z)*(180/Math.PI),n=o-s-this.currentRotation;for(;n>180;)n-=360;for(;n<-180;)n+=360;this.currentRotation+=n,this.arrowElement.style.transform=`translate(-50%, -50%) rotate(${-this.currentRotation}deg)`,this.isActive&&requestAnimationFrame(()=>this.update())}setCamera(t){this.camera=t}getNorthDirection(){return this.options.northDirection.clone()}setSize(t){this.options.size=t,this.compassElement.style.width=`${t}px`,this.compassElement.style.height=`${t}px`,this.updateTicksAndLabels(),this.updateStyles()}setPosition(t,e){t&&(this.options.position=t),e&&(this.options.offset=e);let o=this.getPositionStyles().split(";").filter(s=>s.trim());this.compassElement.style.top="",this.compassElement.style.right="",this.compassElement.style.bottom="",this.compassElement.style.left="",o.forEach(s=>{let[r,n]=s.split(":").map(c=>c.trim());r&&n&&(this.compassElement.style[r]=n)})}setColors(t){this.options.colors={...this.options.colors,...t},this.updateStyles()}static resetCameraToNorth(t,e=!0,i=new a.Vector3(0,0,-1)){if(e){let o=t.quaternion.clone(),s=new a.Quaternion,r=new a.Matrix4;r.lookAt(t.position,t.position.clone().add(i),new a.Vector3(0,1,0)),s.setFromRotationMatrix(r);let n=500,c=Date.now(),l=()=>{let h=Date.now()-c,p=Math.min(h/n,1),d=1-Math.pow(1-p,3);t.quaternion.slerpQuaternions(o,s,d),p<1&&requestAnimationFrame(l)};l()}else t.lookAt(t.position.clone().add(i))}updateStyles(){let t=document.getElementById("threejs-compass-styles");t&&t.remove(),this.setupStyles()}dispose(){if(this.stop(),this.compassElement&&this.compassElement.parentNode&&this.compassElement.parentNode.removeChild(this.compassElement),document.querySelectorAll(".threejs-compass-overlay").length===0){let e=document.getElementById("threejs-compass-styles");e&&e.remove()}}};export{m as a};
@@ -0,0 +1 @@
1
+ import*as d from"three";var E=class extends d.EventDispatcher{constructor(e,t={}){super();this.mesh=null;this.currentData=null;this.isLoading=!1;this.generatedTextureUrls=new Set;this.scene=e,this.widthSegments=t.widthSegments??50,this.depthSegments=t.depthSegments??50,this.elevationScale=t.elevationScale??1,this.baseColor=t.baseColor??9139029,this.wireframe=t.wireframe??!1,this.textureUrl=t.textureUrl,this.mapboxOptions=t.mapbox,this.receiveShadow=t.receiveShadow??!0,this.castShadow=t.castShadow??!0,this.useDemoData=t.useDemoData??!1}setMapboxOptions(e){this.mapboxOptions=e}async loadTerrain(e,t){if(this.isLoading){console.warn("Terrain is already loading");return}this.isLoading=!0,this.dispatchEvent({type:"updateStarted",center:e,dimensions:t});try{let a=await this.fetchElevationData(e,t);this.currentData=a,this.dispatchEvent({type:"dataLoaded",data:a});let n=await this.resolveTexture(e,t);await this.createMesh(a,n)}catch(a){console.error("Error loading terrain:",a),this.dispatchEvent({type:"error",message:"Failed to load terrain",error:a})}finally{this.isLoading=!1}}async updateTerrain(e,t){if(!this.currentData&&!e){console.warn("No current terrain data and no center provided");return}let a=e||this.currentData.center,n=t||this.currentData.dimensions;await this.loadTerrain(a,n)}async fetchElevationData(e,t){if(this.useDemoData)return this.generateDemoData(e,t);let a=[],n=111320,l=111320*Math.max(Math.abs(Math.cos(e.latitude*Math.PI/180)),1e-6),s=t.depth/n,i=t.width/l,o=s/this.depthSegments,m=i/this.widthSegments,c=e.latitude+s/2,h=e.longitude-i/2;for(let p=0;p<=this.depthSegments;p++)for(let x=0;x<=this.widthSegments;x++)a.push({latitude:c-p*o,longitude:h+x*m});let r=await fetch("https://api.open-elevation.com/api/v1/lookup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locations:a})});if(!r.ok)throw new Error(`Elevation API error: ${r.statusText}`);let b=(await r.json()).results,u=[],f=1/0,T=-1/0;for(let p=0;p<=this.depthSegments;p++){let x=[];for(let v=0;v<=this.widthSegments;v++){let S=p*(this.widthSegments+1)+v,w=b[S].elevation;x.push(w),f=Math.min(f,w),T=Math.max(T,w)}u.push(x)}return{center:e,dimensions:t,elevations:u,minElevation:f,maxElevation:T}}generateDemoData(e,t){let a=[],n=1/0,l=-1/0,s=e.latitude+e.longitude;for(let i=0;i<=this.depthSegments;i++){let o=[];for(let m=0;m<=this.widthSegments;m++){let c=m/this.widthSegments*4,h=i/this.depthSegments*4,r=0;r+=Math.sin(c+s)*500,r+=Math.cos(h+s)*500,r+=Math.sin(c*2+s)*200,r+=Math.cos(h*2+s)*200,r+=Math.sin(c*4+s)*50,r+=Math.cos(h*4+s)*50,r+=(Math.random()-.5)*30,o.push(r),n=Math.min(n,r),l=Math.max(l,r)}a.push(o)}return{center:e,dimensions:t,elevations:a,minElevation:n,maxElevation:l}}async createMesh(e,t){this.mesh&&(this.scene.remove(this.mesh),this.mesh.geometry.dispose(),Array.isArray(this.mesh.material)?this.mesh.material.forEach(i=>i.dispose()):this.mesh.material.dispose());let a=new d.PlaneGeometry(e.dimensions.width,e.dimensions.depth,this.widthSegments,this.depthSegments),n=a.attributes.position,l=0;for(let i=0;i<=this.depthSegments;i++)for(let o=0;o<=this.widthSegments;o++){let c=(e.elevations[i][o]-e.minElevation)*this.elevationScale;n.setZ(l,c),l++}a.computeVertexNormals();let s;if(t?.url)try{let i=await new d.TextureLoader().loadAsync(t.url);s=new d.MeshStandardMaterial({map:i,wireframe:this.wireframe})}catch(i){console.warn("Failed to load terrain texture, using base color.",i),s=new d.MeshStandardMaterial({color:this.baseColor,wireframe:this.wireframe})}finally{t.revokeOnUse&&this.releaseGeneratedTexture(t.url)}else s=new d.MeshStandardMaterial({color:this.baseColor,wireframe:this.wireframe});this.mesh=new d.Mesh(a,s),this.mesh.rotation.x=-Math.PI/2,this.mesh.receiveShadow=this.receiveShadow,this.mesh.castShadow=this.castShadow,this.scene.add(this.mesh),this.dispatchEvent({type:"meshLoaded",mesh:this.mesh})}async resolveTexture(e,t){if(this.textureUrl)return{url:this.textureUrl,revokeOnUse:!1};if(this.mapboxOptions)try{let a=await this.fetchMapboxTexture(e,t,this.mapboxOptions);return this.generatedTextureUrls.add(a),{url:a,revokeOnUse:!0}}catch(a){console.warn("Failed to fetch Mapbox imagery, falling back to base material.",a);return}}computeBoundingBox(e,t,a){let l=e.latitude*Math.PI/180,s=Math.cos(l),i=111320*Math.max(Math.abs(s),1e-6),o=Math.max(0,a),m=t.width*(1+o),h=t.depth*(1+o)/2/111320,r=m/2/i,g=(p,x,v)=>Math.min(Math.max(p,x),v),b=g(e.latitude-h,-90,90),u=g(e.latitude+h,-90,90),f=g(e.longitude-r,-180,180),T=g(e.longitude+r,-180,180);return{minLat:b,maxLat:u,minLon:f,maxLon:T}}async fetchMapboxTexture(e,t,a){let l=(a.styleId??"mapbox/satellite-v9").replace("mapbox://styles/","").replace(/^\/+/,""),s=Math.min(1280,Math.max(1,Math.floor(a.imageWidth??1024))),i=Math.min(1280,Math.max(1,Math.floor(a.imageHeight??1024))),o=a.highResolution?"@2x":"",m=a.imageFormat??"png",c=a.paddingRatio??.1,h=this.computeBoundingBox(e,t,c),r=`${h.minLon.toFixed(6)},${h.minLat.toFixed(6)},${h.maxLon.toFixed(6)},${h.maxLat.toFixed(6)}`,g=new URLSearchParams({access_token:a.accessToken,format:m}),b=`https://api.mapbox.com/styles/v1/${l}/static/[${r}]/${s}x${i}${o}?${g.toString()}`,u=await fetch(b);if(!u.ok)throw new Error(`Mapbox imagery request failed: ${u.status} ${u.statusText}`);let f=await u.blob();if(typeof URL>"u"||typeof URL.createObjectURL!="function")throw new Error("URL.createObjectURL is not available in this environment");return URL.createObjectURL(f)}releaseGeneratedTexture(e){this.generatedTextureUrls.has(e)&&(typeof URL<"u"&&typeof URL.revokeObjectURL=="function"&&URL.revokeObjectURL(e),this.generatedTextureUrls.delete(e))}getMesh(){return this.mesh}getData(){return this.currentData}isTerrainLoading(){return this.isLoading}dispose(){if(this.mesh&&(this.scene.remove(this.mesh),this.mesh.geometry.dispose(),Array.isArray(this.mesh.material)?this.mesh.material.forEach(e=>e.dispose()):this.mesh.material.dispose(),this.mesh=null),this.currentData=null,this.generatedTextureUrls.size>0)for(let e of Array.from(this.generatedTextureUrls))this.releaseGeneratedTexture(e)}};export{E as a};
@@ -0,0 +1,44 @@
1
+ import*as o from"three";import{GLTFLoader as u}from"three/examples/jsm/loaders/GLTFLoader.js";import{FBXLoader as E}from"three/examples/jsm/loaders/FBXLoader.js";import{OBJLoader as b}from"three/examples/jsm/loaders/OBJLoader.js";import{USDLoader as y}from"three/examples/jsm/loaders/USDLoader.js";import{ColladaLoader as v}from"three/examples/jsm/loaders/ColladaLoader.js";import{STLLoader as R}from"three/examples/jsm/loaders/STLLoader.js";import{PLYLoader as L}from"three/examples/jsm/loaders/PLYLoader.js";import{ThreeMFLoader as T}from"three/examples/jsm/loaders/3MFLoader.js";var f=class extends o.EventDispatcher{constructor(){super();this.cache=new Map;this.placeholder=null;this.loadedAsset=null;this.lowResAsset=null;this.errorColor=16729156;this.errorOpacity=.5;this.gltfLoader=new u,this.fbxLoader=new E,this.objLoader=new b,this.usdLoader=new y,this.colladaLoader=new v,this.stlLoader=new R,this.plyLoader=new L,this.threeMFLoader=new T}createPlaceholder(e,r=5227511,l=.3){let[a,c,i]=e,d=new o.BoxGeometry(a,c,i),t=new o.ShaderMaterial({side:o.DoubleSide,depthWrite:!1,blending:o.AdditiveBlending,transparent:!0,uniforms:{color:{value:new o.Color(r)},opacity:{value:l},fillProgress:{value:0},time:{value:0},isError:{value:0},yMin:{value:-c/2},yMax:{value:c/2}},vertexShader:`
2
+ varying vec3 vPosition;
3
+ void main() {
4
+ vPosition = position;
5
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
6
+ }
7
+ `,fragmentShader:`
8
+ uniform vec3 color;
9
+ uniform float opacity;
10
+ uniform float fillProgress;
11
+ uniform float time;
12
+ uniform float isError;
13
+ uniform float yMin;
14
+ uniform float yMax;
15
+ varying vec3 vPosition;
16
+
17
+ void main() {
18
+ float normalizedY = (vPosition.y - yMin) / (yMax - yMin); // Normalize based on actual geometry bounds
19
+ float alpha = opacity;
20
+
21
+ // Create fill-up effect
22
+ if (normalizedY > fillProgress) {
23
+ alpha *= 0.1; // Reduce opacity for unfilled parts
24
+ }
25
+
26
+ // Error state effects
27
+ if (isError > 0.5) {
28
+ // Add pulsing effect for error state
29
+ float pulse = 0.5 + 0.5 * sin(time * 4.0);
30
+ alpha *= (0.3 + 0.4 * pulse);
31
+
32
+ // Add error pattern
33
+ float stripe = sin(vPosition.y * 20.0 + time * 2.0);
34
+ alpha *= (0.7 + 0.3 * step(0.0, stripe));
35
+ }
36
+
37
+ // Add edge glow
38
+ vec3 viewDirection = normalize(cameraPosition - vPosition);
39
+ float edgeIntensity = pow(1.0 - abs(dot(viewDirection, normalize(vPosition))), 2.0);
40
+
41
+ vec3 finalColor = color + edgeIntensity * 0.5;
42
+ gl_FragColor = vec4(finalColor, alpha);
43
+ }
44
+ `}),s=new o.Mesh(d,t);return this.positionAssetAtBottomCenter(s),s}updatePlaceholder(e){if(this.placeholder&&this.placeholder instanceof o.Mesh){let r=this.placeholder.material;r.uniforms&&r.uniforms.fillProgress&&(r.uniforms.fillProgress.value=e)}}setPlaceholderError(){if(this.placeholder&&this.placeholder instanceof o.Mesh){let e=this.placeholder.material;e.uniforms&&(e.uniforms.color&&(e.uniforms.color.value=new o.Color(this.errorColor)),e.uniforms.opacity&&(e.uniforms.opacity.value=this.errorOpacity),e.uniforms.fillProgress&&(e.uniforms.fillProgress.value=0),e.uniforms.isError&&(e.uniforms.isError.value=1))}}updatePlaceholderAnimation(e){if(this.placeholder&&this.placeholder instanceof o.Mesh){let r=this.placeholder.material;r.uniforms&&r.uniforms.time&&(r.uniforms.time.value+=e)}}positionAssetAtBottomCenter(e){e.updateMatrixWorld(!0);let r=new o.Box3().setFromObject(e);if(r.isEmpty())return;let l=r.getCenter(new o.Vector3),a=new o.Vector3(l.x,r.min.y-.01,l.z);!Number.isFinite(a.x)||!Number.isFinite(a.y)||!Number.isFinite(a.z)||(e.position.sub(a),e.userData.bottomCenterOffset=a,e.updateMatrixWorld(!0))}ensureBottomCenterOffset(e){let r=e.userData.bottomCenterOffset;if(r instanceof o.Vector3)return r;if(r&&typeof r=="object"){let{x:l=0,y:a=0,z:c=0}=r,i=new o.Vector3(l??0,a??0,c??0);return e.userData.bottomCenterOffset=i,i}return null}normalizeBottomCenterData(e){let r=this.ensureBottomCenterOffset(e)!==null;return e.children.forEach(l=>this.normalizeBottomCenterData(l)),r}async load(e){let{type:r,url:l,size:a,lowResUrl:c,enableCaching:i=!0,disablePlaceholder:d=!1,placeholderColor:t=5227511,placeholderOpacity:s=.4,errorColor:p=16729156,errorOpacity:m=.5}=e;if(i&&this.cache.has(l)){let n=this.cache.get(l).clone(!0);return this.normalizeBottomCenterData(n)?n.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(n),this.loadedAsset=n,this.dispatchEvent({type:"loaded",asset:n}),n}this.errorColor=p,this.errorOpacity=m,a&&!d&&(this.placeholder=this.createPlaceholder(a,t,s),this.dispatchEvent({type:"placeholderCreated",placeholder:this.placeholder}));try{if(c){let h=await this.loadModel(r,c,!0);this.lowResAsset=h,this.dispatchEvent({type:"lowResLoaded",lowRes:h})}let n=await this.loadModel(r,l,!1);if(this.loadedAsset=n,i){let h=n.clone(!0);this.normalizeBottomCenterData(h)?h.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(h),this.cache.set(l,h)}return this.dispatchEvent({type:"loaded",asset:n}),n}catch(n){throw this.setPlaceholderError(),this.dispatchEvent({type:"error",error:n}),n}}loadModel(e,r,l){return new Promise((a,c)=>{let i=t=>{let s=-1;t.lengthComputable&&t.total>0&&t.loaded<=t.total&&(s=t.loaded/t.total*100),this.dispatchEvent({type:"progress",loaded:t.loaded,total:t.total,percentage:s}),!l&&s>=0&&this.updatePlaceholder(s/100)},d=t=>{c(t)};switch(e){case"gltf":this.gltfLoader.load(r,t=>{let s=t.scene;this.positionAssetAtBottomCenter(s),a(s)},i,d);break;case"fbx":this.fbxLoader.load(r,t=>{this.positionAssetAtBottomCenter(t),a(t)},i,d);break;case"obj":this.objLoader.load(r,t=>{this.positionAssetAtBottomCenter(t),a(t)},i,d);break;case"usd":case"usdz":this.usdLoader.load(r,t=>{this.positionAssetAtBottomCenter(t),a(t)},i,d);break;case"dae":this.colladaLoader.load(r,t=>{let s=t.scene;this.positionAssetAtBottomCenter(s),a(s)},i,d);break;case"stl":this.stlLoader.load(r,t=>{let s=new o.MeshStandardMaterial({color:8947848}),p=new o.Mesh(t,s);this.positionAssetAtBottomCenter(p),a(p)},i,d);break;case"ply":this.plyLoader.load(r,t=>{let s=new o.MeshStandardMaterial({vertexColors:!0}),p=new o.Mesh(t,s);this.positionAssetAtBottomCenter(p),a(p)},i,d);break;case"3mf":this.threeMFLoader.load(r,t=>{this.positionAssetAtBottomCenter(t),a(t)},i,d);break;default:c(new Error(`Unsupported asset type: ${e}`))}})}getPlaceholder(){return this.placeholder}getAsset(){return this.loadedAsset}getLowResAsset(){return this.lowResAsset}clearCache(){this.cache.clear()}removeFromCache(e){this.cache.delete(e)}getCacheSize(){return this.cache.size}};export{f as a};
@@ -0,0 +1 @@
1
+ import*as o from"three";var z=1440*60*1e3,h=Math.PI/180,Y=180/Math.PI,W=2440588,A=2451545,p=(i,n,e)=>Math.min(Math.max(i,n),e),y=i=>((i+180)%360+360)%360-180,I=i=>i%4===0&&i%100!==0||i%400===0,C=(i,n)=>{let e=I(n)?366:365;return p(Math.floor(i),1,e)},w=i=>{let n=i%24;return n<0?n+24:n},P=new o.Color(16747612),F=new o.Color(16757898),G=new o.Color(16750950),U=new o.Color(3549732),H=new o.Color(12109270),Z=i=>i.valueOf()/z-.5+W,S=i=>Z(i)-A,D=i=>h*(357.5291+.98560028*i),v=i=>{let n=h*(1.9148*Math.sin(i)+.02*Math.sin(2*i)+3e-4*Math.sin(3*i)),e=h*102.9372;return i+n+e+Math.PI},_=i=>{let n=h*23.4397;return Math.asin(Math.sin(n)*Math.sin(i))},k=i=>{let n=h*23.4397;return Math.atan2(Math.sin(i)*Math.cos(n),Math.cos(i))},O=(i,n)=>h*(280.16+360.9856235*i)-n,B=(i,n,e)=>Math.atan2(Math.sin(i),Math.cos(i)*Math.sin(n)-Math.tan(e)*Math.cos(n)),N=(i,n,e)=>Math.asin(Math.sin(n)*Math.sin(e)+Math.cos(n)*Math.cos(e)*Math.cos(i)),j=i=>{let n=Date.UTC(i.getUTCFullYear(),0,0),e=i.getTime()-n;return Math.floor(e/(1440*60*1e3))},J=i=>h*(134.963+13.064993*i),q=i=>h*(218.316+13.176396*i),K=i=>h*(125.044-.052954*i),V=(i,n,e,t)=>{let s=h*1.274*Math.sin(2*i-2*e-n),r=h*.658*Math.sin(2*i-2*e),a=h*.186*Math.sin(e);return i+s+r+a},Q=(i,n)=>h*5.128*Math.sin(i-n),X=(i,n,e)=>Math.atan2(Math.sin(i),Math.cos(i)*Math.sin(n)-Math.tan(e)*Math.cos(n)),$=(i,n,e)=>Math.asin(Math.sin(n)*Math.sin(e)+Math.cos(n)*Math.cos(e)*Math.cos(i)),ee=(i,n)=>{let e=i-n;return Math.atan2(Math.sin(e),Math.cos(e))},te=i=>(1+Math.cos(i))/2,ie=(i,n)=>{let e=p(Math.sin(n)+.1,0,1);switch(i){case"sunny":return{sunIntensity:2.5*e,sunColor:new o.Color(16773839),ambientIntensity:.25+.45*e,ambientColor:new o.Color(16115663),hemisphereIntensity:.4+.4*e,hemisphereSkyColor:new o.Color(12114175),hemisphereGroundColor:new o.Color(16044458),shadowBias:-1e-4};case"partly-cloudy":return{sunIntensity:1.1*e,sunColor:new o.Color(16774885),ambientIntensity:.45+.35*e,ambientColor:new o.Color(15265009),hemisphereIntensity:.5+.3*e,hemisphereSkyColor:new o.Color(13162475),hemisphereGroundColor:new o.Color(15129026),shadowBias:-1e-4};case"overcast":return{sunIntensity:.35*e,sunColor:new o.Color(15791359),ambientIntensity:.75,ambientColor:new o.Color(14278117),hemisphereIntensity:.8,hemisphereSkyColor:new o.Color(13489631),hemisphereGroundColor:new o.Color(13158600),shadowBias:-1e-4};default:return{sunIntensity:1*e,sunColor:new o.Color(16767411),ambientIntensity:.35+.25*e,ambientColor:new o.Color(16769988),hemisphereIntensity:.4+.3*e,hemisphereSkyColor:new o.Color(16763043),hemisphereGroundColor:new o.Color(6243898),shadowBias:-2e-4}}},R=class extends o.EventDispatcher{constructor(e,t={}){super();this.createdLight=!1;this.createdHemisphere=!1;this.createdMoonLight=!1;this.scene=e;let s=t.latitude??51.5072,r=t.longitude??-.1276;this.latitude=p(s,-90,90),this.longitude=y(r),this.referenceYear=t.referenceYear??new Date().getUTCFullYear(),this.dayOfYear=C(t.dayOfYear??172,this.referenceYear),this.timeOfDay=w(t.timeOfDay??12),this.timeZoneOffsetMinutes=t.timeZoneOffsetMinutes??0,this.weather=t.weather??"sunny",this.useSystemTime=t.useSystemTime??!1,this.lightDistance=t.lightDistance??150,this.shadowCameraSize=t.shadowCameraSize??100,this.shadowCameraFar=t.shadowCameraFar??600,this.enableMoonLight=t.enableMoonLight??!0,this.minMoonIllumination=t.minMoonIllumination??.1;let a=t.light;this.light=a??new o.DirectionalLight(16777215,1),this.createdLight=!a,this.light.parent||this.scene.add(this.light),this.light.target.parent||this.scene.add(this.light.target),this.configureShadowMap(this.light),t.ambientLight&&(this.ambientLight=t.ambientLight),(t.enableHemisphereLight??!0)&&(this.hemisphereLight=new o.HemisphereLight(t.hemisphereSkyColor??12244223,t.hemisphereGroundColor??7628634,t.hemisphereIntensity??.45),this.scene.add(this.hemisphereLight),this.createdHemisphere=!0),this.enableMoonLight&&(this.moonLight=new o.DirectionalLight(H,0),this.scene.add(this.moonLight),this.moonLight.target.position.set(0,0,0),this.scene.add(this.moonLight.target),this.configureShadowMap(this.moonLight),this.createdMoonLight=!0,t.showMoonHelper&&(this.moonHelper=new o.DirectionalLightHelper(this.moonLight,t.moonHelperSize??20,t.moonHelperColor??12109270),this.scene.add(this.moonHelper))),t.showHelper&&(this.helper=new o.DirectionalLightHelper(this.light,t.helperSize??25,t.helperColor??16765567),this.scene.add(this.helper)),this.state={date:new Date,latitude:this.latitude,longitude:this.longitude,solarAzimuth:0,solarAltitude:0,weather:this.weather,useSystemTime:this.useSystemTime},this.update()}getLight(){return this.light}getHemisphereLight(){return this.hemisphereLight}getMoonLight(){return this.moonLight}getMoonPhase(){return this.state.moonPhase}getMoonIllumination(){return this.state.moonIllumination}getState(){return{...this.state,date:new Date(this.state.date.getTime())}}getDayOfYear(){return this.dayOfYear}getTimeOfDay(){return this.timeOfDay}getTimeZoneOffset(){return this.timeZoneOffsetMinutes}getWeather(){return this.weather}usesSystemTime(){return this.useSystemTime}setLatitude(e){let t=p(e,-90,90);t!==this.latitude&&(this.latitude=t,this.update())}setLongitude(e){let t=y(e);t!==this.longitude&&(this.longitude=t,this.update())}setLocation(e,t){let s=!1,r=p(e,-90,90);r!==this.latitude&&(this.latitude=r,s=!0);let a=y(t);a!==this.longitude&&(this.longitude=a,s=!0),s&&this.update()}setDayOfYear(e){let t=C(e,this.referenceYear);t!==this.dayOfYear&&(this.dayOfYear=t,this.update())}setTimeOfDay(e){let t=w(e);t!==this.timeOfDay&&(this.timeOfDay=t,this.update())}setTimeZoneOffset(e){e!==this.timeZoneOffsetMinutes&&(this.timeZoneOffsetMinutes=e,this.update())}setWeather(e){e!==this.weather&&(this.weather=e,this.dispatchEvent({type:"weatherChanged",weather:e}),this.update())}setUseSystemTime(e){e!==this.useSystemTime&&(this.useSystemTime=e,this.dispatchEvent({type:"systemTimeToggled",useSystemTime:this.useSystemTime}),this.update())}update(e){let t=this.computeDate(e),s=this.computeSunPosition(t);this.applySunPosition(s,t);let r;this.enableMoonLight&&this.moonLight&&(r=this.computeMoonPosition(t),this.applyMoonPosition(r)),this.state={date:t,latitude:this.latitude,longitude:this.longitude,solarAzimuth:s.azimuth,solarAltitude:s.altitude,weather:this.weather,useSystemTime:this.useSystemTime,lunarAzimuth:r?.azimuth,lunarAltitude:r?.altitude,moonPhase:r?.phase,moonIllumination:r?.illumination},this.applyWeather(s.altitude),this.dispatchEvent({type:"stateChanged",state:this.getState()})}dispose(){this.helper&&(this.scene.remove(this.helper),this.helper.dispose(),this.helper=void 0),this.moonHelper&&(this.scene.remove(this.moonHelper),this.moonHelper.dispose(),this.moonHelper=void 0),this.createdHemisphere&&this.hemisphereLight&&(this.scene.remove(this.hemisphereLight),this.hemisphereLight.dispose(),this.hemisphereLight=void 0),this.createdMoonLight&&this.moonLight&&(this.scene.remove(this.moonLight),this.moonLight.shadow?.map&&this.moonLight.shadow.map.dispose(),this.moonLight.dispose(),this.moonLight=void 0),this.createdLight&&this.light&&(this.scene.remove(this.light),this.light.shadow?.map&&this.light.shadow.map.dispose(),this.light.dispose())}configureShadowMap(e){e.castShadow=!0;let t=e.shadow.camera;if(t instanceof o.OrthographicCamera&&typeof this.shadowCameraSize=="number"){let s=this.shadowCameraSize;t.left=-s,t.right=s,t.top=s,t.bottom=-s,t.near=.5,t.far=this.shadowCameraFar,t.updateProjectionMatrix()}e.shadow.mapSize.set(2048,2048),e.shadow.bias=-5e-4}computeDate(e){if(e)return new Date(e.getTime());if(this.useSystemTime){let u=new Date;return this.referenceYear=u.getUTCFullYear(),this.dayOfYear=j(u),this.timeOfDay=u.getUTCHours()+u.getUTCMinutes()/60+u.getUTCSeconds()/3600,u}let t=I(this.referenceYear)?366:365,s=p(this.dayOfYear,1,t),r=new Date(Date.UTC(this.referenceYear,0,1,0,0,0,0)),a=(s-1)*24*60+this.timeOfDay*60-this.timeZoneOffsetMinutes;return r.setUTCMinutes(a),r}computeSunPosition(e){let t=S(e),s=-this.longitude*h,r=this.latitude*h,a=D(t),u=v(a),m=_(u),l=k(u),c=O(t,s)-l;return{azimuth:B(c,r,m),altitude:N(c,r,m)}}applySunPosition(e,t){let s=this.lightDistance,r=e.altitude,a=e.azimuth,u=-s*Math.cos(r)*Math.sin(a),m=s*Math.sin(r),l=s*Math.cos(r)*Math.cos(a);this.light.position.set(u,m,l),this.light.target.position.set(0,0,0),this.light.target.updateMatrixWorld(),this.helper&&this.helper.update(),this.useSystemTime||(this.referenceYear=t.getUTCFullYear())}applyWeather(e){let t=ie(this.weather,e),s=e*Y,r=-6,u=4-r,m=p((s-r)/u,0,1),l=1-m,d=t.sunColor.lerp(P,l),c=t.ambientColor.lerp(F,l),g=t.hemisphereSkyColor.lerp(G,l),b=t.hemisphereGroundColor.lerp(U,l),f=t.sunIntensity*m,M=Math.max(.05,t.ambientIntensity*(.3+.7*m)),L=Math.max(.05,t.hemisphereIntensity*(.35+.65*m));this.light.intensity=f,this.light.visible=e>0&&f>.001,this.light.color.copy(d),this.light.shadow.bias=t.shadowBias,this.ambientLight&&(this.ambientLight.intensity=M,this.ambientLight.color.copy(c)),this.hemisphereLight&&(this.hemisphereLight.intensity=L,this.hemisphereLight.color.copy(g),this.hemisphereLight.groundColor.copy(b))}computeMoonPosition(e){let t=S(e),s=-this.longitude*h,r=this.latitude*h,a=D(t),u=v(a),m=J(t),l=q(t),d=K(t),c=V(l,m,a,d),g=Q(c,d),b=h*23.4397,f=Math.asin(Math.sin(g)*Math.cos(b)+Math.cos(g)*Math.sin(b)*Math.sin(c)),M=Math.atan2(Math.sin(c)*Math.cos(b)-Math.tan(g)*Math.sin(b),Math.cos(c)),E=O(t,s)-M,T=ee(c,u),x=te(T);return{azimuth:X(E,r,f),altitude:$(E,r,f),phase:T,illumination:x}}applyMoonPosition(e){if(!this.moonLight)return;let t=this.lightDistance,s=e.altitude,r=e.azimuth,a=-t*Math.cos(s)*Math.sin(r),u=t*Math.sin(s),m=t*Math.cos(s)*Math.cos(r);this.moonLight.position.set(a,u,m),this.moonLight.target.position.set(0,0,0),this.moonLight.target.updateMatrixWorld();let l=s>0&&e.illumination>=this.minMoonIllumination,d=.015,c=this.weather==="overcast"?.3:this.weather==="partly-cloudy"?.7:1,g=Math.max(0,Math.sin(s));this.moonLight.intensity=d*e.illumination*c*g,this.moonLight.visible=l,this.moonLight.color.copy(H),this.moonHelper&&(this.moonHelper.update(),this.moonHelper.visible=l)}};export{R as a};
@@ -0,0 +1 @@
1
+ import*as a from"three";import{CSS2DObject as m}from"three/examples/jsm/renderers/CSS2DRenderer";var u=(i=>(i.VERTEX="vertex",i.FACE="face",i.EDGE="edge",i.DISABLED="disabled",i))(u||{});var h=class extends a.EventDispatcher{constructor(e,t,i={}){super();this.measurements=[];this.raycaster=new a.Raycaster;this.isInteractive=!1;this.domElement=null;this.controls=null;this.defaultTargets=[];this.activeTargets=[];this.currentMeasurement=null;this.activeInteractionOptions=null;this.pendingMeasurementOptions=null;this.previewLine=null;this.previewLabel=null;this.snapMarker=null;this.originalCursor="";this.cursorHidden=!1;this.defaultOptions={lineColor:16711680,labelColor:"#ffffff",lineWidth:2,fontSize:16,fontFamily:"Arial, sans-serif",snapMode:"vertex",snapEnabled:!0,snapDistance:.05,targets:[],isDynamic:!1};this.previewColor=65535;this.markerColor=65280;this.markerSize=.08;this.markerVisible=!0;this.isEditMode=!1;this.editingMeasurement=null;this.editingPoint=null;this.startEditSprite=null;this.endEditSprite=null;this.editSpriteMaterial=null;this.isDragging=!1;this.onMouseClick=e=>{if(!this.isInteractive)return;let t=this.getSnapResult(e);t&&(this.currentMeasurement?this.completeMeasurement(t):this.startMeasurement(t))};this.onMouseMove=e=>{if(!this.isInteractive)return;let t=this.getSnapResult(e);if(!t){this.hideSnapMarker(),this.showCursor();return}this.currentMeasurement?(this.updateSnapMarker(t.point,!0),this.hideCursor(),this.updatePreview(t.point)):(this.updateSnapMarker(t.point,!0),this.hideCursor())};this.onKeyDown=e=>{this.isInteractive&&e.key==="Escape"&&this.cancelCurrentMeasurement()};this.onEditMouseDown=e=>{if(!this.isEditMode||!this.domElement)return;let t=new a.Vector2,i=this.domElement.getBoundingClientRect();t.x=(e.clientX-i.left)/i.width*2-1,t.y=-((e.clientY-i.top)/i.height)*2+1,this.raycaster.setFromCamera(t,this.camera);let n=[this.startEditSprite,this.endEditSprite].filter(r=>r!==null),s=this.raycaster.intersectObjects(n);if(s.length>0){let r=s[0].object;this.editingPoint=r.userData.editPoint,this.isDragging=!0,this.disableControls(),this.editingPoint==="start"&&this.startEditSprite?this.startEditSprite.visible=!1:this.editingPoint==="end"&&this.endEditSprite&&(this.endEditSprite.visible=!1),this.createSnapMarker(),this.snapMarker&&(this.snapMarker.position.copy(r.position),this.snapMarker.visible=!0),this.hideCursor()}};this.onEditMouseMove=e=>{if(!this.isEditMode||!this.isDragging||!this.editingMeasurement)return;let t=this.getSnapResult(e);t&&(this.snapMarker&&(this.snapMarker.position.copy(t.point),this.snapMarker.visible=this.markerVisible),this.editingPoint==="start"?this.updateMeasurementPreview(t.point,this.editingMeasurement.end.position):this.editingPoint==="end"&&this.updateMeasurementPreview(this.editingMeasurement.start.position,t.point))};this.onEditMouseUp=e=>{if(!this.isEditMode||!this.isDragging||!this.editingMeasurement||!this.editingPoint)return;let t=this.getSnapResult(e);if(!t){this.cancelEdit();return}let i=this.editingPoint==="start"?this.editingMeasurement.start:this.editingMeasurement.end;if(i.position.copy(t.point),this.editingMeasurement.options.isDynamic&&t.object){let l=t.object.worldToLocal(t.point.clone());i.anchor={object:t.object,localPosition:l}}else i.anchor=void 0;let s=this.editingMeasurement.start.position.distanceTo(this.editingMeasurement.end.position);this.editingMeasurement.distance=s;let r=[this.editingMeasurement.start.position,this.editingMeasurement.end.position];this.editingMeasurement.line.geometry.setFromPoints(r),this.editingMeasurement.line.geometry.attributes.position.needsUpdate=!0;let o=this.editingMeasurement.start.position.clone().add(this.editingMeasurement.end.position).multiplyScalar(.5);this.editingMeasurement.label.position.copy(o),this.updateLabelText(this.editingMeasurement.label.element,s),this.startEditSprite&&(this.startEditSprite.position.copy(this.editingMeasurement.start.position),this.startEditSprite.visible=!0),this.endEditSprite&&(this.endEditSprite.position.copy(this.editingMeasurement.end.position),this.endEditSprite.visible=!0),this.removeSnapMarker(),this.showCursor(),this.enableControls(),this.dispatchEvent({type:"measurementUpdated",measurement:this.editingMeasurement}),this.isDragging=!1,this.editingPoint=null};this.scene=e,this.camera=t;let{domElement:n,controls:s}=i;n&&(this.domElement=n),s&&(this.controls=s),this.previewMaterial=new a.LineDashedMaterial({color:this.previewColor,linewidth:this.defaultOptions.lineWidth,dashSize:.1,gapSize:.05}),this.markerMaterial=new a.SpriteMaterial({map:this.createCrosshairTexture(),color:this.markerColor,transparent:!0,opacity:.8,sizeAttenuation:!1,depthTest:!1}),this.editSpriteMaterial=new a.SpriteMaterial({map:this.createDotTexture(),color:16755200,transparent:!0,opacity:.9,sizeAttenuation:!1,depthTest:!1}),this.raycaster.params.Line.threshold=.01,this.raycaster.params.Points.threshold=.01}createCrosshairTexture(){let t=document.createElement("canvas");t.width=64,t.height=64;let i=t.getContext("2d"),n=64/2,s=64/2,r=20,o=6;i.clearRect(0,0,64,64),i.strokeStyle="#ffffff",i.lineWidth=3,i.lineCap="round",i.beginPath(),i.moveTo(n-r,s),i.lineTo(n-o,s),i.moveTo(n+o,s),i.lineTo(n+r,s),i.moveTo(n,s-r),i.lineTo(n,s-o),i.moveTo(n,s+o),i.lineTo(n,s+r),i.stroke(),i.strokeStyle="#000000",i.lineWidth=5,i.globalCompositeOperation="destination-over",i.beginPath(),i.moveTo(n-r,s),i.lineTo(n-o,s),i.moveTo(n+o,s),i.lineTo(n+r,s),i.moveTo(n,s-r),i.lineTo(n,s-o),i.moveTo(n,s+o),i.lineTo(n,s+r),i.stroke();let l=new a.CanvasTexture(t);return l.needsUpdate=!0,l}createDotTexture(){let t=document.createElement("canvas");t.width=64,t.height=64;let i=t.getContext("2d"),n=64/2,s=64/2,r=12;i.clearRect(0,0,64,64),i.fillStyle="#ffffff",i.beginPath(),i.arc(n,s,r,0,Math.PI*2),i.fill(),i.strokeStyle="#000000",i.lineWidth=3,i.beginPath(),i.arc(n,s,r,0,Math.PI*2),i.stroke();let o=new a.CanvasTexture(t);return o.needsUpdate=!0,o}createMeasurementPoint(e,t,i){if(!t)return{position:e.clone()};let n=i?.clone()??t.worldToLocal(e.clone());return{position:t.localToWorld(n.clone()),anchor:{object:t,localPosition:n}}}updateMeasurementPoint(e){if(!e.anchor)return!1;let t=e.anchor.localPosition.clone();return e.anchor.object.localToWorld(t),e.position.equals(t)?!1:(e.position.copy(t),!0)}addMeasurement(e,t,i={}){let n=!!(i.startObject||i.endObject),s=this.resolveMeasurementOptions(i,i.isDynamic??n),r=this.createMeasurementPoint(e,i.startObject,i.startLocalPosition),o=this.createMeasurementPoint(t,i.endObject,i.endLocalPosition);return this.addMeasurementFromPoints(r,o,s,{id:i.id})}resolveMeasurementOptions(e={},t){let i;e.targets&&e.targets.length>0?i=e.targets:this.defaultOptions.targets.length>0?i=this.defaultOptions.targets:this.defaultTargets.length>0&&(i=this.defaultTargets);let n=i&&i.length>0?i:this.getAllMeshes(),s=e.isDynamic??t??this.defaultOptions.isDynamic;return{lineColor:e.lineColor??this.defaultOptions.lineColor,labelColor:e.labelColor??this.defaultOptions.labelColor,lineWidth:e.lineWidth??this.defaultOptions.lineWidth,fontSize:e.fontSize??this.defaultOptions.fontSize,fontFamily:e.fontFamily??this.defaultOptions.fontFamily,snapMode:e.snapMode??this.defaultOptions.snapMode,snapEnabled:e.snapEnabled??this.defaultOptions.snapEnabled,snapDistance:e.snapDistance??this.defaultOptions.snapDistance,targets:n,isDynamic:s}}getActiveMeasurementOptions(){return this.isEditMode&&this.editingMeasurement?this.editingMeasurement.options:this.activeInteractionOptions}addDynamicMeasurement(e,t,i=new a.Vector3,n=new a.Vector3){let s=e.localToWorld(i.clone()),r=t.localToWorld(n.clone());return this.addMeasurement(s,r,{startObject:e,endObject:t,startLocalPosition:i,endLocalPosition:n})}addMeasurementToObject(e,t,i=new a.Vector3){let n=t.localToWorld(i.clone());return this.addMeasurement(e,n,{endObject:t,endLocalPosition:i})}addMeasurementFromPoints(e,t,i,n){let s=n?.id||this.generateId(),r=e.position.distanceTo(t.position),o=new a.BufferGeometry().setFromPoints([e.position,t.position]),l=new a.Line(o,new a.LineBasicMaterial({color:i.lineColor,linewidth:i.lineWidth})),c=this.createLabel(r,i),p=e.position.clone().add(t.position).multiplyScalar(.5);c.position.copy(p);let d={id:s,start:e,end:t,line:l,label:c,distance:r,options:{...i,targets:[...i.targets]}};return this.scene.add(l),this.scene.add(c),this.measurements.push(d),this.dispatchEvent({type:"measurementCreated",measurement:d}),d}updateDynamicMeasurements(){let e=!1;for(let t of this.measurements){if(!t.options.isDynamic)continue;let i=!1;if(this.updateMeasurementPoint(t.start)&&(i=!0),this.updateMeasurementPoint(t.end)&&(i=!0),i){let n=t.start.position.distanceTo(t.end.position);t.distance=n;let s=[t.start.position,t.end.position];t.line.geometry.setFromPoints(s),t.line.geometry.attributes.position.needsUpdate=!0;let r=t.start.position.clone().add(t.end.position).multiplyScalar(.5);t.label.position.copy(r),this.updateLabelText(t.label.element,n),e=!0}}return e}setDynamicMode(e){this.setDefaultMeasurementOptions({isDynamic:e})}getDynamicMode(){return this.defaultOptions.isDynamic}enterEditMode(e,t){this.exitEditMode();let i;if(typeof e=="string"?i=this.measurements.find(s=>s.id===e):i=this.measurements[e],!i){console.warn("Measurement not found:",e);return}if(!this.domElement){console.warn("DOM element not set. Call setDomElement() or enableInteraction() first.");return}this.isEditMode=!0,this.editingMeasurement=i;let n=t&&t.length>0?t:i.options.targets.length>0?i.options.targets:this.getAllMeshes();this.activeTargets=n,t&&t.length>0&&(i.options.targets=[...t]),this.createEditSprites(),this.domElement.addEventListener("mousedown",this.onEditMouseDown),this.domElement.addEventListener("mousemove",this.onEditMouseMove),this.domElement.addEventListener("mouseup",this.onEditMouseUp),this.domElement.style.cursor="pointer",this.dispatchEvent({type:"editModeEntered",measurement:i})}exitEditMode(){if(!this.isEditMode)return;let e=this.editingMeasurement;this.removeEditSprites(),this.domElement&&(this.domElement.removeEventListener("mousedown",this.onEditMouseDown),this.domElement.removeEventListener("mousemove",this.onEditMouseMove),this.domElement.removeEventListener("mouseup",this.onEditMouseUp),this.domElement.style.cursor=this.isInteractive?"crosshair":"default"),this.isEditMode=!1,this.editingMeasurement=null,this.editingPoint=null,this.isDragging=!1,this.activeTargets=[],e&&this.dispatchEvent({type:"editModeExited",measurement:e})}setDomElement(e){this.domElement=e}setControls(e){this.controls=e}setTargetObjects(e){this.defaultTargets=e.length>0?e:this.getAllMeshes(),this.defaultOptions.targets=[...this.defaultTargets]}setDefaultMeasurementOptions(e){e.lineColor!==void 0&&(this.defaultOptions.lineColor=e.lineColor),e.labelColor!==void 0&&(this.defaultOptions.labelColor=e.labelColor),e.lineWidth!==void 0&&(this.defaultOptions.lineWidth=e.lineWidth),e.fontSize!==void 0&&(this.defaultOptions.fontSize=e.fontSize),e.fontFamily!==void 0&&(this.defaultOptions.fontFamily=e.fontFamily),e.snapMode!==void 0&&(this.defaultOptions.snapMode=e.snapMode),e.snapEnabled!==void 0&&(this.defaultOptions.snapEnabled=e.snapEnabled),e.snapDistance!==void 0&&(this.defaultOptions.snapDistance=e.snapDistance),e.targets!==void 0&&(this.defaultTargets=e.targets,this.defaultOptions.targets=[...e.targets],this.activeInteractionOptions&&(this.activeInteractionOptions.targets=[...e.targets],this.activeTargets=e.targets)),e.isDynamic!==void 0&&(this.defaultOptions.isDynamic=e.isDynamic,this.activeInteractionOptions&&(this.activeInteractionOptions.isDynamic=e.isDynamic)),this.activeInteractionOptions&&(e.lineColor!==void 0&&(this.activeInteractionOptions.lineColor=e.lineColor),e.labelColor!==void 0&&(this.activeInteractionOptions.labelColor=e.labelColor),e.lineWidth!==void 0&&(this.activeInteractionOptions.lineWidth=e.lineWidth),e.fontSize!==void 0&&(this.activeInteractionOptions.fontSize=e.fontSize),e.fontFamily!==void 0&&(this.activeInteractionOptions.fontFamily=e.fontFamily),e.snapMode!==void 0&&(this.activeInteractionOptions.snapMode=e.snapMode),e.snapEnabled!==void 0&&(this.activeInteractionOptions.snapEnabled=e.snapEnabled),e.snapDistance!==void 0&&(this.activeInteractionOptions.snapDistance=e.snapDistance))}disableControls(){this.controls&&(this.controls.enabled=!1)}enableControls(){this.controls&&(this.controls.enabled=!0)}enableInteraction(e={}){this.isInteractive&&this.disableInteraction();let t=this.resolveMeasurementOptions(e);this.activeInteractionOptions={...t,targets:[...t.targets]},this.activeTargets=this.activeInteractionOptions.targets.length>0?this.activeInteractionOptions.targets:this.getAllMeshes(),this.isInteractive=!0,this.domElement&&(this.domElement.addEventListener("click",this.onMouseClick),this.domElement.addEventListener("mousemove",this.onMouseMove),this.domElement.addEventListener("keydown",this.onKeyDown),this.domElement.style.cursor="crosshair"),this.createSnapMarker(),this.dispatchEvent({type:"started"})}disableInteraction(){!this.isInteractive||!this.domElement||(this.exitEditMode(),this.domElement.removeEventListener("click",this.onMouseClick),this.domElement.removeEventListener("mousemove",this.onMouseMove),this.domElement.removeEventListener("keydown",this.onKeyDown),this.showCursor(),this.domElement.style.cursor="default",this.cancelCurrentMeasurement(),this.removeSnapMarker(),this.isInteractive=!1,this.activeInteractionOptions=null,this.activeTargets=[],this.dispatchEvent({type:"ended"}))}undoLast(){if(this.measurements.length===0)return;let e=this.measurements.pop();this.removeMeasurementFromScene(e),this.dispatchEvent({type:"measurementRemoved",measurement:e})}removeMeasurement(e){let t=this.measurements.indexOf(e);t!==-1&&(this.measurements.splice(t,1),this.removeMeasurementFromScene(e),this.dispatchEvent({type:"measurementRemoved",measurement:e}))}clearAll(){let e=this.measurements.length;this.measurements.forEach(t=>{this.removeMeasurementFromScene(t)}),this.measurements=[],this.dispatchEvent({type:"measurementsCleared",count:e})}getMeasurements(){return[...this.measurements]}serializeMeasurementPoint(e){return{position:e.position.toArray(),anchorObjectId:e.anchor?.object.uuid,anchorLocalPosition:e.anchor?e.anchor.localPosition.toArray():void 0}}serialize(){return this.measurements.map(e=>({id:e.id,start:this.serializeMeasurementPoint(e.start),end:this.serializeMeasurementPoint(e.end),distance:e.distance,options:{snapMode:e.options.snapMode,snapEnabled:e.options.snapEnabled,snapDistance:e.options.snapDistance,lineColor:e.options.lineColor,labelColor:e.options.labelColor,lineWidth:e.options.lineWidth,fontSize:e.options.fontSize,fontFamily:e.options.fontFamily,isDynamic:e.options.isDynamic,targetObjectIds:e.options.targets.map(t=>t.uuid)}}))}deserialize(e){this.clearAll(),e.forEach(t=>{let i=new a.Vector3().fromArray(t.start.position),n=new a.Vector3().fromArray(t.end.position),s=t.start.anchorObjectId?this.scene.getObjectByProperty("uuid",t.start.anchorObjectId):null,r=t.end.anchorObjectId?this.scene.getObjectByProperty("uuid",t.end.anchorObjectId):null,o=t.options.targetObjectIds&&t.options.targetObjectIds.length>0?t.options.targetObjectIds.map(l=>this.scene.getObjectByProperty("uuid",l)).filter(l=>l!==void 0):void 0;this.addMeasurement(i,n,{id:t.id,targets:o&&o.length>0?o:void 0,snapMode:t.options.snapMode,snapEnabled:t.options.snapEnabled,snapDistance:t.options.snapDistance,lineColor:t.options.lineColor,labelColor:t.options.labelColor,lineWidth:t.options.lineWidth,fontSize:t.options.fontSize,fontFamily:t.options.fontFamily,isDynamic:t.options.isDynamic,startObject:s||void 0,startLocalPosition:t.start.anchorLocalPosition?new a.Vector3().fromArray(t.start.anchorLocalPosition):void 0,endObject:r||void 0,endLocalPosition:t.end.anchorLocalPosition?new a.Vector3().fromArray(t.end.anchorLocalPosition):void 0})})}dispose(){this.exitEditMode(),this.disableInteraction(),this.clearAll(),this.previewMaterial.dispose(),this.markerMaterial.map&&this.markerMaterial.map.dispose(),this.markerMaterial.dispose(),this.editSpriteMaterial&&(this.editSpriteMaterial.map&&this.editSpriteMaterial.map.dispose(),this.editSpriteMaterial.dispose())}hideCursor(){!this.domElement||this.cursorHidden||(this.originalCursor=this.domElement.style.cursor,this.domElement.style.cursor="none",this.cursorHidden=!0)}showCursor(){!this.domElement||!this.cursorHidden||(this.domElement.style.cursor=this.originalCursor||"crosshair",this.cursorHidden=!1)}createSnapMarker(){this.markerVisible&&(this.snapMarker&&this.scene.remove(this.snapMarker),this.snapMarker=new a.Sprite(this.markerMaterial),this.snapMarker.scale.setScalar(this.markerSize),this.snapMarker.visible=!1,this.snapMarker.renderOrder=999,this.snapMarker.material.depthTest=!1,this.scene.add(this.snapMarker))}updateSnapMarker(e,t=!0){!this.snapMarker||!this.markerVisible||(this.snapMarker.position.copy(e),this.snapMarker.visible=t)}hideSnapMarker(){this.snapMarker&&(this.snapMarker.visible=!1)}removeSnapMarker(){this.snapMarker&&(this.scene.remove(this.snapMarker),this.snapMarker=null)}startMeasurement(e){let t=this.generateId(),i=e.point,n=this.activeInteractionOptions??this.defaultOptions,s={...n,targets:[...n.targets]};this.pendingMeasurementOptions=s,this.hideSnapMarker();let r=new a.BufferGeometry().setFromPoints([i,i]);this.previewLine=new a.Line(r,this.previewMaterial),this.previewLine.computeLineDistances(),this.scene.add(this.previewLine),this.previewLabel=this.createLabel(0,s),this.previewLabel.position.copy(i),this.scene.add(this.previewLabel);let o=s.isDynamic&&e.object?this.createMeasurementPoint(i,e.object):this.createMeasurementPoint(i);this.currentMeasurement={id:t,start:o}}updatePreview(e){if(!this.currentMeasurement||!this.previewLine||!this.previewLabel)return;let t=this.currentMeasurement.start,i=t.position.distanceTo(e),n=new a.BufferGeometry().setFromPoints([t.position,e]);this.previewLine.geometry.dispose(),this.previewLine.geometry=n,this.previewLine.computeLineDistances();let s=t.position.clone().add(e).multiplyScalar(.5);this.previewLabel.position.copy(s),this.updateLabelText(this.previewLabel.element,i),this.dispatchEvent({type:"previewUpdated",start:t.position,current:e,distance:i})}completeMeasurement(e){if(!this.currentMeasurement)return;let t=this.currentMeasurement.start,i=e.point,n=this.pendingMeasurementOptions??this.activeInteractionOptions??this.defaultOptions;this.disableInteraction(),this.cleanupPreview();let s={...n,targets:[...n.targets]},r=s.isDynamic&&e.object?this.createMeasurementPoint(i,e.object):this.createMeasurementPoint(i);this.addMeasurementFromPoints(t,r,s),this.currentMeasurement=null,this.pendingMeasurementOptions=null,this.createSnapMarker()}cancelCurrentMeasurement(){this.cleanupPreview(),this.currentMeasurement=null,this.pendingMeasurementOptions=null,this.createSnapMarker()}cleanupPreview(){this.previewLine&&(this.scene.remove(this.previewLine),this.previewLine.geometry.dispose(),this.previewLine=null),this.previewLabel&&(this.scene.remove(this.previewLabel),this.previewLabel.element.parentNode&&this.previewLabel.element.parentNode.removeChild(this.previewLabel.element),this.previewLabel=null)}getSnapResult(e){let t=new a.Vector2,i=this.domElement.getBoundingClientRect();t.x=(e.clientX-i.left)/i.width*2-1,t.y=-((e.clientY-i.top)/i.height)*2+1;let n=this.getActiveMeasurementOptions()??this.defaultOptions,s=this.activeTargets.length>0?this.activeTargets:n.targets.length>0?n.targets:this.getAllMeshes();this.raycaster.setFromCamera(t,this.camera);let r=this.raycaster.intersectObjects(s,!0);if(r.length===0)return null;let o=r[0],l=o.point.clone(),c=!1,p="disabled";if(n.snapEnabled){let d=this.performSnapping(o,n);l=d.point,c=d.snapped,p=d.snapMode}return{point:l,originalPoint:o.point,snapped:c,snapMode:p,object:o.object}}performSnapping(e,t){let i=e.point,n=i.clone(),s=!1,r="disabled";if(t.snapMode==="vertex"){let o=this.snapToVertex(e,t.snapDistance);o&&(n=o,s=!0,r="vertex")}else t.snapMode==="face"&&(s=!0,r="face");return{point:n,originalPoint:i,snapped:s,snapMode:r,object:e.object}}snapToVertex(e,t){let i=e.object.geometry;if(!i.attributes.position)return null;let n=i.attributes.position,s=e.object.matrixWorld,r=new a.Vector3,o=1/0,l=!1;for(let c=0;c<n.count;c++){let p=new a.Vector3;p.fromBufferAttribute(n,c),p.applyMatrix4(s);let d=p.distanceTo(e.point);d<t&&d<o&&(o=d,r.copy(p),l=!0)}return l?r:null}createLabel(e,t){let i=document.createElement("div");i.className="measurement-label",Object.assign(i.style,{color:t.labelColor,fontSize:`${t.fontSize}px`,fontFamily:t.fontFamily,fontWeight:"bold",background:"rgba(0, 0, 0, 0.9)",padding:"8px 12px",borderRadius:"8px",border:"2px solid rgba(255, 255, 255, 0.3)",whiteSpace:"nowrap",userSelect:"none",pointerEvents:"auto",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.5)",textShadow:"1px 1px 2px rgba(0, 0, 0, 0.8)",zIndex:"1000",cursor:"pointer"}),this.updateLabelText(i,e);let n=new m(i);return i.addEventListener("dblclick",s=>{s.stopPropagation();let r=this.measurements.find(o=>o.label===n);r&&this.enterEditMode(r.id)}),n}updateLabelText(e,t){let i=`${t.toFixed(2)}m`;e.textContent=i}removeMeasurementFromScene(e){this.scene.remove(e.line),this.scene.remove(e.label),e.line.geometry.dispose(),e.line.material instanceof a.Material&&e.line.material.dispose(),e.label.element.parentNode&&e.label.element.parentNode.removeChild(e.label.element)}getAllMeshes(){let e=[];return this.scene.traverse(t=>{t instanceof a.Mesh&&e.push(t)}),e}generateId(){return`measurement_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}createEditSprites(){if(!this.editingMeasurement||!this.editSpriteMaterial)return;let e=this.editingMeasurement;this.startEditSprite=new a.Sprite(this.editSpriteMaterial.clone()),this.startEditSprite.position.copy(e.start.position),this.startEditSprite.scale.set(this.markerSize,this.markerSize,1),this.startEditSprite.userData.editPoint="start",this.scene.add(this.startEditSprite),this.endEditSprite=new a.Sprite(this.editSpriteMaterial.clone()),this.endEditSprite.position.copy(e.end.position),this.endEditSprite.scale.set(this.markerSize,this.markerSize,1),this.endEditSprite.userData.editPoint="end",this.scene.add(this.endEditSprite)}removeEditSprites(){this.startEditSprite&&(this.scene.remove(this.startEditSprite),this.startEditSprite.material instanceof a.Material&&this.startEditSprite.material.dispose(),this.startEditSprite=null),this.endEditSprite&&(this.scene.remove(this.endEditSprite),this.endEditSprite.material instanceof a.Material&&this.endEditSprite.material.dispose(),this.endEditSprite=null)}cancelEdit(){this.isDragging=!1,this.editingPoint=null,this.enableControls(),this.startEditSprite&&(this.startEditSprite.visible=!0),this.endEditSprite&&(this.endEditSprite.visible=!0),this.removeSnapMarker(),this.showCursor()}updateMeasurementPreview(e,t){if(!this.editingMeasurement)return;let i=e.distanceTo(t),n=[e,t];this.editingMeasurement.line.geometry.setFromPoints(n),this.editingMeasurement.line.geometry.attributes.position.needsUpdate=!0;let s=e.clone().add(t).multiplyScalar(.5);this.editingMeasurement.label.position.copy(s),this.updateLabelText(this.editingMeasurement.label.element,i)}};export{u as a,h as b};