@react-three/drei 9.88.17 → 9.89.1
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/core/Bounds.cjs.js +1 -1
- package/core/Bounds.d.ts +16 -10
- package/core/Bounds.js +149 -116
- package/core/Outlines.cjs.js +1 -1
- package/core/Outlines.js +6 -3
- package/core/useGLTF.d.ts +3 -2
- package/core/useGLTF.js +1 -3
- package/index.cjs.js +1 -1
- package/package.json +1 -1
- package/react-three-drei-0.0.0-semantic-release.tgz +0 -0
package/core/Bounds.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("three"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("three"),r=require("@react-three/fiber");function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var o=n(e),c=n(t),a=function(e){return e[e.NONE=0]="NONE",e[e.START=1]="START",e[e.ACTIVE=2]="ACTIVE",e}(a||{});const u=e=>e&&e.isOrthographicCamera,i=e=>1-Math.exp(-5*e)+.007*e,s=o.createContext(null);exports.Bounds=function({children:e,maxDuration:t=1,margin:n=1.2,observe:m,fit:p,clip:l,interpolateFunc:x=i,onFit:d}){const f=o.useRef(null),{camera:h,size:y,invalidate:g}=r.useThree(),v=r.useThree((e=>e.controls)),R=o.useRef(d);R.current=d;const M=o.useRef({camPos:new c.Vector3,camRot:new c.Quaternion,camZoom:1}),P=o.useRef({camPos:void 0,camRot:void 0,camZoom:void 0,camUp:void 0,target:void 0}),w=o.useRef(a.NONE),T=o.useRef(0),[V]=o.useState((()=>new c.Box3)),A=o.useMemo((()=>{function e(){const e=V.getSize(new c.Vector3),t=V.getCenter(new c.Vector3),r=Math.max(e.x,e.y,e.z),o=u(h)?4*r:r/(2*Math.atan(Math.PI*h.fov/360)),a=u(h)?4*r:o/h.aspect,i=n*Math.max(o,a);return{box:V,size:e,center:t,distance:i}}return{getSize:e,refresh(e){if((t=e)&&t.isBox3)V.copy(e);else{const t=e||f.current;if(!t)return this;t.updateWorldMatrix(!0,!0),V.setFromObject(t)}var t;if(V.isEmpty()){const e=h.position.length()||10;V.setFromCenterAndSize(new c.Vector3,new c.Vector3(e,e,e))}return M.current.camPos.copy(h.position),M.current.camRot.copy(h.quaternion),u(h)&&(M.current.camZoom=h.zoom),P.current.camPos=void 0,P.current.camRot=void 0,P.current.camZoom=void 0,P.current.camUp=void 0,P.current.target=void 0,this},reset(){const{center:t,distance:r}=e(),n=h.position.clone().sub(t).normalize();P.current.camPos=t.clone().addScaledVector(n,r),P.current.target=t.clone();const o=(new c.Matrix4).lookAt(P.current.camPos,P.current.target,h.up);return P.current.camRot=(new c.Quaternion).setFromRotationMatrix(o),w.current=a.START,T.current=0,this},moveTo(e){return P.current.camPos=Array.isArray(e)?new c.Vector3(...e):e.clone(),w.current=a.START,T.current=0,this},lookAt({target:e,up:t}){P.current.target=Array.isArray(e)?new c.Vector3(...e):e.clone(),P.current.camUp=t?Array.isArray(t)?new c.Vector3(...t):t.clone():h.up.clone();const r=(new c.Matrix4).lookAt(P.current.camPos||h.position,P.current.target,P.current.camUp);return P.current.camRot=(new c.Quaternion).setFromRotationMatrix(r),w.current=a.START,T.current=0,this},to({position:e,target:t}){return this.moveTo(e).lookAt({target:t})},fit(){if(!u(h))return this;let e=0,t=0;const r=[new c.Vector3(V.min.x,V.min.y,V.min.z),new c.Vector3(V.min.x,V.max.y,V.min.z),new c.Vector3(V.min.x,V.min.y,V.max.z),new c.Vector3(V.min.x,V.max.y,V.max.z),new c.Vector3(V.max.x,V.max.y,V.max.z),new c.Vector3(V.max.x,V.max.y,V.min.z),new c.Vector3(V.max.x,V.min.y,V.max.z),new c.Vector3(V.max.x,V.min.y,V.min.z)],o=P.current.camPos||h.position,i=P.current.target||(null==v?void 0:v.target),s=P.current.camUp||h.up,m=i?(new c.Matrix4).lookAt(o,i,s).setPosition(o).invert():h.matrixWorldInverse;for(const n of r)n.applyMatrix4(m),e=Math.max(e,Math.abs(n.y)),t=Math.max(t,Math.abs(n.x));e*=2,t*=2;const p=(h.top-h.bottom)/e,l=(h.right-h.left)/t;return P.current.camZoom=Math.min(p,l)/n,w.current=a.START,T.current=0,R.current&&R.current(this.getSize()),this},clip(){const{distance:t}=e();return h.near=t/100,h.far=100*t,h.updateProjectionMatrix(),v&&(v.maxDistance=10*t,v.update()),g(),this}}}),[V,h,v,n,g]);o.useLayoutEffect((()=>{if(v){const e=()=>{if(v&&P.current.target&&w.current!==a.NONE){const e=(new c.Vector3).setFromMatrixColumn(h.matrix,2),t=M.current.camPos.distanceTo(v.target),r=(P.current.camPos||M.current.camPos).distanceTo(P.current.target),n=(1-T.current)*t+T.current*r;v.target.copy(h.position).addScaledVector(e,-n),v.update()}w.current=a.NONE};return v.addEventListener("start",e),()=>v.removeEventListener("start",e)}}),[v]);const z=o.useRef(0);return o.useLayoutEffect((()=>{(m||0==z.current++)&&(A.refresh(),p&&A.fit(),l&&A.clip())}),[y,l,p,m,h,v]),r.useFrame(((e,r)=>{if(w.current===a.START)w.current=a.ACTIVE,g();else if(w.current===a.ACTIVE){if(T.current+=r/t,T.current>=1)P.current.camPos&&h.position.copy(P.current.camPos),P.current.camRot&&h.quaternion.copy(P.current.camRot),P.current.camUp&&h.up.copy(P.current.camUp),P.current.camZoom&&u(h)&&(h.zoom=P.current.camZoom),h.updateMatrixWorld(),h.updateProjectionMatrix(),v&&P.current.target&&(v.target.copy(P.current.target),v.update()),w.current=a.NONE;else{const e=x(T.current);P.current.camPos&&h.position.lerpVectors(M.current.camPos,P.current.camPos,e),P.current.camRot&&h.quaternion.slerpQuaternions(M.current.camRot,P.current.camRot,e),P.current.camZoom&&u(h)&&(h.zoom=(1-e)*M.current.camZoom+e*P.current.camZoom),h.updateMatrixWorld(),h.updateProjectionMatrix()}g()}})),o.createElement("group",{ref:f},o.createElement(s.Provider,{value:A},e))},exports.useBounds=function(){return o.useContext(s)};
|
package/core/Bounds.d.ts
CHANGED
|
@@ -9,21 +9,27 @@ export type SizeProps = {
|
|
|
9
9
|
export type BoundsApi = {
|
|
10
10
|
getSize: () => SizeProps;
|
|
11
11
|
refresh(object?: THREE.Object3D | THREE.Box3): any;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
reset(): any;
|
|
13
|
+
moveTo(position: THREE.Vector3 | [number, number, number]): any;
|
|
14
|
+
lookAt({ target, up, }: {
|
|
15
|
+
target?: THREE.Vector3 | [number, number, number];
|
|
16
|
+
up?: THREE.Vector3 | [number, number, number];
|
|
17
|
+
}): any;
|
|
18
|
+
to({ position, target }: {
|
|
15
19
|
position: [number, number, number];
|
|
16
|
-
target
|
|
17
|
-
})
|
|
20
|
+
target: [number, number, number];
|
|
21
|
+
}): any;
|
|
22
|
+
fit(): any;
|
|
23
|
+
clip(): any;
|
|
18
24
|
};
|
|
19
25
|
export type BoundsProps = JSX.IntrinsicElements['group'] & {
|
|
20
|
-
|
|
26
|
+
maxDuration?: number;
|
|
27
|
+
margin?: number;
|
|
28
|
+
observe?: boolean;
|
|
21
29
|
fit?: boolean;
|
|
22
30
|
clip?: boolean;
|
|
23
|
-
|
|
24
|
-
margin?: number;
|
|
25
|
-
eps?: number;
|
|
31
|
+
interpolateFunc?: (t: number) => number;
|
|
26
32
|
onFit?: (data: SizeProps) => void;
|
|
27
33
|
};
|
|
28
|
-
export declare function Bounds({ children,
|
|
34
|
+
export declare function Bounds({ children, maxDuration, margin, observe, fit, clip, interpolateFunc, onFit, }: BoundsProps): React.JSX.Element;
|
|
29
35
|
export declare function useBounds(): BoundsApi;
|
package/core/Bounds.js
CHANGED
|
@@ -2,60 +2,66 @@ import * as React from 'react';
|
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { useThree, useFrame } from '@react-three/fiber';
|
|
4
4
|
|
|
5
|
+
// eslint-disable-next-line no-shadow
|
|
6
|
+
var AnimationState = /*#__PURE__*/function (AnimationState) {
|
|
7
|
+
AnimationState[AnimationState["NONE"] = 0] = "NONE";
|
|
8
|
+
AnimationState[AnimationState["START"] = 1] = "START";
|
|
9
|
+
AnimationState[AnimationState["ACTIVE"] = 2] = "ACTIVE";
|
|
10
|
+
return AnimationState;
|
|
11
|
+
}(AnimationState || {});
|
|
5
12
|
const isOrthographic = def => def && def.isOrthographicCamera;
|
|
6
13
|
const isBox3 = def => def && def.isBox3;
|
|
7
|
-
const
|
|
14
|
+
const interpolateFuncDefault = t => {
|
|
15
|
+
// Imitates the previously used THREE.MathUtils.damp
|
|
16
|
+
return 1 - Math.exp(-5 * t) + 0.007 * t;
|
|
17
|
+
};
|
|
18
|
+
const context = /*#__PURE__*/React.createContext(null);
|
|
8
19
|
function Bounds({
|
|
9
20
|
children,
|
|
10
|
-
|
|
21
|
+
maxDuration = 1.0,
|
|
22
|
+
margin = 1.2,
|
|
23
|
+
observe,
|
|
11
24
|
fit,
|
|
12
25
|
clip,
|
|
13
|
-
|
|
14
|
-
margin = 1.2,
|
|
15
|
-
eps = 0.01,
|
|
26
|
+
interpolateFunc = interpolateFuncDefault,
|
|
16
27
|
onFit
|
|
17
28
|
}) {
|
|
18
29
|
const ref = React.useRef(null);
|
|
19
30
|
const {
|
|
20
31
|
camera,
|
|
21
|
-
invalidate,
|
|
22
32
|
size,
|
|
23
|
-
|
|
33
|
+
invalidate
|
|
24
34
|
} = useThree();
|
|
25
|
-
const controls =
|
|
35
|
+
const controls = useThree(state => state.controls);
|
|
26
36
|
const onFitRef = React.useRef(onFit);
|
|
27
37
|
onFitRef.current = onFit;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
focus: new THREE.Vector3(),
|
|
44
|
-
camera: new THREE.Vector3(),
|
|
45
|
-
zoom: 1
|
|
46
|
-
}));
|
|
38
|
+
const origin = React.useRef({
|
|
39
|
+
camPos: new THREE.Vector3(),
|
|
40
|
+
camRot: new THREE.Quaternion(),
|
|
41
|
+
camZoom: 1
|
|
42
|
+
});
|
|
43
|
+
const goal = React.useRef({
|
|
44
|
+
camPos: undefined,
|
|
45
|
+
camRot: undefined,
|
|
46
|
+
camZoom: undefined,
|
|
47
|
+
camUp: undefined,
|
|
48
|
+
target: undefined
|
|
49
|
+
});
|
|
50
|
+
const animationState = React.useRef(AnimationState.NONE);
|
|
51
|
+
const t = React.useRef(0); // represent animation state from 0 to 1
|
|
52
|
+
|
|
47
53
|
const [box] = React.useState(() => new THREE.Box3());
|
|
48
54
|
const api = React.useMemo(() => {
|
|
49
55
|
function getSize() {
|
|
50
|
-
const
|
|
56
|
+
const boxSize = box.getSize(new THREE.Vector3());
|
|
51
57
|
const center = box.getCenter(new THREE.Vector3());
|
|
52
|
-
const maxSize = Math.max(
|
|
58
|
+
const maxSize = Math.max(boxSize.x, boxSize.y, boxSize.z);
|
|
53
59
|
const fitHeightDistance = isOrthographic(camera) ? maxSize * 4 : maxSize / (2 * Math.atan(Math.PI * camera.fov / 360));
|
|
54
60
|
const fitWidthDistance = isOrthographic(camera) ? maxSize * 4 : fitHeightDistance / camera.aspect;
|
|
55
61
|
const distance = margin * Math.max(fitHeightDistance, fitWidthDistance);
|
|
56
62
|
return {
|
|
57
63
|
box,
|
|
58
|
-
size,
|
|
64
|
+
size: boxSize,
|
|
59
65
|
center,
|
|
60
66
|
distance
|
|
61
67
|
};
|
|
@@ -73,102 +79,122 @@ function Bounds({
|
|
|
73
79
|
const max = camera.position.length() || 10;
|
|
74
80
|
box.setFromCenterAndSize(new THREE.Vector3(), new THREE.Vector3(max, max, max));
|
|
75
81
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
82
|
+
origin.current.camPos.copy(camera.position);
|
|
83
|
+
origin.current.camRot.copy(camera.quaternion);
|
|
84
|
+
isOrthographic(camera) && (origin.current.camZoom = camera.zoom);
|
|
85
|
+
goal.current.camPos = undefined;
|
|
86
|
+
goal.current.camRot = undefined;
|
|
87
|
+
goal.current.camZoom = undefined;
|
|
88
|
+
goal.current.camUp = undefined;
|
|
89
|
+
goal.current.target = undefined;
|
|
85
90
|
return this;
|
|
86
91
|
},
|
|
87
|
-
|
|
92
|
+
reset() {
|
|
88
93
|
const {
|
|
94
|
+
center,
|
|
89
95
|
distance
|
|
90
96
|
} = getSize();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
const direction = camera.position.clone().sub(center).normalize();
|
|
98
|
+
goal.current.camPos = center.clone().addScaledVector(direction, distance);
|
|
99
|
+
goal.current.target = center.clone();
|
|
100
|
+
const mCamRot = new THREE.Matrix4().lookAt(goal.current.camPos, goal.current.target, camera.up);
|
|
101
|
+
goal.current.camRot = new THREE.Quaternion().setFromRotationMatrix(mCamRot);
|
|
102
|
+
animationState.current = AnimationState.START;
|
|
103
|
+
t.current = 0;
|
|
104
|
+
return this;
|
|
105
|
+
},
|
|
106
|
+
moveTo(position) {
|
|
107
|
+
goal.current.camPos = Array.isArray(position) ? new THREE.Vector3(...position) : position.clone();
|
|
108
|
+
animationState.current = AnimationState.START;
|
|
109
|
+
t.current = 0;
|
|
110
|
+
return this;
|
|
111
|
+
},
|
|
112
|
+
lookAt({
|
|
113
|
+
target,
|
|
114
|
+
up
|
|
115
|
+
}) {
|
|
116
|
+
goal.current.target = Array.isArray(target) ? new THREE.Vector3(...target) : target.clone();
|
|
117
|
+
if (up) {
|
|
118
|
+
goal.current.camUp = Array.isArray(up) ? new THREE.Vector3(...up) : up.clone();
|
|
119
|
+
} else {
|
|
120
|
+
goal.current.camUp = camera.up.clone();
|
|
121
|
+
}
|
|
122
|
+
const mCamRot = new THREE.Matrix4().lookAt(goal.current.camPos || camera.position, goal.current.target, goal.current.camUp);
|
|
123
|
+
goal.current.camRot = new THREE.Quaternion().setFromRotationMatrix(mCamRot);
|
|
124
|
+
animationState.current = AnimationState.START;
|
|
125
|
+
t.current = 0;
|
|
97
126
|
return this;
|
|
98
127
|
},
|
|
128
|
+
/**
|
|
129
|
+
* @deprecated Use moveTo and lookAt instead
|
|
130
|
+
*/
|
|
99
131
|
to({
|
|
100
132
|
position,
|
|
101
133
|
target
|
|
102
134
|
}) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
goal.focus.copy(center);
|
|
135
|
+
return this.moveTo(position).lookAt({
|
|
136
|
+
target
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
fit() {
|
|
140
|
+
if (!isOrthographic(camera)) {
|
|
141
|
+
// Fit should only modify zoom now. Thus avoid executing it if the camera isn't orthographic
|
|
142
|
+
return this;
|
|
112
143
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
144
|
+
let maxHeight = 0,
|
|
145
|
+
maxWidth = 0;
|
|
146
|
+
const vertices = [new THREE.Vector3(box.min.x, box.min.y, box.min.z), new THREE.Vector3(box.min.x, box.max.y, box.min.z), new THREE.Vector3(box.min.x, box.min.y, box.max.z), new THREE.Vector3(box.min.x, box.max.y, box.max.z), new THREE.Vector3(box.max.x, box.max.y, box.max.z), new THREE.Vector3(box.max.x, box.max.y, box.min.z), new THREE.Vector3(box.max.x, box.min.y, box.max.z), new THREE.Vector3(box.max.x, box.min.y, box.min.z)];
|
|
147
|
+
|
|
148
|
+
// Transform the center and each corner to camera space
|
|
149
|
+
const pos = goal.current.camPos || camera.position;
|
|
150
|
+
const target = goal.current.target || (controls == null ? void 0 : controls.target);
|
|
151
|
+
const up = goal.current.camUp || camera.up;
|
|
152
|
+
const mCamWInv = target ? new THREE.Matrix4().lookAt(pos, target, up).setPosition(pos).invert() : camera.matrixWorldInverse;
|
|
153
|
+
for (const v of vertices) {
|
|
154
|
+
v.applyMatrix4(mCamWInv);
|
|
155
|
+
maxHeight = Math.max(maxHeight, Math.abs(v.y));
|
|
156
|
+
maxWidth = Math.max(maxWidth, Math.abs(v.x));
|
|
117
157
|
}
|
|
158
|
+
maxHeight *= 2;
|
|
159
|
+
maxWidth *= 2;
|
|
160
|
+
const zoomForHeight = (camera.top - camera.bottom) / maxHeight;
|
|
161
|
+
const zoomForWidth = (camera.right - camera.left) / maxWidth;
|
|
162
|
+
goal.current.camZoom = Math.min(zoomForHeight, zoomForWidth) / margin;
|
|
163
|
+
animationState.current = AnimationState.START;
|
|
164
|
+
t.current = 0;
|
|
165
|
+
onFitRef.current && onFitRef.current(this.getSize());
|
|
118
166
|
return this;
|
|
119
167
|
},
|
|
120
|
-
|
|
121
|
-
current.camera.copy(camera.position);
|
|
122
|
-
if (controls) current.focus.copy(controls.target);
|
|
168
|
+
clip() {
|
|
123
169
|
const {
|
|
124
|
-
center,
|
|
125
170
|
distance
|
|
126
171
|
} = getSize();
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
maxWidth = 0;
|
|
134
|
-
const vertices = [new THREE.Vector3(box.min.x, box.min.y, box.min.z), new THREE.Vector3(box.min.x, box.max.y, box.min.z), new THREE.Vector3(box.min.x, box.min.y, box.max.z), new THREE.Vector3(box.min.x, box.max.y, box.max.z), new THREE.Vector3(box.max.x, box.max.y, box.max.z), new THREE.Vector3(box.max.x, box.max.y, box.min.z), new THREE.Vector3(box.max.x, box.min.y, box.max.z), new THREE.Vector3(box.max.x, box.min.y, box.min.z)];
|
|
135
|
-
// Transform the center and each corner to camera space
|
|
136
|
-
center.applyMatrix4(camera.matrixWorldInverse);
|
|
137
|
-
for (const v of vertices) {
|
|
138
|
-
v.applyMatrix4(camera.matrixWorldInverse);
|
|
139
|
-
maxHeight = Math.max(maxHeight, Math.abs(v.y - center.y));
|
|
140
|
-
maxWidth = Math.max(maxWidth, Math.abs(v.x - center.x));
|
|
141
|
-
}
|
|
142
|
-
maxHeight *= 2;
|
|
143
|
-
maxWidth *= 2;
|
|
144
|
-
const zoomForHeight = (camera.top - camera.bottom) / maxHeight;
|
|
145
|
-
const zoomForWidth = (camera.right - camera.left) / maxWidth;
|
|
146
|
-
goal.zoom = Math.min(zoomForHeight, zoomForWidth) / margin;
|
|
147
|
-
if (!damping) {
|
|
148
|
-
camera.zoom = goal.zoom;
|
|
149
|
-
camera.updateProjectionMatrix();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (damping) {
|
|
153
|
-
current.animating = true;
|
|
154
|
-
} else {
|
|
155
|
-
camera.position.copy(goal.camera);
|
|
156
|
-
camera.lookAt(goal.focus);
|
|
157
|
-
if (controls) {
|
|
158
|
-
controls.target.copy(goal.focus);
|
|
159
|
-
controls.update();
|
|
160
|
-
}
|
|
172
|
+
camera.near = distance / 100;
|
|
173
|
+
camera.far = distance * 100;
|
|
174
|
+
camera.updateProjectionMatrix();
|
|
175
|
+
if (controls) {
|
|
176
|
+
controls.maxDistance = distance * 10;
|
|
177
|
+
controls.update();
|
|
161
178
|
}
|
|
162
|
-
if (onFitRef.current) onFitRef.current(this.getSize());
|
|
163
179
|
invalidate();
|
|
164
180
|
return this;
|
|
165
181
|
}
|
|
166
182
|
};
|
|
167
|
-
}, [box, camera, controls, margin,
|
|
183
|
+
}, [box, camera, controls, margin, invalidate]);
|
|
168
184
|
React.useLayoutEffect(() => {
|
|
169
185
|
if (controls) {
|
|
170
186
|
// Try to prevent drag hijacking
|
|
171
|
-
const callback = () =>
|
|
187
|
+
const callback = () => {
|
|
188
|
+
if (controls && goal.current.target && animationState.current !== AnimationState.NONE) {
|
|
189
|
+
const front = new THREE.Vector3().setFromMatrixColumn(camera.matrix, 2);
|
|
190
|
+
const d0 = origin.current.camPos.distanceTo(controls.target);
|
|
191
|
+
const d1 = (goal.current.camPos || origin.current.camPos).distanceTo(goal.current.target);
|
|
192
|
+
const d = (1 - t.current) * d0 + t.current * d1;
|
|
193
|
+
controls.target.copy(camera.position).addScaledVector(front, -d);
|
|
194
|
+
controls.update();
|
|
195
|
+
}
|
|
196
|
+
animationState.current = AnimationState.NONE;
|
|
197
|
+
};
|
|
172
198
|
controls.addEventListener('start', callback);
|
|
173
199
|
return () => controls.removeEventListener('start', callback);
|
|
174
200
|
}
|
|
@@ -184,26 +210,33 @@ function Bounds({
|
|
|
184
210
|
}
|
|
185
211
|
}, [size, clip, fit, observe, camera, controls]);
|
|
186
212
|
useFrame((state, delta) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
213
|
+
// This [additional animation step START] is needed to guarantee that delta used in animation isn't absurdly high (2-3 seconds) which is actually possible if rendering happens on demand...
|
|
214
|
+
if (animationState.current === AnimationState.START) {
|
|
215
|
+
animationState.current = AnimationState.ACTIVE;
|
|
216
|
+
invalidate();
|
|
217
|
+
} else if (animationState.current === AnimationState.ACTIVE) {
|
|
218
|
+
t.current += delta / maxDuration;
|
|
219
|
+
if (t.current >= 1) {
|
|
220
|
+
goal.current.camPos && camera.position.copy(goal.current.camPos);
|
|
221
|
+
goal.current.camRot && camera.quaternion.copy(goal.current.camRot);
|
|
222
|
+
goal.current.camUp && camera.up.copy(goal.current.camUp);
|
|
223
|
+
goal.current.camZoom && isOrthographic(camera) && (camera.zoom = goal.current.camZoom);
|
|
224
|
+
camera.updateMatrixWorld();
|
|
194
225
|
camera.updateProjectionMatrix();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
226
|
+
if (controls && goal.current.target) {
|
|
227
|
+
controls.target.copy(goal.current.target);
|
|
228
|
+
controls.update();
|
|
229
|
+
}
|
|
230
|
+
animationState.current = AnimationState.NONE;
|
|
198
231
|
} else {
|
|
199
|
-
|
|
200
|
-
|
|
232
|
+
const k = interpolateFunc(t.current);
|
|
233
|
+
goal.current.camPos && camera.position.lerpVectors(origin.current.camPos, goal.current.camPos, k);
|
|
234
|
+
goal.current.camRot && camera.quaternion.slerpQuaternions(origin.current.camRot, goal.current.camRot, k);
|
|
235
|
+
goal.current.camZoom && isOrthographic(camera) && (camera.zoom = (1 - k) * origin.current.camZoom + k * goal.current.camZoom);
|
|
236
|
+
camera.updateMatrixWorld();
|
|
237
|
+
camera.updateProjectionMatrix();
|
|
201
238
|
}
|
|
202
239
|
invalidate();
|
|
203
|
-
if (isOrthographic(camera) && !(Math.abs(current.zoom - goal.zoom) < eps)) return;
|
|
204
|
-
if (!isOrthographic(camera) && !equals(current.camera, goal.camera)) return;
|
|
205
|
-
if (controls && !equals(current.focus, goal.focus)) return;
|
|
206
|
-
current.animating = false;
|
|
207
240
|
}
|
|
208
241
|
});
|
|
209
242
|
return /*#__PURE__*/React.createElement("group", {
|
package/core/Outlines.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),n=require("three"),t=require("react"),r=require("./shaderMaterial.cjs.js"),i=require("@react-three/fiber"),o=require("three-stdlib"),c=require("../helpers/constants.cjs.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:function(){return e[t]}})}})),n.default=e,Object.freeze(n)}var l=s(e),u=a(n),d=a(t);const f=r.shaderMaterial({screenspace:!1,color:new u.Color("black"),opacity:1,thickness:.05,size:new u.Vector2},"#include <common>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n uniform float thickness;\n uniform float screenspace;\n uniform vec2 size;\n void main() {\n #if defined (USE_SKINNING)\n\t #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #endif\n #include <begin_vertex>\n\t #include <morphtarget_vertex>\n\t #include <skinning_vertex>\n #include <project_vertex>\n vec4 tNormal = vec4(normal, 0.0);\n vec4 tPosition = vec4(transformed, 1.0);\n #ifdef USE_INSTANCING\n tNormal = instanceMatrix * tNormal;\n tPosition = instanceMatrix * tPosition;\n #endif\n if (screenspace == 0.0) {\n vec3 newPosition = tPosition.xyz + tNormal.xyz * thickness;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); \n } else {\n vec4 clipPosition = projectionMatrix * modelViewMatrix * tPosition;\n vec4 clipNormal = projectionMatrix * modelViewMatrix * tNormal;\n vec2 offset = normalize(clipNormal.xy) * thickness / size * clipPosition.w * 2.0;\n clipPosition.xy += offset;\n gl_Position = clipPosition;\n }\n }",`uniform vec3 color;\n uniform float opacity;\n void main(){\n gl_FragColor = vec4(color, opacity);\n #include <tonemapping_fragment>\n #include <${c.version>=154?"colorspace_fragment":"encodings_fragment"}>\n }`);exports.Outlines=function({color:e="black",opacity:n=1,transparent:t=!1,screenspace:r=!1,toneMapped:c=!0,polygonOffset:s=!1,polygonOffsetFactor:a=0,renderOrder:p=0,thickness:m=.05,angle:g=Math.PI,...v}){const x=d.useRef(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),n=require("three"),t=require("react"),r=require("./shaderMaterial.cjs.js"),i=require("@react-three/fiber"),o=require("three-stdlib"),c=require("../helpers/constants.cjs.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:function(){return e[t]}})}})),n.default=e,Object.freeze(n)}var l=s(e),u=a(n),d=a(t);const f=r.shaderMaterial({screenspace:!1,color:new u.Color("black"),opacity:1,thickness:.05,size:new u.Vector2},"#include <common>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n uniform float thickness;\n uniform float screenspace;\n uniform vec2 size;\n void main() {\n #if defined (USE_SKINNING)\n\t #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #endif\n #include <begin_vertex>\n\t #include <morphtarget_vertex>\n\t #include <skinning_vertex>\n #include <project_vertex>\n vec4 tNormal = vec4(normal, 0.0);\n vec4 tPosition = vec4(transformed, 1.0);\n #ifdef USE_INSTANCING\n tNormal = instanceMatrix * tNormal;\n tPosition = instanceMatrix * tPosition;\n #endif\n if (screenspace == 0.0) {\n vec3 newPosition = tPosition.xyz + tNormal.xyz * thickness;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); \n } else {\n vec4 clipPosition = projectionMatrix * modelViewMatrix * tPosition;\n vec4 clipNormal = projectionMatrix * modelViewMatrix * tNormal;\n vec2 offset = normalize(clipNormal.xy) * thickness / size * clipPosition.w * 2.0;\n clipPosition.xy += offset;\n gl_Position = clipPosition;\n }\n }",`uniform vec3 color;\n uniform float opacity;\n void main(){\n gl_FragColor = vec4(color, opacity);\n #include <tonemapping_fragment>\n #include <${c.version>=154?"colorspace_fragment":"encodings_fragment"}>\n }`);exports.Outlines=function({color:e="black",opacity:n=1,transparent:t=!1,screenspace:r=!1,toneMapped:c=!0,polygonOffset:s=!1,polygonOffsetFactor:a=0,renderOrder:p=0,thickness:m=.05,angle:g=Math.PI,...v}){const x=d.useRef(),[y]=d.useState((()=>new f({side:u.BackSide}))),{gl:h}=i.useThree(),_=h.getDrawingBufferSize(new u.Vector2);d.useMemo((()=>i.extend({OutlinesMaterial:f})),[]);const M=d.useRef(0),b=d.useRef();return d.useLayoutEffect((()=>{const e=x.current;if(!e)return;const n=e.parent;if(n&&n.geometry&&(M.current!==g||b.current!==n.geometry)){M.current=g,b.current=n.geometry;let t=e.children[0];t&&(g&&t.geometry.dispose(),e.remove(t)),n.skeleton?(t=new u.SkinnedMesh,t.material=y,t.bind(n.skeleton,n.bindMatrix),e.add(t)):n.isInstancedMesh?(t=new u.InstancedMesh(n.geometry,y,n.count),t.instanceMatrix=n.instanceMatrix,e.add(t)):(t=new u.Mesh,t.material=y,e.add(t)),t.geometry=g?o.toCreasedNormals(n.geometry,g):n.geometry}})),d.useLayoutEffect((()=>{const o=x.current;if(!o)return;const l=o.children[0];l&&(l.renderOrder=p,i.applyProps(l.material,{transparent:t,thickness:m,color:e,opacity:n,size:_,screenspace:r,toneMapped:c,polygonOffset:s,polygonOffsetFactor:a}))})),d.useEffect((()=>()=>{const e=x.current;if(!e)return;const n=e.children[0];n&&(g&&n.geometry.dispose(),e.remove(n))}),[]),d.createElement("group",l.default({ref:x},v))};
|
package/core/Outlines.js
CHANGED
|
@@ -66,7 +66,7 @@ function Outlines({
|
|
|
66
66
|
angle = Math.PI,
|
|
67
67
|
...props
|
|
68
68
|
}) {
|
|
69
|
-
const ref = React.useRef(
|
|
69
|
+
const ref = React.useRef();
|
|
70
70
|
const [material] = React.useState(() => new OutlinesMaterial({
|
|
71
71
|
side: THREE.BackSide
|
|
72
72
|
}));
|
|
@@ -78,9 +78,10 @@ function Outlines({
|
|
|
78
78
|
OutlinesMaterial
|
|
79
79
|
}), []);
|
|
80
80
|
const oldAngle = React.useRef(0);
|
|
81
|
-
const oldGeometry = React.useRef(
|
|
81
|
+
const oldGeometry = React.useRef();
|
|
82
82
|
React.useLayoutEffect(() => {
|
|
83
83
|
const group = ref.current;
|
|
84
|
+
if (!group) return;
|
|
84
85
|
const parent = group.parent;
|
|
85
86
|
if (parent && parent.geometry) {
|
|
86
87
|
if (oldAngle.current !== angle || oldGeometry.current !== parent.geometry) {
|
|
@@ -113,6 +114,7 @@ function Outlines({
|
|
|
113
114
|
});
|
|
114
115
|
React.useLayoutEffect(() => {
|
|
115
116
|
const group = ref.current;
|
|
117
|
+
if (!group) return;
|
|
116
118
|
const mesh = group.children[0];
|
|
117
119
|
if (mesh) {
|
|
118
120
|
mesh.renderOrder = renderOrder;
|
|
@@ -133,7 +135,8 @@ function Outlines({
|
|
|
133
135
|
return () => {
|
|
134
136
|
// Dispose everything on unmount
|
|
135
137
|
const group = ref.current;
|
|
136
|
-
|
|
138
|
+
if (!group) return;
|
|
139
|
+
const mesh = group.children[0];
|
|
137
140
|
if (mesh) {
|
|
138
141
|
if (angle) mesh.geometry.dispose();
|
|
139
142
|
group.remove(mesh);
|
package/core/useGLTF.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { GLTFLoader } from 'three-stdlib';
|
|
2
|
-
|
|
1
|
+
import { type GLTF, GLTFLoader } from 'three-stdlib';
|
|
2
|
+
import { type ObjectMap } from '@react-three/fiber';
|
|
3
|
+
export declare function useGLTF<T extends string | string[]>(path: T, useDraco?: boolean | string, useMeshOpt?: boolean, extendLoader?: (loader: GLTFLoader) => void): T extends any[] ? (GLTF & ObjectMap)[] : GLTF & ObjectMap;
|
|
3
4
|
export declare namespace useGLTF {
|
|
4
5
|
var preload: (path: string | string[], useDraco?: string | boolean, useMeshOpt?: boolean, extendLoader?: ((loader: GLTFLoader) => void) | undefined) => undefined;
|
|
5
6
|
var clear: (input: string | string[]) => void;
|
package/core/useGLTF.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { GLTFLoader, DRACOLoader, MeshoptDecoder } from 'three-stdlib';
|
|
2
2
|
import { useLoader } from '@react-three/fiber';
|
|
3
3
|
|
|
4
|
-
// @ts-ignore
|
|
5
4
|
let dracoLoader = null;
|
|
6
5
|
let decoderPath = 'https://www.gstatic.com/draco/versioned/decoders/1.5.5/';
|
|
7
6
|
function extensions(useDraco, useMeshopt, extendLoader) {
|
|
@@ -22,8 +21,7 @@ function extensions(useDraco, useMeshopt, extendLoader) {
|
|
|
22
21
|
};
|
|
23
22
|
}
|
|
24
23
|
function useGLTF(path, useDraco = true, useMeshOpt = true, extendLoader) {
|
|
25
|
-
|
|
26
|
-
return gltf;
|
|
24
|
+
return useLoader(GLTFLoader, path, extensions(useDraco, useMeshOpt, extendLoader));
|
|
27
25
|
}
|
|
28
26
|
useGLTF.preload = (path, useDraco = true, useMeshOpt = true, extendLoader) => useLoader.preload(GLTFLoader, path, extensions(useDraco, useMeshOpt, extendLoader));
|
|
29
27
|
useGLTF.clear = input => useLoader.clear(GLTFLoader, input);
|