@tonybfox/threejs-tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +321 -0
  2. package/dist/asset-loader/index.cjs +376 -0
  3. package/dist/asset-loader/index.cjs.map +1 -0
  4. package/dist/asset-loader/index.d.mts +101 -0
  5. package/dist/asset-loader/index.d.ts +101 -0
  6. package/dist/asset-loader/index.mjs +7 -0
  7. package/dist/asset-loader/index.mjs.map +1 -0
  8. package/dist/camera/index.cjs +313 -0
  9. package/dist/camera/index.cjs.map +1 -0
  10. package/dist/camera/index.d.mts +82 -0
  11. package/dist/camera/index.d.ts +82 -0
  12. package/dist/camera/index.mjs +7 -0
  13. package/dist/camera/index.mjs.map +1 -0
  14. package/dist/chunk-5DP6WDB3.mjs +1161 -0
  15. package/dist/chunk-5DP6WDB3.mjs.map +1 -0
  16. package/dist/chunk-BJKSICFA.mjs +1579 -0
  17. package/dist/chunk-BJKSICFA.mjs.map +1 -0
  18. package/dist/chunk-BYRZCHE7.mjs +277 -0
  19. package/dist/chunk-BYRZCHE7.mjs.map +1 -0
  20. package/dist/chunk-EIROAPF7.mjs +387 -0
  21. package/dist/chunk-EIROAPF7.mjs.map +1 -0
  22. package/dist/chunk-EQDOX34V.mjs +164 -0
  23. package/dist/chunk-EQDOX34V.mjs.map +1 -0
  24. package/dist/chunk-IIAZ2WJJ.mjs +405 -0
  25. package/dist/chunk-IIAZ2WJJ.mjs.map +1 -0
  26. package/dist/chunk-L4VIIJZD.mjs +340 -0
  27. package/dist/chunk-L4VIIJZD.mjs.map +1 -0
  28. package/dist/chunk-P35QJCOG.mjs +339 -0
  29. package/dist/chunk-P35QJCOG.mjs.map +1 -0
  30. package/dist/chunk-R64RVBRM.mjs +394 -0
  31. package/dist/chunk-R64RVBRM.mjs.map +1 -0
  32. package/dist/compass/index.cjs +375 -0
  33. package/dist/compass/index.cjs.map +1 -0
  34. package/dist/compass/index.d.mts +58 -0
  35. package/dist/compass/index.d.ts +58 -0
  36. package/dist/compass/index.mjs +7 -0
  37. package/dist/compass/index.mjs.map +1 -0
  38. package/dist/grid/index.cjs +200 -0
  39. package/dist/grid/index.cjs.map +1 -0
  40. package/dist/grid/index.d.mts +43 -0
  41. package/dist/grid/index.d.ts +43 -0
  42. package/dist/grid/index.mjs +7 -0
  43. package/dist/grid/index.mjs.map +1 -0
  44. package/dist/index.cjs +5049 -0
  45. package/dist/index.cjs.map +1 -0
  46. package/dist/index.d.mts +13 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.mjs +47 -0
  49. package/dist/index.mjs.map +1 -0
  50. package/dist/measurements/index.cjs +1198 -0
  51. package/dist/measurements/index.cjs.map +1 -0
  52. package/dist/measurements/index.d.mts +449 -0
  53. package/dist/measurements/index.d.ts +449 -0
  54. package/dist/measurements/index.mjs +9 -0
  55. package/dist/measurements/index.mjs.map +1 -0
  56. package/dist/sunlight/index.cjs +441 -0
  57. package/dist/sunlight/index.cjs.map +1 -0
  58. package/dist/sunlight/index.d.mts +92 -0
  59. package/dist/sunlight/index.d.ts +92 -0
  60. package/dist/sunlight/index.mjs +7 -0
  61. package/dist/sunlight/index.mjs.map +1 -0
  62. package/dist/terrain/index.cjs +423 -0
  63. package/dist/terrain/index.cjs.map +1 -0
  64. package/dist/terrain/index.d.mts +219 -0
  65. package/dist/terrain/index.d.ts +219 -0
  66. package/dist/terrain/index.mjs +7 -0
  67. package/dist/terrain/index.mjs.map +1 -0
  68. package/dist/transform-controls/index.cjs +1587 -0
  69. package/dist/transform-controls/index.cjs.map +1 -0
  70. package/dist/transform-controls/index.d.mts +162 -0
  71. package/dist/transform-controls/index.d.ts +162 -0
  72. package/dist/transform-controls/index.mjs +13 -0
  73. package/dist/transform-controls/index.mjs.map +1 -0
  74. package/dist/view-helper/index.cjs +430 -0
  75. package/dist/view-helper/index.cjs.map +1 -0
  76. package/dist/view-helper/index.d.mts +75 -0
  77. package/dist/view-helper/index.d.ts +75 -0
  78. package/dist/view-helper/index.mjs +7 -0
  79. package/dist/view-helper/index.mjs.map +1 -0
  80. package/package.json +124 -0
