@react-three-dom/core 0.3.0 → 0.4.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 +120 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -5
- package/dist/index.d.ts +63 -5
- package/dist/index.js +121 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Object3D, Scene, Camera, WebGLRenderer, Intersection, Vector3 } from 'three';
|
|
2
2
|
|
|
3
|
-
declare const version = "0.
|
|
3
|
+
declare const version = "0.4.0";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Enable or disable debug logging globally.
|
|
@@ -261,6 +261,17 @@ interface R3FDOM {
|
|
|
261
261
|
setInspectMode(on: boolean): void;
|
|
262
262
|
/** Returns true if inspect mode is currently active. */
|
|
263
263
|
getInspectMode(): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Manually register a Three.js object (and materialize its mirror DOM node).
|
|
266
|
+
* Useful in `manual` mode or to add specific objects in `auto` mode that
|
|
267
|
+
* were excluded by a filter.
|
|
268
|
+
*/
|
|
269
|
+
r3fRegister(obj: Object3D): void;
|
|
270
|
+
/**
|
|
271
|
+
* Unregister a previously registered object and its descendants.
|
|
272
|
+
* Removes the mirror DOM node and store entry.
|
|
273
|
+
*/
|
|
274
|
+
r3fUnregister(obj: Object3D): void;
|
|
264
275
|
/**
|
|
265
276
|
* Manually sweep orphaned objects from the store.
|
|
266
277
|
* Removes objects that are no longer in any tracked scene graph.
|
|
@@ -400,6 +411,8 @@ declare class ObjectStore {
|
|
|
400
411
|
/**
|
|
401
412
|
* Unregister an entire subtree (object + all descendants).
|
|
402
413
|
*/
|
|
414
|
+
/** Mark a root as tracked without traversing/registering its children. */
|
|
415
|
+
addTrackedRoot(root: Object3D): void;
|
|
403
416
|
unregisterTree(root: Object3D): void;
|
|
404
417
|
/**
|
|
405
418
|
* Refresh dynamic Tier 1 fields from the live Three.js object.
|
|
@@ -1010,7 +1023,7 @@ declare class InspectController {
|
|
|
1010
1023
|
updateCamera(camera: Camera): void;
|
|
1011
1024
|
/** Activate inspect mode — creates overlay on top of canvas. */
|
|
1012
1025
|
enable(): void;
|
|
1013
|
-
/** Deactivate inspect mode — removes overlay and clears
|
|
1026
|
+
/** Deactivate inspect mode — removes overlay and clears all inspect state. */
|
|
1014
1027
|
disable(): void;
|
|
1015
1028
|
/** Disable and release all resources. */
|
|
1016
1029
|
dispose(): void;
|
|
@@ -1044,6 +1057,19 @@ interface ThreeDomProps {
|
|
|
1044
1057
|
* Default: true when canvasId is omitted, false otherwise.
|
|
1045
1058
|
*/
|
|
1046
1059
|
primary?: boolean;
|
|
1060
|
+
/**
|
|
1061
|
+
* Registration mode:
|
|
1062
|
+
* - "auto" (default): traverses and registers all objects in the scene.
|
|
1063
|
+
* - "manual": nothing is auto-registered. Use `useR3FRegister` hook or
|
|
1064
|
+
* `__R3F_DOM__.r3fRegister()` to add objects explicitly.
|
|
1065
|
+
*/
|
|
1066
|
+
mode?: 'auto' | 'manual';
|
|
1067
|
+
/**
|
|
1068
|
+
* Filter function for auto mode. Only objects that pass the filter are
|
|
1069
|
+
* registered. Ignored in manual mode.
|
|
1070
|
+
* Example: `filter={(obj) => !!obj.userData.testId}`
|
|
1071
|
+
*/
|
|
1072
|
+
filter?: (obj: Object3D) => boolean;
|
|
1047
1073
|
/** CSS selector or HTMLElement for the mirror DOM root. Default: "#three-dom-root" */
|
|
1048
1074
|
root?: string | HTMLElement;
|
|
1049
1075
|
/** Objects to process per amortized batch per frame. Default: 500 */
|
|
@@ -1073,7 +1099,7 @@ declare function getHighlighter(canvasId?: string): Highlighter | null;
|
|
|
1073
1099
|
declare function getInspectController(canvasId?: string): InspectController | null;
|
|
1074
1100
|
/** List all active canvas IDs. */
|
|
1075
1101
|
declare function getCanvasIds(): string[];
|
|
1076
|
-
declare function ThreeDom({ canvasId, primary, root, batchSize, syncBudgetMs, maxDomNodes, initialDepth, enabled, debug, inspect: inspectProp, }?: ThreeDomProps): null;
|
|
1102
|
+
declare function ThreeDom({ canvasId, primary, root, mode, filter, batchSize, syncBudgetMs, maxDomNodes, initialDepth, enabled, debug, inspect: inspectProp, }?: ThreeDomProps): null;
|
|
1077
1103
|
|
|
1078
1104
|
/**
|
|
1079
1105
|
* Patch Object3D.prototype.add and Object3D.prototype.remove to intercept
|
|
@@ -1083,7 +1109,7 @@ declare function ThreeDom({ canvasId, primary, root, batchSize, syncBudgetMs, ma
|
|
|
1083
1109
|
* @param mirror - The DomMirror managing the parallel DOM tree
|
|
1084
1110
|
* @returns A cleanup function that unregisters this store/mirror pair
|
|
1085
1111
|
*/
|
|
1086
|
-
declare function patchObject3D(store: ObjectStore, mirror: DomMirror): () => void;
|
|
1112
|
+
declare function patchObject3D(store: ObjectStore, mirror: DomMirror, instanceKey?: string): () => void;
|
|
1087
1113
|
/**
|
|
1088
1114
|
* Restore the original Object3D.prototype.add and remove methods.
|
|
1089
1115
|
* Called automatically when the last store/mirror pair is removed.
|
|
@@ -1766,4 +1792,36 @@ declare function circlePath(center: {
|
|
|
1766
1792
|
*/
|
|
1767
1793
|
declare function resolveObject(idOrUuid: string): Object3D;
|
|
1768
1794
|
|
|
1769
|
-
|
|
1795
|
+
/**
|
|
1796
|
+
* Registers a Three.js object with the react-three-dom bridge on mount and
|
|
1797
|
+
* unregisters it on unmount. Works in both `auto` and `manual` mode.
|
|
1798
|
+
*
|
|
1799
|
+
* - In `manual` mode this is the primary way to opt objects into the mirror DOM.
|
|
1800
|
+
* - In `auto` mode it can force-register objects excluded by a `filter`.
|
|
1801
|
+
* - Handles `ref.current` identity changes automatically.
|
|
1802
|
+
* - If the bridge isn't ready on mount, retries each frame until available.
|
|
1803
|
+
* - Supports multi-canvas via the optional `canvasId` parameter.
|
|
1804
|
+
*
|
|
1805
|
+
* @param ref - Ref to the Three.js object to register
|
|
1806
|
+
* @param canvasId - Optional canvas ID for multi-canvas setups. When omitted,
|
|
1807
|
+
* uses the primary bridge (`window.__R3F_DOM__`).
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* ```tsx
|
|
1811
|
+
* function Wall({ geometry }) {
|
|
1812
|
+
* const ref = useRef<Mesh>(null!);
|
|
1813
|
+
* useR3FRegister(ref);
|
|
1814
|
+
* return <mesh ref={ref} geometry={geometry} userData={{ testId: 'wall' }} />;
|
|
1815
|
+
* }
|
|
1816
|
+
*
|
|
1817
|
+
* // Multi-canvas
|
|
1818
|
+
* function Overlay() {
|
|
1819
|
+
* const ref = useRef<Mesh>(null!);
|
|
1820
|
+
* useR3FRegister(ref, 'overlay');
|
|
1821
|
+
* return <mesh ref={ref} />;
|
|
1822
|
+
* }
|
|
1823
|
+
* ```
|
|
1824
|
+
*/
|
|
1825
|
+
declare function useR3FRegister(ref: React.RefObject<Object3D | null>, canvasId?: string): void;
|
|
1826
|
+
|
|
1827
|
+
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, useR3FRegister, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Object3D, Scene, Camera, WebGLRenderer, Intersection, Vector3 } from 'three';
|
|
2
2
|
|
|
3
|
-
declare const version = "0.
|
|
3
|
+
declare const version = "0.4.0";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Enable or disable debug logging globally.
|
|
@@ -261,6 +261,17 @@ interface R3FDOM {
|
|
|
261
261
|
setInspectMode(on: boolean): void;
|
|
262
262
|
/** Returns true if inspect mode is currently active. */
|
|
263
263
|
getInspectMode(): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Manually register a Three.js object (and materialize its mirror DOM node).
|
|
266
|
+
* Useful in `manual` mode or to add specific objects in `auto` mode that
|
|
267
|
+
* were excluded by a filter.
|
|
268
|
+
*/
|
|
269
|
+
r3fRegister(obj: Object3D): void;
|
|
270
|
+
/**
|
|
271
|
+
* Unregister a previously registered object and its descendants.
|
|
272
|
+
* Removes the mirror DOM node and store entry.
|
|
273
|
+
*/
|
|
274
|
+
r3fUnregister(obj: Object3D): void;
|
|
264
275
|
/**
|
|
265
276
|
* Manually sweep orphaned objects from the store.
|
|
266
277
|
* Removes objects that are no longer in any tracked scene graph.
|
|
@@ -400,6 +411,8 @@ declare class ObjectStore {
|
|
|
400
411
|
/**
|
|
401
412
|
* Unregister an entire subtree (object + all descendants).
|
|
402
413
|
*/
|
|
414
|
+
/** Mark a root as tracked without traversing/registering its children. */
|
|
415
|
+
addTrackedRoot(root: Object3D): void;
|
|
403
416
|
unregisterTree(root: Object3D): void;
|
|
404
417
|
/**
|
|
405
418
|
* Refresh dynamic Tier 1 fields from the live Three.js object.
|
|
@@ -1010,7 +1023,7 @@ declare class InspectController {
|
|
|
1010
1023
|
updateCamera(camera: Camera): void;
|
|
1011
1024
|
/** Activate inspect mode — creates overlay on top of canvas. */
|
|
1012
1025
|
enable(): void;
|
|
1013
|
-
/** Deactivate inspect mode — removes overlay and clears
|
|
1026
|
+
/** Deactivate inspect mode — removes overlay and clears all inspect state. */
|
|
1014
1027
|
disable(): void;
|
|
1015
1028
|
/** Disable and release all resources. */
|
|
1016
1029
|
dispose(): void;
|
|
@@ -1044,6 +1057,19 @@ interface ThreeDomProps {
|
|
|
1044
1057
|
* Default: true when canvasId is omitted, false otherwise.
|
|
1045
1058
|
*/
|
|
1046
1059
|
primary?: boolean;
|
|
1060
|
+
/**
|
|
1061
|
+
* Registration mode:
|
|
1062
|
+
* - "auto" (default): traverses and registers all objects in the scene.
|
|
1063
|
+
* - "manual": nothing is auto-registered. Use `useR3FRegister` hook or
|
|
1064
|
+
* `__R3F_DOM__.r3fRegister()` to add objects explicitly.
|
|
1065
|
+
*/
|
|
1066
|
+
mode?: 'auto' | 'manual';
|
|
1067
|
+
/**
|
|
1068
|
+
* Filter function for auto mode. Only objects that pass the filter are
|
|
1069
|
+
* registered. Ignored in manual mode.
|
|
1070
|
+
* Example: `filter={(obj) => !!obj.userData.testId}`
|
|
1071
|
+
*/
|
|
1072
|
+
filter?: (obj: Object3D) => boolean;
|
|
1047
1073
|
/** CSS selector or HTMLElement for the mirror DOM root. Default: "#three-dom-root" */
|
|
1048
1074
|
root?: string | HTMLElement;
|
|
1049
1075
|
/** Objects to process per amortized batch per frame. Default: 500 */
|
|
@@ -1073,7 +1099,7 @@ declare function getHighlighter(canvasId?: string): Highlighter | null;
|
|
|
1073
1099
|
declare function getInspectController(canvasId?: string): InspectController | null;
|
|
1074
1100
|
/** List all active canvas IDs. */
|
|
1075
1101
|
declare function getCanvasIds(): string[];
|
|
1076
|
-
declare function ThreeDom({ canvasId, primary, root, batchSize, syncBudgetMs, maxDomNodes, initialDepth, enabled, debug, inspect: inspectProp, }?: ThreeDomProps): null;
|
|
1102
|
+
declare function ThreeDom({ canvasId, primary, root, mode, filter, batchSize, syncBudgetMs, maxDomNodes, initialDepth, enabled, debug, inspect: inspectProp, }?: ThreeDomProps): null;
|
|
1077
1103
|
|
|
1078
1104
|
/**
|
|
1079
1105
|
* Patch Object3D.prototype.add and Object3D.prototype.remove to intercept
|
|
@@ -1083,7 +1109,7 @@ declare function ThreeDom({ canvasId, primary, root, batchSize, syncBudgetMs, ma
|
|
|
1083
1109
|
* @param mirror - The DomMirror managing the parallel DOM tree
|
|
1084
1110
|
* @returns A cleanup function that unregisters this store/mirror pair
|
|
1085
1111
|
*/
|
|
1086
|
-
declare function patchObject3D(store: ObjectStore, mirror: DomMirror): () => void;
|
|
1112
|
+
declare function patchObject3D(store: ObjectStore, mirror: DomMirror, instanceKey?: string): () => void;
|
|
1087
1113
|
/**
|
|
1088
1114
|
* Restore the original Object3D.prototype.add and remove methods.
|
|
1089
1115
|
* Called automatically when the last store/mirror pair is removed.
|
|
@@ -1766,4 +1792,36 @@ declare function circlePath(center: {
|
|
|
1766
1792
|
*/
|
|
1767
1793
|
declare function resolveObject(idOrUuid: string): Object3D;
|
|
1768
1794
|
|
|
1769
|
-
|
|
1795
|
+
/**
|
|
1796
|
+
* Registers a Three.js object with the react-three-dom bridge on mount and
|
|
1797
|
+
* unregisters it on unmount. Works in both `auto` and `manual` mode.
|
|
1798
|
+
*
|
|
1799
|
+
* - In `manual` mode this is the primary way to opt objects into the mirror DOM.
|
|
1800
|
+
* - In `auto` mode it can force-register objects excluded by a `filter`.
|
|
1801
|
+
* - Handles `ref.current` identity changes automatically.
|
|
1802
|
+
* - If the bridge isn't ready on mount, retries each frame until available.
|
|
1803
|
+
* - Supports multi-canvas via the optional `canvasId` parameter.
|
|
1804
|
+
*
|
|
1805
|
+
* @param ref - Ref to the Three.js object to register
|
|
1806
|
+
* @param canvasId - Optional canvas ID for multi-canvas setups. When omitted,
|
|
1807
|
+
* uses the primary bridge (`window.__R3F_DOM__`).
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* ```tsx
|
|
1811
|
+
* function Wall({ geometry }) {
|
|
1812
|
+
* const ref = useRef<Mesh>(null!);
|
|
1813
|
+
* useR3FRegister(ref);
|
|
1814
|
+
* return <mesh ref={ref} geometry={geometry} userData={{ testId: 'wall' }} />;
|
|
1815
|
+
* }
|
|
1816
|
+
*
|
|
1817
|
+
* // Multi-canvas
|
|
1818
|
+
* function Overlay() {
|
|
1819
|
+
* const ref = useRef<Mesh>(null!);
|
|
1820
|
+
* useR3FRegister(ref, 'overlay');
|
|
1821
|
+
* return <mesh ref={ref} />;
|
|
1822
|
+
* }
|
|
1823
|
+
* ```
|
|
1824
|
+
*/
|
|
1825
|
+
declare function useR3FRegister(ref: React.RefObject<Object3D | null>, canvasId?: string): void;
|
|
1826
|
+
|
|
1827
|
+
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, useR3FRegister, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Box3, Object3D, Vector3, Matrix4, Frustum, Raycaster, Vector2, BufferGeometry, Material, Color, MeshBasicMaterial, DoubleSide, Mesh, BoxGeometry, EdgesGeometry, LineBasicMaterial, LineSegments, InstancedMesh, PerspectiveCamera, OrthographicCamera } from 'three';
|
|
2
|
-
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { useThree, useFrame } from '@react-three/fiber';
|
|
4
4
|
import { computeBoundsTree, disposeBoundsTree, acceleratedRaycast } from 'three-mesh-bvh';
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.4.0";
|
|
8
8
|
|
|
9
9
|
// src/debug.ts
|
|
10
10
|
var _enabled = false;
|
|
@@ -399,6 +399,7 @@ var ObjectStore = class {
|
|
|
399
399
|
this._dirtyQueue.delete(obj);
|
|
400
400
|
this._flatListDirty = true;
|
|
401
401
|
delete obj.userData.__r3fdom_tracked;
|
|
402
|
+
delete obj.userData.__r3fdom_manual;
|
|
402
403
|
if (meta.testId) {
|
|
403
404
|
this._objectsByTestId.delete(meta.testId);
|
|
404
405
|
}
|
|
@@ -419,6 +420,10 @@ var ObjectStore = class {
|
|
|
419
420
|
/**
|
|
420
421
|
* Unregister an entire subtree (object + all descendants).
|
|
421
422
|
*/
|
|
423
|
+
/** Mark a root as tracked without traversing/registering its children. */
|
|
424
|
+
addTrackedRoot(root) {
|
|
425
|
+
this._trackedRoots.add(root);
|
|
426
|
+
}
|
|
422
427
|
unregisterTree(root) {
|
|
423
428
|
root.traverse((obj) => {
|
|
424
429
|
this.unregister(obj);
|
|
@@ -1515,16 +1520,16 @@ function findTrackingPair(obj) {
|
|
|
1515
1520
|
}
|
|
1516
1521
|
return null;
|
|
1517
1522
|
}
|
|
1518
|
-
function registerSubtree(obj, store, mirror) {
|
|
1523
|
+
function registerSubtree(obj, store, mirror, instanceKey) {
|
|
1519
1524
|
obj.traverse((child) => {
|
|
1520
|
-
if (!store.has(child)) {
|
|
1525
|
+
if (!store.has(child) && shouldRegister(instanceKey, child)) {
|
|
1521
1526
|
store.register(child);
|
|
1522
1527
|
mirror.onObjectAdded(child);
|
|
1523
1528
|
}
|
|
1524
1529
|
});
|
|
1525
1530
|
}
|
|
1526
|
-
function patchObject3D(store, mirror) {
|
|
1527
|
-
_activePairs.push({ store, mirror });
|
|
1531
|
+
function patchObject3D(store, mirror, instanceKey = "") {
|
|
1532
|
+
_activePairs.push({ store, mirror, instanceKey });
|
|
1528
1533
|
if (!_patched) {
|
|
1529
1534
|
r3fLog("patch", "Patching Object3D.prototype.add and .remove");
|
|
1530
1535
|
_originalAdd = Object3D.prototype.add;
|
|
@@ -1537,7 +1542,7 @@ function patchObject3D(store, mirror) {
|
|
|
1537
1542
|
if (obj === this) continue;
|
|
1538
1543
|
try {
|
|
1539
1544
|
r3fLog("patch", `patchedAdd: "${obj.name || obj.type}" added to "${this.name || this.type}"`);
|
|
1540
|
-
registerSubtree(obj, pair.store, pair.mirror);
|
|
1545
|
+
registerSubtree(obj, pair.store, pair.mirror, pair.instanceKey);
|
|
1541
1546
|
} catch (err) {
|
|
1542
1547
|
r3fLog("patch", `patchedAdd: failed to register "${obj.name || obj.type}"`, err);
|
|
1543
1548
|
}
|
|
@@ -3096,7 +3101,7 @@ var InspectController = class {
|
|
|
3096
3101
|
this._overlay = overlay;
|
|
3097
3102
|
r3fLog("inspect", "Inspect mode enabled \u2014 hover to highlight, click to select");
|
|
3098
3103
|
}
|
|
3099
|
-
/** Deactivate inspect mode — removes overlay and clears
|
|
3104
|
+
/** Deactivate inspect mode — removes overlay and clears all inspect state. */
|
|
3100
3105
|
disable() {
|
|
3101
3106
|
if (!this._active) return;
|
|
3102
3107
|
this._active = false;
|
|
@@ -3343,6 +3348,15 @@ var _mirrors = /* @__PURE__ */ new Map();
|
|
|
3343
3348
|
var _selectionManagers = /* @__PURE__ */ new Map();
|
|
3344
3349
|
var _highlighters = /* @__PURE__ */ new Map();
|
|
3345
3350
|
var _inspectControllers = /* @__PURE__ */ new Map();
|
|
3351
|
+
var _filters = /* @__PURE__ */ new Map();
|
|
3352
|
+
var _modes = /* @__PURE__ */ new Map();
|
|
3353
|
+
function shouldRegister(instanceKey, obj) {
|
|
3354
|
+
const mode = _modes.get(instanceKey);
|
|
3355
|
+
if (mode === "manual") return false;
|
|
3356
|
+
const filter = _filters.get(instanceKey);
|
|
3357
|
+
if (filter) return filter(obj);
|
|
3358
|
+
return true;
|
|
3359
|
+
}
|
|
3346
3360
|
function getStore2(canvasId = "") {
|
|
3347
3361
|
return _stores.get(canvasId) ?? null;
|
|
3348
3362
|
}
|
|
@@ -3493,6 +3507,31 @@ function exposeGlobalAPI(store, gl, cameraRef, selMgr, inspCtrl, mirror, canvasI
|
|
|
3493
3507
|
}
|
|
3494
3508
|
return state;
|
|
3495
3509
|
},
|
|
3510
|
+
r3fRegister: (obj) => {
|
|
3511
|
+
if (store.has(obj)) return;
|
|
3512
|
+
if (!store.isInTrackedScene(obj)) {
|
|
3513
|
+
console.warn(
|
|
3514
|
+
`[react-three-dom] r3fRegister: object "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" is not in a tracked scene. Add it to the scene graph first.`
|
|
3515
|
+
);
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
obj.userData.__r3fdom_manual = true;
|
|
3519
|
+
store.register(obj);
|
|
3520
|
+
mirror?.onObjectAdded(obj);
|
|
3521
|
+
mirror?.materialize(obj.uuid);
|
|
3522
|
+
r3fLog("bridge", `r3fRegister: "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" (${obj.type})`);
|
|
3523
|
+
},
|
|
3524
|
+
r3fUnregister: (obj) => {
|
|
3525
|
+
if (!store.has(obj)) return;
|
|
3526
|
+
if (!obj.userData?.__r3fdom_manual) {
|
|
3527
|
+
r3fLog("bridge", `r3fUnregister skipped \u2014 "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" was auto-registered`);
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3530
|
+
delete obj.userData.__r3fdom_manual;
|
|
3531
|
+
mirror?.onObjectRemoved(obj);
|
|
3532
|
+
obj.traverse((child) => store.unregister(child));
|
|
3533
|
+
r3fLog("bridge", `r3fUnregister: "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" (${obj.type})`);
|
|
3534
|
+
},
|
|
3496
3535
|
fuzzyFind: (query, limit = 5) => {
|
|
3497
3536
|
const q = query.toLowerCase();
|
|
3498
3537
|
const results = [];
|
|
@@ -3615,6 +3654,10 @@ function createStubBridge(error, canvasId) {
|
|
|
3615
3654
|
setInspectMode: () => {
|
|
3616
3655
|
},
|
|
3617
3656
|
getInspectMode: () => false,
|
|
3657
|
+
r3fRegister: () => {
|
|
3658
|
+
},
|
|
3659
|
+
r3fUnregister: () => {
|
|
3660
|
+
},
|
|
3618
3661
|
sweepOrphans: () => 0,
|
|
3619
3662
|
getDiagnostics: () => ({
|
|
3620
3663
|
version,
|
|
@@ -3649,6 +3692,8 @@ function ThreeDom({
|
|
|
3649
3692
|
canvasId,
|
|
3650
3693
|
primary,
|
|
3651
3694
|
root = "#three-dom-root",
|
|
3695
|
+
mode = "auto",
|
|
3696
|
+
filter,
|
|
3652
3697
|
batchSize = 500,
|
|
3653
3698
|
syncBudgetMs = 0.5,
|
|
3654
3699
|
maxDomNodes = 2e3,
|
|
@@ -3723,18 +3768,38 @@ function ThreeDom({
|
|
|
3723
3768
|
mirror.setRoot(rootElement);
|
|
3724
3769
|
r3fLog("setup", "Store and mirror created");
|
|
3725
3770
|
ensureCustomElements(store);
|
|
3726
|
-
|
|
3771
|
+
_modes.set(instanceKey, mode);
|
|
3772
|
+
_filters.set(instanceKey, filter ?? null);
|
|
3773
|
+
unpatch = patchObject3D(store, mirror, instanceKey);
|
|
3727
3774
|
setInteractionState(store, camera, gl, size);
|
|
3728
|
-
r3fLog("setup",
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3775
|
+
r3fLog("setup", `Object3D patched (mode=${mode}), interaction state set`);
|
|
3776
|
+
if (mode === "auto") {
|
|
3777
|
+
if (filter) {
|
|
3778
|
+
store.addTrackedRoot(scene);
|
|
3779
|
+
scene.traverse((obj) => {
|
|
3780
|
+
if (filter(obj)) {
|
|
3781
|
+
store.register(obj);
|
|
3782
|
+
mirror.onObjectAdded(obj);
|
|
3783
|
+
}
|
|
3784
|
+
});
|
|
3785
|
+
} else {
|
|
3786
|
+
store.registerTree(scene);
|
|
3787
|
+
}
|
|
3788
|
+
if (!store.has(camera)) {
|
|
3789
|
+
const camMeta = store.register(camera);
|
|
3790
|
+
camMeta.parentUuid = scene.uuid;
|
|
3791
|
+
mirror.materialize(camera.uuid);
|
|
3792
|
+
}
|
|
3793
|
+
mirror.materializeSubtree(scene.uuid, initialDepth);
|
|
3794
|
+
if (!filter) {
|
|
3795
|
+
cancelAsyncReg = store.registerTreeAsync(scene);
|
|
3796
|
+
}
|
|
3797
|
+
} else {
|
|
3798
|
+
store.addTrackedRoot(scene);
|
|
3799
|
+
store.register(scene);
|
|
3800
|
+
mirror.onObjectAdded(scene);
|
|
3734
3801
|
}
|
|
3735
|
-
|
|
3736
|
-
cancelAsyncReg = store.registerTreeAsync(scene);
|
|
3737
|
-
r3fLog("setup", `Scene registered: ${store.getCount()} objects, async watcher started`);
|
|
3802
|
+
r3fLog("setup", `Scene registered (mode=${mode}): ${store.getCount()} objects`);
|
|
3738
3803
|
selectionManager = new SelectionManager();
|
|
3739
3804
|
highlighter = new Highlighter();
|
|
3740
3805
|
highlighter.attach(scene, selectionManager, camera, gl, store);
|
|
@@ -3806,6 +3871,8 @@ function ThreeDom({
|
|
|
3806
3871
|
_selectionManagers.delete(instanceKey);
|
|
3807
3872
|
_highlighters.delete(instanceKey);
|
|
3808
3873
|
_inspectControllers.delete(instanceKey);
|
|
3874
|
+
_modes.delete(instanceKey);
|
|
3875
|
+
_filters.delete(instanceKey);
|
|
3809
3876
|
if (debug) enableDebug(false);
|
|
3810
3877
|
r3fLog("setup", "ThreeDom cleanup complete");
|
|
3811
3878
|
};
|
|
@@ -3853,7 +3920,42 @@ function ThreeDom({
|
|
|
3853
3920
|
});
|
|
3854
3921
|
return null;
|
|
3855
3922
|
}
|
|
3923
|
+
function getAPI(canvasId) {
|
|
3924
|
+
if (canvasId) {
|
|
3925
|
+
return window.__R3F_DOM_INSTANCES__?.[canvasId];
|
|
3926
|
+
}
|
|
3927
|
+
return window.__R3F_DOM__;
|
|
3928
|
+
}
|
|
3929
|
+
function useR3FRegister(ref, canvasId) {
|
|
3930
|
+
const trackedObj = useRef(null);
|
|
3931
|
+
const canvasIdRef = useRef(canvasId);
|
|
3932
|
+
canvasIdRef.current = canvasId;
|
|
3933
|
+
const register = useCallback((obj) => {
|
|
3934
|
+
const api = getAPI(canvasIdRef.current);
|
|
3935
|
+
if (!api) return false;
|
|
3936
|
+
api.r3fRegister(obj);
|
|
3937
|
+
trackedObj.current = obj;
|
|
3938
|
+
return true;
|
|
3939
|
+
}, []);
|
|
3940
|
+
const unregister = useCallback(() => {
|
|
3941
|
+
if (!trackedObj.current) return;
|
|
3942
|
+
const api = getAPI(canvasIdRef.current);
|
|
3943
|
+
api?.r3fUnregister(trackedObj.current);
|
|
3944
|
+
trackedObj.current = null;
|
|
3945
|
+
}, []);
|
|
3946
|
+
useEffect(() => {
|
|
3947
|
+
const obj = ref.current;
|
|
3948
|
+
if (obj) register(obj);
|
|
3949
|
+
return () => unregister();
|
|
3950
|
+
}, [ref, register, unregister]);
|
|
3951
|
+
useFrame(() => {
|
|
3952
|
+
const current = ref.current;
|
|
3953
|
+
if (current === trackedObj.current) return;
|
|
3954
|
+
unregister();
|
|
3955
|
+
if (current) register(current);
|
|
3956
|
+
});
|
|
3957
|
+
}
|
|
3856
3958
|
|
|
3857
|
-
export { DomMirror, Highlighter, InspectController, MANAGED_ATTRIBUTES, ObjectStore, RaycastAccelerator, SelectionManager, TAG_MAP, ThreeDom, ThreeElement, 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, getStore2 as getStore, getTagForType, hover3D, isDebugEnabled, isInFrustum, isPatched, linePath, patchObject3D, pointerMiss3D, previewDragWorldDelta, projectAllSamplePoints, projectToScreen, r3fLog, rectPath, resolveObject, restoreObject3D, screenDeltaToWorld, unhover3D, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|
|
3959
|
+
export { DomMirror, Highlighter, InspectController, MANAGED_ATTRIBUTES, ObjectStore, RaycastAccelerator, SelectionManager, TAG_MAP, ThreeDom, ThreeElement, 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, getStore2 as getStore, getTagForType, hover3D, isDebugEnabled, isInFrustum, isPatched, linePath, patchObject3D, pointerMiss3D, previewDragWorldDelta, projectAllSamplePoints, projectToScreen, r3fLog, rectPath, resolveObject, restoreObject3D, screenDeltaToWorld, unhover3D, useR3FRegister, verifyRaycastHit, verifyRaycastHitMultiPoint, version, wheel3D };
|
|
3858
3960
|
//# sourceMappingURL=index.js.map
|
|
3859
3961
|
//# sourceMappingURL=index.js.map
|