@react-three/drei 11.0.0-alpha.5 → 11.0.0-alpha.7
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/README.md +19 -3
- package/core/index.d.mts +195 -52
- package/core/index.d.ts +195 -52
- package/core/index.mjs +543 -240
- package/experimental/index.d.mts +20 -0
- package/experimental/index.d.ts +20 -0
- package/external/index.d.mts +38 -2
- package/external/index.d.ts +38 -2
- package/external/index.mjs +3 -4
- package/index.d.mts +212 -54
- package/index.d.ts +212 -54
- package/index.mjs +544 -241
- package/legacy/index.d.mts +211 -56
- package/legacy/index.d.ts +211 -56
- package/legacy/index.mjs +687 -260
- package/native/index.d.mts +321 -392
- package/native/index.d.ts +321 -392
- package/native/index.mjs +1843 -1815
- package/package.json +7 -7
- package/webgpu/chunks/inspector-runtime.mjs +112 -0
- package/webgpu/index.d.mts +418 -398
- package/webgpu/index.d.ts +418 -398
- package/webgpu/index.mjs +2392 -1953
package/core/index.mjs
CHANGED
|
@@ -2,9 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import { forwardRef, useImperativeHandle, useMemo, useEffect, useCallback, useRef, useLayoutEffect, useState, Fragment, createContext, useContext } from 'react';
|
|
3
3
|
import { useThree, useFrame, extend, createPortal, useInstanceHandle, context as context$9, useLoader, applyProps, addEffect, addAfterEffect } from '@react-three/fiber';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
|
-
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, Object3D, CanvasTexture,
|
|
5
|
+
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, Object3D, CanvasTexture, PerspectiveCamera as PerspectiveCamera$1, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, BufferAttribute, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DoubleSide, DepthTexture, DepthFormat, UnsignedShortType, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, Camera, CubeReflectionMapping, EquirectangularReflectionMapping, Scene, RepeatWrapping } from 'three';
|
|
6
6
|
import { ArcballControls as ArcballControls$1 } from 'three/examples/jsm/controls/ArcballControls.js';
|
|
7
|
-
import { useGesture } from '@use-gesture/react';
|
|
8
7
|
import { FirstPersonControls as FirstPersonControls$1 } from 'three/examples/jsm/controls/FirstPersonControls.js';
|
|
9
8
|
import { FlyControls as FlyControls$1 } from 'three/examples/jsm/controls/FlyControls.js';
|
|
10
9
|
import { create as create$1 } from 'zustand';
|
|
@@ -13,6 +12,7 @@ import { MapControls as MapControls$1 } from 'three/examples/jsm/controls/MapCon
|
|
|
13
12
|
import { misc, easing } from 'maath';
|
|
14
13
|
import { OrbitControls as OrbitControls$1 } from 'three/addons/controls/OrbitControls.js';
|
|
15
14
|
import { PointerLockControls as PointerLockControls$1 } from 'three/examples/jsm/controls/PointerLockControls.js';
|
|
15
|
+
import { useGesture } from '@use-gesture/react';
|
|
16
16
|
import * as ReactDOM from 'react-dom/client';
|
|
17
17
|
import { TrackballControls as TrackballControls$1 } from 'three/examples/jsm/controls/TrackballControls.js';
|
|
18
18
|
import { SimplexNoise } from 'three/examples/jsm/math/SimplexNoise.js';
|
|
@@ -31,7 +31,6 @@ import { TransformControls as TransformControls$1 } from 'three/examples/jsm/con
|
|
|
31
31
|
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js';
|
|
32
32
|
import { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';
|
|
33
33
|
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
|
|
34
|
-
import { Events } from 'hls.js';
|
|
35
34
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
|
36
35
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
37
36
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
@@ -1172,11 +1171,11 @@ const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
|
1172
1171
|
);
|
|
1173
1172
|
|
|
1174
1173
|
const initialModelPosition = /* @__PURE__ */ new THREE.Vector3();
|
|
1175
|
-
const mousePosition2D = /* @__PURE__ */ new THREE.Vector2();
|
|
1176
1174
|
const mousePosition3D = /* @__PURE__ */ new THREE.Vector3();
|
|
1177
1175
|
const dragOffset = /* @__PURE__ */ new THREE.Vector3();
|
|
1178
1176
|
const dragPlaneNormal = /* @__PURE__ */ new THREE.Vector3();
|
|
1179
1177
|
const dragPlane = /* @__PURE__ */ new THREE.Plane();
|
|
1178
|
+
const startPointerPos = /* @__PURE__ */ new THREE.Vector3();
|
|
1180
1179
|
const DragControls = React.forwardRef(
|
|
1181
1180
|
({
|
|
1182
1181
|
autoTransform = true,
|
|
@@ -1192,90 +1191,132 @@ const DragControls = React.forwardRef(
|
|
|
1192
1191
|
...props
|
|
1193
1192
|
}, fRef) => {
|
|
1194
1193
|
const defaultControls = useThree((state) => state.controls);
|
|
1195
|
-
const { camera,
|
|
1194
|
+
const { camera, invalidate } = useThree();
|
|
1196
1195
|
const ref = React.useRef(null);
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
1232
|
-
raycaster.ray.intersectPlane(dragPlane, mousePosition3D);
|
|
1233
|
-
const previousLocalMatrix = ref.current.matrix.clone();
|
|
1234
|
-
const previousWorldMatrix = ref.current.matrixWorld.clone();
|
|
1235
|
-
const intendedNewPosition = new THREE.Vector3(
|
|
1236
|
-
mousePosition3D.x - dragOffset.x,
|
|
1237
|
-
mousePosition3D.y - dragOffset.y,
|
|
1238
|
-
mousePosition3D.z - dragOffset.z
|
|
1239
|
-
);
|
|
1240
|
-
if (dragLimits) {
|
|
1241
|
-
intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
|
|
1242
|
-
intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
|
|
1243
|
-
intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
|
|
1244
|
-
}
|
|
1245
|
-
if (autoTransform) {
|
|
1246
|
-
ref.current.matrix.setPosition(intendedNewPosition);
|
|
1247
|
-
const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
|
|
1248
|
-
const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
|
|
1249
|
-
onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
1250
|
-
} else {
|
|
1251
|
-
const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
|
|
1252
|
-
tempMatrix.setPosition(intendedNewPosition);
|
|
1253
|
-
const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
|
|
1254
|
-
const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
|
|
1255
|
-
onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
1196
|
+
const dragState = React.useRef({
|
|
1197
|
+
active: false,
|
|
1198
|
+
intentional: false,
|
|
1199
|
+
// Has moved past threshold
|
|
1200
|
+
pointerId: -1
|
|
1201
|
+
});
|
|
1202
|
+
const threshold = dragConfig?.threshold ?? 0;
|
|
1203
|
+
const filterTaps = dragConfig?.filterTaps ?? true;
|
|
1204
|
+
const handlePointerDown = React.useCallback(
|
|
1205
|
+
(event) => {
|
|
1206
|
+
event.stopPropagation();
|
|
1207
|
+
event.target.setPointerCapture(event.pointerId);
|
|
1208
|
+
dragState.current.active = true;
|
|
1209
|
+
dragState.current.intentional = threshold === 0;
|
|
1210
|
+
dragState.current.pointerId = event.pointerId;
|
|
1211
|
+
if (defaultControls) defaultControls.enabled = false;
|
|
1212
|
+
ref.current.matrix.decompose(initialModelPosition, new THREE.Quaternion(), new THREE.Vector3());
|
|
1213
|
+
mousePosition3D.copy(event.point);
|
|
1214
|
+
startPointerPos.copy(event.point);
|
|
1215
|
+
dragOffset.copy(mousePosition3D).sub(initialModelPosition);
|
|
1216
|
+
if (!axisLock) {
|
|
1217
|
+
camera.getWorldDirection(dragPlaneNormal).negate();
|
|
1218
|
+
} else {
|
|
1219
|
+
switch (axisLock) {
|
|
1220
|
+
case "x":
|
|
1221
|
+
dragPlaneNormal.set(1, 0, 0);
|
|
1222
|
+
break;
|
|
1223
|
+
case "y":
|
|
1224
|
+
dragPlaneNormal.set(0, 1, 0);
|
|
1225
|
+
break;
|
|
1226
|
+
case "z":
|
|
1227
|
+
dragPlaneNormal.set(0, 0, 1);
|
|
1228
|
+
break;
|
|
1256
1229
|
}
|
|
1257
|
-
invalidate();
|
|
1258
|
-
},
|
|
1259
|
-
onDragEnd: () => {
|
|
1260
|
-
if (defaultControls) defaultControls.enabled = true;
|
|
1261
|
-
onDragEnd && onDragEnd();
|
|
1262
|
-
invalidate();
|
|
1263
1230
|
}
|
|
1231
|
+
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
1232
|
+
if (dragState.current.intentional) {
|
|
1233
|
+
onDragStart && onDragStart(initialModelPosition);
|
|
1234
|
+
}
|
|
1235
|
+
invalidate();
|
|
1264
1236
|
},
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1237
|
+
[defaultControls, camera, axisLock, threshold, onDragStart, invalidate]
|
|
1238
|
+
);
|
|
1239
|
+
const handlePointerMove = React.useCallback(
|
|
1240
|
+
(event) => {
|
|
1241
|
+
if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
|
|
1242
|
+
const intersection = event.ray.intersectPlane(dragPlane, mousePosition3D);
|
|
1243
|
+
if (!intersection) return;
|
|
1244
|
+
if (!dragState.current.intentional) {
|
|
1245
|
+
const distance = mousePosition3D.distanceTo(startPointerPos);
|
|
1246
|
+
if (distance < threshold) return;
|
|
1247
|
+
dragState.current.intentional = true;
|
|
1248
|
+
onDragStart && onDragStart(initialModelPosition);
|
|
1270
1249
|
}
|
|
1271
|
-
|
|
1250
|
+
const previousLocalMatrix = ref.current.matrix.clone();
|
|
1251
|
+
const previousWorldMatrix = ref.current.matrixWorld.clone();
|
|
1252
|
+
const intendedNewPosition = new THREE.Vector3(
|
|
1253
|
+
mousePosition3D.x - dragOffset.x,
|
|
1254
|
+
mousePosition3D.y - dragOffset.y,
|
|
1255
|
+
mousePosition3D.z - dragOffset.z
|
|
1256
|
+
);
|
|
1257
|
+
if (dragLimits) {
|
|
1258
|
+
intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
|
|
1259
|
+
intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
|
|
1260
|
+
intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
|
|
1261
|
+
}
|
|
1262
|
+
if (autoTransform) {
|
|
1263
|
+
ref.current.matrix.setPosition(intendedNewPosition);
|
|
1264
|
+
const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
|
|
1265
|
+
const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
|
|
1266
|
+
onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
1267
|
+
} else {
|
|
1268
|
+
const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
|
|
1269
|
+
tempMatrix.setPosition(intendedNewPosition);
|
|
1270
|
+
const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
|
|
1271
|
+
const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
|
|
1272
|
+
onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
1273
|
+
}
|
|
1274
|
+
invalidate();
|
|
1275
|
+
},
|
|
1276
|
+
[autoTransform, dragLimits, threshold, onDragStart, onDrag, invalidate]
|
|
1272
1277
|
);
|
|
1278
|
+
const handlePointerUp = React.useCallback(
|
|
1279
|
+
(event) => {
|
|
1280
|
+
if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
|
|
1281
|
+
event.target.releasePointerCapture(event.pointerId);
|
|
1282
|
+
const wasIntentional = dragState.current.intentional;
|
|
1283
|
+
dragState.current.active = false;
|
|
1284
|
+
dragState.current.intentional = false;
|
|
1285
|
+
dragState.current.pointerId = -1;
|
|
1286
|
+
if (defaultControls) defaultControls.enabled = true;
|
|
1287
|
+
if (wasIntentional || !filterTaps) {
|
|
1288
|
+
onDragEnd && onDragEnd();
|
|
1289
|
+
}
|
|
1290
|
+
invalidate();
|
|
1291
|
+
},
|
|
1292
|
+
[defaultControls, filterTaps, onDragEnd, invalidate]
|
|
1293
|
+
);
|
|
1294
|
+
const handlePointerEnter = React.useCallback(() => {
|
|
1295
|
+
onHover && onHover(true);
|
|
1296
|
+
}, [onHover]);
|
|
1297
|
+
const handlePointerLeave = React.useCallback(() => {
|
|
1298
|
+
onHover && onHover(false);
|
|
1299
|
+
}, [onHover]);
|
|
1273
1300
|
React.useImperativeHandle(fRef, () => ref.current, []);
|
|
1274
1301
|
React.useLayoutEffect(() => {
|
|
1275
1302
|
if (!matrix) return;
|
|
1276
1303
|
ref.current.matrix = matrix;
|
|
1277
1304
|
}, [matrix]);
|
|
1278
|
-
return /* @__PURE__ */ React.createElement(
|
|
1305
|
+
return /* @__PURE__ */ React.createElement(
|
|
1306
|
+
"group",
|
|
1307
|
+
{
|
|
1308
|
+
ref,
|
|
1309
|
+
onPointerDown: handlePointerDown,
|
|
1310
|
+
onPointerMove: handlePointerMove,
|
|
1311
|
+
onPointerUp: handlePointerUp,
|
|
1312
|
+
onPointerEnter: handlePointerEnter,
|
|
1313
|
+
onPointerLeave: handlePointerLeave,
|
|
1314
|
+
matrix,
|
|
1315
|
+
matrixAutoUpdate: false,
|
|
1316
|
+
...props
|
|
1317
|
+
},
|
|
1318
|
+
children
|
|
1319
|
+
);
|
|
1279
1320
|
}
|
|
1280
1321
|
);
|
|
1281
1322
|
|
|
@@ -1393,7 +1434,7 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
1393
1434
|
source.removeEventListener("keyup", upHandler);
|
|
1394
1435
|
window.removeEventListener("blur", blurHandler);
|
|
1395
1436
|
};
|
|
1396
|
-
}, [domElement, key]);
|
|
1437
|
+
}, [domElement, key, onChange]);
|
|
1397
1438
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
1398
1439
|
}
|
|
1399
1440
|
function useKeyboardControls(sel) {
|
|
@@ -1415,20 +1456,28 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
1415
1456
|
const controls = React.useMemo(() => new MapControls$1(explCamera), [explCamera]);
|
|
1416
1457
|
React.useEffect(() => {
|
|
1417
1458
|
controls.connect(explDomElement);
|
|
1459
|
+
return () => void controls.dispose();
|
|
1460
|
+
}, [explDomElement, controls]);
|
|
1461
|
+
React.useEffect(() => {
|
|
1418
1462
|
const callback = (e) => {
|
|
1419
1463
|
invalidate();
|
|
1420
1464
|
if (onChange) onChange(e);
|
|
1421
1465
|
};
|
|
1466
|
+
const onStartCb = (e) => {
|
|
1467
|
+
if (onStart) onStart(e);
|
|
1468
|
+
};
|
|
1469
|
+
const onEndCb = (e) => {
|
|
1470
|
+
if (onEnd) onEnd(e);
|
|
1471
|
+
};
|
|
1422
1472
|
controls.addEventListener("change", callback);
|
|
1423
|
-
|
|
1424
|
-
|
|
1473
|
+
controls.addEventListener("start", onStartCb);
|
|
1474
|
+
controls.addEventListener("end", onEndCb);
|
|
1425
1475
|
return () => {
|
|
1426
|
-
controls.
|
|
1476
|
+
controls.removeEventListener("start", onStartCb);
|
|
1477
|
+
controls.removeEventListener("end", onEndCb);
|
|
1427
1478
|
controls.removeEventListener("change", callback);
|
|
1428
|
-
if (onStart) controls.removeEventListener("start", onStart);
|
|
1429
|
-
if (onEnd) controls.removeEventListener("end", onEnd);
|
|
1430
1479
|
};
|
|
1431
|
-
}, [onChange, onStart, onEnd, controls, invalidate
|
|
1480
|
+
}, [onChange, onStart, onEnd, controls, invalidate]);
|
|
1432
1481
|
React.useEffect(() => {
|
|
1433
1482
|
if (makeDefault) {
|
|
1434
1483
|
const old = get().controls;
|
|
@@ -1436,7 +1485,9 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
1436
1485
|
return () => set({ controls: old });
|
|
1437
1486
|
}
|
|
1438
1487
|
}, [makeDefault, controls]);
|
|
1439
|
-
useFrame(() =>
|
|
1488
|
+
useFrame(() => {
|
|
1489
|
+
if (controls.enabled) controls.update();
|
|
1490
|
+
}, -1);
|
|
1440
1491
|
return /* @__PURE__ */ React.createElement("primitive", { ref, object: controls, enableDamping: true, ...rest });
|
|
1441
1492
|
});
|
|
1442
1493
|
|
|
@@ -1562,20 +1613,16 @@ const OrbitControls = /* @__PURE__ */ React.forwardRef(
|
|
|
1562
1613
|
onEnd,
|
|
1563
1614
|
...restProps
|
|
1564
1615
|
}, ref) => {
|
|
1565
|
-
const invalidate = useThree(
|
|
1566
|
-
const defaultCamera = useThree((state) => state.camera);
|
|
1567
|
-
const gl = useThree((state) => state.gl);
|
|
1568
|
-
const events = useThree((state) => state.events);
|
|
1569
|
-
const setEvents = useThree((state) => state.setEvents);
|
|
1570
|
-
const set = useThree((state) => state.set);
|
|
1571
|
-
const get = useThree((state) => state.get);
|
|
1572
|
-
const performance = useThree((state) => state.performance);
|
|
1616
|
+
const { invalidate, camera: defaultCamera, renderer, events, setEvents, set, get, performance } = useThree();
|
|
1573
1617
|
const explCamera = camera || defaultCamera;
|
|
1574
|
-
const explDomElement = domElement || events.connected ||
|
|
1618
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
1575
1619
|
const controls = React.useMemo(() => new OrbitControls$1(explCamera), [explCamera]);
|
|
1576
|
-
useFrame(
|
|
1577
|
-
|
|
1578
|
-
|
|
1620
|
+
useFrame(
|
|
1621
|
+
() => {
|
|
1622
|
+
if (controls.enabled) controls.update();
|
|
1623
|
+
},
|
|
1624
|
+
{ before: "update" }
|
|
1625
|
+
);
|
|
1579
1626
|
React.useEffect(() => {
|
|
1580
1627
|
if (keyEvents) {
|
|
1581
1628
|
controls.connect(keyEvents === true ? explDomElement : keyEvents);
|
|
@@ -1689,9 +1736,8 @@ function PresentationControls({
|
|
|
1689
1736
|
azimuth = [-Infinity, Infinity],
|
|
1690
1737
|
damping = 0.25
|
|
1691
1738
|
}) {
|
|
1692
|
-
const events = useThree(
|
|
1693
|
-
const
|
|
1694
|
-
const explDomElement = domElement || events.connected || gl.domElement;
|
|
1739
|
+
const { events, renderer, invalidate } = useThree();
|
|
1740
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
1695
1741
|
const { size } = useThree();
|
|
1696
1742
|
const rPolar = React.useMemo(
|
|
1697
1743
|
() => [rotation[0] + polar[0], rotation[0] + polar[1]],
|
|
@@ -1708,18 +1754,20 @@ function PresentationControls({
|
|
|
1708
1754
|
React.useEffect(() => {
|
|
1709
1755
|
if (global && cursor && enabled) {
|
|
1710
1756
|
explDomElement.style.cursor = "grab";
|
|
1711
|
-
|
|
1757
|
+
renderer.domElement.style.cursor = "";
|
|
1712
1758
|
return () => {
|
|
1713
1759
|
explDomElement.style.cursor = "default";
|
|
1714
|
-
|
|
1760
|
+
renderer.domElement.style.cursor = "default";
|
|
1715
1761
|
};
|
|
1716
1762
|
}
|
|
1717
1763
|
}, [global, cursor, explDomElement, enabled]);
|
|
1718
1764
|
const [animation] = React.useState({ scale: 1, rotation: rInitial, damping });
|
|
1719
1765
|
const ref = React.useRef(null);
|
|
1720
1766
|
useFrame((state, delta) => {
|
|
1721
|
-
|
|
1722
|
-
easing.
|
|
1767
|
+
let changed = false;
|
|
1768
|
+
changed ||= easing.damp3(ref.current.scale, animation.scale, animation.damping, delta);
|
|
1769
|
+
changed ||= easing.dampE(ref.current.rotation, animation.rotation, animation.damping, delta);
|
|
1770
|
+
if (changed) state.invalidate();
|
|
1723
1771
|
});
|
|
1724
1772
|
const bind = useGesture(
|
|
1725
1773
|
{
|
|
@@ -1727,6 +1775,7 @@ function PresentationControls({
|
|
|
1727
1775
|
if (cursor && !global && enabled) explDomElement.style.cursor = last ? "auto" : "grab";
|
|
1728
1776
|
},
|
|
1729
1777
|
onDrag: ({ down, delta: [x, y], memo: [oldY, oldX] = animation.rotation || rInitial }) => {
|
|
1778
|
+
invalidate();
|
|
1730
1779
|
if (!enabled) return [y, x];
|
|
1731
1780
|
if (cursor) explDomElement.style.cursor = down ? "grabbing" : "grab";
|
|
1732
1781
|
x = MathUtils.clamp(oldX + x / size.width * Math.PI * speed, ...rAzimuth);
|
|
@@ -1735,9 +1784,12 @@ function PresentationControls({
|
|
|
1735
1784
|
animation.rotation = snap && !down ? rInitial : [y, x, 0];
|
|
1736
1785
|
animation.damping = snap && !down && typeof snap !== "boolean" ? snap : damping;
|
|
1737
1786
|
return [y, x];
|
|
1787
|
+
},
|
|
1788
|
+
onDragEnd: () => {
|
|
1789
|
+
invalidate();
|
|
1738
1790
|
}
|
|
1739
1791
|
},
|
|
1740
|
-
{ target: global ? explDomElement : void 0 }
|
|
1792
|
+
{ target: global ? explDomElement : void 0, enabled }
|
|
1741
1793
|
);
|
|
1742
1794
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
1743
1795
|
}
|
|
@@ -1746,6 +1798,10 @@ function roundToPixelRatio(value) {
|
|
|
1746
1798
|
const ratio = window.devicePixelRatio || 1;
|
|
1747
1799
|
return Math.round(value * ratio) / ratio;
|
|
1748
1800
|
}
|
|
1801
|
+
function getMaxAnisotropy(renderer) {
|
|
1802
|
+
const r = renderer;
|
|
1803
|
+
return r?.getMaxAnisotropy?.() ?? r?.capabilities?.getMaxAnisotropy?.() ?? 1;
|
|
1804
|
+
}
|
|
1749
1805
|
|
|
1750
1806
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
1751
1807
|
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1772,6 +1828,7 @@ function ScrollControls({
|
|
|
1772
1828
|
const [fixed] = React.useState(() => document.createElement("div"));
|
|
1773
1829
|
const target = gl.domElement.parentNode;
|
|
1774
1830
|
const scroll = React.useRef(0);
|
|
1831
|
+
const disableScrollUpdate = React.useRef(false);
|
|
1775
1832
|
const state = React.useMemo(() => {
|
|
1776
1833
|
const state2 = {
|
|
1777
1834
|
el,
|
|
@@ -1853,16 +1910,20 @@ function ScrollControls({
|
|
|
1853
1910
|
const scrollLength = el[horizontal ? "scrollWidth" : "scrollHeight"];
|
|
1854
1911
|
const scrollThreshold = scrollLength - containerLength;
|
|
1855
1912
|
let current = 0;
|
|
1856
|
-
let disableScroll =
|
|
1913
|
+
let disableScroll = false;
|
|
1857
1914
|
let firstRun = true;
|
|
1858
1915
|
const onScroll = () => {
|
|
1859
1916
|
if (!enabled || firstRun) return;
|
|
1917
|
+
if (disableScrollUpdate.current) {
|
|
1918
|
+
disableScrollUpdate.current = false;
|
|
1919
|
+
return;
|
|
1920
|
+
}
|
|
1860
1921
|
invalidate();
|
|
1861
1922
|
current = el[horizontal ? "scrollLeft" : "scrollTop"];
|
|
1862
1923
|
scroll.current = current / scrollThreshold;
|
|
1863
1924
|
if (infinite) {
|
|
1864
1925
|
if (!disableScroll) {
|
|
1865
|
-
if (current >= scrollThreshold) {
|
|
1926
|
+
if (current >= scrollThreshold - 1) {
|
|
1866
1927
|
const damp = 1 - state.offset;
|
|
1867
1928
|
el[horizontal ? "scrollLeft" : "scrollTop"] = 1;
|
|
1868
1929
|
scroll.current = state.offset = -damp;
|
|
@@ -1879,11 +1940,34 @@ function ScrollControls({
|
|
|
1879
1940
|
};
|
|
1880
1941
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
1881
1942
|
requestAnimationFrame(() => firstRun = false);
|
|
1882
|
-
const
|
|
1883
|
-
|
|
1943
|
+
const onResize = () => {
|
|
1944
|
+
if (!el) return;
|
|
1945
|
+
const scrollLength2 = el[horizontal ? "scrollWidth" : "scrollHeight"];
|
|
1946
|
+
const containerLength2 = el[horizontal ? "clientWidth" : "clientHeight"];
|
|
1947
|
+
disableScrollUpdate.current = true;
|
|
1948
|
+
el[horizontal ? "scrollLeft" : "scrollTop"] = state.offset * (scrollLength2 - containerLength2);
|
|
1949
|
+
};
|
|
1950
|
+
const onWheel = (e) => {
|
|
1951
|
+
if (horizontal) {
|
|
1952
|
+
const previous = el.scrollLeft;
|
|
1953
|
+
el.scrollLeft += e.deltaY / 2;
|
|
1954
|
+
if (infinite && previous === el.scrollLeft) {
|
|
1955
|
+
onScroll();
|
|
1956
|
+
}
|
|
1957
|
+
} else if (infinite) {
|
|
1958
|
+
if (el.scrollTop <= 1 && e.deltaY < 0) {
|
|
1959
|
+
onScroll();
|
|
1960
|
+
} else if (el.scrollTop >= el.scrollHeight - el.clientHeight - 1 && e.deltaY > 0) {
|
|
1961
|
+
onScroll();
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
if (horizontal || infinite) el.addEventListener("wheel", onWheel, { passive: true });
|
|
1966
|
+
if (horizontal) window.addEventListener("resize", onResize);
|
|
1884
1967
|
return () => {
|
|
1885
1968
|
el.removeEventListener("scroll", onScroll);
|
|
1886
|
-
if (horizontal) el.removeEventListener("wheel", onWheel);
|
|
1969
|
+
if (horizontal || infinite) el.removeEventListener("wheel", onWheel);
|
|
1970
|
+
if (horizontal) window.removeEventListener("resize", onResize);
|
|
1887
1971
|
};
|
|
1888
1972
|
}
|
|
1889
1973
|
}, [el, events, size, infinite, state, invalidate, horizontal, enabled]);
|
|
@@ -2300,10 +2384,10 @@ const CloudInstance = /* @__PURE__ */ React.forwardRef(
|
|
|
2300
2384
|
return /* @__PURE__ */ React.createElement("group", { ref, ...props });
|
|
2301
2385
|
}
|
|
2302
2386
|
);
|
|
2303
|
-
const Cloud = /* @__PURE__ */ React.forwardRef((props, fref) => {
|
|
2387
|
+
const Cloud = /* @__PURE__ */ React.forwardRef(({ materialFactory, ...props }, fref) => {
|
|
2304
2388
|
const parent = React.useContext(context$6);
|
|
2305
2389
|
if (parent) return /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props });
|
|
2306
|
-
return /* @__PURE__ */ React.createElement(Clouds,
|
|
2390
|
+
return /* @__PURE__ */ React.createElement(Clouds, { materialFactory }, /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props }));
|
|
2307
2391
|
});
|
|
2308
2392
|
|
|
2309
2393
|
const CatmullRomLine = /* @__PURE__ */ React.forwardRef(function CatmullRomLine2({
|
|
@@ -2825,7 +2909,7 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
2825
2909
|
return {
|
|
2826
2910
|
font,
|
|
2827
2911
|
size,
|
|
2828
|
-
height,
|
|
2912
|
+
depth: height,
|
|
2829
2913
|
bevelThickness,
|
|
2830
2914
|
bevelSize,
|
|
2831
2915
|
bevelEnabled,
|
|
@@ -3008,7 +3092,7 @@ const FaceMaterial = ({
|
|
|
3008
3092
|
"meshBasicMaterial",
|
|
3009
3093
|
{
|
|
3010
3094
|
map: texture,
|
|
3011
|
-
"map-anisotropy":
|
|
3095
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
3012
3096
|
attach: `material-${index}`,
|
|
3013
3097
|
color: hover ? hoverColor : "white",
|
|
3014
3098
|
transparent: true,
|
|
@@ -3119,7 +3203,7 @@ function AxisHead({
|
|
|
3119
3203
|
"spriteMaterial",
|
|
3120
3204
|
{
|
|
3121
3205
|
map: texture,
|
|
3122
|
-
"map-anisotropy":
|
|
3206
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
3123
3207
|
alphaTest: 0.3,
|
|
3124
3208
|
opacity: label ? 1 : 0.75,
|
|
3125
3209
|
toneMapped: false
|
|
@@ -3264,6 +3348,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3264
3348
|
}, ref) => {
|
|
3265
3349
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
3266
3350
|
const forceEven = useThree((state) => state.internal.forceEven);
|
|
3351
|
+
const { frustum } = useThree();
|
|
3267
3352
|
const [el] = React.useState(() => document.createElement(as));
|
|
3268
3353
|
const root = React.useRef(null);
|
|
3269
3354
|
const group = React.useRef(null);
|
|
@@ -3293,22 +3378,18 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3293
3378
|
if (group.current) {
|
|
3294
3379
|
if (!root.current) {
|
|
3295
3380
|
root.current = ReactDOM.createRoot(el);
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3381
|
+
scene.updateMatrixWorld();
|
|
3382
|
+
if (transform) {
|
|
3383
|
+
el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
|
|
3384
|
+
} else {
|
|
3385
|
+
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
|
|
3386
|
+
}
|
|
3302
3387
|
}
|
|
3303
3388
|
if (target) {
|
|
3304
3389
|
if (prepend) target.prepend(el);
|
|
3305
3390
|
else target.appendChild(el);
|
|
3306
3391
|
}
|
|
3307
3392
|
return () => {
|
|
3308
|
-
if (root.current) {
|
|
3309
|
-
root.current.unmount();
|
|
3310
|
-
root.current = null;
|
|
3311
|
-
}
|
|
3312
3393
|
if (target && target.contains(el)) {
|
|
3313
3394
|
target.removeChild(el);
|
|
3314
3395
|
}
|
|
@@ -3442,8 +3523,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3442
3523
|
if (transformOuterRef.current) {
|
|
3443
3524
|
const el2 = transformOuterRef.current.children[0];
|
|
3444
3525
|
if (el2?.clientWidth && el2?.clientHeight) {
|
|
3445
|
-
|
|
3446
|
-
if (isOrthographicCamera || geometry) {
|
|
3526
|
+
if (geometry) {
|
|
3447
3527
|
if (props.scale) {
|
|
3448
3528
|
if (!Array.isArray(props.scale)) {
|
|
3449
3529
|
occlusionMeshRef.current.scale.setScalar(1 / props.scale);
|
|
@@ -3475,64 +3555,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3475
3555
|
}
|
|
3476
3556
|
}
|
|
3477
3557
|
});
|
|
3478
|
-
|
|
3479
|
-
() => ({
|
|
3480
|
-
vertexShader: !transform ? (
|
|
3481
|
-
/* glsl */
|
|
3482
|
-
`
|
|
3483
|
-
/*
|
|
3484
|
-
This shader is from the THREE's SpriteMaterial.
|
|
3485
|
-
We need to turn the backing plane into a Sprite
|
|
3486
|
-
(make it always face the camera) if "transfrom"
|
|
3487
|
-
is false.
|
|
3488
|
-
*/
|
|
3489
|
-
#include <common>
|
|
3490
|
-
|
|
3491
|
-
void main() {
|
|
3492
|
-
vec2 center = vec2(0., 1.);
|
|
3493
|
-
float rotation = 0.0;
|
|
3494
|
-
|
|
3495
|
-
// This is somewhat arbitrary, but it seems to work well
|
|
3496
|
-
// Need to figure out how to derive this dynamically if it even matters
|
|
3497
|
-
float size = 0.03;
|
|
3498
|
-
|
|
3499
|
-
vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
|
|
3500
|
-
vec2 scale;
|
|
3501
|
-
scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
|
|
3502
|
-
scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
|
|
3503
|
-
|
|
3504
|
-
bool isPerspective = isPerspectiveMatrix( projectionMatrix );
|
|
3505
|
-
if ( isPerspective ) scale *= - mvPosition.z;
|
|
3506
|
-
|
|
3507
|
-
vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
|
|
3508
|
-
vec2 rotatedPosition;
|
|
3509
|
-
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
|
|
3510
|
-
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
|
|
3511
|
-
mvPosition.xy += rotatedPosition;
|
|
3512
|
-
|
|
3513
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
3514
|
-
}
|
|
3515
|
-
`
|
|
3516
|
-
) : void 0,
|
|
3517
|
-
fragmentShader: (
|
|
3518
|
-
/* glsl */
|
|
3519
|
-
`
|
|
3520
|
-
void main() {
|
|
3521
|
-
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
3522
|
-
}
|
|
3523
|
-
`
|
|
3524
|
-
)
|
|
3525
|
-
}),
|
|
3526
|
-
[transform]
|
|
3527
|
-
);
|
|
3528
|
-
return /* @__PURE__ */ React.createElement("group", { ...props, ref: group }, occlude && !isRayCastOcclusion && /* @__PURE__ */ React.createElement("mesh", { castShadow, receiveShadow, ref: occlusionMeshRef }, geometry || /* @__PURE__ */ React.createElement("planeGeometry", null), material || /* @__PURE__ */ React.createElement(
|
|
3529
|
-
"shaderMaterial",
|
|
3530
|
-
{
|
|
3531
|
-
side: DoubleSide,
|
|
3532
|
-
vertexShader: shaders.vertexShader,
|
|
3533
|
-
fragmentShader: shaders.fragmentShader
|
|
3534
|
-
}
|
|
3535
|
-
)));
|
|
3558
|
+
return /* @__PURE__ */ React.createElement("group", { ...props, ref: group }, occlude && !isRayCastOcclusion && /* @__PURE__ */ React.createElement("mesh", { castShadow, receiveShadow, ref: occlusionMeshRef }, geometry || /* @__PURE__ */ React.createElement("planeGeometry", null), material));
|
|
3536
3559
|
}
|
|
3537
3560
|
);
|
|
3538
3561
|
|
|
@@ -4385,6 +4408,7 @@ const mW = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
4385
4408
|
const mL = /* @__PURE__ */ new THREE.Matrix4();
|
|
4386
4409
|
const mL0Inv = /* @__PURE__ */ new THREE.Matrix4();
|
|
4387
4410
|
const mdL = /* @__PURE__ */ new THREE.Matrix4();
|
|
4411
|
+
const mdW = /* @__PURE__ */ new THREE.Matrix4();
|
|
4388
4412
|
const mG = /* @__PURE__ */ new THREE.Matrix4();
|
|
4389
4413
|
const bb = /* @__PURE__ */ new THREE.Box3();
|
|
4390
4414
|
const bbObj = /* @__PURE__ */ new THREE.Box3();
|
|
@@ -4499,7 +4523,8 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4499
4523
|
onDragStart && onDragStart(props2);
|
|
4500
4524
|
invalidate();
|
|
4501
4525
|
},
|
|
4502
|
-
onDrag: (
|
|
4526
|
+
onDrag: (mdW_) => {
|
|
4527
|
+
mdW.copy(mdW_);
|
|
4503
4528
|
mP.copy(parentRef.current.matrixWorld);
|
|
4504
4529
|
mPInv.copy(mP).invert();
|
|
4505
4530
|
mW.copy(mW0).premultiply(mdW);
|
|
@@ -4511,12 +4536,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4511
4536
|
}
|
|
4512
4537
|
const target = resolveObject(object);
|
|
4513
4538
|
if (target) target.matrix.copy(mL);
|
|
4514
|
-
onDrag && onDrag(mL, mdL, mW, mdW);
|
|
4539
|
+
onDrag && onDrag({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
4515
4540
|
invalidate();
|
|
4516
4541
|
},
|
|
4517
4542
|
onDragEnd: () => {
|
|
4518
4543
|
dragState.current = null;
|
|
4519
|
-
if (onDragEnd) onDragEnd();
|
|
4544
|
+
if (onDragEnd) onDragEnd({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
4520
4545
|
invalidate();
|
|
4521
4546
|
},
|
|
4522
4547
|
onHover: (props2) => {
|
|
@@ -4627,7 +4652,9 @@ const TransformControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4627
4652
|
const group = React.useRef(null);
|
|
4628
4653
|
React.useLayoutEffect(() => {
|
|
4629
4654
|
if (object) {
|
|
4630
|
-
controls.attach(
|
|
4655
|
+
controls.attach(
|
|
4656
|
+
object instanceof THREE.Object3D ? object : object.current
|
|
4657
|
+
);
|
|
4631
4658
|
} else if (group.current instanceof THREE.Object3D) {
|
|
4632
4659
|
controls.attach(group.current);
|
|
4633
4660
|
}
|
|
@@ -4723,7 +4750,7 @@ const PointMaterial = /* @__PURE__ */ React.forwardRef((props, ref) => {
|
|
|
4723
4750
|
return /* @__PURE__ */ React.createElement("primitive", { ...props, object: material, ref, attach: "material" });
|
|
4724
4751
|
});
|
|
4725
4752
|
|
|
4726
|
-
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop =
|
|
4753
|
+
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop = false, autoplay, ...props }, ref) => {
|
|
4727
4754
|
const sound = React.useRef(null);
|
|
4728
4755
|
React.useImperativeHandle(ref, () => sound.current, []);
|
|
4729
4756
|
const camera = useThree(({ camera: camera2 }) => camera2);
|
|
@@ -4735,7 +4762,9 @@ const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, l
|
|
|
4735
4762
|
_sound.setBuffer(Array.isArray(buffer) ? buffer[0] : buffer);
|
|
4736
4763
|
_sound.setRefDistance(distance);
|
|
4737
4764
|
_sound.setLoop(loop);
|
|
4738
|
-
if (autoplay && !_sound.isPlaying)
|
|
4765
|
+
if (autoplay && !_sound.isPlaying) {
|
|
4766
|
+
_sound.play();
|
|
4767
|
+
}
|
|
4739
4768
|
}
|
|
4740
4769
|
}, [buffer, camera, distance, loop]);
|
|
4741
4770
|
React.useEffect(() => {
|
|
@@ -4804,7 +4833,6 @@ const tempMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
4804
4833
|
const translation = /* @__PURE__ */ new THREE.Vector3();
|
|
4805
4834
|
const rotation = /* @__PURE__ */ new THREE.Quaternion();
|
|
4806
4835
|
const scale = /* @__PURE__ */ new THREE.Vector3();
|
|
4807
|
-
const isInstancedBufferAttribute = (attr) => attr.isInstancedBufferAttribute;
|
|
4808
4836
|
const Instance = /* @__PURE__ */ React.forwardRef(({ context, children, ...props }, ref) => {
|
|
4809
4837
|
React.useMemo(() => extend({ PositionMesh }), []);
|
|
4810
4838
|
const group = React.useRef(null);
|
|
@@ -4824,24 +4852,20 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
4824
4852
|
const parentRef = React.useRef(null);
|
|
4825
4853
|
React.useImperativeHandle(ref, () => parentRef.current, []);
|
|
4826
4854
|
const [instances, setInstances] = React.useState([]);
|
|
4855
|
+
const boundsDirty = React.useRef(true);
|
|
4827
4856
|
const [[matrices, colors]] = React.useState(() => {
|
|
4828
4857
|
const mArray = new Float32Array(limit * 16);
|
|
4829
4858
|
for (let i = 0; i < limit; i++) tempMatrix.identity().toArray(mArray, i * 16);
|
|
4830
4859
|
return [mArray, new Float32Array([...new Array(limit * 3)].map(() => 1))];
|
|
4831
4860
|
});
|
|
4832
4861
|
React.useEffect(() => {
|
|
4833
|
-
parentRef.current.instanceMatrix.needsUpdate = true;
|
|
4862
|
+
if (parentRef.current) parentRef.current.instanceMatrix.needsUpdate = true;
|
|
4834
4863
|
});
|
|
4835
4864
|
let iterations = 0;
|
|
4836
4865
|
let count = 0;
|
|
4837
|
-
const attributes = React.useRef([]);
|
|
4838
|
-
React.useLayoutEffect(() => {
|
|
4839
|
-
attributes.current = Object.entries(parentRef.current.geometry.attributes).filter(
|
|
4840
|
-
([_name, value]) => isInstancedBufferAttribute(value)
|
|
4841
|
-
);
|
|
4842
|
-
});
|
|
4843
4866
|
useFrame(() => {
|
|
4844
4867
|
if (frames === Infinity || iterations < frames) {
|
|
4868
|
+
if (!parentRef.current) return;
|
|
4845
4869
|
parentRef.current.updateMatrix();
|
|
4846
4870
|
parentRef.current.updateMatrixWorld();
|
|
4847
4871
|
parentMatrix.copy(parentRef.current.matrixWorld).invert();
|
|
@@ -4862,13 +4886,22 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
4862
4886
|
}
|
|
4863
4887
|
iterations++;
|
|
4864
4888
|
}
|
|
4889
|
+
if (boundsDirty.current && (frames === Infinity || iterations === frames)) {
|
|
4890
|
+
boundsDirty.current = false;
|
|
4891
|
+
if (parentRef.current.boundingBox) parentRef.current.computeBoundingBox();
|
|
4892
|
+
if (parentRef.current.boundingSphere) parentRef.current.computeBoundingSphere();
|
|
4893
|
+
}
|
|
4865
4894
|
});
|
|
4866
4895
|
const api = React.useMemo(
|
|
4867
4896
|
() => ({
|
|
4868
4897
|
getParent: () => parentRef,
|
|
4869
4898
|
subscribe: (ref2) => {
|
|
4870
4899
|
setInstances((instances2) => [...instances2, ref2]);
|
|
4871
|
-
|
|
4900
|
+
boundsDirty.current = true;
|
|
4901
|
+
return () => {
|
|
4902
|
+
setInstances((instances2) => instances2.filter((item) => item.current !== ref2.current));
|
|
4903
|
+
boundsDirty.current = true;
|
|
4904
|
+
};
|
|
4872
4905
|
}
|
|
4873
4906
|
}),
|
|
4874
4907
|
[]
|
|
@@ -4893,10 +4926,23 @@ const Merged = /* @__PURE__ */ React.forwardRef(function Merged2({ meshes, child
|
|
|
4893
4926
|
if (!isArray) {
|
|
4894
4927
|
for (const key of Object.keys(meshes)) if (!meshes[key].isMesh) delete meshes[key];
|
|
4895
4928
|
}
|
|
4896
|
-
const render = (args) =>
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4929
|
+
const render = (args) => {
|
|
4930
|
+
if (isArray) {
|
|
4931
|
+
return children(
|
|
4932
|
+
...args
|
|
4933
|
+
);
|
|
4934
|
+
}
|
|
4935
|
+
const instanceMap = {};
|
|
4936
|
+
const keys = Object.keys(meshes).filter((key) => meshes[key].isMesh);
|
|
4937
|
+
keys.forEach((key, i) => {
|
|
4938
|
+
instanceMap[key] = args[i];
|
|
4939
|
+
});
|
|
4940
|
+
return children(instanceMap);
|
|
4941
|
+
};
|
|
4942
|
+
const components = (isArray ? meshes : Object.values(meshes)).map((mesh) => {
|
|
4943
|
+
const { geometry, material } = mesh;
|
|
4944
|
+
return /* @__PURE__ */ React.createElement(Instances, { key: geometry.uuid, geometry, material, ...props });
|
|
4945
|
+
});
|
|
4900
4946
|
return /* @__PURE__ */ React.createElement("group", { ref }, renderRecursive(render, components));
|
|
4901
4947
|
});
|
|
4902
4948
|
function renderRecursive(render, components, results = []) {
|
|
@@ -5970,12 +6016,13 @@ function Sampler({ children, weight, transform, instances, mesh, count = 16, ...
|
|
|
5970
6016
|
return /* @__PURE__ */ React.createElement("group", { ref: group, ...props }, children);
|
|
5971
6017
|
}
|
|
5972
6018
|
|
|
6019
|
+
const pathStyle = (path) => path.userData?.style;
|
|
5973
6020
|
const Svg = /* @__PURE__ */ forwardRef(
|
|
5974
6021
|
function R3FSvg({ src, skipFill, skipStrokes, fillMaterial, strokeMaterial, fillMeshProps, strokeMeshProps, ...props }, ref) {
|
|
5975
6022
|
const svg = useLoader(SVGLoader, !src.startsWith("<svg") ? src : `data:image/svg+xml;utf8,${src}`);
|
|
5976
6023
|
const strokeGeometries = useMemo(
|
|
5977
6024
|
() => skipStrokes ? [] : svg.paths.map(
|
|
5978
|
-
(path) => path
|
|
6025
|
+
(path) => pathStyle(path)?.stroke === void 0 || pathStyle(path).stroke === "none" ? null : path.subPaths.map((subPath) => SVGLoader.pointsToStroke(subPath.getPoints(), pathStyle(path)))
|
|
5979
6026
|
),
|
|
5980
6027
|
[svg, skipStrokes]
|
|
5981
6028
|
);
|
|
@@ -5983,21 +6030,21 @@ const Svg = /* @__PURE__ */ forwardRef(
|
|
|
5983
6030
|
return () => strokeGeometries.forEach((group) => group && group.map((g) => g.dispose()));
|
|
5984
6031
|
}, [strokeGeometries]);
|
|
5985
6032
|
let renderOrder = 0;
|
|
5986
|
-
return /* @__PURE__ */ React.createElement("object3D", { ref, ...props }, /* @__PURE__ */ React.createElement("object3D", { scale: [1, -1, 1] }, svg.paths.map((path, p) => /* @__PURE__ */ React.createElement(Fragment, { key: p }, !skipFill && path
|
|
6033
|
+
return /* @__PURE__ */ React.createElement("object3D", { ref, ...props }, /* @__PURE__ */ React.createElement("object3D", { scale: [1, -1, 1] }, svg.paths.map((path, p) => /* @__PURE__ */ React.createElement(Fragment, { key: p }, !skipFill && pathStyle(path)?.fill !== void 0 && pathStyle(path).fill !== "none" && SVGLoader.createShapes(path).map((shape, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, ...fillMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement("shapeGeometry", { args: [shape] }), /* @__PURE__ */ React.createElement(
|
|
5987
6034
|
"meshBasicMaterial",
|
|
5988
6035
|
{
|
|
5989
|
-
color: path.
|
|
5990
|
-
opacity: path.
|
|
6036
|
+
color: pathStyle(path).fill,
|
|
6037
|
+
opacity: pathStyle(path).fillOpacity,
|
|
5991
6038
|
transparent: true,
|
|
5992
6039
|
side: DoubleSide,
|
|
5993
6040
|
depthWrite: false,
|
|
5994
6041
|
...fillMaterial
|
|
5995
6042
|
}
|
|
5996
|
-
))), !skipStrokes && path
|
|
6043
|
+
))), !skipStrokes && pathStyle(path)?.stroke !== void 0 && pathStyle(path).stroke !== "none" && path.subPaths.map((_subPath, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, geometry: strokeGeometries[p][s], ...strokeMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement(
|
|
5997
6044
|
"meshBasicMaterial",
|
|
5998
6045
|
{
|
|
5999
|
-
color: path.
|
|
6000
|
-
opacity: path.
|
|
6046
|
+
color: pathStyle(path).stroke,
|
|
6047
|
+
opacity: pathStyle(path).strokeOpacity,
|
|
6001
6048
|
transparent: true,
|
|
6002
6049
|
side: DoubleSide,
|
|
6003
6050
|
depthWrite: false,
|
|
@@ -6220,8 +6267,8 @@ function useVideoTexture(srcOrSrcObject, {
|
|
|
6220
6267
|
});
|
|
6221
6268
|
if (src && IS_BROWSER && src.endsWith(".m3u8")) {
|
|
6222
6269
|
const hls = hlsRef.current = await getHls(hlsConfig);
|
|
6223
|
-
if (hls) {
|
|
6224
|
-
hls.on(Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
6270
|
+
if (hls && _HLSModule) {
|
|
6271
|
+
hls.on(_HLSModule.Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
6225
6272
|
hls.attachMedia(video2);
|
|
6226
6273
|
}
|
|
6227
6274
|
}
|
|
@@ -6441,9 +6488,125 @@ function Fbx({
|
|
|
6441
6488
|
return /* @__PURE__ */ React.createElement(Clone, { ...props, object });
|
|
6442
6489
|
}
|
|
6443
6490
|
|
|
6491
|
+
const SERVICE_KEY = "__drei_ktx2_service__";
|
|
6492
|
+
const DEFAULT_TRANSCODER_PATH = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
6493
|
+
class KTX2LoaderServiceImpl {
|
|
6494
|
+
loader = null;
|
|
6495
|
+
renderer = null;
|
|
6496
|
+
_isReady = false;
|
|
6497
|
+
transcoderPath = DEFAULT_TRANSCODER_PATH;
|
|
6498
|
+
pendingCallbacks = [];
|
|
6499
|
+
/**
|
|
6500
|
+
* Get or create the singleton KTX2Loader instance.
|
|
6501
|
+
* The loader is created lazily on first access.
|
|
6502
|
+
*/
|
|
6503
|
+
getLoader() {
|
|
6504
|
+
if (!this.loader) {
|
|
6505
|
+
this.loader = new KTX2Loader();
|
|
6506
|
+
this.loader.setTranscoderPath(this.transcoderPath);
|
|
6507
|
+
}
|
|
6508
|
+
return this.loader;
|
|
6509
|
+
}
|
|
6510
|
+
/**
|
|
6511
|
+
* Register a renderer and call detectSupport.
|
|
6512
|
+
* Should be called from within React context (useLayoutEffect).
|
|
6513
|
+
* Flushes any queued callbacks.
|
|
6514
|
+
*/
|
|
6515
|
+
registerRenderer(renderer) {
|
|
6516
|
+
if (this._isReady && this.renderer === renderer) {
|
|
6517
|
+
return;
|
|
6518
|
+
}
|
|
6519
|
+
this.renderer = renderer;
|
|
6520
|
+
const loader = this.getLoader();
|
|
6521
|
+
loader.detectSupport(renderer);
|
|
6522
|
+
this._isReady = true;
|
|
6523
|
+
this.flushPendingCallbacks();
|
|
6524
|
+
}
|
|
6525
|
+
/**
|
|
6526
|
+
* Check if the service is ready (has renderer registered).
|
|
6527
|
+
*/
|
|
6528
|
+
isReady() {
|
|
6529
|
+
return this._isReady;
|
|
6530
|
+
}
|
|
6531
|
+
/**
|
|
6532
|
+
* Get the registered renderer, if any.
|
|
6533
|
+
*/
|
|
6534
|
+
getRenderer() {
|
|
6535
|
+
return this.renderer;
|
|
6536
|
+
}
|
|
6537
|
+
/**
|
|
6538
|
+
* Register a callback to run when renderer becomes available.
|
|
6539
|
+
* If renderer is already available, runs immediately.
|
|
6540
|
+
*/
|
|
6541
|
+
onReady(callback) {
|
|
6542
|
+
if (this._isReady) {
|
|
6543
|
+
callback();
|
|
6544
|
+
} else {
|
|
6545
|
+
this.pendingCallbacks.push(callback);
|
|
6546
|
+
}
|
|
6547
|
+
}
|
|
6548
|
+
/**
|
|
6549
|
+
* Process all pending callbacks.
|
|
6550
|
+
*/
|
|
6551
|
+
flushPendingCallbacks() {
|
|
6552
|
+
const callbacks = this.pendingCallbacks;
|
|
6553
|
+
this.pendingCallbacks = [];
|
|
6554
|
+
for (const callback of callbacks) {
|
|
6555
|
+
try {
|
|
6556
|
+
callback();
|
|
6557
|
+
} catch (error) {
|
|
6558
|
+
console.error("KTX2LoaderService: Error in pending callback:", error);
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
}
|
|
6562
|
+
/**
|
|
6563
|
+
* Set the transcoder path for basis/ktx2 decoding.
|
|
6564
|
+
*/
|
|
6565
|
+
setTranscoderPath(path) {
|
|
6566
|
+
this.transcoderPath = path;
|
|
6567
|
+
if (this.loader) {
|
|
6568
|
+
this.loader.setTranscoderPath(path);
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
/**
|
|
6572
|
+
* Get the current transcoder path.
|
|
6573
|
+
*/
|
|
6574
|
+
getTranscoderPath() {
|
|
6575
|
+
return this.transcoderPath;
|
|
6576
|
+
}
|
|
6577
|
+
/**
|
|
6578
|
+
* Dispose of the loader and reset state.
|
|
6579
|
+
* Useful for testing or cleanup.
|
|
6580
|
+
*/
|
|
6581
|
+
dispose() {
|
|
6582
|
+
if (this.loader) {
|
|
6583
|
+
this.loader.dispose();
|
|
6584
|
+
}
|
|
6585
|
+
const path = this.transcoderPath;
|
|
6586
|
+
this.loader = null;
|
|
6587
|
+
this.renderer = null;
|
|
6588
|
+
this._isReady = false;
|
|
6589
|
+
this.transcoderPath = path;
|
|
6590
|
+
this.pendingCallbacks = [];
|
|
6591
|
+
}
|
|
6592
|
+
}
|
|
6593
|
+
const KTX2LoaderService = globalThis[SERVICE_KEY] || (globalThis[SERVICE_KEY] = new KTX2LoaderServiceImpl());
|
|
6594
|
+
|
|
6444
6595
|
let dracoLoader = null;
|
|
6445
6596
|
let decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.5.5/";
|
|
6446
|
-
|
|
6597
|
+
let legacyApiWarned = false;
|
|
6598
|
+
function isOptionsObject(arg) {
|
|
6599
|
+
return typeof arg === "object" && arg !== null && !Array.isArray(arg);
|
|
6600
|
+
}
|
|
6601
|
+
function warnLegacyApi() {
|
|
6602
|
+
if (!legacyApiWarned) {
|
|
6603
|
+
legacyApiWarned = true;
|
|
6604
|
+
console.warn(
|
|
6605
|
+
"useGLTF: Boolean arguments are deprecated. Use options object instead:\n useGLTF(path, { draco: true, meshopt: true, ktx2: true })"
|
|
6606
|
+
);
|
|
6607
|
+
}
|
|
6608
|
+
}
|
|
6609
|
+
function extensions(useDraco = true, useMeshopt = true, useKTX2 = false, extendLoader, renderer) {
|
|
6447
6610
|
return (loader) => {
|
|
6448
6611
|
if (extendLoader) {
|
|
6449
6612
|
extendLoader(loader);
|
|
@@ -6459,36 +6622,110 @@ function extensions(useDraco = true, useMeshopt = true, extendLoader) {
|
|
|
6459
6622
|
const decoder = typeof MeshoptDecoder === "function" ? MeshoptDecoder() : MeshoptDecoder;
|
|
6460
6623
|
loader.setMeshoptDecoder(decoder);
|
|
6461
6624
|
}
|
|
6625
|
+
if (useKTX2) {
|
|
6626
|
+
const ktx2Loader = KTX2LoaderService.getLoader();
|
|
6627
|
+
if (typeof useKTX2 === "string") {
|
|
6628
|
+
ktx2Loader.setTranscoderPath(useKTX2);
|
|
6629
|
+
}
|
|
6630
|
+
if (renderer) {
|
|
6631
|
+
ktx2Loader.detectSupport(renderer);
|
|
6632
|
+
}
|
|
6633
|
+
loader.setKTX2Loader(ktx2Loader);
|
|
6634
|
+
}
|
|
6462
6635
|
};
|
|
6463
6636
|
}
|
|
6464
|
-
|
|
6465
|
-
|
|
6637
|
+
function useGLTF(path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) {
|
|
6638
|
+
let draco = true;
|
|
6639
|
+
let meshopt = true;
|
|
6640
|
+
let ktx2 = false;
|
|
6641
|
+
let extendLoader;
|
|
6642
|
+
if (isOptionsObject(optionsOrDraco)) {
|
|
6643
|
+
draco = optionsOrDraco.draco ?? true;
|
|
6644
|
+
meshopt = optionsOrDraco.meshopt ?? true;
|
|
6645
|
+
ktx2 = optionsOrDraco.ktx2 ?? false;
|
|
6646
|
+
extendLoader = optionsOrDraco.extendLoader;
|
|
6647
|
+
} else if (optionsOrDraco !== void 0) {
|
|
6648
|
+
warnLegacyApi();
|
|
6649
|
+
draco = optionsOrDraco;
|
|
6650
|
+
meshopt = useMeshoptArg ?? true;
|
|
6651
|
+
ktx2 = useKTX2Arg ?? false;
|
|
6652
|
+
extendLoader = extendLoaderArg;
|
|
6653
|
+
}
|
|
6654
|
+
const renderer = useThree((state) => state.renderer);
|
|
6655
|
+
useLayoutEffect(() => {
|
|
6656
|
+
if (ktx2) {
|
|
6657
|
+
KTX2LoaderService.registerRenderer(renderer);
|
|
6658
|
+
}
|
|
6659
|
+
}, [ktx2, renderer]);
|
|
6660
|
+
return useLoader(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, ktx2 ? renderer : void 0));
|
|
6661
|
+
}
|
|
6662
|
+
useGLTF.preload = (path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) => {
|
|
6663
|
+
let draco = true;
|
|
6664
|
+
let meshopt = true;
|
|
6665
|
+
let ktx2 = false;
|
|
6666
|
+
let extendLoader;
|
|
6667
|
+
if (isOptionsObject(optionsOrDraco)) {
|
|
6668
|
+
draco = optionsOrDraco.draco ?? true;
|
|
6669
|
+
meshopt = optionsOrDraco.meshopt ?? true;
|
|
6670
|
+
ktx2 = optionsOrDraco.ktx2 ?? false;
|
|
6671
|
+
extendLoader = optionsOrDraco.extendLoader;
|
|
6672
|
+
} else if (optionsOrDraco !== void 0) {
|
|
6673
|
+
warnLegacyApi();
|
|
6674
|
+
draco = optionsOrDraco;
|
|
6675
|
+
meshopt = useMeshoptArg ?? true;
|
|
6676
|
+
ktx2 = useKTX2Arg ?? false;
|
|
6677
|
+
extendLoader = extendLoaderArg;
|
|
6678
|
+
}
|
|
6679
|
+
if (ktx2) {
|
|
6680
|
+
KTX2LoaderService.onReady(() => {
|
|
6681
|
+
const renderer = KTX2LoaderService.getRenderer();
|
|
6682
|
+
useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, renderer));
|
|
6683
|
+
});
|
|
6684
|
+
} else {
|
|
6685
|
+
useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, false, extendLoader));
|
|
6686
|
+
}
|
|
6687
|
+
};
|
|
6466
6688
|
useGLTF.clear = (path) => useLoader.clear(GLTFLoader, path);
|
|
6467
6689
|
useGLTF.setDecoderPath = (path) => {
|
|
6468
6690
|
decoderPath = path;
|
|
6469
6691
|
};
|
|
6692
|
+
useGLTF.setKTX2TranscoderPath = (path) => {
|
|
6693
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
6694
|
+
};
|
|
6470
6695
|
const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
6471
|
-
({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => {
|
|
6472
|
-
const
|
|
6696
|
+
({ src, useDraco, useMeshOpt, extendLoader, options, ...props }, ref) => {
|
|
6697
|
+
const opts = options ?? {
|
|
6698
|
+
draco: useDraco,
|
|
6699
|
+
meshopt: useMeshOpt,
|
|
6700
|
+
extendLoader
|
|
6701
|
+
};
|
|
6702
|
+
const { scene } = useGLTF(src, opts);
|
|
6473
6703
|
return /* @__PURE__ */ React.createElement(Clone, { ref, ...props, object: scene });
|
|
6474
6704
|
}
|
|
6475
6705
|
);
|
|
6476
6706
|
|
|
6477
|
-
let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
6478
6707
|
function useKTX2(input, basisPath = true, extendLoader) {
|
|
6479
6708
|
const renderer = useThree((state) => state.renderer);
|
|
6709
|
+
useLayoutEffect(() => {
|
|
6710
|
+
KTX2LoaderService.registerRenderer(renderer);
|
|
6711
|
+
}, [renderer]);
|
|
6480
6712
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
6481
6713
|
if (extendLoader) {
|
|
6482
6714
|
extendLoader(loader);
|
|
6483
6715
|
}
|
|
6484
6716
|
if (basisPath) {
|
|
6485
|
-
|
|
6717
|
+
const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
|
|
6718
|
+
loader.setTranscoderPath(path);
|
|
6486
6719
|
}
|
|
6487
6720
|
loader.detectSupport(renderer);
|
|
6488
6721
|
});
|
|
6489
6722
|
useEffect(() => {
|
|
6490
6723
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
6491
|
-
array.forEach((texture) =>
|
|
6724
|
+
array.forEach((texture) => {
|
|
6725
|
+
if ("initTexture" in renderer) {
|
|
6726
|
+
renderer.initTexture(texture);
|
|
6727
|
+
}
|
|
6728
|
+
});
|
|
6492
6729
|
}, [renderer, textures]);
|
|
6493
6730
|
if (IsObject(input)) {
|
|
6494
6731
|
const keys = Object.keys(input);
|
|
@@ -6499,23 +6736,81 @@ function useKTX2(input, basisPath = true, extendLoader) {
|
|
|
6499
6736
|
return textures;
|
|
6500
6737
|
}
|
|
6501
6738
|
}
|
|
6502
|
-
useKTX2.preload = (url, basisPath = true, extendLoader) =>
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6739
|
+
useKTX2.preload = (url, basisPath = true, extendLoader) => {
|
|
6740
|
+
KTX2LoaderService.onReady(() => {
|
|
6741
|
+
const renderer = KTX2LoaderService.getRenderer();
|
|
6742
|
+
useLoader.preload(KTX2Loader, url, (loader) => {
|
|
6743
|
+
if (extendLoader) {
|
|
6744
|
+
extendLoader(loader);
|
|
6745
|
+
}
|
|
6746
|
+
if (basisPath) {
|
|
6747
|
+
const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
|
|
6748
|
+
loader.setTranscoderPath(path);
|
|
6749
|
+
}
|
|
6750
|
+
if (renderer) {
|
|
6751
|
+
loader.detectSupport(renderer);
|
|
6752
|
+
}
|
|
6753
|
+
});
|
|
6754
|
+
});
|
|
6755
|
+
};
|
|
6510
6756
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
6511
6757
|
useKTX2.setTranscoderPath = (path) => {
|
|
6512
|
-
|
|
6758
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
6513
6759
|
};
|
|
6514
6760
|
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
6515
6761
|
const texture = useKTX2(input, basisPath, extendLoader);
|
|
6516
6762
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
6517
6763
|
};
|
|
6518
6764
|
|
|
6765
|
+
const useVariants = (model, inVariant) => {
|
|
6766
|
+
const [activeVariant, setActiveVariant] = useState(null);
|
|
6767
|
+
const [materials, setMaterials] = useState([]);
|
|
6768
|
+
useEffect(() => {
|
|
6769
|
+
model.parser.getDependencies("material").then((materials2) => {
|
|
6770
|
+
setMaterials(materials2);
|
|
6771
|
+
});
|
|
6772
|
+
}, [model]);
|
|
6773
|
+
const variants = useMemo(() => {
|
|
6774
|
+
return model.userData.gltfExtensions?.KHR_materials_variants?.variants;
|
|
6775
|
+
}, [model]);
|
|
6776
|
+
const applyVariant = useCallback(
|
|
6777
|
+
(variantIndex) => {
|
|
6778
|
+
model.scene.traverse(async (object) => {
|
|
6779
|
+
if (!("isMesh" in object) || !object.userData.gltfExtensions) return;
|
|
6780
|
+
const meshObject = object;
|
|
6781
|
+
const meshVariantDef = meshObject.userData.gltfExtensions.KHR_materials_variants;
|
|
6782
|
+
if (!meshVariantDef) return;
|
|
6783
|
+
if (!meshObject.userData.originalMaterial) meshObject.userData.originalMaterial = meshObject.material;
|
|
6784
|
+
const mapping = meshVariantDef.mappings.find((mapping2) => mapping2.variants.includes(variantIndex));
|
|
6785
|
+
if (mapping) {
|
|
6786
|
+
meshObject.material = await model.parser.getDependency("material", mapping.material);
|
|
6787
|
+
model.parser.assignFinalMaterial(meshObject);
|
|
6788
|
+
} else meshObject.material = meshObject.userData.originalMaterial;
|
|
6789
|
+
if (Array.isArray(meshObject.material)) for (const mat of meshObject.material) mat.needsUpdate = true;
|
|
6790
|
+
else meshObject.material.needsUpdate = true;
|
|
6791
|
+
});
|
|
6792
|
+
},
|
|
6793
|
+
[model]
|
|
6794
|
+
);
|
|
6795
|
+
const setVariant = useCallback(
|
|
6796
|
+
(variantName) => {
|
|
6797
|
+
if (!variants) return;
|
|
6798
|
+
const newVariant = variantName && variants.some((v) => v.name === variantName) ? variantName : null;
|
|
6799
|
+
setActiveVariant(newVariant);
|
|
6800
|
+
},
|
|
6801
|
+
[variants]
|
|
6802
|
+
);
|
|
6803
|
+
useEffect(() => {
|
|
6804
|
+
if (!variants) return;
|
|
6805
|
+
const variantIndex = variants.findIndex((v) => v.name === activeVariant);
|
|
6806
|
+
applyVariant(variantIndex > -1 ? variantIndex : 0);
|
|
6807
|
+
}, [variants, activeVariant, applyVariant]);
|
|
6808
|
+
useEffect(() => {
|
|
6809
|
+
setVariant(inVariant ?? null);
|
|
6810
|
+
}, [inVariant, setVariant]);
|
|
6811
|
+
return { variants, activeVariant, setVariant, materials };
|
|
6812
|
+
};
|
|
6813
|
+
|
|
6519
6814
|
const WebcamVideoTexture = /* @__PURE__ */ forwardRef(
|
|
6520
6815
|
({
|
|
6521
6816
|
constraints = {
|
|
@@ -6703,6 +6998,7 @@ function useEffectfulState(fn, deps = [], cb) {
|
|
|
6703
6998
|
}
|
|
6704
6999
|
|
|
6705
7000
|
function Stats({ showPanel = 0, className, parent }) {
|
|
7001
|
+
React.useEffect(() => void console.warn("drei: <Stats /> is deprecated, use <StatsGl /> instead."), []);
|
|
6706
7002
|
const stats = useEffectfulState(() => new StatsImpl(), []);
|
|
6707
7003
|
React.useEffect(() => {
|
|
6708
7004
|
if (stats) {
|
|
@@ -6731,6 +7027,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
6731
7027
|
const stats2 = new Stats$1({
|
|
6732
7028
|
...props
|
|
6733
7029
|
});
|
|
7030
|
+
stats2.init(renderer);
|
|
6734
7031
|
return stats2;
|
|
6735
7032
|
}, [renderer]);
|
|
6736
7033
|
React.useImperativeHandle(fref, () => stats.domElement, [stats]);
|
|
@@ -6748,7 +7045,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
6748
7045
|
return () => {
|
|
6749
7046
|
if (classNames.length) stats.domElement.classList.remove(...classNames);
|
|
6750
7047
|
node?.removeChild(stats.domElement);
|
|
6751
|
-
stats.
|
|
7048
|
+
stats.dispose();
|
|
6752
7049
|
};
|
|
6753
7050
|
}
|
|
6754
7051
|
}, [parent, stats, className, id, clearStatsGlStyle]);
|
|
@@ -6756,7 +7053,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
6756
7053
|
() => {
|
|
6757
7054
|
stats.begin();
|
|
6758
7055
|
},
|
|
6759
|
-
{ before: "
|
|
7056
|
+
{ before: "update" }
|
|
6760
7057
|
);
|
|
6761
7058
|
useFrame(
|
|
6762
7059
|
() => {
|
|
@@ -6806,11 +7103,11 @@ const RenderCubeTexture = /* @__PURE__ */ React.forwardRef(
|
|
|
6806
7103
|
depthBuffer,
|
|
6807
7104
|
generateMipmaps
|
|
6808
7105
|
};
|
|
6809
|
-
const fboA2 = new
|
|
7106
|
+
const fboA2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
6810
7107
|
fboA2.texture.isRenderTargetTexture = !flip;
|
|
6811
7108
|
fboA2.texture.flipY = true;
|
|
6812
7109
|
fboA2.texture.type = THREE.HalfFloatType;
|
|
6813
|
-
const fboB2 = new
|
|
7110
|
+
const fboB2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
6814
7111
|
fboB2.texture.isRenderTargetTexture = !flip;
|
|
6815
7112
|
fboB2.texture.flipY = true;
|
|
6816
7113
|
fboB2.texture.type = THREE.HalfFloatType;
|
|
@@ -7139,8 +7436,9 @@ const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
|
7139
7436
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
7140
7437
|
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
7141
7438
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
7142
|
-
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
7143
7439
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
7440
|
+
const canvasRight = canvasSize.left + canvasSize.width;
|
|
7441
|
+
const isOffscreen = trackBottom < canvasSize.top || trackTop > canvasBottom || right < canvasSize.left || trackLeft > canvasRight;
|
|
7144
7442
|
const rawBottom = canvasBottom - trackBottom;
|
|
7145
7443
|
const rawLeft = trackLeft - canvasSize.left;
|
|
7146
7444
|
const rawTop = trackTop - canvasSize.top;
|
|
@@ -7700,12 +7998,12 @@ useEnvironment.preload = (preloadOptions) => {
|
|
|
7700
7998
|
if (extensions) extensions(loader2);
|
|
7701
7999
|
});
|
|
7702
8000
|
};
|
|
7703
|
-
const
|
|
8001
|
+
const clearDefaultOptions = {
|
|
7704
8002
|
files: defaultFiles,
|
|
7705
8003
|
preset: void 0
|
|
7706
8004
|
};
|
|
7707
8005
|
useEnvironment.clear = (clearOptions) => {
|
|
7708
|
-
const options = { ...
|
|
8006
|
+
const options = { ...clearDefaultOptions, ...clearOptions };
|
|
7709
8007
|
let { files } = options;
|
|
7710
8008
|
const { preset } = options;
|
|
7711
8009
|
if (preset) {
|
|
@@ -8399,9 +8697,14 @@ function Select({
|
|
|
8399
8697
|
const oldControlsEnabled = controls?.enabled;
|
|
8400
8698
|
let isDown = false;
|
|
8401
8699
|
function prepareRay(event, vec) {
|
|
8402
|
-
const
|
|
8700
|
+
const canvas = gl.domElement;
|
|
8701
|
+
const rect = canvas.getBoundingClientRect();
|
|
8702
|
+
const x = event.clientX - rect.left;
|
|
8703
|
+
const y = event.clientY - rect.top;
|
|
8403
8704
|
const { width, height } = size;
|
|
8404
|
-
|
|
8705
|
+
const normalizedX = x / width * 2 - 1;
|
|
8706
|
+
const normalizedY = -(y / height) * 2 + 1;
|
|
8707
|
+
vec.set(normalizedX, normalizedY, -1);
|
|
8405
8708
|
}
|
|
8406
8709
|
function onSelectStart(event) {
|
|
8407
8710
|
if (controls) controls.enabled = false;
|
|
@@ -8480,4 +8783,4 @@ function useSelect() {
|
|
|
8480
8783
|
return React.useContext(context);
|
|
8481
8784
|
}
|
|
8482
8785
|
|
|
8483
|
-
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrailTexture, useVideoTexture };
|
|
8786
|
+
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrailTexture, useVariants, useVideoTexture };
|