@react-three-dom/core 0.1.0 → 0.3.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.
- package/dist/index.cjs +1941 -689
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +758 -43
- package/dist/index.d.ts +758 -43
- package/dist/index.js +1931 -691
- package/dist/index.js.map +1 -1
- package/package.json +19 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
import { Object3D, Camera, WebGLRenderer, Vector3 } from 'three';
|
|
1
|
+
import { Object3D, Scene, Camera, WebGLRenderer, Intersection, Vector3 } from 'three';
|
|
2
2
|
|
|
3
|
-
declare const version = "0.
|
|
3
|
+
declare const version = "0.3.0";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Enable or disable debug logging globally.
|
|
7
|
+
* When enabled, all r3fLog calls will output to console.log.
|
|
8
|
+
*/
|
|
9
|
+
declare function enableDebug(on?: boolean): void;
|
|
10
|
+
/**
|
|
11
|
+
* Check if debug logging is currently enabled.
|
|
12
|
+
*/
|
|
13
|
+
declare function isDebugEnabled(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Log a debug message. Only outputs when debug is enabled via:
|
|
16
|
+
* - enableDebug(true)
|
|
17
|
+
* - window.__R3F_DOM_DEBUG__ = true
|
|
18
|
+
* - <ThreeDom debug /> prop
|
|
19
|
+
*
|
|
20
|
+
* @param area - Module area (e.g. 'setup', 'store', 'patch', 'click', 'drag')
|
|
21
|
+
* @param msg - Human-readable message
|
|
22
|
+
* @param data - Optional data payload (object, error, etc.)
|
|
23
|
+
*/
|
|
24
|
+
declare function r3fLog(area: string, msg: string, data?: unknown): void;
|
|
4
25
|
|
|
5
26
|
interface ObjectMetadata {
|
|
6
27
|
/** Three.js internal UUID */
|
|
@@ -23,6 +44,14 @@ interface ObjectMetadata {
|
|
|
23
44
|
triangleCount?: number;
|
|
24
45
|
/** Instance count for InstancedMesh */
|
|
25
46
|
instanceCount?: number;
|
|
47
|
+
/** Field of view in degrees (PerspectiveCamera only) */
|
|
48
|
+
fov?: number;
|
|
49
|
+
/** Near clipping plane (cameras only) */
|
|
50
|
+
near?: number;
|
|
51
|
+
/** Far clipping plane (cameras only) */
|
|
52
|
+
far?: number;
|
|
53
|
+
/** Zoom level (cameras only) */
|
|
54
|
+
zoom?: number;
|
|
26
55
|
/** Local position as [x, y, z] */
|
|
27
56
|
position: [number, number, number];
|
|
28
57
|
/** Local euler rotation as [x, y, z] in radians */
|
|
@@ -36,6 +65,11 @@ interface ObjectMetadata {
|
|
|
36
65
|
/** Flag indicating bounds need recomputation */
|
|
37
66
|
boundsDirty: boolean;
|
|
38
67
|
}
|
|
68
|
+
/** Options for inspect(). Include geometry buffers only when needed to avoid perf impact. */
|
|
69
|
+
interface InspectOptions {
|
|
70
|
+
/** If true, include vertex positions and triangle indices in geometry. Default: false. */
|
|
71
|
+
includeGeometryData?: boolean;
|
|
72
|
+
}
|
|
39
73
|
interface GeometryInspection {
|
|
40
74
|
/** Geometry class type */
|
|
41
75
|
type: string;
|
|
@@ -53,6 +87,10 @@ interface GeometryInspection {
|
|
|
53
87
|
center: [number, number, number];
|
|
54
88
|
radius: number;
|
|
55
89
|
};
|
|
90
|
+
/** Position attribute data (x,y,z per vertex). Only set when inspect(..., { includeGeometryData: true }). */
|
|
91
|
+
positionData?: number[];
|
|
92
|
+
/** Index buffer (triangle indices). Only set when inspect(..., { includeGeometryData: true }) and geometry is indexed. */
|
|
93
|
+
indexData?: number[];
|
|
56
94
|
}
|
|
57
95
|
interface MaterialInspection {
|
|
58
96
|
/** Material class type */
|
|
@@ -96,6 +134,16 @@ interface SnapshotNode {
|
|
|
96
134
|
position: [number, number, number];
|
|
97
135
|
rotation: [number, number, number];
|
|
98
136
|
scale: [number, number, number];
|
|
137
|
+
/** Geometry class name (meshes only) */
|
|
138
|
+
geometryType?: string;
|
|
139
|
+
/** Material class name (meshes only) */
|
|
140
|
+
materialType?: string;
|
|
141
|
+
/** Total vertex count (meshes only) */
|
|
142
|
+
vertexCount?: number;
|
|
143
|
+
/** Triangle count (meshes only) */
|
|
144
|
+
triangleCount?: number;
|
|
145
|
+
/** Instance count (InstancedMesh only) */
|
|
146
|
+
instanceCount?: number;
|
|
99
147
|
children: SnapshotNode[];
|
|
100
148
|
}
|
|
101
149
|
interface SceneSnapshot {
|
|
@@ -114,18 +162,47 @@ interface StoreEvent {
|
|
|
114
162
|
}
|
|
115
163
|
type StoreListener = (event: StoreEvent) => void;
|
|
116
164
|
interface R3FDOM {
|
|
165
|
+
/**
|
|
166
|
+
* Whether the bridge is fully initialized and ready to use.
|
|
167
|
+
* - `true`: ThreeDom setup completed successfully, all methods are live.
|
|
168
|
+
* - `false`: Bridge exists but setup failed or is still initializing.
|
|
169
|
+
*
|
|
170
|
+
* Test waiters should check `_ready === true` instead of just `typeof !== 'undefined'`.
|
|
171
|
+
*/
|
|
172
|
+
_ready: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* If `_ready` is false, contains the error message from the failed setup.
|
|
175
|
+
* Undefined when `_ready` is true.
|
|
176
|
+
*/
|
|
177
|
+
_error?: string;
|
|
117
178
|
/** Tier 1: O(1) lookup by testId */
|
|
118
179
|
getByTestId(id: string): ObjectMetadata | null;
|
|
119
180
|
/** Tier 1: O(1) lookup by uuid */
|
|
120
181
|
getByUuid(uuid: string): ObjectMetadata | null;
|
|
121
182
|
/** Tier 1: O(1) lookup by name (returns array, names aren't unique) */
|
|
122
183
|
getByName(name: string): ObjectMetadata[];
|
|
184
|
+
/** Get direct children of an object by testId or uuid */
|
|
185
|
+
getChildren(idOrUuid: string): ObjectMetadata[];
|
|
186
|
+
/** Get parent of an object by testId or uuid (null if root or not found) */
|
|
187
|
+
getParent(idOrUuid: string): ObjectMetadata | null;
|
|
123
188
|
/** Total number of tracked objects */
|
|
124
189
|
getCount(): number;
|
|
190
|
+
/** Get all objects of a given Three.js type (Mesh, Group, Line, Points, etc.) */
|
|
191
|
+
getByType(type: string): ObjectMetadata[];
|
|
192
|
+
/** Get all objects with a given geometry type (e.g. "BoxGeometry", "BufferGeometry") */
|
|
193
|
+
getByGeometryType(type: string): ObjectMetadata[];
|
|
194
|
+
/** Get all objects with a given material type (e.g. "MeshStandardMaterial") */
|
|
195
|
+
getByMaterialType(type: string): ObjectMetadata[];
|
|
196
|
+
/** Get objects that have a specific userData key (and optionally matching value) */
|
|
197
|
+
getByUserData(key: string, value?: unknown): ObjectMetadata[];
|
|
198
|
+
/** Count objects of a given Three.js type */
|
|
199
|
+
getCountByType(type: string): number;
|
|
200
|
+
/** Batch lookup: get metadata for multiple objects by testId or uuid in one call */
|
|
201
|
+
getObjects(ids: string[]): Record<string, ObjectMetadata | null>;
|
|
125
202
|
/** Full structured JSON snapshot from Tier 1 store */
|
|
126
203
|
snapshot(): SceneSnapshot;
|
|
127
|
-
/** Tier 2: on-demand heavy inspection (reads live Three.js object) */
|
|
128
|
-
inspect(idOrUuid: string): ObjectInspection | null;
|
|
204
|
+
/** Tier 2: on-demand heavy inspection (reads live Three.js object). Use includeGeometryData: true to get vertex/index buffers. */
|
|
205
|
+
inspect(idOrUuid: string, options?: InspectOptions): ObjectInspection | null;
|
|
129
206
|
/** Deterministic click on a 3D object */
|
|
130
207
|
click(idOrUuid: string): void;
|
|
131
208
|
/** Deterministic double-click on a 3D object */
|
|
@@ -134,12 +211,14 @@ interface R3FDOM {
|
|
|
134
211
|
contextMenu(idOrUuid: string): void;
|
|
135
212
|
/** Deterministic hover on a 3D object */
|
|
136
213
|
hover(idOrUuid: string): void;
|
|
137
|
-
/**
|
|
214
|
+
/** Unhover / pointer-leave — resets hover state by moving pointer off-canvas */
|
|
215
|
+
unhover(): void;
|
|
216
|
+
/** Deterministic drag on a 3D object (async — dispatches multi-step pointer sequence) */
|
|
138
217
|
drag(idOrUuid: string, delta: {
|
|
139
218
|
x: number;
|
|
140
219
|
y: number;
|
|
141
220
|
z: number;
|
|
142
|
-
}): void
|
|
221
|
+
}): Promise<void>;
|
|
143
222
|
/** Dispatch a wheel/scroll event on a 3D object */
|
|
144
223
|
wheel(idOrUuid: string, options?: {
|
|
145
224
|
deltaY?: number;
|
|
@@ -147,21 +226,136 @@ interface R3FDOM {
|
|
|
147
226
|
}): void;
|
|
148
227
|
/** Click empty space to trigger onPointerMissed */
|
|
149
228
|
pointerMiss(): void;
|
|
229
|
+
/** Draw a freeform path on the canvas (for drawing/annotation apps) */
|
|
230
|
+
drawPath(points: Array<{
|
|
231
|
+
x: number;
|
|
232
|
+
y: number;
|
|
233
|
+
pressure?: number;
|
|
234
|
+
}>, options?: {
|
|
235
|
+
stepDelayMs?: number;
|
|
236
|
+
pointerType?: 'mouse' | 'pen' | 'touch';
|
|
237
|
+
clickAtEnd?: boolean;
|
|
238
|
+
}): Promise<{
|
|
239
|
+
eventCount: number;
|
|
240
|
+
pointCount: number;
|
|
241
|
+
}>;
|
|
150
242
|
/** Select an object (shows highlight wireframe in scene) */
|
|
151
243
|
select(idOrUuid: string): void;
|
|
152
244
|
/** Clear selection */
|
|
153
245
|
clearSelection(): void;
|
|
246
|
+
/** Get uuids of currently selected objects (for DevTools panel sync) */
|
|
247
|
+
getSelection(): string[];
|
|
154
248
|
/** Raw Three.js object access (for advanced debugging) */
|
|
155
249
|
getObject3D(idOrUuid: string): Object3D | null;
|
|
250
|
+
/**
|
|
251
|
+
* Resolve uuid for display: if the object is the first mesh of a Group (e.g. table top),
|
|
252
|
+
* returns the parent group uuid so the whole group is highlighted; otherwise returns the given uuid.
|
|
253
|
+
*/
|
|
254
|
+
getSelectionDisplayTarget(uuid: string): string;
|
|
255
|
+
/**
|
|
256
|
+
* Enable or disable "inspect mode" for the mirror DOM.
|
|
257
|
+
* When true, mirror elements use pointer-events: auto so the DevTools element picker
|
|
258
|
+
* can select 3D objects by clicking on the canvas (e.g. hold Alt while using the picker).
|
|
259
|
+
* When false, pointer-events: none so normal 3D interaction works.
|
|
260
|
+
*/
|
|
261
|
+
setInspectMode(on: boolean): void;
|
|
262
|
+
/** Returns true if inspect mode is currently active. */
|
|
263
|
+
getInspectMode(): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Manually sweep orphaned objects from the store.
|
|
266
|
+
* Removes objects that are no longer in any tracked scene graph.
|
|
267
|
+
* Runs automatically every ~30s, but can be called after large
|
|
268
|
+
* scene changes (e.g. floor unload) for immediate cleanup.
|
|
269
|
+
* Returns the number of orphans removed.
|
|
270
|
+
*/
|
|
271
|
+
sweepOrphans(): number;
|
|
272
|
+
/**
|
|
273
|
+
* Rich diagnostics for test runners and debugging.
|
|
274
|
+
* Returns bridge health, scene stats, and WebGL context info.
|
|
275
|
+
*/
|
|
276
|
+
getDiagnostics(): BridgeDiagnostics;
|
|
277
|
+
/**
|
|
278
|
+
* Fuzzy search: find objects whose testId or name contains the query string.
|
|
279
|
+
* Returns up to `limit` matches. Used by test runners to suggest corrections
|
|
280
|
+
* when an object is not found.
|
|
281
|
+
*/
|
|
282
|
+
fuzzyFind(query: string, limit?: number): ObjectMetadata[];
|
|
283
|
+
/** Get current camera state (position, rotation, fov, near, far, zoom, type) */
|
|
284
|
+
getCameraState(): CameraState;
|
|
285
|
+
/** Canvas identifier for multi-canvas apps. Undefined for the default/primary canvas. */
|
|
286
|
+
canvasId?: string;
|
|
156
287
|
/** Library version */
|
|
157
288
|
version: string;
|
|
158
289
|
}
|
|
290
|
+
interface CameraState {
|
|
291
|
+
type: 'PerspectiveCamera' | 'OrthographicCamera' | string;
|
|
292
|
+
position: [number, number, number];
|
|
293
|
+
rotation: [number, number, number];
|
|
294
|
+
/** World-space target the camera is looking at (derived from camera direction) */
|
|
295
|
+
target: [number, number, number];
|
|
296
|
+
/** Field of view in degrees (PerspectiveCamera only) */
|
|
297
|
+
fov?: number;
|
|
298
|
+
/** Near clipping plane */
|
|
299
|
+
near: number;
|
|
300
|
+
/** Far clipping plane */
|
|
301
|
+
far: number;
|
|
302
|
+
/** Zoom level */
|
|
303
|
+
zoom: number;
|
|
304
|
+
/** Aspect ratio (PerspectiveCamera only) */
|
|
305
|
+
aspect?: number;
|
|
306
|
+
/** Left/right/top/bottom (OrthographicCamera only) */
|
|
307
|
+
left?: number;
|
|
308
|
+
right?: number;
|
|
309
|
+
top?: number;
|
|
310
|
+
bottom?: number;
|
|
311
|
+
}
|
|
312
|
+
interface BridgeDiagnostics {
|
|
313
|
+
version: string;
|
|
314
|
+
ready: boolean;
|
|
315
|
+
error?: string;
|
|
316
|
+
objectCount: number;
|
|
317
|
+
meshCount: number;
|
|
318
|
+
groupCount: number;
|
|
319
|
+
lightCount: number;
|
|
320
|
+
cameraCount: number;
|
|
321
|
+
materializedDomNodes: number;
|
|
322
|
+
maxDomNodes: number;
|
|
323
|
+
canvasWidth: number;
|
|
324
|
+
canvasHeight: number;
|
|
325
|
+
webglRenderer: string;
|
|
326
|
+
dirtyQueueSize: number;
|
|
327
|
+
}
|
|
159
328
|
declare global {
|
|
160
329
|
interface Window {
|
|
330
|
+
/** Default / primary bridge instance (last mounted, or explicitly marked primary). */
|
|
161
331
|
__R3F_DOM__?: R3FDOM;
|
|
332
|
+
/** Registry of all active bridge instances keyed by canvasId. */
|
|
333
|
+
__R3F_DOM_INSTANCES__?: Record<string, R3FDOM>;
|
|
334
|
+
/** Set to true to enable debug logging from @react-three-dom/core */
|
|
335
|
+
__R3F_DOM_DEBUG__?: boolean;
|
|
336
|
+
/** @internal Mirror element currently hovered by DevTools inspector. */
|
|
337
|
+
__r3fdom_hovered__?: HTMLElement | null;
|
|
338
|
+
/** @internal Mirror element currently selected via DevTools / inspect mode. */
|
|
339
|
+
__r3fdom_selected_element__?: HTMLElement | null;
|
|
162
340
|
}
|
|
163
341
|
}
|
|
164
342
|
|
|
343
|
+
/**
|
|
344
|
+
* @module ObjectStore
|
|
345
|
+
*
|
|
346
|
+
* Central registry for all tracked Three.js objects in a react-three-dom session.
|
|
347
|
+
* Provides two-tier data access: Tier 1 (lightweight metadata cached per-frame)
|
|
348
|
+
* and Tier 2 (on-demand deep inspection of geometry, materials, and bounds).
|
|
349
|
+
* Designed for BIM-scale scenes (100k+ objects) with O(1) lookups by uuid,
|
|
350
|
+
* testId, and name, plus amortized flat-list iteration and async registration.
|
|
351
|
+
*/
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Source of truth for all tracked Three.js objects.
|
|
355
|
+
* Maintains O(1) indexes by uuid, testId, and name, a dirty queue for
|
|
356
|
+
* priority per-frame sync, and an event system for add/remove/update
|
|
357
|
+
* notifications consumed by DomMirror and the devtools panel.
|
|
358
|
+
*/
|
|
165
359
|
declare class ObjectStore {
|
|
166
360
|
private _metaByObject;
|
|
167
361
|
private _objectByUuid;
|
|
@@ -175,14 +369,32 @@ declare class ObjectStore {
|
|
|
175
369
|
/**
|
|
176
370
|
* Register a single object into the store.
|
|
177
371
|
* Populates Tier 1 metadata and all indexes.
|
|
372
|
+
* Tags the object with `__r3fdom_tracked = true` for O(1) scene membership checks.
|
|
178
373
|
*/
|
|
179
374
|
register(obj: Object3D): ObjectMetadata;
|
|
180
375
|
/**
|
|
181
|
-
* Register an entire subtree (object + all descendants).
|
|
376
|
+
* Register an entire subtree (object + all descendants) synchronously.
|
|
377
|
+
* Prefer `registerTreeAsync` for large scenes (100k+) to avoid blocking.
|
|
182
378
|
*/
|
|
183
379
|
registerTree(root: Object3D): void;
|
|
380
|
+
private _asyncRegQueue;
|
|
381
|
+
private _asyncRegHandle;
|
|
382
|
+
private _asyncRegBatchSize;
|
|
383
|
+
/**
|
|
384
|
+
* Register an entire subtree asynchronously using requestIdleCallback.
|
|
385
|
+
* Processes ~1000 objects per idle slice to avoid blocking the main thread.
|
|
386
|
+
*
|
|
387
|
+
* IMPORTANT: install patchObject3D BEFORE calling this so that objects
|
|
388
|
+
* added to the scene during async registration are caught by the patch.
|
|
389
|
+
*
|
|
390
|
+
* Returns a cancel function. Also cancelled automatically by dispose().
|
|
391
|
+
*/
|
|
392
|
+
registerTreeAsync(root: Object3D): () => void;
|
|
393
|
+
private _scheduleRegChunk;
|
|
394
|
+
private _cancelAsyncRegistration;
|
|
184
395
|
/**
|
|
185
396
|
* Unregister a single object from the store.
|
|
397
|
+
* Clears the `__r3fdom_tracked` flag.
|
|
186
398
|
*/
|
|
187
399
|
unregister(obj: Object3D): void;
|
|
188
400
|
/**
|
|
@@ -190,7 +402,10 @@ declare class ObjectStore {
|
|
|
190
402
|
*/
|
|
191
403
|
unregisterTree(root: Object3D): void;
|
|
192
404
|
/**
|
|
193
|
-
* Refresh Tier 1
|
|
405
|
+
* Refresh dynamic Tier 1 fields from the live Three.js object.
|
|
406
|
+
* Only reads transform, visibility, children count, and parent —
|
|
407
|
+
* skips static fields (geometry, material) that don't change per-frame.
|
|
408
|
+
* Mutates metadata in-place to avoid allocation.
|
|
194
409
|
* Returns true if any values changed.
|
|
195
410
|
*/
|
|
196
411
|
update(obj: Object3D): boolean;
|
|
@@ -198,14 +413,55 @@ declare class ObjectStore {
|
|
|
198
413
|
* Compute full inspection data from a live Three.js object.
|
|
199
414
|
* This reads geometry buffers, material properties, world bounds, etc.
|
|
200
415
|
* Cost: 0.1–2ms depending on geometry complexity.
|
|
416
|
+
* Pass { includeGeometryData: true } to include vertex positions and triangle indices (higher cost for large meshes).
|
|
201
417
|
*/
|
|
202
|
-
inspect(idOrUuid: string): ObjectInspection | null;
|
|
418
|
+
inspect(idOrUuid: string, options?: InspectOptions): ObjectInspection | null;
|
|
203
419
|
/** Get metadata by testId. O(1). */
|
|
204
420
|
getByTestId(testId: string): ObjectMetadata | null;
|
|
205
421
|
/** Get metadata by uuid. O(1). */
|
|
206
422
|
getByUuid(uuid: string): ObjectMetadata | null;
|
|
207
423
|
/** Get metadata by name (returns array since names aren't unique). O(1). */
|
|
208
424
|
getByName(name: string): ObjectMetadata[];
|
|
425
|
+
/** Get direct children of an object by testId or uuid. Returns empty array if not found. */
|
|
426
|
+
getChildren(idOrUuid: string): ObjectMetadata[];
|
|
427
|
+
/** Get parent of an object by testId or uuid. Returns null if not found or if root. */
|
|
428
|
+
getParent(idOrUuid: string): ObjectMetadata | null;
|
|
429
|
+
/**
|
|
430
|
+
* Batch lookup: get metadata for multiple objects by testId or uuid.
|
|
431
|
+
* Returns a Map from the requested id to its metadata (or null if not found).
|
|
432
|
+
* Single round-trip — much more efficient than calling getByTestId/getByUuid
|
|
433
|
+
* in a loop for BIM/CAD scenes with many objects.
|
|
434
|
+
* O(k) where k is the number of requested ids.
|
|
435
|
+
*/
|
|
436
|
+
getObjects(ids: string[]): Map<string, ObjectMetadata | null>;
|
|
437
|
+
/**
|
|
438
|
+
* Get all objects of a given Three.js type (e.g. "Mesh", "Group", "Line").
|
|
439
|
+
* Linear scan — O(n) where n is total tracked objects.
|
|
440
|
+
*/
|
|
441
|
+
getByType(type: string): ObjectMetadata[];
|
|
442
|
+
/**
|
|
443
|
+
* Get all objects with a given geometry type (e.g. "BoxGeometry", "BufferGeometry").
|
|
444
|
+
* Linear scan — O(n). Only meshes/points/lines have geometryType.
|
|
445
|
+
*/
|
|
446
|
+
getByGeometryType(type: string): ObjectMetadata[];
|
|
447
|
+
/**
|
|
448
|
+
* Get all objects with a given material type (e.g. "MeshStandardMaterial").
|
|
449
|
+
* Linear scan — O(n). Only meshes/points/lines have materialType.
|
|
450
|
+
*/
|
|
451
|
+
getByMaterialType(type: string): ObjectMetadata[];
|
|
452
|
+
/**
|
|
453
|
+
* Get all objects that have a specific userData key.
|
|
454
|
+
* If `value` is provided, only returns objects where `userData[key]` matches.
|
|
455
|
+
* Uses JSON.stringify for deep equality on complex values.
|
|
456
|
+
* Linear scan — O(n).
|
|
457
|
+
*/
|
|
458
|
+
getByUserData(key: string, value?: unknown): ObjectMetadata[];
|
|
459
|
+
/**
|
|
460
|
+
* Count objects of a given Three.js type.
|
|
461
|
+
* More efficient than getByType().length — no array allocation.
|
|
462
|
+
* Linear scan — O(n).
|
|
463
|
+
*/
|
|
464
|
+
getCountByType(type: string): number;
|
|
209
465
|
/** Get the raw Three.js Object3D by testId or uuid. */
|
|
210
466
|
getObject3D(idOrUuid: string): Object3D | null;
|
|
211
467
|
/** Get metadata for a known Object3D reference. */
|
|
@@ -217,9 +473,10 @@ declare class ObjectStore {
|
|
|
217
473
|
/** Check if a root scene is tracked. */
|
|
218
474
|
isTrackedRoot(obj: Object3D): boolean;
|
|
219
475
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
476
|
+
* Check if an object belongs to a tracked scene.
|
|
477
|
+
* Fast path: checks the `__r3fdom_tracked` flag set during register (O(1)).
|
|
478
|
+
* Fallback: walks up the parent chain to find a tracked root.
|
|
479
|
+
* The fallback is needed for newly added objects that aren't registered yet.
|
|
223
480
|
*/
|
|
224
481
|
isInTrackedScene(obj: Object3D): boolean;
|
|
225
482
|
/**
|
|
@@ -239,10 +496,32 @@ declare class ObjectStore {
|
|
|
239
496
|
/** Subscribe to store events (add, remove, update). */
|
|
240
497
|
subscribe(listener: StoreListener): () => void;
|
|
241
498
|
private _emit;
|
|
499
|
+
/**
|
|
500
|
+
* Sweep objects in `_objectByUuid` that are no longer in any tracked scene.
|
|
501
|
+
* This catches objects that were removed from the scene graph without
|
|
502
|
+
* triggering the patched Object3D.remove (e.g. direct `.children` splice,
|
|
503
|
+
* or the remove hook failing silently).
|
|
504
|
+
*
|
|
505
|
+
* At BIM scale, call this periodically (e.g. every 30s or after a floor
|
|
506
|
+
* load/unload) to prevent memory leaks from retained Object3D references.
|
|
507
|
+
*
|
|
508
|
+
* Returns the number of orphans cleaned up.
|
|
509
|
+
*/
|
|
510
|
+
sweepOrphans(): number;
|
|
242
511
|
/** Remove all tracked objects and reset state. */
|
|
243
512
|
dispose(): void;
|
|
244
513
|
}
|
|
245
514
|
|
|
515
|
+
/**
|
|
516
|
+
* @module DomMirror
|
|
517
|
+
*
|
|
518
|
+
* Maintains a parallel DOM tree that mirrors the Three.js scene graph using
|
|
519
|
+
* custom elements (<three-mesh>, <three-group>, etc.). This enables standard
|
|
520
|
+
* DOM tooling — CSS selectors, DevTools Elements panel, Accessibility tree —
|
|
521
|
+
* to work with 3D objects. Only a subset of objects are materialized as DOM
|
|
522
|
+
* nodes at any time (capped via LRU eviction) to stay performant at BIM scale.
|
|
523
|
+
*/
|
|
524
|
+
|
|
246
525
|
/**
|
|
247
526
|
* Manages the parallel DOM tree that mirrors the Three.js scene graph.
|
|
248
527
|
*
|
|
@@ -261,12 +540,30 @@ declare class DomMirror {
|
|
|
261
540
|
private _lruSize;
|
|
262
541
|
private _maxNodes;
|
|
263
542
|
private _parentMap;
|
|
543
|
+
/** When true, mirror elements use pointer-events: auto so DevTools element picker can select them. */
|
|
544
|
+
private _inspectMode;
|
|
545
|
+
/** Async materialization state for inspect mode */
|
|
546
|
+
private _asyncQueue;
|
|
547
|
+
private _asyncIdleHandle;
|
|
548
|
+
private _asyncBatchSize;
|
|
264
549
|
constructor(store: ObjectStore, maxNodes?: number);
|
|
265
550
|
/**
|
|
266
551
|
* Set the root DOM element where the mirror tree will be appended.
|
|
267
552
|
* Typically a hidden div: <div id="three-dom-root" style="display:none">
|
|
268
553
|
*/
|
|
269
554
|
setRoot(rootElement: HTMLElement): void;
|
|
555
|
+
/**
|
|
556
|
+
* Enable or disable "inspect mode". When turning on, kicks off async
|
|
557
|
+
* chunked materialization so the full tree becomes browsable in the
|
|
558
|
+
* Elements tab without blocking the main thread.
|
|
559
|
+
*
|
|
560
|
+
* At BIM scale (100k-200k objects) the old synchronous loop would freeze
|
|
561
|
+
* the page for 2-10s. The new approach uses requestIdleCallback to
|
|
562
|
+
* spread work across idle frames (~200 nodes per idle slice, ~5ms each).
|
|
563
|
+
*/
|
|
564
|
+
setInspectMode(on: boolean): void;
|
|
565
|
+
/** Whether inspect mode is currently enabled. */
|
|
566
|
+
getInspectMode(): boolean;
|
|
270
567
|
/**
|
|
271
568
|
* Build the initial DOM tree from the scene.
|
|
272
569
|
* Materializes the top 2 levels of the scene hierarchy.
|
|
@@ -285,8 +582,14 @@ declare class DomMirror {
|
|
|
285
582
|
/**
|
|
286
583
|
* Remove a DOM node but keep JS metadata in the ObjectStore.
|
|
287
584
|
* Called by LRU eviction or when an object is removed from the scene.
|
|
585
|
+
* Also dematerializes any materialized descendants so they don't become
|
|
586
|
+
* orphaned entries in the LRU / _nodes maps.
|
|
288
587
|
*/
|
|
289
588
|
dematerialize(uuid: string): void;
|
|
589
|
+
/**
|
|
590
|
+
* Collect all materialized descendants of a uuid by walking _parentMap.
|
|
591
|
+
*/
|
|
592
|
+
private _collectMaterializedDescendants;
|
|
290
593
|
/**
|
|
291
594
|
* Called when a new object is added to the tracked scene.
|
|
292
595
|
* Only materializes if the parent is already materialized (lazy expansion).
|
|
@@ -315,6 +618,14 @@ declare class DomMirror {
|
|
|
315
618
|
* Get the materialized DOM element for an object, if it exists.
|
|
316
619
|
*/
|
|
317
620
|
getElement(uuid: string): HTMLElement | null;
|
|
621
|
+
/**
|
|
622
|
+
* Get or lazily materialize a DOM element for an object.
|
|
623
|
+
* Also materializes the ancestor chain so the element is correctly
|
|
624
|
+
* nested in the DOM tree. Used by InspectController so that
|
|
625
|
+
* hover/click always produces a valid mirror element regardless
|
|
626
|
+
* of whether async materialization has reached it yet.
|
|
627
|
+
*/
|
|
628
|
+
getOrMaterialize(uuid: string): HTMLElement | null;
|
|
318
629
|
/**
|
|
319
630
|
* Check if an object has a materialized DOM node.
|
|
320
631
|
*/
|
|
@@ -346,6 +657,14 @@ declare class DomMirror {
|
|
|
346
657
|
* Insert a newly created element into the correct position in the DOM tree.
|
|
347
658
|
*/
|
|
348
659
|
private _insertIntoDom;
|
|
660
|
+
/**
|
|
661
|
+
* Materialize all ancestors of a uuid from root down, so the target
|
|
662
|
+
* element will be correctly nested when materialized.
|
|
663
|
+
*/
|
|
664
|
+
private _materializeAncestorChain;
|
|
665
|
+
private _startAsyncMaterialization;
|
|
666
|
+
private _cancelAsyncMaterialization;
|
|
667
|
+
private _scheduleAsyncChunk;
|
|
349
668
|
/**
|
|
350
669
|
* Parse common CSS selector patterns and resolve to a uuid from the store.
|
|
351
670
|
* Supports:
|
|
@@ -369,6 +688,15 @@ declare class DomMirror {
|
|
|
369
688
|
private _evictLRU;
|
|
370
689
|
}
|
|
371
690
|
|
|
691
|
+
/**
|
|
692
|
+
* @module CustomElements
|
|
693
|
+
*
|
|
694
|
+
* Defines and registers the custom HTML elements (<three-scene>, <three-mesh>,
|
|
695
|
+
* <three-light>, etc.) used by DomMirror to represent Three.js objects in the
|
|
696
|
+
* DOM. The ThreeElement base class exposes interactive properties (metadata,
|
|
697
|
+
* inspect, object3D) accessible from the DevTools console via `$0.metadata`.
|
|
698
|
+
*/
|
|
699
|
+
|
|
372
700
|
/**
|
|
373
701
|
* Maps Three.js object types to custom element tag names.
|
|
374
702
|
* Multiple Three.js types can map to the same tag.
|
|
@@ -460,6 +788,14 @@ declare class ThreeElement extends HTMLElement {
|
|
|
460
788
|
*/
|
|
461
789
|
declare function ensureCustomElements(store: ObjectStore): void;
|
|
462
790
|
|
|
791
|
+
/**
|
|
792
|
+
* @module attributes
|
|
793
|
+
*
|
|
794
|
+
* Serializes ObjectStore Tier 1 metadata into DOM data-attributes and applies
|
|
795
|
+
* them to mirror elements with minimal DOM writes. Only attributes whose values
|
|
796
|
+
* actually changed are written, keeping per-frame cost near zero for static objects.
|
|
797
|
+
*/
|
|
798
|
+
|
|
463
799
|
/** All attribute names we manage (for diffing). */
|
|
464
800
|
declare const MANAGED_ATTRIBUTES: string[];
|
|
465
801
|
/**
|
|
@@ -479,7 +815,20 @@ declare function computeAttributes(meta: ObjectMetadata): Map<string, string>;
|
|
|
479
815
|
*/
|
|
480
816
|
declare function applyAttributes(element: HTMLElement, meta: ObjectMetadata, prevAttrs: Map<string, string>): number;
|
|
481
817
|
|
|
818
|
+
/**
|
|
819
|
+
* @module SelectionManager
|
|
820
|
+
*
|
|
821
|
+
* Lightweight selection state manager for 3D objects. Supports single and
|
|
822
|
+
* multi-selection, notifies listeners on change so Highlighter and the
|
|
823
|
+
* devtools inspector panel can react. Decoupled from rendering — purely
|
|
824
|
+
* manages which Object3D references are "selected".
|
|
825
|
+
*/
|
|
826
|
+
|
|
482
827
|
type SelectionListener = (selected: Object3D[]) => void;
|
|
828
|
+
/**
|
|
829
|
+
* Tracks the set of currently selected Object3D instances and notifies
|
|
830
|
+
* subscribers when the selection changes.
|
|
831
|
+
*/
|
|
483
832
|
declare class SelectionManager {
|
|
484
833
|
/** Currently selected objects (ordered by selection time). */
|
|
485
834
|
private _selected;
|
|
@@ -509,68 +858,222 @@ declare class SelectionManager {
|
|
|
509
858
|
dispose(): void;
|
|
510
859
|
}
|
|
511
860
|
|
|
861
|
+
/**
|
|
862
|
+
* @module Highlighter
|
|
863
|
+
*
|
|
864
|
+
* Renders Chrome DevTools-style translucent fill overlays on hovered and
|
|
865
|
+
* selected Three.js objects. Subscribes to SelectionManager for selection
|
|
866
|
+
* state and polls `window.__r3fdom_hovered__` for DevTools element-picker
|
|
867
|
+
* hover. Highlight meshes are marked `__r3fdom_internal` so they're excluded
|
|
868
|
+
* from raycasting and the ObjectStore.
|
|
869
|
+
*/
|
|
870
|
+
|
|
512
871
|
interface HighlighterOptions {
|
|
513
|
-
/** Whether to show a tooltip above highlighted objects. Default: true */
|
|
514
872
|
showTooltip?: boolean;
|
|
515
873
|
}
|
|
874
|
+
/**
|
|
875
|
+
* Manages hover and selection highlight overlays in the 3D scene.
|
|
876
|
+
* Attaches to a Scene + SelectionManager and creates/disposes translucent
|
|
877
|
+
* mesh clones that track the source object's world transform each frame.
|
|
878
|
+
*/
|
|
516
879
|
declare class Highlighter {
|
|
517
|
-
|
|
518
|
-
private _selectedEntries;
|
|
519
|
-
/** Hover overlay (temporary, single object at a time) */
|
|
520
|
-
private _hoverEntries;
|
|
521
|
-
private _camera;
|
|
522
|
-
private _renderer;
|
|
880
|
+
private _scene;
|
|
523
881
|
private _unsubscribe;
|
|
524
|
-
private
|
|
525
|
-
|
|
882
|
+
private _hoverEntries;
|
|
883
|
+
private _hoverTarget;
|
|
884
|
+
private _selectedEntries;
|
|
526
885
|
private _hoverPollId;
|
|
527
|
-
private
|
|
528
|
-
/** Store reference for resolving objects */
|
|
886
|
+
private _lastHoveredUuid;
|
|
529
887
|
private _store;
|
|
530
|
-
constructor(
|
|
531
|
-
|
|
888
|
+
constructor(_options?: HighlighterOptions);
|
|
889
|
+
/** Bind to a scene and selection manager, start hover polling. */
|
|
890
|
+
attach(scene: Scene, selectionManager: SelectionManager, _camera: Camera, _renderer: WebGLRenderer, store: {
|
|
532
891
|
getObject3D(uuid: string): Object3D | null;
|
|
533
892
|
}): void;
|
|
893
|
+
/** Unbind from the scene, stop polling, and remove all highlights. */
|
|
534
894
|
detach(): void;
|
|
895
|
+
/** Sync highlight group transforms to their source objects. Call each frame. */
|
|
535
896
|
update(): void;
|
|
536
|
-
highlight(
|
|
537
|
-
unhighlight(obj: Object3D): void;
|
|
538
|
-
clearAll(): void;
|
|
539
|
-
isHighlighted(obj: Object3D): boolean;
|
|
540
|
-
/** Show a temporary hover highlight for an object and its children */
|
|
897
|
+
/** Show a hover highlight on the given object (replaces any previous hover). */
|
|
541
898
|
showHoverHighlight(obj: Object3D): void;
|
|
542
|
-
/**
|
|
899
|
+
/** Remove the current hover highlight. */
|
|
543
900
|
clearHoverHighlight(): void;
|
|
544
|
-
private
|
|
545
|
-
|
|
546
|
-
|
|
901
|
+
private _clearHoverVisuals;
|
|
902
|
+
/** Check if an object currently has a selection highlight. */
|
|
903
|
+
isHighlighted(obj: Object3D): boolean;
|
|
904
|
+
/** Remove all hover and selection highlights. */
|
|
905
|
+
clearAll(): void;
|
|
906
|
+
private _syncSelectionHighlights;
|
|
907
|
+
private _addSelectionHighlight;
|
|
908
|
+
private _removeSelectionHighlight;
|
|
909
|
+
private _clearAllSelectionHighlights;
|
|
547
910
|
private _startHoverPolling;
|
|
548
911
|
private _stopHoverPolling;
|
|
549
912
|
private _pollDevToolsHover;
|
|
550
|
-
private
|
|
551
|
-
|
|
913
|
+
private _disposeHighlightGroup;
|
|
914
|
+
/** Detach and release all resources. */
|
|
915
|
+
dispose(): void;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* @module RaycastAccelerator
|
|
920
|
+
*
|
|
921
|
+
* Two-layer acceleration structure for BIM-scale raycasting (100k+ objects).
|
|
922
|
+
* Layer 1 maintains a pre-filtered flat list of raycastable meshes from the
|
|
923
|
+
* ObjectStore (avoids recursive scene traversal). Layer 2 uses three-mesh-bvh
|
|
924
|
+
* to build per-geometry BVH trees, turning per-mesh triangle intersection
|
|
925
|
+
* from O(t) brute-force into O(log t). Combined: ~0.01–0.1ms at 200k objects.
|
|
926
|
+
*/
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Maintains an accelerated raycast target list and per-geometry BVH trees.
|
|
930
|
+
* Rebuilds lazily when the ObjectStore emits changes, with a per-rebuild
|
|
931
|
+
* BVH budget to avoid blocking the main thread on large model loads.
|
|
932
|
+
*/
|
|
933
|
+
declare class RaycastAccelerator {
|
|
934
|
+
private _store;
|
|
935
|
+
private _targets;
|
|
936
|
+
private _dirty;
|
|
937
|
+
private _unsubscribe;
|
|
938
|
+
private _bvhBuiltFor;
|
|
939
|
+
constructor(store: ObjectStore);
|
|
940
|
+
/** Force a target list rebuild on the next raycast. */
|
|
941
|
+
markDirty(): void;
|
|
942
|
+
private _rebuild;
|
|
943
|
+
/**
|
|
944
|
+
* Build a BVH for a mesh's geometry if it doesn't have one yet.
|
|
945
|
+
* Uses indirect mode to avoid modifying the index buffer.
|
|
946
|
+
* Skips disposed geometries and does NOT mark failed builds so they
|
|
947
|
+
* can be retried (e.g. after geometry is re-uploaded).
|
|
948
|
+
*/
|
|
949
|
+
private _ensureBVH;
|
|
950
|
+
/**
|
|
951
|
+
* Raycast from mouse position against only raycastable meshes.
|
|
952
|
+
* Returns the closest non-internal hit, or null.
|
|
953
|
+
*/
|
|
954
|
+
raycastAtMouse(e: MouseEvent, camera: Camera, canvas: HTMLCanvasElement): Object3D | null;
|
|
955
|
+
/**
|
|
956
|
+
* Raycast from NDC coordinates. Used by raycastVerify.
|
|
957
|
+
*/
|
|
958
|
+
raycastAtNdc(ndcX: number, ndcY: number, camera: Camera): Intersection[];
|
|
959
|
+
/** Current number of raycastable targets. */
|
|
960
|
+
get targetCount(): number;
|
|
961
|
+
/** Unsubscribe from the store and release the target list. */
|
|
962
|
+
dispose(): void;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* @module InspectController
|
|
967
|
+
*
|
|
968
|
+
* Chrome DevTools-style inspect mode for 3D scenes. When enabled, places a
|
|
969
|
+
* transparent overlay on top of the WebGL canvas that intercepts all pointer
|
|
970
|
+
* events (preventing R3F's event system and camera controls from consuming
|
|
971
|
+
* them), raycasts to identify the object under the cursor, drives
|
|
972
|
+
* hover/selection highlights, and sets a global reference so the DevTools
|
|
973
|
+
* extension can reveal the corresponding mirror DOM node.
|
|
974
|
+
* Zero overhead when disabled — no overlay, no listeners.
|
|
975
|
+
*/
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Manages the inspect-mode lifecycle: creates/removes an overlay div,
|
|
979
|
+
* throttles raycasts, and coordinates Highlighter + SelectionManager + DomMirror.
|
|
980
|
+
*/
|
|
981
|
+
declare class InspectController {
|
|
982
|
+
private _active;
|
|
983
|
+
private _camera;
|
|
984
|
+
private _renderer;
|
|
985
|
+
private _selectionManager;
|
|
986
|
+
private _highlighter;
|
|
987
|
+
private _raycastAccelerator;
|
|
988
|
+
private _mirror;
|
|
989
|
+
private _store;
|
|
990
|
+
private _lastRaycastTime;
|
|
991
|
+
private _hoveredObject;
|
|
992
|
+
private _hoverRevealTimer;
|
|
993
|
+
private _overlay;
|
|
994
|
+
private _boundPointerMove;
|
|
995
|
+
private _boundPointerDown;
|
|
996
|
+
private _boundContextMenu;
|
|
997
|
+
constructor(opts: {
|
|
998
|
+
camera: Camera;
|
|
999
|
+
renderer: WebGLRenderer;
|
|
1000
|
+
selectionManager: SelectionManager;
|
|
1001
|
+
highlighter: Highlighter;
|
|
1002
|
+
raycastAccelerator: RaycastAccelerator;
|
|
1003
|
+
mirror: DomMirror;
|
|
1004
|
+
store: {
|
|
1005
|
+
getObject3D(uuid: string): Object3D | null;
|
|
1006
|
+
};
|
|
1007
|
+
});
|
|
1008
|
+
get active(): boolean;
|
|
1009
|
+
/** Update the camera reference (e.g. after a camera switch). */
|
|
1010
|
+
updateCamera(camera: Camera): void;
|
|
1011
|
+
/** Activate inspect mode — creates overlay on top of canvas. */
|
|
1012
|
+
enable(): void;
|
|
1013
|
+
/** Deactivate inspect mode — removes overlay and clears hover state. */
|
|
1014
|
+
disable(): void;
|
|
1015
|
+
/** Disable and release all resources. */
|
|
552
1016
|
dispose(): void;
|
|
1017
|
+
private _raycastFromEvent;
|
|
1018
|
+
/**
|
|
1019
|
+
* Resolve a raw raycast hit to the logical selection target.
|
|
1020
|
+
* Walks up to find the best Group parent if applicable.
|
|
1021
|
+
*/
|
|
1022
|
+
private _resolveTarget;
|
|
1023
|
+
private _onPointerMove;
|
|
1024
|
+
/**
|
|
1025
|
+
* After hovering an object for HOVER_REVEAL_DEBOUNCE_MS, auto-reveal its
|
|
1026
|
+
* mirror element in the Elements tab.
|
|
1027
|
+
*/
|
|
1028
|
+
private _scheduleHoverReveal;
|
|
1029
|
+
private _cancelHoverReveal;
|
|
1030
|
+
private _onPointerDown;
|
|
553
1031
|
}
|
|
554
1032
|
|
|
555
1033
|
interface ThreeDomProps {
|
|
1034
|
+
/**
|
|
1035
|
+
* Unique identifier for this canvas instance. Required when using multiple
|
|
1036
|
+
* canvases. The bridge is registered in `window.__R3F_DOM_INSTANCES__[canvasId]`.
|
|
1037
|
+
* When omitted the bridge is only set on `window.__R3F_DOM__`.
|
|
1038
|
+
*/
|
|
1039
|
+
canvasId?: string;
|
|
1040
|
+
/**
|
|
1041
|
+
* Mark this canvas as the primary / default instance.
|
|
1042
|
+
* `window.__R3F_DOM__` always points to the primary bridge.
|
|
1043
|
+
* When only one canvas is used (no canvasId), it is implicitly primary.
|
|
1044
|
+
* Default: true when canvasId is omitted, false otherwise.
|
|
1045
|
+
*/
|
|
1046
|
+
primary?: boolean;
|
|
556
1047
|
/** CSS selector or HTMLElement for the mirror DOM root. Default: "#three-dom-root" */
|
|
557
1048
|
root?: string | HTMLElement;
|
|
558
1049
|
/** Objects to process per amortized batch per frame. Default: 500 */
|
|
559
1050
|
batchSize?: number;
|
|
560
1051
|
/** Max time budget (ms) for sync work per frame. Default: 0.5 */
|
|
561
|
-
|
|
1052
|
+
syncBudgetMs?: number;
|
|
562
1053
|
/** Max materialized DOM nodes (LRU eviction). Default: 2000 */
|
|
563
1054
|
maxDomNodes?: number;
|
|
564
1055
|
/** Initial DOM tree materialization depth. Default: 3 */
|
|
565
1056
|
initialDepth?: number;
|
|
566
1057
|
/** Disable all sync. Default: true */
|
|
567
1058
|
enabled?: boolean;
|
|
1059
|
+
/** Enable debug logging to browser console. Default: false */
|
|
1060
|
+
debug?: boolean;
|
|
1061
|
+
/** Enable inspect mode on mount. Default: false */
|
|
1062
|
+
inspect?: boolean;
|
|
568
1063
|
}
|
|
569
|
-
|
|
570
|
-
declare function
|
|
571
|
-
|
|
572
|
-
declare function
|
|
573
|
-
|
|
1064
|
+
/** Get the store for a canvas instance. Default: primary ('') instance. */
|
|
1065
|
+
declare function getStore(canvasId?: string): ObjectStore | null;
|
|
1066
|
+
/** Get the mirror for a canvas instance. Default: primary ('') instance. */
|
|
1067
|
+
declare function getMirror(canvasId?: string): DomMirror | null;
|
|
1068
|
+
/** Get the selection manager for a canvas instance. */
|
|
1069
|
+
declare function getSelectionManager(canvasId?: string): SelectionManager | null;
|
|
1070
|
+
/** Get the highlighter for a canvas instance. */
|
|
1071
|
+
declare function getHighlighter(canvasId?: string): Highlighter | null;
|
|
1072
|
+
/** Get the inspect controller for a canvas instance. */
|
|
1073
|
+
declare function getInspectController(canvasId?: string): InspectController | null;
|
|
1074
|
+
/** List all active canvas IDs. */
|
|
1075
|
+
declare function getCanvasIds(): string[];
|
|
1076
|
+
declare function ThreeDom({ canvasId, primary, root, batchSize, syncBudgetMs, maxDomNodes, initialDepth, enabled, debug, inspect: inspectProp, }?: ThreeDomProps): null;
|
|
574
1077
|
|
|
575
1078
|
/**
|
|
576
1079
|
* Patch Object3D.prototype.add and Object3D.prototype.remove to intercept
|
|
@@ -622,6 +1125,16 @@ declare function createFlatSnapshot(store: ObjectStore): {
|
|
|
622
1125
|
objects: ObjectMetadata[];
|
|
623
1126
|
};
|
|
624
1127
|
|
|
1128
|
+
/**
|
|
1129
|
+
* @module projection
|
|
1130
|
+
*
|
|
1131
|
+
* Projects Three.js objects from world space to screen-space CSS pixel
|
|
1132
|
+
* coordinates using a multi-strategy approach (bbox center → face centers →
|
|
1133
|
+
* corners → origin fallback). Also provides frustum visibility checks and
|
|
1134
|
+
* screen-to-world conversion for drag deltas. Core utility used by all
|
|
1135
|
+
* interaction modules to determine where to dispatch synthetic events.
|
|
1136
|
+
*/
|
|
1137
|
+
|
|
625
1138
|
/** Screen-space coordinates in CSS pixels relative to the canvas. */
|
|
626
1139
|
interface ScreenPoint {
|
|
627
1140
|
/** X coordinate in CSS pixels, left = 0. */
|
|
@@ -680,6 +1193,15 @@ declare function screenDeltaToWorld(dx: number, dy: number, obj: Object3D, camer
|
|
|
680
1193
|
*/
|
|
681
1194
|
declare function projectAllSamplePoints(obj: Object3D, camera: Camera, size: CanvasSize): ScreenPoint[];
|
|
682
1195
|
|
|
1196
|
+
/**
|
|
1197
|
+
* @module raycastVerify
|
|
1198
|
+
*
|
|
1199
|
+
* Post-dispatch raycast verification for interaction modules. After a synthetic
|
|
1200
|
+
* event is dispatched at projected screen coordinates, casts a ray to confirm
|
|
1201
|
+
* the intended object is actually the frontmost hit. Reports occlusion with
|
|
1202
|
+
* the identity of the occluding object for clear error messages.
|
|
1203
|
+
*/
|
|
1204
|
+
|
|
683
1205
|
/** Result of a raycast verification. */
|
|
684
1206
|
interface RaycastResult {
|
|
685
1207
|
/** Whether the intended object was hit. */
|
|
@@ -831,6 +1353,15 @@ declare function hover3D(idOrUuid: string, options?: Hover3DOptions): Hover3DRes
|
|
|
831
1353
|
*/
|
|
832
1354
|
declare function unhover3D(): void;
|
|
833
1355
|
|
|
1356
|
+
/**
|
|
1357
|
+
* @module dispatch
|
|
1358
|
+
*
|
|
1359
|
+
* Low-level synthetic PointerEvent/MouseEvent/WheelEvent dispatch on the
|
|
1360
|
+
* canvas element. Produces the exact DOM event sequences that R3F's internal
|
|
1361
|
+
* event system expects (e.g. pointerdown → pointerup → click). All higher-level
|
|
1362
|
+
* interaction modules (click3D, hover3D, drag3D, etc.) delegate here.
|
|
1363
|
+
*/
|
|
1364
|
+
|
|
834
1365
|
/**
|
|
835
1366
|
* Dispatch a full click sequence on the canvas at the given screen point.
|
|
836
1367
|
*
|
|
@@ -914,6 +1445,15 @@ declare function dispatchPointerMiss(canvas: HTMLCanvasElement, point?: ScreenPo
|
|
|
914
1445
|
*/
|
|
915
1446
|
declare function dispatchUnhover(canvas: HTMLCanvasElement): void;
|
|
916
1447
|
|
|
1448
|
+
/**
|
|
1449
|
+
* @module drag
|
|
1450
|
+
*
|
|
1451
|
+
* Deterministic drag interactions on 3D objects. Supports world-space deltas
|
|
1452
|
+
* (move N units along an axis) and screen-space deltas (move N pixels).
|
|
1453
|
+
* Projects start/end points and dispatches a full pointerdown → pointermove × N
|
|
1454
|
+
* → pointerup sequence on the canvas.
|
|
1455
|
+
*/
|
|
1456
|
+
|
|
917
1457
|
/** World-space drag delta. */
|
|
918
1458
|
interface WorldDelta {
|
|
919
1459
|
x: number;
|
|
@@ -1045,10 +1585,185 @@ interface PointerMiss3DOptions {
|
|
|
1045
1585
|
*/
|
|
1046
1586
|
declare function pointerMiss3D(options?: PointerMiss3DOptions): void;
|
|
1047
1587
|
|
|
1588
|
+
/** A 2D screen-space point in CSS pixels, relative to the canvas top-left. */
|
|
1589
|
+
interface DrawPoint {
|
|
1590
|
+
/** X coordinate in CSS pixels from canvas left edge. */
|
|
1591
|
+
x: number;
|
|
1592
|
+
/** Y coordinate in CSS pixels from canvas top edge. */
|
|
1593
|
+
y: number;
|
|
1594
|
+
/** Optional pressure (0–1). Default: 0.5 */
|
|
1595
|
+
pressure?: number;
|
|
1596
|
+
}
|
|
1597
|
+
/** Options for drawPath. */
|
|
1598
|
+
interface DrawPathOptions {
|
|
1599
|
+
/**
|
|
1600
|
+
* Delay in milliseconds between successive pointermove events.
|
|
1601
|
+
* Useful for apps that sample pointer events per-frame.
|
|
1602
|
+
* Default: 0 (dispatch all moves synchronously, which is fastest)
|
|
1603
|
+
*/
|
|
1604
|
+
stepDelayMs?: number;
|
|
1605
|
+
/**
|
|
1606
|
+
* Pointer type. Some drawing apps differentiate between mouse and pen.
|
|
1607
|
+
* Default: 'mouse'
|
|
1608
|
+
*/
|
|
1609
|
+
pointerType?: 'mouse' | 'pen' | 'touch';
|
|
1610
|
+
/**
|
|
1611
|
+
* If true, also dispatches a 'click' event at the end of the path.
|
|
1612
|
+
* Useful if the app interprets short strokes as clicks.
|
|
1613
|
+
* Default: false
|
|
1614
|
+
*/
|
|
1615
|
+
clickAtEnd?: boolean;
|
|
1616
|
+
/**
|
|
1617
|
+
* If provided, draws on a specific canvas element.
|
|
1618
|
+
* Default: the R3F canvas (from the current renderer).
|
|
1619
|
+
*/
|
|
1620
|
+
canvas?: HTMLCanvasElement;
|
|
1621
|
+
}
|
|
1622
|
+
/** Result of a drawPath operation. */
|
|
1623
|
+
interface DrawPathResult {
|
|
1624
|
+
/** Total number of pointer events dispatched. */
|
|
1625
|
+
eventCount: number;
|
|
1626
|
+
/** The number of points in the path. */
|
|
1627
|
+
pointCount: number;
|
|
1628
|
+
/** First point of the path. */
|
|
1629
|
+
startPoint: DrawPoint;
|
|
1630
|
+
/** Last point of the path. */
|
|
1631
|
+
endPoint: DrawPoint;
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Simulate a freeform drawing stroke on the canvas.
|
|
1635
|
+
*
|
|
1636
|
+
* Dispatches a full pointer sequence through the provided path of points:
|
|
1637
|
+
* `pointerdown` at the first point, `pointermove` at each subsequent point,
|
|
1638
|
+
* and `pointerup` at the last point.
|
|
1639
|
+
*
|
|
1640
|
+
* This is designed for canvas drawing applications (e.g. whiteboard, annotation
|
|
1641
|
+
* tools, CAD sketch mode) that respond to pointer events to create geometry.
|
|
1642
|
+
*
|
|
1643
|
+
* @param points Array of screen-space points (min 2 required)
|
|
1644
|
+
* @param options Drawing options
|
|
1645
|
+
* @returns Result with event counts and start/end points
|
|
1646
|
+
* @throws If fewer than 2 points are provided
|
|
1647
|
+
*
|
|
1648
|
+
* @example
|
|
1649
|
+
* ```typescript
|
|
1650
|
+
* // Draw a simple line from (100, 100) to (300, 200)
|
|
1651
|
+
* await drawPath([
|
|
1652
|
+
* { x: 100, y: 100 },
|
|
1653
|
+
* { x: 200, y: 150 },
|
|
1654
|
+
* { x: 300, y: 200 },
|
|
1655
|
+
* ]);
|
|
1656
|
+
*
|
|
1657
|
+
* // Draw with pen pressure simulation
|
|
1658
|
+
* await drawPath([
|
|
1659
|
+
* { x: 50, y: 50, pressure: 0.2 },
|
|
1660
|
+
* { x: 100, y: 80, pressure: 0.6 },
|
|
1661
|
+
* { x: 150, y: 70, pressure: 0.9 },
|
|
1662
|
+
* { x: 200, y: 60, pressure: 0.4 },
|
|
1663
|
+
* ], { pointerType: 'pen', stepDelayMs: 16 });
|
|
1664
|
+
* ```
|
|
1665
|
+
*/
|
|
1666
|
+
declare function drawPath(points: DrawPoint[], options?: DrawPathOptions): Promise<DrawPathResult>;
|
|
1667
|
+
/**
|
|
1668
|
+
* Generate an array of DrawPoints along a straight line.
|
|
1669
|
+
* Useful for creating uniform stroke paths programmatically.
|
|
1670
|
+
*
|
|
1671
|
+
* @param start Start point (screen-space CSS pixels)
|
|
1672
|
+
* @param end End point (screen-space CSS pixels)
|
|
1673
|
+
* @param steps Number of intermediate points (excluding start/end). Default: 10
|
|
1674
|
+
* @param pressure Uniform pressure for all points. Default: 0.5
|
|
1675
|
+
* @returns Array of DrawPoints including start and end
|
|
1676
|
+
*
|
|
1677
|
+
* @example
|
|
1678
|
+
* ```typescript
|
|
1679
|
+
* const points = linePath({ x: 0, y: 0 }, { x: 200, y: 200 }, 20);
|
|
1680
|
+
* await drawPath(points);
|
|
1681
|
+
* ```
|
|
1682
|
+
*/
|
|
1683
|
+
declare function linePath(start: {
|
|
1684
|
+
x: number;
|
|
1685
|
+
y: number;
|
|
1686
|
+
}, end: {
|
|
1687
|
+
x: number;
|
|
1688
|
+
y: number;
|
|
1689
|
+
}, steps?: number, pressure?: number): DrawPoint[];
|
|
1690
|
+
/**
|
|
1691
|
+
* Generate an array of DrawPoints along a quadratic bezier curve.
|
|
1692
|
+
* Great for simulating smooth freehand drawing strokes.
|
|
1693
|
+
*
|
|
1694
|
+
* @param start Start point
|
|
1695
|
+
* @param control Control point (determines curve shape)
|
|
1696
|
+
* @param end End point
|
|
1697
|
+
* @param steps Number of steps. Default: 20
|
|
1698
|
+
* @param pressure Uniform pressure. Default: 0.5
|
|
1699
|
+
* @returns Array of DrawPoints along the curve
|
|
1700
|
+
*
|
|
1701
|
+
* @example
|
|
1702
|
+
* ```typescript
|
|
1703
|
+
* const points = curvePath(
|
|
1704
|
+
* { x: 50, y: 200 }, // start
|
|
1705
|
+
* { x: 150, y: 50 }, // control (peak of the curve)
|
|
1706
|
+
* { x: 250, y: 200 }, // end
|
|
1707
|
+
* 30,
|
|
1708
|
+
* );
|
|
1709
|
+
* await drawPath(points);
|
|
1710
|
+
* ```
|
|
1711
|
+
*/
|
|
1712
|
+
declare function curvePath(start: {
|
|
1713
|
+
x: number;
|
|
1714
|
+
y: number;
|
|
1715
|
+
}, control: {
|
|
1716
|
+
x: number;
|
|
1717
|
+
y: number;
|
|
1718
|
+
}, end: {
|
|
1719
|
+
x: number;
|
|
1720
|
+
y: number;
|
|
1721
|
+
}, steps?: number, pressure?: number): DrawPoint[];
|
|
1722
|
+
/**
|
|
1723
|
+
* Generate an array of DrawPoints forming a rectangle.
|
|
1724
|
+
* Useful for drawing rectangular selections or bounding boxes.
|
|
1725
|
+
*
|
|
1726
|
+
* @param topLeft Top-left corner
|
|
1727
|
+
* @param bottomRight Bottom-right corner
|
|
1728
|
+
* @param pointsPerSide Number of points per side. Default: 5
|
|
1729
|
+
* @param pressure Uniform pressure. Default: 0.5
|
|
1730
|
+
* @returns Array of DrawPoints tracing the rectangle
|
|
1731
|
+
*/
|
|
1732
|
+
declare function rectPath(topLeft: {
|
|
1733
|
+
x: number;
|
|
1734
|
+
y: number;
|
|
1735
|
+
}, bottomRight: {
|
|
1736
|
+
x: number;
|
|
1737
|
+
y: number;
|
|
1738
|
+
}, pointsPerSide?: number, pressure?: number): DrawPoint[];
|
|
1739
|
+
/**
|
|
1740
|
+
* Generate an array of DrawPoints forming a circle/ellipse.
|
|
1741
|
+
*
|
|
1742
|
+
* @param center Center of the circle (screen-space)
|
|
1743
|
+
* @param radiusX Horizontal radius in CSS pixels
|
|
1744
|
+
* @param radiusY Vertical radius in CSS pixels. Default: same as radiusX (circle)
|
|
1745
|
+
* @param steps Number of points. Default: 36 (10° increments)
|
|
1746
|
+
* @param pressure Uniform pressure. Default: 0.5
|
|
1747
|
+
* @returns Array of DrawPoints forming the circle
|
|
1748
|
+
*/
|
|
1749
|
+
declare function circlePath(center: {
|
|
1750
|
+
x: number;
|
|
1751
|
+
y: number;
|
|
1752
|
+
}, radiusX: number, radiusY?: number, steps?: number, pressure?: number): DrawPoint[];
|
|
1753
|
+
|
|
1754
|
+
/**
|
|
1755
|
+
* @module resolve
|
|
1756
|
+
*
|
|
1757
|
+
* Shared resolution helpers for all interaction modules. Caches references
|
|
1758
|
+
* to the current ObjectStore, Camera, WebGLRenderer, and canvas size (set
|
|
1759
|
+
* by ThreeDom each frame) so interaction functions can resolve objects and
|
|
1760
|
+
* access rendering state without prop-drilling.
|
|
1761
|
+
*/
|
|
1762
|
+
|
|
1048
1763
|
/**
|
|
1049
1764
|
* Resolve a testId or uuid to a live Object3D reference.
|
|
1050
1765
|
* Throws a descriptive error if the object is not found.
|
|
1051
1766
|
*/
|
|
1052
1767
|
declare function resolveObject(idOrUuid: string): Object3D;
|
|
1053
1768
|
|
|
1054
|
-
export { type CanvasSize, type Click3DOptions, type Click3DResult, DomMirror, type Drag3DOptions, type Drag3DResult, type DragOptions, type GeometryInspection, Highlighter, type HighlighterOptions, type Hover3DOptions, type Hover3DResult, MANAGED_ATTRIBUTES, type MaterialInspection, type ObjectInspection, type ObjectMetadata, ObjectStore, type PointerMiss3DOptions, type ProjectionResult, type R3FDOM, type RaycastResult, type SceneSnapshot, type ScreenDelta, type ScreenPoint, type SelectionListener, SelectionManager, type SnapshotNode, type StoreEvent, type StoreEventType, type StoreListener, TAG_MAP, ThreeDom, type ThreeDomProps, ThreeElement, type ThreeTagName, type Wheel3DOptions, type Wheel3DResult, type WheelOptions, type WorldDelta, applyAttributes, click3D, computeAttributes, contextMenu3D, createFlatSnapshot, createSnapshot, dispatchClick, dispatchContextMenu, dispatchDoubleClick, dispatchDrag, dispatchHover, dispatchPointerMiss, dispatchUnhover, dispatchWheel, doubleClick3D, drag3D, ensureCustomElements, getHighlighter, getMirror, getSelectionManager, getStore, getTagForType, hover3D, isInFrustum, isPatched, patchObject3D, pointerMiss3D, previewDragWorldDelta, projectAllSamplePoints, projectToScreen, resolveObject, restoreObject3D, screenDeltaToWorld, unhover3D, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|
|
1769
|
+
export { type CameraState, type CanvasSize, type Click3DOptions, type Click3DResult, DomMirror, type Drag3DOptions, type Drag3DResult, type DragOptions, type DrawPathOptions, type DrawPathResult, type DrawPoint, type GeometryInspection, Highlighter, type HighlighterOptions, type Hover3DOptions, type Hover3DResult, InspectController, type InspectOptions, MANAGED_ATTRIBUTES, type MaterialInspection, type ObjectInspection, type ObjectMetadata, ObjectStore, type PointerMiss3DOptions, type ProjectionResult, type R3FDOM, RaycastAccelerator, type RaycastResult, type SceneSnapshot, type ScreenDelta, type ScreenPoint, type SelectionListener, SelectionManager, type SnapshotNode, type StoreEvent, type StoreEventType, type StoreListener, TAG_MAP, ThreeDom, type ThreeDomProps, ThreeElement, type ThreeTagName, type Wheel3DOptions, type Wheel3DResult, type WheelOptions, type WorldDelta, applyAttributes, circlePath, click3D, computeAttributes, contextMenu3D, createFlatSnapshot, createSnapshot, curvePath, dispatchClick, dispatchContextMenu, dispatchDoubleClick, dispatchDrag, dispatchHover, dispatchPointerMiss, dispatchUnhover, dispatchWheel, doubleClick3D, drag3D, drawPath, enableDebug, ensureCustomElements, getCanvasIds, getHighlighter, getInspectController, getMirror, getSelectionManager, getStore, getTagForType, hover3D, isDebugEnabled, isInFrustum, isPatched, linePath, patchObject3D, pointerMiss3D, previewDragWorldDelta, projectAllSamplePoints, projectToScreen, r3fLog, rectPath, resolveObject, restoreObject3D, screenDeltaToWorld, unhover3D, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|