@react-three-dom/core 0.3.0 → 0.5.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 +147 -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 +148 -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.5.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.5.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.5.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,17 @@ 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)) {
|
|
1526
|
+
ensureAncestorChain(child, store, mirror);
|
|
1521
1527
|
store.register(child);
|
|
1522
1528
|
mirror.onObjectAdded(child);
|
|
1523
1529
|
}
|
|
1524
1530
|
});
|
|
1525
1531
|
}
|
|
1526
|
-
function patchObject3D(store, mirror) {
|
|
1527
|
-
_activePairs.push({ store, mirror });
|
|
1532
|
+
function patchObject3D(store, mirror, instanceKey = "") {
|
|
1533
|
+
_activePairs.push({ store, mirror, instanceKey });
|
|
1528
1534
|
if (!_patched) {
|
|
1529
1535
|
r3fLog("patch", "Patching Object3D.prototype.add and .remove");
|
|
1530
1536
|
_originalAdd = Object3D.prototype.add;
|
|
@@ -1537,7 +1543,7 @@ function patchObject3D(store, mirror) {
|
|
|
1537
1543
|
if (obj === this) continue;
|
|
1538
1544
|
try {
|
|
1539
1545
|
r3fLog("patch", `patchedAdd: "${obj.name || obj.type}" added to "${this.name || this.type}"`);
|
|
1540
|
-
registerSubtree(obj, pair.store, pair.mirror);
|
|
1546
|
+
registerSubtree(obj, pair.store, pair.mirror, pair.instanceKey);
|
|
1541
1547
|
} catch (err) {
|
|
1542
1548
|
r3fLog("patch", `patchedAdd: failed to register "${obj.name || obj.type}"`, err);
|
|
1543
1549
|
}
|
|
@@ -3096,7 +3102,7 @@ var InspectController = class {
|
|
|
3096
3102
|
this._overlay = overlay;
|
|
3097
3103
|
r3fLog("inspect", "Inspect mode enabled \u2014 hover to highlight, click to select");
|
|
3098
3104
|
}
|
|
3099
|
-
/** Deactivate inspect mode — removes overlay and clears
|
|
3105
|
+
/** Deactivate inspect mode — removes overlay and clears all inspect state. */
|
|
3100
3106
|
disable() {
|
|
3101
3107
|
if (!this._active) return;
|
|
3102
3108
|
this._active = false;
|
|
@@ -3343,6 +3349,30 @@ var _mirrors = /* @__PURE__ */ new Map();
|
|
|
3343
3349
|
var _selectionManagers = /* @__PURE__ */ new Map();
|
|
3344
3350
|
var _highlighters = /* @__PURE__ */ new Map();
|
|
3345
3351
|
var _inspectControllers = /* @__PURE__ */ new Map();
|
|
3352
|
+
var _filters = /* @__PURE__ */ new Map();
|
|
3353
|
+
var _modes = /* @__PURE__ */ new Map();
|
|
3354
|
+
function shouldRegister(instanceKey, obj) {
|
|
3355
|
+
const mode = _modes.get(instanceKey);
|
|
3356
|
+
if (mode === "manual") return false;
|
|
3357
|
+
const filter = _filters.get(instanceKey);
|
|
3358
|
+
if (filter) return filter(obj);
|
|
3359
|
+
return true;
|
|
3360
|
+
}
|
|
3361
|
+
function ensureAncestorChain(obj, store, mirror) {
|
|
3362
|
+
const chain = [];
|
|
3363
|
+
let cursor = obj.parent;
|
|
3364
|
+
while (cursor) {
|
|
3365
|
+
if (store.has(cursor)) break;
|
|
3366
|
+
chain.push(cursor);
|
|
3367
|
+
cursor = cursor.parent;
|
|
3368
|
+
}
|
|
3369
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
3370
|
+
const ancestor = chain[i];
|
|
3371
|
+
store.register(ancestor);
|
|
3372
|
+
mirror.onObjectAdded(ancestor);
|
|
3373
|
+
mirror.materialize(ancestor.uuid);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3346
3376
|
function getStore2(canvasId = "") {
|
|
3347
3377
|
return _stores.get(canvasId) ?? null;
|
|
3348
3378
|
}
|
|
@@ -3493,6 +3523,38 @@ function exposeGlobalAPI(store, gl, cameraRef, selMgr, inspCtrl, mirror, canvasI
|
|
|
3493
3523
|
}
|
|
3494
3524
|
return state;
|
|
3495
3525
|
},
|
|
3526
|
+
r3fRegister: (obj) => {
|
|
3527
|
+
if (store.has(obj)) return;
|
|
3528
|
+
if (!store.isInTrackedScene(obj)) {
|
|
3529
|
+
console.warn(
|
|
3530
|
+
`[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.`
|
|
3531
|
+
);
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
obj.userData.__r3fdom_manual = true;
|
|
3535
|
+
ensureAncestorChain(obj, store, mirror);
|
|
3536
|
+
let count = 0;
|
|
3537
|
+
obj.traverse((child) => {
|
|
3538
|
+
if (!store.has(child)) {
|
|
3539
|
+
store.register(child);
|
|
3540
|
+
mirror?.onObjectAdded(child);
|
|
3541
|
+
mirror?.materialize(child.uuid);
|
|
3542
|
+
count++;
|
|
3543
|
+
}
|
|
3544
|
+
});
|
|
3545
|
+
r3fLog("bridge", `r3fRegister: "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" (${obj.type}) \u2014 ${count} objects`);
|
|
3546
|
+
},
|
|
3547
|
+
r3fUnregister: (obj) => {
|
|
3548
|
+
if (!store.has(obj)) return;
|
|
3549
|
+
if (!obj.userData?.__r3fdom_manual) {
|
|
3550
|
+
r3fLog("bridge", `r3fUnregister skipped \u2014 "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" was auto-registered`);
|
|
3551
|
+
return;
|
|
3552
|
+
}
|
|
3553
|
+
delete obj.userData.__r3fdom_manual;
|
|
3554
|
+
mirror?.onObjectRemoved(obj);
|
|
3555
|
+
obj.traverse((child) => store.unregister(child));
|
|
3556
|
+
r3fLog("bridge", `r3fUnregister: "${obj.userData?.testId || obj.name || obj.uuid.slice(0, 8)}" (${obj.type})`);
|
|
3557
|
+
},
|
|
3496
3558
|
fuzzyFind: (query, limit = 5) => {
|
|
3497
3559
|
const q = query.toLowerCase();
|
|
3498
3560
|
const results = [];
|
|
@@ -3615,6 +3677,10 @@ function createStubBridge(error, canvasId) {
|
|
|
3615
3677
|
setInspectMode: () => {
|
|
3616
3678
|
},
|
|
3617
3679
|
getInspectMode: () => false,
|
|
3680
|
+
r3fRegister: () => {
|
|
3681
|
+
},
|
|
3682
|
+
r3fUnregister: () => {
|
|
3683
|
+
},
|
|
3618
3684
|
sweepOrphans: () => 0,
|
|
3619
3685
|
getDiagnostics: () => ({
|
|
3620
3686
|
version,
|
|
@@ -3649,6 +3715,8 @@ function ThreeDom({
|
|
|
3649
3715
|
canvasId,
|
|
3650
3716
|
primary,
|
|
3651
3717
|
root = "#three-dom-root",
|
|
3718
|
+
mode = "auto",
|
|
3719
|
+
filter,
|
|
3652
3720
|
batchSize = 500,
|
|
3653
3721
|
syncBudgetMs = 0.5,
|
|
3654
3722
|
maxDomNodes = 2e3,
|
|
@@ -3723,18 +3791,42 @@ function ThreeDom({
|
|
|
3723
3791
|
mirror.setRoot(rootElement);
|
|
3724
3792
|
r3fLog("setup", "Store and mirror created");
|
|
3725
3793
|
ensureCustomElements(store);
|
|
3726
|
-
|
|
3794
|
+
_modes.set(instanceKey, mode);
|
|
3795
|
+
_filters.set(instanceKey, filter ?? null);
|
|
3796
|
+
unpatch = patchObject3D(store, mirror, instanceKey);
|
|
3727
3797
|
setInteractionState(store, camera, gl, size);
|
|
3728
|
-
r3fLog("setup",
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3798
|
+
r3fLog("setup", `Object3D patched (mode=${mode}), interaction state set`);
|
|
3799
|
+
if (mode === "auto") {
|
|
3800
|
+
if (filter) {
|
|
3801
|
+
store.addTrackedRoot(scene);
|
|
3802
|
+
store.register(scene);
|
|
3803
|
+
mirror.onObjectAdded(scene);
|
|
3804
|
+
scene.traverse((obj) => {
|
|
3805
|
+
if (obj === scene) return;
|
|
3806
|
+
if (filter(obj)) {
|
|
3807
|
+
ensureAncestorChain(obj, store, mirror);
|
|
3808
|
+
store.register(obj);
|
|
3809
|
+
mirror.onObjectAdded(obj);
|
|
3810
|
+
}
|
|
3811
|
+
});
|
|
3812
|
+
} else {
|
|
3813
|
+
store.registerTree(scene);
|
|
3814
|
+
}
|
|
3815
|
+
if (!store.has(camera)) {
|
|
3816
|
+
const camMeta = store.register(camera);
|
|
3817
|
+
camMeta.parentUuid = scene.uuid;
|
|
3818
|
+
mirror.materialize(camera.uuid);
|
|
3819
|
+
}
|
|
3820
|
+
mirror.materializeSubtree(scene.uuid, initialDepth);
|
|
3821
|
+
if (!filter) {
|
|
3822
|
+
cancelAsyncReg = store.registerTreeAsync(scene);
|
|
3823
|
+
}
|
|
3824
|
+
} else {
|
|
3825
|
+
store.addTrackedRoot(scene);
|
|
3826
|
+
store.register(scene);
|
|
3827
|
+
mirror.onObjectAdded(scene);
|
|
3734
3828
|
}
|
|
3735
|
-
|
|
3736
|
-
cancelAsyncReg = store.registerTreeAsync(scene);
|
|
3737
|
-
r3fLog("setup", `Scene registered: ${store.getCount()} objects, async watcher started`);
|
|
3829
|
+
r3fLog("setup", `Scene registered (mode=${mode}): ${store.getCount()} objects`);
|
|
3738
3830
|
selectionManager = new SelectionManager();
|
|
3739
3831
|
highlighter = new Highlighter();
|
|
3740
3832
|
highlighter.attach(scene, selectionManager, camera, gl, store);
|
|
@@ -3806,6 +3898,8 @@ function ThreeDom({
|
|
|
3806
3898
|
_selectionManagers.delete(instanceKey);
|
|
3807
3899
|
_highlighters.delete(instanceKey);
|
|
3808
3900
|
_inspectControllers.delete(instanceKey);
|
|
3901
|
+
_modes.delete(instanceKey);
|
|
3902
|
+
_filters.delete(instanceKey);
|
|
3809
3903
|
if (debug) enableDebug(false);
|
|
3810
3904
|
r3fLog("setup", "ThreeDom cleanup complete");
|
|
3811
3905
|
};
|
|
@@ -3853,7 +3947,42 @@ function ThreeDom({
|
|
|
3853
3947
|
});
|
|
3854
3948
|
return null;
|
|
3855
3949
|
}
|
|
3950
|
+
function getAPI(canvasId) {
|
|
3951
|
+
if (canvasId) {
|
|
3952
|
+
return window.__R3F_DOM_INSTANCES__?.[canvasId];
|
|
3953
|
+
}
|
|
3954
|
+
return window.__R3F_DOM__;
|
|
3955
|
+
}
|
|
3956
|
+
function useR3FRegister(ref, canvasId) {
|
|
3957
|
+
const trackedObj = useRef(null);
|
|
3958
|
+
const canvasIdRef = useRef(canvasId);
|
|
3959
|
+
canvasIdRef.current = canvasId;
|
|
3960
|
+
const register = useCallback((obj) => {
|
|
3961
|
+
const api = getAPI(canvasIdRef.current);
|
|
3962
|
+
if (!api) return false;
|
|
3963
|
+
api.r3fRegister(obj);
|
|
3964
|
+
trackedObj.current = obj;
|
|
3965
|
+
return true;
|
|
3966
|
+
}, []);
|
|
3967
|
+
const unregister = useCallback(() => {
|
|
3968
|
+
if (!trackedObj.current) return;
|
|
3969
|
+
const api = getAPI(canvasIdRef.current);
|
|
3970
|
+
api?.r3fUnregister(trackedObj.current);
|
|
3971
|
+
trackedObj.current = null;
|
|
3972
|
+
}, []);
|
|
3973
|
+
useEffect(() => {
|
|
3974
|
+
const obj = ref.current;
|
|
3975
|
+
if (obj) register(obj);
|
|
3976
|
+
return () => unregister();
|
|
3977
|
+
}, [ref, register, unregister]);
|
|
3978
|
+
useFrame(() => {
|
|
3979
|
+
const current = ref.current;
|
|
3980
|
+
if (current === trackedObj.current) return;
|
|
3981
|
+
unregister();
|
|
3982
|
+
if (current) register(current);
|
|
3983
|
+
});
|
|
3984
|
+
}
|
|
3856
3985
|
|
|
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 };
|
|
3986
|
+
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
3987
|
//# sourceMappingURL=index.js.map
|
|
3859
3988
|
//# sourceMappingURL=index.js.map
|