@@ -0,0 +1,449 @@
1
+ import * as THREE from 'three';
2
+ import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
3
+
4
+ /**
5
+ * Defines how a measurement point is attached to a scene object.
6
+ */
7
+ interface MeasurementAnchor {
8
+ /** Object the point is attached to */
9
+ object: THREE.Object3D;
10
+ /** Local position relative to the object */
11
+ localPosition: THREE.Vector3;
12
+ }
13
+ /**
14
+ * Represents a measurement point in world space with an optional anchor.
15
+ */
16
+ interface MeasurementPoint {
17
+ /** World position of the measurement point */
18
+ position: THREE.Vector3;
19
+ /** Optional attachment data for dynamic updates */
20
+ anchor?: MeasurementAnchor;
21
+ }
22
+ /**
23
+ * Per-measurement configuration captured at creation time.
24
+ */
25
+ interface MeasurementOptions {
26
+ /** Render color for the measurement line */
27
+ lineColor: number;
28
+ /** Render color for the measurement label text */
29
+ labelColor: string;
30
+ /** Width of the rendered line */
31
+ lineWidth: number;
32
+ /** Font size for label text */
33
+ fontSize: number;
34
+ /** Font family for label text */
35
+ fontFamily: string;
36
+ /** Snapping mode used when the measurement was created */
37
+ snapMode: SnapMode;
38
+ /** Whether snapping was enabled for this measurement */
39
+ snapEnabled: boolean;
40
+ /** Snap distance threshold for this measurement */
41
+ snapDistance: number;
42
+ /** Targets that were considered for snapping */
43
+ targets: THREE.Object3D[];
44
+ /** Whether this measurement should remain linked to scene objects */
45
+ isDynamic: boolean;
46
+ }
47
+ /**
48
+ * Runtime representation of a measurement inside the scene.
49
+ */
50
+ interface Measurement {
51
+ /** Unique identifier for the measurement */
52
+ id: string;
53
+ /** Starting point of the measurement */
54
+ start: MeasurementPoint;
55
+ /** Ending point of the measurement */
56
+ end: MeasurementPoint;
57
+ /** The line geometry representing the measurement */
58
+ line: THREE.Line;
59
+ /** The CSS2D label showing the distance */
60
+ label: CSS2DObject;
61
+ /** The calculated distance between start and end points */
62
+ distance: number;
63
+ /** Config that should be reused when editing this measurement */
64
+ options: MeasurementOptions;
65
+ }
66
+ /**
67
+ * Options accepted when creating or importing a measurement.
68
+ */
69
+ interface MeasurementCreationOptions {
70
+ /** Explicit measurement identifier */
71
+ id?: string;
72
+ /** Objects that should be considered for snapping/intersections */
73
+ targets?: THREE.Object3D[];
74
+ /** Whether snapping should be enabled */
75
+ snapEnabled?: boolean;
76
+ /** Snap distance threshold */
77
+ snapDistance?: number;
78
+ /** Snapping mode */
79
+ snapMode?: SnapMode;
80
+ /** Line color */
81
+ lineColor?: number;
82
+ /** Label color */
83
+ labelColor?: string;
84
+ /** Line width */
85
+ lineWidth?: number;
86
+ /** Label font size */
87
+ fontSize?: number;
88
+ /** Label font family */
89
+ fontFamily?: string;
90
+ /** Whether the measurement should stay linked to objects */
91
+ isDynamic?: boolean;
92
+ /** Object the start point should follow */
93
+ startObject?: THREE.Object3D;
94
+ /** Local position relative to startObject (defaults to world position converted to local) */
95
+ startLocalPosition?: THREE.Vector3;
96
+ /** Object the end point should follow */
97
+ endObject?: THREE.Object3D;
98
+ /** Local position relative to endObject (defaults to world position converted to local) */
99
+ endLocalPosition?: THREE.Vector3;
100
+ }
101
+ /**
102
+ * Serializable measurement point data for export/import.
103
+ */
104
+ interface MeasurementPointData {
105
+ /** Position as array [x, y, z] */
106
+ position: [number, number, number];
107
+ /** UUID of the anchor object if the point is dynamic */
108
+ anchorObjectId?: string;
109
+ /** Local position relative to the anchor object */
110
+ anchorLocalPosition?: [number, number, number];
111
+ }
112
+ /**
113
+ * Serializable measurement configuration data.
114
+ */
115
+ interface SerializedMeasurementOptions {
116
+ /** Snapping mode used by the measurement */
117
+ snapMode: SnapMode;
118
+ /** Whether snapping was enabled for the measurement */
119
+ snapEnabled: boolean;
120
+ /** Snap distance threshold used by the measurement */
121
+ snapDistance: number;
122
+ /** Measurement line color */
123
+ lineColor: number;
124
+ /** Measurement label color */
125
+ labelColor: string;
126
+ /** Measurement line width */
127
+ lineWidth: number;
128
+ /** Measurement label font size */
129
+ fontSize: number;
130
+ /** Measurement label font family */
131
+ fontFamily: string;
132
+ /** Whether the measurement should stay linked to objects */
133
+ isDynamic: boolean;
134
+ /** UUIDs of the target objects captured for this measurement */
135
+ targetObjectIds?: string[];
136
+ }
137
+ /**
138
+ * Serializable measurement data for export/import.
139
+ */
140
+ interface MeasurementData {
141
+ /** Unique identifier */
142
+ id: string;
143
+ /** Starting point data */
144
+ start: MeasurementPointData;
145
+ /** Ending point data */
146
+ end: MeasurementPointData;
147
+ /** Calculated distance */
148
+ distance: number;
149
+ /** Captured configuration for the measurement */
150
+ options: SerializedMeasurementOptions;
151
+ }
152
+ /**
153
+ * Configuration options for the measurement tool
154
+ */
155
+ interface MeasurementToolOptions {
156
+ /** DOM element for mouse interactions (required for interactive mode and editing) */
157
+ domElement?: HTMLElement;
158
+ /** Camera controls to disable during edit dragging (e.g., OrbitControls) */
159
+ controls?: {
160
+ enabled: boolean;
161
+ };
162
+ }
163
+ /**
164
+ * Snapping mode options
165
+ */
166
+ declare enum SnapMode {
167
+ VERTEX = "vertex",
168
+ FACE = "face",
169
+ EDGE = "edge",
170
+ DISABLED = "disabled"
171
+ }
172
+ /**
173
+ * Event types dispatched by the measurement tool
174
+ */
175
+ interface MeasurementToolEvents {
176
+ /** Fired when a new measurement is created */
177
+ measurementCreated: {
178
+ measurement: Measurement;
179
+ };
180
+ /** Fired when a measurement is removed */
181
+ measurementRemoved: {
182
+ measurement: Measurement;
183
+ };
184
+ /** Fired when all measurements are cleared */
185
+ measurementsCleared: {
186
+ count: number;
187
+ };
188
+ /** Fired when interactive mode starts */
189
+ started: {};
190
+ /** Fired when interactive mode ends */
191
+ ended: {};
192
+ /** Fired when preview line is updated */
193
+ previewUpdated: {
194
+ start: THREE.Vector3;
195
+ current: THREE.Vector3;
196
+ distance: number;
197
+ };
198
+ /** Fired when edit mode is entered */
199
+ editModeEntered: {
200
+ measurement: Measurement;
201
+ };
202
+ /** Fired when edit mode is exited */
203
+ editModeExited: {
204
+ measurement: Measurement;
205
+ };
206
+ /** Fired when a measurement is updated */
207
+ measurementUpdated: {
208
+ measurement: Measurement;
209
+ };
210
+ }
211
+ /**
212
+ * Raycast result with snapping information
213
+ */
214
+ interface SnapResult {
215
+ /** The snapped position */
216
+ point: THREE.Vector3;
217
+ /** The original intersection point */
218
+ originalPoint: THREE.Vector3;
219
+ /** Whether snapping occurred */
220
+ snapped: boolean;
221
+ /** The snap mode that was applied */
222
+ snapMode: SnapMode;
223
+ /** The object that was intersected */
224
+ object: THREE.Object3D;
225
+ }
226
+
227
+ /**
228
+ * Main measurement tool class for Three.js scenes
229
+ * Provides both programmatic and interactive measurement creation
230
+ *
231
+ * **Important**: This tool uses CSS2DObject for labels, which requires
232
+ * CSS2DRenderer to be set up and rendered alongside your main WebGL renderer.
233
+ *
234
+ * @example
235
+ * ```javascript
236
+ * import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
237
+ *
238
+ * // Set up CSS2DRenderer
239
+ * const css2dRenderer = new CSS2DRenderer()
240
+ * css2dRenderer.setSize(window.innerWidth, window.innerHeight)
241
+ * css2dRenderer.domElement.style.position = 'absolute'
242
+ * css2dRenderer.domElement.style.top = '0'
243
+ * css2dRenderer.domElement.style.pointerEvents = 'none'
244
+ * document.body.appendChild(css2dRenderer.domElement)
245
+ *
246
+ * // In your animation loop:
247
+ * function animate() {
248
+ * renderer.render(scene, camera) // WebGL rendering
249
+ * css2dRenderer.render(scene, camera) // CSS2D label rendering
250
+ * }
251
+ * ```
252
+ */
253
+ declare class MeasurementTool extends THREE.EventDispatcher<MeasurementToolEvents> {
254
+ private scene;
255
+ private camera;
256
+ private measurements;
257
+ private raycaster;
258
+ private isInteractive;
259
+ private domElement;
260
+ private controls;
261
+ private defaultTargets;
262
+ private activeTargets;
263
+ private currentMeasurement;
264
+ private activeInteractionOptions;
265
+ private pendingMeasurementOptions;
266
+ private previewLine;
267
+ private previewLabel;
268
+ private snapMarker;
269
+ private originalCursor;
270
+ private cursorHidden;
271
+ private defaultOptions;
272
+ private previewColor;
273
+ private markerColor;
274
+ private markerSize;
275
+ private markerVisible;
276
+ private isEditMode;
277
+ private editingMeasurement;
278
+ private editingPoint;
279
+ private startEditSprite;
280
+ private endEditSprite;
281
+ private editSpriteMaterial;
282
+ private isDragging;
283
+ private previewMaterial;
284
+ private markerMaterial;
285
+ /**
286
+ * Create a crosshair texture for the snap marker sprite
287
+ */
288
+ private createCrosshairTexture;
289
+ /**
290
+ * Create a dot texture for edit point sprites
291
+ */
292
+ private createDotTexture;
293
+ constructor(scene: THREE.Scene, camera: THREE.Camera, options?: MeasurementToolOptions);
294
+ /**
295
+ * Create a measurement point that optionally tracks a scene object.
296
+ */
297
+ private createMeasurementPoint;
298
+ /**
299
+ * Update a measurement point's world position from its anchor (if dynamic)
300
+ */
301
+ private updateMeasurementPoint;
302
+ /**
303
+ * Add a measurement between two world positions with optional attachments.
304
+ *
305
+ * @param start - Starting world position
306
+ * @param end - Ending world position
307
+ * @param options - Optional configuration for the measurement
308
+ */
309
+ addMeasurement(start: THREE.Vector3, end: THREE.Vector3, options?: MeasurementCreationOptions): Measurement;
310
+ private resolveMeasurementOptions;
311
+ private getActiveMeasurementOptions;
312
+ /**
313
+ * @deprecated Use addMeasurement(obj1, obj2, { startLocalPos, endLocalPos }) instead
314
+ * Add a dynamic measurement between two objects
315
+ */
316
+ addDynamicMeasurement(startObject: THREE.Object3D, endObject: THREE.Object3D, startLocalPos?: THREE.Vector3, endLocalPos?: THREE.Vector3): Measurement;
317
+ /**
318
+ * @deprecated Use addMeasurement(staticPos, targetObject, { endLocalPos }) instead
319
+ * Add a measurement from a static point to a dynamic object
320
+ */
321
+ addMeasurementToObject(staticPos: THREE.Vector3, targetObject: THREE.Object3D, objectLocalPos?: THREE.Vector3): Measurement;
322
+ /**
323
+ * Core method to add a measurement from two measurement points
324
+ */
325
+ private addMeasurementFromPoints;
326
+ /**
327
+ * Update all dynamic measurements in real-time
328
+ * Call this in your animation loop to keep dynamic measurements up-to-date
329
+ */
330
+ updateDynamicMeasurements(): boolean;
331
+ /**
332
+ * Set whether interactive measurements should be dynamic or static
333
+ */
334
+ setDynamicMode(enabled: boolean): void;
335
+ /**
336
+ * Get the current dynamic mode state
337
+ */
338
+ getDynamicMode(): boolean;
339
+ /**
340
+ * Enter edit mode for a specific measurement
341
+ * Shows edit sprites at the measurement endpoints
342
+ * @param measurementIdOrIndex - The measurement ID or index
343
+ * @param targets - Optional target objects for snapping during edit
344
+ */
345
+ enterEditMode(measurementIdOrIndex: string | number, targets?: THREE.Object3D[]): void;
346
+ /**
347
+ * Exit edit mode
348
+ */
349
+ exitEditMode(): void;
350
+ /**
351
+ * Set the DOM element for interactions (both measurement and edit mode)
352
+ */
353
+ setDomElement(domElement: HTMLElement): void;
354
+ /**
355
+ * Set the camera controls to disable during edit dragging
356
+ */
357
+ setControls(controls: {
358
+ enabled: boolean;
359
+ }): void;
360
+ /**
361
+ * Set target objects for snapping (used in both interactive mode and edit mode)
362
+ */
363
+ setTargetObjects(targets: THREE.Object3D[]): void;
364
+ /**
365
+ * Update default measurement options used when none are provided explicitly.
366
+ */
367
+ setDefaultMeasurementOptions(options: Partial<MeasurementCreationOptions>): void;
368
+ /**
369
+ * Disable camera controls (used during edit dragging)
370
+ */
371
+ private disableControls;
372
+ /**
373
+ * Enable camera controls (used after edit dragging)
374
+ */
375
+ private enableControls;
376
+ /**
377
+ * Enable interactive measurement mode
378
+ */
379
+ enableInteraction(options?: MeasurementCreationOptions): void;
380
+ /**
381
+ * Disable interactive measurement mode
382
+ */
383
+ disableInteraction(): void;
384
+ /**
385
+ * Remove the last measurement (undo)
386
+ */
387
+ undoLast(): void;
388
+ /**
389
+ * Remove a specific measurement
390
+ */
391
+ removeMeasurement(measurement: Measurement): void;
392
+ /**
393
+ * Clear all measurements
394
+ */
395
+ clearAll(): void;
396
+ /**
397
+ * Get all measurements
398
+ */
399
+ getMeasurements(): Measurement[];
400
+ /**
401
+ * Convert a MeasurementPoint to serializable data
402
+ */
403
+ private serializeMeasurementPoint;
404
+ /**
405
+ * Serialize measurements to JSON-compatible format
406
+ * Note: Dynamic measurements will lose their object references and become static when deserialized
407
+ */
408
+ serialize(): MeasurementData[];
409
+ /**
410
+ * Deserialize measurements from JSON data
411
+ * Note: Dynamic measurements become static since object references are lost
412
+ */
413
+ deserialize(data: MeasurementData[]): void;
414
+ /**
415
+ * Dispose of all resources
416
+ */
417
+ dispose(): void;
418
+ private onMouseClick;
419
+ private onMouseMove;
420
+ private onKeyDown;
421
+ private hideCursor;
422
+ private showCursor;
423
+ private createSnapMarker;
424
+ private updateSnapMarker;
425
+ private hideSnapMarker;
426
+ private removeSnapMarker;
427
+ private startMeasurement;
428
+ private updatePreview;
429
+ private completeMeasurement;
430
+ private cancelCurrentMeasurement;
431
+ private cleanupPreview;
432
+ private getSnapResult;
433
+ private performSnapping;
434
+ private snapToVertex;
435
+ private createLabel;
436
+ private updateLabelText;
437
+ private removeMeasurementFromScene;
438
+ private getAllMeshes;
439
+ private generateId;
440
+ private createEditSprites;
441
+ private removeEditSprites;
442
+ private onEditMouseDown;
443
+ private onEditMouseMove;
444
+ private onEditMouseUp;
445
+ private cancelEdit;
446
+ private updateMeasurementPreview;
447
+ }
448
+
449
+ export { type Measurement, type MeasurementData, type MeasurementPoint, type MeasurementPointData, MeasurementTool, type MeasurementToolEvents, type MeasurementToolOptions, SnapMode, type SnapResult };
@@ -0,0 +1,9 @@
1
+ import {
2
+ MeasurementTool,
3
+ SnapMode
4
+ } from "../chunk-5DP6WDB3.mjs";
5
+ export {
6
+ MeasurementTool,
7
+ SnapMode
8
+ };
9
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}