@react-three/fiber 8.0.0-beta.5 → 8.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/declarations/src/core/events.d.ts +11 -6
- package/dist/declarations/src/core/hooks.d.ts +6 -6
- package/dist/declarations/src/core/index.d.ts +12 -4
- package/dist/declarations/src/core/store.d.ts +7 -18
- package/dist/declarations/src/core/utils.d.ts +2 -1
- package/dist/{index-e2a317e2.cjs.prod.js → index-45f5b2a2.cjs.prod.js} +125 -121
- package/dist/{index-5dc2de40.cjs.dev.js → index-4782ba04.cjs.dev.js} +125 -121
- package/dist/{index-32069e53.esm.js → index-74b1fd6b.esm.js} +124 -121
- package/dist/react-three-fiber.cjs.dev.js +22 -6
- package/dist/react-three-fiber.cjs.prod.js +22 -6
- package/dist/react-three-fiber.esm.js +21 -6
- package/native/dist/react-three-fiber-native.cjs.dev.js +22 -6
- package/native/dist/react-three-fiber-native.cjs.prod.js +22 -6
- package/native/dist/react-three-fiber-native.esm.js +21 -6
- package/package.json +1 -1
|
@@ -5,17 +5,16 @@ export interface Intersection extends THREE.Intersection {
|
|
|
5
5
|
eventObject: THREE.Object3D;
|
|
6
6
|
}
|
|
7
7
|
export interface IntersectionEvent<TSourceEvent> extends Intersection {
|
|
8
|
+
eventObject: THREE.Object3D;
|
|
8
9
|
intersections: Intersection[];
|
|
9
|
-
stopped: boolean;
|
|
10
10
|
unprojectedPoint: THREE.Vector3;
|
|
11
|
+
pointer: THREE.Vector2;
|
|
12
|
+
delta: number;
|
|
11
13
|
ray: THREE.Ray;
|
|
12
14
|
camera: Camera;
|
|
13
15
|
stopPropagation: () => void;
|
|
14
|
-
sourceEvent: TSourceEvent;
|
|
15
16
|
nativeEvent: TSourceEvent;
|
|
16
|
-
|
|
17
|
-
spaceX: number;
|
|
18
|
-
spaceY: number;
|
|
17
|
+
stopped: boolean;
|
|
19
18
|
}
|
|
20
19
|
export declare type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera;
|
|
21
20
|
export declare type ThreeEvent<TEvent> = IntersectionEvent<TEvent>;
|
|
@@ -47,8 +46,14 @@ export declare type EventHandlers = {
|
|
|
47
46
|
onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void;
|
|
48
47
|
onWheel?: (event: ThreeEvent<WheelEvent>) => void;
|
|
49
48
|
};
|
|
49
|
+
export declare type FilterFunction = (items: THREE.Intersection[], state: RootState) => THREE.Intersection[];
|
|
50
|
+
export declare type ComputeFunction = (event: DomEvent, root: RootState, previous?: RootState) => void;
|
|
50
51
|
export interface EventManager<TTarget> {
|
|
51
|
-
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
priority: number;
|
|
54
|
+
compute?: ComputeFunction;
|
|
55
|
+
filter?: FilterFunction;
|
|
56
|
+
connected?: TTarget;
|
|
52
57
|
handlers?: Events;
|
|
53
58
|
connect?: (target: TTarget) => void;
|
|
54
59
|
disconnect?: () => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import
|
|
3
|
-
import { StateSelector, EqualityChecker, UseBoundStore } from 'zustand';
|
|
2
|
+
import { StateSelector, EqualityChecker } from 'zustand';
|
|
4
3
|
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
5
4
|
import { RootState, RenderCallback } from './store';
|
|
6
5
|
import { ObjectMap } from './utils';
|
|
@@ -11,15 +10,16 @@ export declare type Extensions = (loader: THREE.Loader) => void;
|
|
|
11
10
|
export declare type LoaderResult<T> = T extends any[] ? Loader<T[number]> : Loader<T>;
|
|
12
11
|
export declare type ConditionalType<Child, Parent, Truthy, Falsy> = Child extends Parent ? Truthy : Falsy;
|
|
13
12
|
export declare type BranchingReturn<T, Parent, Coerced> = ConditionalType<T, Parent, Coerced, T>;
|
|
14
|
-
|
|
13
|
+
declare type noop = (...args: any[]) => any;
|
|
14
|
+
declare type PickFunction<T extends noop> = (...args: Parameters<T>) => ReturnType<T>;
|
|
15
|
+
export declare function useStore(): import("zustand").UseBoundStore<RootState, import("zustand").StoreApi<RootState>>;
|
|
15
16
|
export declare function useThree<T = RootState>(selector?: StateSelector<RootState, T>, equalityFn?: EqualityChecker<T>): T;
|
|
16
|
-
export declare function useInject(state: Partial<RootState>): [React.FC<{
|
|
17
|
-
children: React.ReactNode;
|
|
18
|
-
}>, UseBoundStore<RootState, import("zustand").StoreApi<RootState>>];
|
|
19
17
|
export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
|
|
20
18
|
export declare function useGraph(object: THREE.Object3D): ObjectMap;
|
|
19
|
+
export declare function useMemoizedFn<T extends noop>(fn?: T): PickFunction<T>;
|
|
21
20
|
export declare function useLoader<T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTF, GLTF & ObjectMap>[] : BranchingReturn<T, GLTF, GLTF & ObjectMap>;
|
|
22
21
|
export declare namespace useLoader {
|
|
23
22
|
var preload: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions | undefined) => undefined;
|
|
24
23
|
var clear: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U) => void;
|
|
25
24
|
}
|
|
25
|
+
export {};
|
|
@@ -5,8 +5,8 @@ import { UseBoundStore } from 'zustand';
|
|
|
5
5
|
import { Renderer, StoreProps, context, RootState, Size } from './store';
|
|
6
6
|
import { extend, Root } from './renderer';
|
|
7
7
|
import { addEffect, addAfterEffect, addTail } from './loop';
|
|
8
|
-
import { EventManager } from './events';
|
|
9
|
-
import { dispose } from './utils';
|
|
8
|
+
import { EventManager, ComputeFunction } from './events';
|
|
9
|
+
import { dispose, getRootState } from './utils';
|
|
10
10
|
declare const roots: Map<Element, Root>;
|
|
11
11
|
declare const invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState | undefined, frame?: THREE.XRFrame | undefined) => void;
|
|
12
12
|
declare const reconciler: import("react-reconciler").Reconciler<unknown, unknown, unknown, unknown, unknown>, applyProps: typeof import("./utils").applyProps;
|
|
@@ -28,7 +28,15 @@ export declare type ReconcilerRoot<TCanvas extends Element> = {
|
|
|
28
28
|
declare function createRoot<TCanvas extends Element>(canvas: TCanvas): ReconcilerRoot<TCanvas>;
|
|
29
29
|
declare function render<TCanvas extends Element>(element: React.ReactNode, canvas: TCanvas, config?: RenderProps<TCanvas>): UseBoundStore<RootState>;
|
|
30
30
|
declare function unmountComponentAtNode<TElement extends Element>(canvas: TElement, callback?: (canvas: TElement) => void): void;
|
|
31
|
-
declare
|
|
31
|
+
export declare type InjectState = Partial<Omit<RootState, 'set' | 'get' | 'setSize' | 'setFrameloop' | 'setDpr' | 'events' | 'invalidate' | 'advance' | 'performance' | 'internal'> & {
|
|
32
|
+
events: {
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
priority?: number;
|
|
35
|
+
compute?: ComputeFunction;
|
|
36
|
+
connected?: any;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: InjectState): React.ReactNode;
|
|
32
40
|
declare const act: any;
|
|
33
41
|
export * from './hooks';
|
|
34
|
-
export { context, render, createRoot, unmountComponentAtNode, createPortal, reconciler, applyProps, dispose, invalidate, advance, extend, addEffect, addAfterEffect, addTail, act, roots as _roots, };
|
|
42
|
+
export { context, render, createRoot, unmountComponentAtNode, createPortal, reconciler, applyProps, dispose, invalidate, advance, extend, addEffect, addAfterEffect, addTail, getRootState, act, roots as _roots, };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import * as ReactThreeFiber from '../three-types';
|
|
4
|
-
import { GetState, SetState, UseBoundStore } from 'zustand';
|
|
4
|
+
import { GetState, SetState, StoreApi, UseBoundStore } from 'zustand';
|
|
5
5
|
import { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from './events';
|
|
6
6
|
export interface Intersection extends THREE.Intersection {
|
|
7
7
|
eventObject: THREE.Object3D;
|
|
@@ -23,11 +23,6 @@ export declare type Viewport = Size & {
|
|
|
23
23
|
aspect: number;
|
|
24
24
|
};
|
|
25
25
|
export declare type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera;
|
|
26
|
-
export declare type Raycaster = THREE.Raycaster & {
|
|
27
|
-
enabled: boolean;
|
|
28
|
-
filter?: FilterFunction;
|
|
29
|
-
computeOffsets?: ComputeOffsetsFunction;
|
|
30
|
-
};
|
|
31
26
|
export declare type RenderCallback = (state: RootState, delta: number, frame?: THREE.XRFrame) => void;
|
|
32
27
|
export declare type Performance = {
|
|
33
28
|
current: number;
|
|
@@ -59,7 +54,7 @@ export declare type RootState = {
|
|
|
59
54
|
camera: Camera & {
|
|
60
55
|
manual?: boolean;
|
|
61
56
|
};
|
|
62
|
-
raycaster: Raycaster;
|
|
57
|
+
raycaster: THREE.Raycaster;
|
|
63
58
|
events: EventManager<any>;
|
|
64
59
|
xr: {
|
|
65
60
|
connect: () => void;
|
|
@@ -67,7 +62,7 @@ export declare type RootState = {
|
|
|
67
62
|
};
|
|
68
63
|
scene: THREE.Scene;
|
|
69
64
|
controls: THREE.EventDispatcher | null;
|
|
70
|
-
|
|
65
|
+
pointer: THREE.Vector2;
|
|
71
66
|
clock: THREE.Clock;
|
|
72
67
|
linear: boolean;
|
|
73
68
|
flat: boolean;
|
|
@@ -75,7 +70,7 @@ export declare type RootState = {
|
|
|
75
70
|
performance: Performance;
|
|
76
71
|
size: Size;
|
|
77
72
|
viewport: Viewport & {
|
|
78
|
-
getCurrentViewport: (camera?: Camera, target?: THREE.Vector3
|
|
73
|
+
getCurrentViewport: (camera?: Camera, target?: THREE.Vector3 | Parameters<THREE.Vector3['set']>, size?: Size) => Omit<Viewport, 'dpr' | 'initialDpr'>;
|
|
79
74
|
};
|
|
80
75
|
set: SetState<RootState>;
|
|
81
76
|
get: GetState<RootState>;
|
|
@@ -85,15 +80,9 @@ export declare type RootState = {
|
|
|
85
80
|
setDpr: (dpr: Dpr) => void;
|
|
86
81
|
setFrameloop: (frameloop?: 'always' | 'demand' | 'never') => void;
|
|
87
82
|
onPointerMissed?: (event: MouseEvent) => void;
|
|
83
|
+
previousRoot?: UseBoundStore<RootState, StoreApi<RootState>>;
|
|
88
84
|
internal: InternalState;
|
|
89
85
|
};
|
|
90
|
-
export declare type FilterFunction = (items: THREE.Intersection[], state: RootState) => THREE.Intersection[];
|
|
91
|
-
export declare type ComputeOffsetsFunction = (event: any, state: RootState) => {
|
|
92
|
-
offsetX: number;
|
|
93
|
-
offsetY: number;
|
|
94
|
-
width?: number;
|
|
95
|
-
height?: number;
|
|
96
|
-
};
|
|
97
86
|
export declare type StoreProps = {
|
|
98
87
|
gl: THREE.WebGLRenderer;
|
|
99
88
|
size: Size;
|
|
@@ -104,12 +93,12 @@ export declare type StoreProps = {
|
|
|
104
93
|
frameloop?: 'always' | 'demand' | 'never';
|
|
105
94
|
performance?: Partial<Omit<Performance, 'regress'>>;
|
|
106
95
|
dpr?: Dpr;
|
|
107
|
-
raycaster?: Partial<Raycaster>;
|
|
96
|
+
raycaster?: Partial<THREE.Raycaster>;
|
|
108
97
|
camera?: (Camera | Partial<ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> & ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> & ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>>) & {
|
|
109
98
|
manual?: boolean;
|
|
110
99
|
};
|
|
111
100
|
onPointerMissed?: (event: MouseEvent) => void;
|
|
112
101
|
};
|
|
113
|
-
declare const context: React.Context<UseBoundStore<RootState,
|
|
102
|
+
declare const context: React.Context<UseBoundStore<RootState, StoreApi<RootState>>>;
|
|
114
103
|
declare const createStore: (invalidate: (state?: RootState | undefined) => void, advance: (timestamp: number, runGlobalEffects?: boolean | undefined, state?: RootState | undefined, frame?: THREE.XRFrame | undefined) => void) => UseBoundStore<RootState>;
|
|
115
104
|
export { createStore, context };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import { AttachType, Instance, InstanceProps, LocalState } from './renderer';
|
|
3
|
-
import { Dpr } from './store';
|
|
3
|
+
import { Dpr, RootState } from './store';
|
|
4
4
|
export declare const DEFAULT = "__default";
|
|
5
5
|
export declare type DiffSet = {
|
|
6
6
|
memoized: {
|
|
@@ -21,6 +21,7 @@ export declare type ObjectMap = {
|
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
export declare function calculateDpr(dpr: Dpr): number;
|
|
24
|
+
export declare const getRootState: (obj: THREE.Object3D) => RootState | undefined;
|
|
24
25
|
export declare function filterKeys<TObj extends {
|
|
25
26
|
[key: string]: any;
|
|
26
27
|
}, TOmit extends boolean, TKey extends keyof TObj>(obj: TObj, omit: TOmit, ...keys: TKey[]): TOmit extends true ? Omit<TObj, TKey> : Pick<TObj, TKey>;
|
|
@@ -44,6 +44,15 @@ const isDiffSet = def => def && !!def.memoized && !!def.changes;
|
|
|
44
44
|
function calculateDpr(dpr) {
|
|
45
45
|
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns instance root state
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
const getRootState = obj => {
|
|
52
|
+
var _r3f;
|
|
53
|
+
|
|
54
|
+
return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
|
|
55
|
+
};
|
|
47
56
|
/**
|
|
48
57
|
* Picks or omits keys from an object
|
|
49
58
|
* `omit` will filter out keys, and otherwise cherry-pick them.
|
|
@@ -53,11 +62,7 @@ function filterKeys(obj, omit, ...keys) {
|
|
|
53
62
|
const keysToSelect = new Set(keys);
|
|
54
63
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
55
64
|
const shouldInclude = !omit;
|
|
56
|
-
|
|
57
|
-
if (keysToSelect.has(key) === shouldInclude) {
|
|
58
|
-
acc[key] = value;
|
|
59
|
-
}
|
|
60
|
-
|
|
65
|
+
if (keysToSelect.has(key) === shouldInclude) acc[key] = value;
|
|
61
66
|
return acc;
|
|
62
67
|
}, {});
|
|
63
68
|
}
|
|
@@ -411,6 +416,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
|
411
416
|
|
|
412
417
|
function removeInteractivity(store, object) {
|
|
413
418
|
const {
|
|
419
|
+
events,
|
|
414
420
|
internal
|
|
415
421
|
} = store.getState(); // Removes every trace of an object from the data store
|
|
416
422
|
|
|
@@ -418,6 +424,7 @@ function removeInteractivity(store, object) {
|
|
|
418
424
|
internal.initialHits = internal.initialHits.filter(o => o !== object);
|
|
419
425
|
internal.hovered.forEach((value, key) => {
|
|
420
426
|
if (value.eventObject === object || value.object === object) {
|
|
427
|
+
// Clear out intersects, they are outdated by now
|
|
421
428
|
internal.hovered.delete(key);
|
|
422
429
|
}
|
|
423
430
|
});
|
|
@@ -427,31 +434,8 @@ function removeInteractivity(store, object) {
|
|
|
427
434
|
}
|
|
428
435
|
function createEvents(store) {
|
|
429
436
|
const temp = new THREE__namespace.Vector3();
|
|
430
|
-
/** Sets up defaultRaycaster */
|
|
431
|
-
|
|
432
|
-
function prepareRay(event) {
|
|
433
|
-
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
434
|
-
|
|
435
|
-
const state = store.getState();
|
|
436
|
-
const {
|
|
437
|
-
raycaster,
|
|
438
|
-
mouse,
|
|
439
|
-
camera,
|
|
440
|
-
size
|
|
441
|
-
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
442
|
-
// Events trigger outside of canvas when moved
|
|
443
|
-
|
|
444
|
-
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
445
|
-
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
446
|
-
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
447
|
-
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
448
|
-
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
449
|
-
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
450
|
-
raycaster.setFromCamera(mouse, camera);
|
|
451
|
-
}
|
|
452
437
|
/** Calculates delta */
|
|
453
438
|
|
|
454
|
-
|
|
455
439
|
function calculateDistance(event) {
|
|
456
440
|
const {
|
|
457
441
|
internal
|
|
@@ -471,55 +455,70 @@ function createEvents(store) {
|
|
|
471
455
|
}));
|
|
472
456
|
}
|
|
473
457
|
|
|
474
|
-
function intersect(filter) {
|
|
458
|
+
function intersect(event, filter) {
|
|
475
459
|
const state = store.getState();
|
|
476
|
-
const
|
|
477
|
-
raycaster,
|
|
478
|
-
internal
|
|
479
|
-
} = state; // Skip event handling when noEvents is set
|
|
480
|
-
|
|
481
|
-
if (!raycaster.enabled) return [];
|
|
482
|
-
const seen = new Set();
|
|
460
|
+
const duplicates = new Set();
|
|
483
461
|
const intersections = []; // Allow callers to eliminate event objects
|
|
484
462
|
|
|
485
|
-
const eventsObjects = filter ? filter(internal.interaction) : internal.interaction; //
|
|
463
|
+
const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction; // Reset all raycaster cameras to undefined
|
|
464
|
+
|
|
465
|
+
eventsObjects.forEach(obj => {
|
|
466
|
+
const state = getRootState(obj);
|
|
467
|
+
|
|
468
|
+
if (state) {
|
|
469
|
+
state.raycaster.camera = undefined;
|
|
470
|
+
}
|
|
471
|
+
}); // Collect events
|
|
472
|
+
|
|
473
|
+
let hits = eventsObjects // Intersect objects
|
|
474
|
+
.flatMap(obj => {
|
|
475
|
+
const state = getRootState(obj); // Skip event handling when noEvents is set, or when the raycasters camera is null
|
|
476
|
+
|
|
477
|
+
if (!state || !state.events.enabled || state.raycaster.camera === null) return []; // When the camera is undefined we have to call the event layers update function
|
|
478
|
+
|
|
479
|
+
if (state.raycaster.camera === undefined) {
|
|
480
|
+
var _state$previousRoot;
|
|
481
|
+
|
|
482
|
+
state.events.compute == null ? void 0 : state.events.compute(event, state, (_state$previousRoot = state.previousRoot) == null ? void 0 : _state$previousRoot.getState()); // If the camera is still undefined we have to skip this layer entirely
|
|
486
483
|
|
|
487
|
-
|
|
484
|
+
if (state.raycaster.camera === undefined) state.raycaster.camera = null;
|
|
485
|
+
} // Intersect object by object
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
return state.raycaster.camera ? state.raycaster.intersectObject(obj, true) : [];
|
|
489
|
+
}) // Sort by event priority and distance
|
|
490
|
+
.sort((a, b) => {
|
|
491
|
+
const aState = getRootState(a.object);
|
|
492
|
+
const bState = getRootState(b.object);
|
|
493
|
+
if (!aState || !bState) return 0;
|
|
494
|
+
return bState.events.priority - aState.events.priority || a.distance - b.distance;
|
|
495
|
+
}) // Filter out duplicates
|
|
496
|
+
.filter(item => {
|
|
488
497
|
const id = makeId(item);
|
|
489
|
-
if (
|
|
490
|
-
|
|
498
|
+
if (duplicates.has(id)) return false;
|
|
499
|
+
duplicates.add(id);
|
|
491
500
|
return true;
|
|
492
501
|
}); // https://github.com/mrdoob/three.js/issues/16031
|
|
493
|
-
// Allow custom userland intersect sort order
|
|
502
|
+
// Allow custom userland intersect sort order, this likely only makes sense on the root filter
|
|
494
503
|
|
|
495
|
-
if (
|
|
504
|
+
if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
|
|
496
505
|
|
|
497
|
-
for (const
|
|
498
|
-
let eventObject =
|
|
506
|
+
for (const hit of hits) {
|
|
507
|
+
let eventObject = hit.object; // Bubble event up
|
|
499
508
|
|
|
500
509
|
while (eventObject) {
|
|
501
510
|
var _r3f2;
|
|
502
511
|
|
|
503
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...
|
|
512
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
504
513
|
eventObject
|
|
505
514
|
});
|
|
506
515
|
eventObject = eventObject.parent;
|
|
507
516
|
}
|
|
508
|
-
}
|
|
517
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
509
518
|
|
|
510
|
-
return intersections;
|
|
511
|
-
}
|
|
512
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
function patchIntersects(intersections, event) {
|
|
516
|
-
const {
|
|
517
|
-
internal
|
|
518
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
519
|
-
// intersect.
|
|
520
519
|
|
|
521
|
-
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
522
|
-
for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
|
|
520
|
+
if ('pointerId' in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
521
|
+
for (let captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
523
522
|
intersections.push(captureData.intersection);
|
|
524
523
|
}
|
|
525
524
|
}
|
|
@@ -532,13 +531,13 @@ function createEvents(store) {
|
|
|
532
531
|
function handleIntersects(intersections, event, delta, callback) {
|
|
533
532
|
const {
|
|
534
533
|
raycaster,
|
|
535
|
-
|
|
534
|
+
pointer,
|
|
536
535
|
camera,
|
|
537
536
|
internal
|
|
538
537
|
} = store.getState(); // If anything has been found, forward it to the event listeners
|
|
539
538
|
|
|
540
539
|
if (intersections.length) {
|
|
541
|
-
const unprojectedPoint = temp.set(
|
|
540
|
+
const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
|
|
542
541
|
const localState = {
|
|
543
542
|
stopped: false
|
|
544
543
|
};
|
|
@@ -589,8 +588,7 @@ function createEvents(store) {
|
|
|
589
588
|
|
|
590
589
|
let raycastEvent = { ...hit,
|
|
591
590
|
...extractEventProps,
|
|
592
|
-
|
|
593
|
-
spaceY: mouse.y,
|
|
591
|
+
pointer,
|
|
594
592
|
intersections,
|
|
595
593
|
stopped: localState.stopped,
|
|
596
594
|
delta,
|
|
@@ -627,8 +625,6 @@ function createEvents(store) {
|
|
|
627
625
|
setPointerCapture,
|
|
628
626
|
releasePointerCapture
|
|
629
627
|
},
|
|
630
|
-
sourceEvent: event,
|
|
631
|
-
// deprecated
|
|
632
628
|
nativeEvent: event
|
|
633
629
|
}; // Call subscribers
|
|
634
630
|
|
|
@@ -693,14 +689,15 @@ function createEvents(store) {
|
|
|
693
689
|
const {
|
|
694
690
|
onPointerMissed,
|
|
695
691
|
internal
|
|
696
|
-
} = store.getState();
|
|
697
|
-
|
|
692
|
+
} = store.getState(); //prepareRay(event)
|
|
693
|
+
|
|
698
694
|
internal.lastEvent.current = event; // Get fresh intersects
|
|
699
695
|
|
|
700
696
|
const isPointerMove = name === 'onPointerMove';
|
|
701
697
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
702
|
-
const filter = isPointerMove ? filterPointerEvents : undefined;
|
|
703
|
-
|
|
698
|
+
const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
|
|
699
|
+
|
|
700
|
+
const hits = intersect(event, filter);
|
|
704
701
|
const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
|
|
705
702
|
|
|
706
703
|
if (name === 'onPointerDown') {
|
|
@@ -1180,16 +1177,18 @@ const createStore = (invalidate, advance) => {
|
|
|
1180
1177
|
}));
|
|
1181
1178
|
|
|
1182
1179
|
return {
|
|
1180
|
+
set,
|
|
1181
|
+
get,
|
|
1183
1182
|
// Mock objects that have to be configured
|
|
1184
1183
|
gl: null,
|
|
1185
1184
|
camera: null,
|
|
1186
1185
|
raycaster: null,
|
|
1187
1186
|
events: {
|
|
1187
|
+
priority: 1,
|
|
1188
|
+
enabled: true,
|
|
1188
1189
|
connected: false
|
|
1189
1190
|
},
|
|
1190
1191
|
xr: null,
|
|
1191
|
-
set,
|
|
1192
|
-
get,
|
|
1193
1192
|
invalidate: () => invalidate(get()),
|
|
1194
1193
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1195
1194
|
linear: false,
|
|
@@ -1197,7 +1196,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1197
1196
|
scene: prepare(new THREE__namespace.Scene()),
|
|
1198
1197
|
controls: null,
|
|
1199
1198
|
clock: new THREE__namespace.Clock(),
|
|
1200
|
-
|
|
1199
|
+
pointer: new THREE__namespace.Vector2(),
|
|
1201
1200
|
frameloop: 'always',
|
|
1202
1201
|
onPointerMissed: undefined,
|
|
1203
1202
|
performance: {
|
|
@@ -1266,6 +1265,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1266
1265
|
frameloop
|
|
1267
1266
|
}));
|
|
1268
1267
|
},
|
|
1268
|
+
previousRoot: undefined,
|
|
1269
1269
|
internal: {
|
|
1270
1270
|
active: false,
|
|
1271
1271
|
priority: 0,
|
|
@@ -1467,43 +1467,6 @@ function useStore() {
|
|
|
1467
1467
|
function useThree(selector = state => state, equalityFn) {
|
|
1468
1468
|
return useStore()(selector, equalityFn);
|
|
1469
1469
|
}
|
|
1470
|
-
function useInject(state) {
|
|
1471
|
-
const useOriginalStore = useStore();
|
|
1472
|
-
const useInjectStore = React__namespace.useMemo(() => {
|
|
1473
|
-
const useInjected = (sel = state => state) => {
|
|
1474
|
-
// Execute the useStore hook with the selector once, to maintain reactivity, result doesn't matter
|
|
1475
|
-
useOriginalStore(sel); // Inject data and return the result, either selected or raw
|
|
1476
|
-
|
|
1477
|
-
return sel({ ...useOriginalStore.getState(),
|
|
1478
|
-
...state
|
|
1479
|
-
});
|
|
1480
|
-
};
|
|
1481
|
-
|
|
1482
|
-
useInjected.setState = useOriginalStore.setState;
|
|
1483
|
-
useInjected.destroy = useOriginalStore.destroy; // Patch getState
|
|
1484
|
-
|
|
1485
|
-
useInjected.getState = () => {
|
|
1486
|
-
return { ...useOriginalStore.getState(),
|
|
1487
|
-
...state
|
|
1488
|
-
};
|
|
1489
|
-
}; // Patch subscribe
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
useInjected.subscribe = listener => {
|
|
1493
|
-
return useOriginalStore.subscribe((current, previous) => listener({ ...current,
|
|
1494
|
-
...state
|
|
1495
|
-
}, previous));
|
|
1496
|
-
};
|
|
1497
|
-
|
|
1498
|
-
return useInjected;
|
|
1499
|
-
}, [useOriginalStore, state]); // Return the patched store and a provider component
|
|
1500
|
-
|
|
1501
|
-
return React__namespace.useMemo(() => [({
|
|
1502
|
-
children
|
|
1503
|
-
}) => /*#__PURE__*/React__namespace.createElement(context.Provider, {
|
|
1504
|
-
value: useInjectStore
|
|
1505
|
-
}, children), useInjectStore], [useInjectStore]);
|
|
1506
|
-
}
|
|
1507
1470
|
function useFrame(callback, renderPriority = 0) {
|
|
1508
1471
|
const subscribe = useStore().getState().internal.subscribe; // Update ref
|
|
1509
1472
|
|
|
@@ -1530,6 +1493,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1530
1493
|
};
|
|
1531
1494
|
}
|
|
1532
1495
|
|
|
1496
|
+
function useMemoizedFn(fn) {
|
|
1497
|
+
const fnRef = React__namespace.useRef(fn);
|
|
1498
|
+
React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
|
|
1499
|
+
return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
|
|
1500
|
+
}
|
|
1533
1501
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1534
1502
|
// Use suspense to load async assets
|
|
1535
1503
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1629,9 +1597,7 @@ function createRoot(canvas) {
|
|
|
1629
1597
|
params,
|
|
1630
1598
|
...options
|
|
1631
1599
|
} = raycastOptions || {};
|
|
1632
|
-
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1633
|
-
enabled: true,
|
|
1634
|
-
...options
|
|
1600
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1635
1601
|
});
|
|
1636
1602
|
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1637
1603
|
params: { ...raycaster.params,
|
|
@@ -1785,9 +1751,10 @@ function Provider({
|
|
|
1785
1751
|
internal: { ...state.internal,
|
|
1786
1752
|
active: true
|
|
1787
1753
|
}
|
|
1788
|
-
})); // Connect events
|
|
1754
|
+
})); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1755
|
+
// a shared target, and not on the canvas itself
|
|
1789
1756
|
|
|
1790
|
-
state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1757
|
+
state.events.connect == null ? void 0 : state.events.connect(target.parentNode); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1791
1758
|
|
|
1792
1759
|
if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1793
1760
|
}, []);
|
|
@@ -1834,20 +1801,56 @@ function createPortal(children, container, state) {
|
|
|
1834
1801
|
}
|
|
1835
1802
|
|
|
1836
1803
|
function Portal({
|
|
1837
|
-
state,
|
|
1804
|
+
state = {},
|
|
1838
1805
|
children,
|
|
1839
1806
|
container
|
|
1840
1807
|
}) {
|
|
1841
1808
|
/** This has to be a component because it would not be able to call useThree/useStore otherwise since
|
|
1842
|
-
* if this is our environment, then we are
|
|
1809
|
+
* if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
|
|
1843
1810
|
* the "R3F hooks can only be used within the Canvas component!" warning:
|
|
1844
1811
|
* <Canvas>
|
|
1845
1812
|
* {createPortal(...)} */
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1813
|
+
const {
|
|
1814
|
+
events,
|
|
1815
|
+
...rest
|
|
1816
|
+
} = state;
|
|
1817
|
+
const previousRoot = useStore();
|
|
1818
|
+
const [raycaster] = React__namespace.useState(() => new THREE__namespace.Raycaster());
|
|
1819
|
+
const inject = React__namespace.useCallback((state, injectState) => {
|
|
1820
|
+
const intersect = { ...state
|
|
1821
|
+
};
|
|
1822
|
+
|
|
1823
|
+
if (injectState) {
|
|
1824
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1825
|
+
Object.keys(state).forEach(key => {
|
|
1826
|
+
if (state[key] !== injectState[key]) delete intersect[key];
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
return { ...intersect,
|
|
1831
|
+
scene: container,
|
|
1832
|
+
previousRoot,
|
|
1833
|
+
raycaster,
|
|
1834
|
+
events: { ...state.events,
|
|
1835
|
+
...events
|
|
1836
|
+
},
|
|
1837
|
+
...rest
|
|
1838
|
+
};
|
|
1839
|
+
}, [state]);
|
|
1840
|
+
const [useInjectStore] = React__namespace.useState(() => {
|
|
1841
|
+
const store = create__default['default']((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1842
|
+
set,
|
|
1843
|
+
get
|
|
1844
|
+
}));
|
|
1845
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1846
|
+
return store;
|
|
1847
|
+
});
|
|
1848
|
+
React__namespace.useEffect(() => {
|
|
1849
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1850
|
+
}, [inject]);
|
|
1851
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, reconciler.createPortal( /*#__PURE__*/React__namespace.createElement(context.Provider, {
|
|
1852
|
+
value: useInjectStore
|
|
1853
|
+
}, children), useInjectStore, null));
|
|
1851
1854
|
}
|
|
1852
1855
|
|
|
1853
1856
|
reconciler.injectIntoDevTools({
|
|
@@ -1869,6 +1872,7 @@ exports.createPortal = createPortal;
|
|
|
1869
1872
|
exports.createRoot = createRoot;
|
|
1870
1873
|
exports.dispose = dispose;
|
|
1871
1874
|
exports.extend = extend;
|
|
1875
|
+
exports.getRootState = getRootState;
|
|
1872
1876
|
exports.invalidate = invalidate;
|
|
1873
1877
|
exports.omit = omit;
|
|
1874
1878
|
exports.pick = pick;
|
|
@@ -1879,7 +1883,7 @@ exports.threeTypes = threeTypes;
|
|
|
1879
1883
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
1880
1884
|
exports.useFrame = useFrame;
|
|
1881
1885
|
exports.useGraph = useGraph;
|
|
1882
|
-
exports.useInject = useInject;
|
|
1883
1886
|
exports.useLoader = useLoader;
|
|
1887
|
+
exports.useMemoizedFn = useMemoizedFn;
|
|
1884
1888
|
exports.useStore = useStore;
|
|
1885
1889
|
exports.useThree = useThree;
|