@react-three/fiber 10.0.0-canary.b0fafc8 → 10.0.0-canary.c3fa45d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +363 -91
- package/dist/index.d.cts +156 -27
- package/dist/index.d.mts +156 -27
- package/dist/index.d.ts +156 -27
- package/dist/index.mjs +364 -92
- package/dist/legacy.cjs +357 -91
- package/dist/legacy.d.cts +156 -27
- package/dist/legacy.d.mts +156 -27
- package/dist/legacy.d.ts +156 -27
- package/dist/legacy.mjs +358 -92
- package/dist/webgpu/index.cjs +738 -102
- package/dist/webgpu/index.d.cts +241 -40
- package/dist/webgpu/index.d.mts +241 -40
- package/dist/webgpu/index.d.ts +241 -40
- package/dist/webgpu/index.mjs +735 -103
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
|
-
import { RenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, WebGLCubeRenderTarget, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera,
|
|
2
|
+
import { RenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, WebGLCubeRenderTarget, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer } from 'three/webgpu';
|
|
3
3
|
import { WebGLRenderTarget, WebGLRenderer } from 'three';
|
|
4
4
|
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
5
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
@@ -139,7 +139,7 @@ function useEnvironment({
|
|
|
139
139
|
useLoader$1.clear(loader, multiFile ? [files] : files);
|
|
140
140
|
}
|
|
141
141
|
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
142
|
-
}, [files, renderer.domElement]);
|
|
142
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
143
143
|
const loaderResult = useLoader$1(
|
|
144
144
|
loader,
|
|
145
145
|
multiFile ? [files] : files,
|
|
@@ -339,7 +339,22 @@ function EnvironmentPortal({
|
|
|
339
339
|
environmentIntensity,
|
|
340
340
|
environmentRotation
|
|
341
341
|
});
|
|
342
|
-
}, [
|
|
342
|
+
}, [
|
|
343
|
+
children,
|
|
344
|
+
virtualScene,
|
|
345
|
+
fbo.texture,
|
|
346
|
+
scene,
|
|
347
|
+
defaultScene,
|
|
348
|
+
background,
|
|
349
|
+
frames,
|
|
350
|
+
gl,
|
|
351
|
+
blur,
|
|
352
|
+
backgroundBlurriness,
|
|
353
|
+
backgroundIntensity,
|
|
354
|
+
backgroundRotation,
|
|
355
|
+
environmentIntensity,
|
|
356
|
+
environmentRotation
|
|
357
|
+
]);
|
|
343
358
|
let count = 1;
|
|
344
359
|
useFrame$1(() => {
|
|
345
360
|
if (frames === Infinity || count < frames) {
|
|
@@ -975,6 +990,9 @@ function applyProps(object, props) {
|
|
|
975
990
|
else target.set(value);
|
|
976
991
|
} else {
|
|
977
992
|
root[key] = value;
|
|
993
|
+
if (key.endsWith("Node") && root.isMaterial) {
|
|
994
|
+
root.needsUpdate = true;
|
|
995
|
+
}
|
|
978
996
|
if (rootState && rootState.renderer?.outputColorSpace === SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
979
997
|
root[key].format === RGBAFormat && root[key].type === UnsignedByteType) {
|
|
980
998
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
@@ -1008,38 +1026,60 @@ function applyProps(object, props) {
|
|
|
1008
1026
|
return object;
|
|
1009
1027
|
}
|
|
1010
1028
|
|
|
1029
|
+
const DEFAULT_POINTER_ID = 0;
|
|
1030
|
+
const XR_POINTER_ID_START = 1e3;
|
|
1031
|
+
function getPointerState(internal, pointerId) {
|
|
1032
|
+
let state = internal.pointerMap.get(pointerId);
|
|
1033
|
+
if (!state) {
|
|
1034
|
+
state = {
|
|
1035
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
1036
|
+
captured: /* @__PURE__ */ new Map(),
|
|
1037
|
+
initialClick: [0, 0],
|
|
1038
|
+
initialHits: []
|
|
1039
|
+
};
|
|
1040
|
+
internal.pointerMap.set(pointerId, state);
|
|
1041
|
+
}
|
|
1042
|
+
return state;
|
|
1043
|
+
}
|
|
1044
|
+
function getPointerId(event) {
|
|
1045
|
+
return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
|
|
1046
|
+
}
|
|
1011
1047
|
function makeId(event) {
|
|
1012
1048
|
return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
|
|
1013
1049
|
}
|
|
1014
|
-
function releaseInternalPointerCapture(
|
|
1015
|
-
const
|
|
1050
|
+
function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
1051
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1052
|
+
if (!pointerState) return;
|
|
1053
|
+
const captureData = pointerState.captured.get(obj);
|
|
1016
1054
|
if (captureData) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
capturedMap.delete(pointerId);
|
|
1020
|
-
captureData.target.releasePointerCapture(pointerId);
|
|
1021
|
-
}
|
|
1055
|
+
pointerState.captured.delete(obj);
|
|
1056
|
+
captureData.target.releasePointerCapture(pointerId);
|
|
1022
1057
|
}
|
|
1023
1058
|
}
|
|
1024
1059
|
function removeInteractivity(store, object) {
|
|
1025
1060
|
const { internal } = store.getState();
|
|
1026
1061
|
internal.interaction = internal.interaction.filter((o) => o !== object);
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1062
|
+
for (const [pointerId, pointerState] of internal.pointerMap) {
|
|
1063
|
+
pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
|
|
1064
|
+
pointerState.hovered.forEach((value, key) => {
|
|
1065
|
+
if (value.eventObject === object || value.object === object) {
|
|
1066
|
+
pointerState.hovered.delete(key);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
if (pointerState.captured.has(object)) {
|
|
1070
|
+
releaseInternalPointerCapture(internal, object, pointerId);
|
|
1031
1071
|
}
|
|
1032
|
-
}
|
|
1033
|
-
internal.capturedMap.forEach((captures, pointerId) => {
|
|
1034
|
-
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
1035
|
-
});
|
|
1072
|
+
}
|
|
1036
1073
|
unregisterVisibility(store, object);
|
|
1037
1074
|
}
|
|
1038
1075
|
function createEvents(store) {
|
|
1039
|
-
function calculateDistance(event) {
|
|
1076
|
+
function calculateDistance(event, pointerId) {
|
|
1040
1077
|
const { internal } = store.getState();
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1078
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1079
|
+
if (!pointerState) return 0;
|
|
1080
|
+
const [initialX, initialY] = pointerState.initialClick;
|
|
1081
|
+
const dx = event.offsetX - initialX;
|
|
1082
|
+
const dy = event.offsetY - initialY;
|
|
1043
1083
|
return Math.round(Math.sqrt(dx * dx + dy * dy));
|
|
1044
1084
|
}
|
|
1045
1085
|
function filterPointerEvents(objects) {
|
|
@@ -1075,6 +1115,15 @@ function createEvents(store) {
|
|
|
1075
1115
|
return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
|
|
1076
1116
|
}
|
|
1077
1117
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
1118
|
+
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
1119
|
+
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
1120
|
+
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
1121
|
+
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
1122
|
+
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
1123
|
+
if (aInteractivePriority !== bInteractivePriority) {
|
|
1124
|
+
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1078
1127
|
const aState = getRootState(a.object);
|
|
1079
1128
|
const bState = getRootState(b.object);
|
|
1080
1129
|
const aPriority = aState?.events?.priority ?? 1;
|
|
@@ -1096,9 +1145,13 @@ function createEvents(store) {
|
|
|
1096
1145
|
eventObject = eventObject.parent;
|
|
1097
1146
|
}
|
|
1098
1147
|
}
|
|
1099
|
-
if ("pointerId" in event
|
|
1100
|
-
|
|
1101
|
-
|
|
1148
|
+
if ("pointerId" in event) {
|
|
1149
|
+
const pointerId = event.pointerId;
|
|
1150
|
+
const pointerState = state.internal.pointerMap.get(pointerId);
|
|
1151
|
+
if (pointerState?.captured.size) {
|
|
1152
|
+
for (const captureData of pointerState.captured.values()) {
|
|
1153
|
+
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
1154
|
+
}
|
|
1102
1155
|
}
|
|
1103
1156
|
}
|
|
1104
1157
|
return intersections;
|
|
@@ -1111,27 +1164,25 @@ function createEvents(store) {
|
|
|
1111
1164
|
if (state) {
|
|
1112
1165
|
const { raycaster, pointer, camera, internal } = state;
|
|
1113
1166
|
const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
|
|
1114
|
-
const hasPointerCapture = (id) =>
|
|
1167
|
+
const hasPointerCapture = (id) => {
|
|
1168
|
+
const pointerState = internal.pointerMap.get(id);
|
|
1169
|
+
return pointerState?.captured.has(hit.eventObject) ?? false;
|
|
1170
|
+
};
|
|
1115
1171
|
const setPointerCapture = (id) => {
|
|
1116
1172
|
const captureData = { intersection: hit, target: event.target };
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
} else {
|
|
1120
|
-
internal.capturedMap.set(id, /* @__PURE__ */ new Map([[hit.eventObject, captureData]]));
|
|
1121
|
-
}
|
|
1173
|
+
const pointerState = getPointerState(internal, id);
|
|
1174
|
+
pointerState.captured.set(hit.eventObject, captureData);
|
|
1122
1175
|
event.target.setPointerCapture(id);
|
|
1123
1176
|
};
|
|
1124
1177
|
const releasePointerCapture = (id) => {
|
|
1125
|
-
|
|
1126
|
-
if (captures) {
|
|
1127
|
-
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
1128
|
-
}
|
|
1178
|
+
releaseInternalPointerCapture(internal, hit.eventObject, id);
|
|
1129
1179
|
};
|
|
1130
1180
|
const extractEventProps = {};
|
|
1131
1181
|
for (const prop in event) {
|
|
1132
1182
|
const property = event[prop];
|
|
1133
1183
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
1134
1184
|
}
|
|
1185
|
+
const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
|
|
1135
1186
|
const raycastEvent = {
|
|
1136
1187
|
...hit,
|
|
1137
1188
|
...extractEventProps,
|
|
@@ -1142,18 +1193,19 @@ function createEvents(store) {
|
|
|
1142
1193
|
unprojectedPoint,
|
|
1143
1194
|
ray: raycaster.ray,
|
|
1144
1195
|
camera,
|
|
1196
|
+
pointerId: eventPointerId,
|
|
1145
1197
|
// Hijack stopPropagation, which just sets a flag
|
|
1146
1198
|
stopPropagation() {
|
|
1147
|
-
const
|
|
1199
|
+
const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
|
|
1148
1200
|
if (
|
|
1149
1201
|
// ...if this pointer hasn't been captured
|
|
1150
|
-
!
|
|
1151
|
-
|
|
1202
|
+
!pointerState?.captured.size || // ... or if the hit object is capturing the pointer
|
|
1203
|
+
pointerState.captured.has(hit.eventObject)
|
|
1152
1204
|
) {
|
|
1153
1205
|
raycastEvent.stopped = localState.stopped = true;
|
|
1154
|
-
if (
|
|
1206
|
+
if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
|
|
1155
1207
|
const higher = intersections.slice(0, intersections.indexOf(hit));
|
|
1156
|
-
cancelPointer([...higher, hit]);
|
|
1208
|
+
cancelPointer([...higher, hit], eventPointerId);
|
|
1157
1209
|
}
|
|
1158
1210
|
}
|
|
1159
1211
|
},
|
|
@@ -1169,15 +1221,18 @@ function createEvents(store) {
|
|
|
1169
1221
|
}
|
|
1170
1222
|
return intersections;
|
|
1171
1223
|
}
|
|
1172
|
-
function cancelPointer(intersections) {
|
|
1224
|
+
function cancelPointer(intersections, pointerId) {
|
|
1173
1225
|
const { internal } = store.getState();
|
|
1174
|
-
|
|
1226
|
+
const pid = pointerId ?? DEFAULT_POINTER_ID;
|
|
1227
|
+
const pointerState = internal.pointerMap.get(pid);
|
|
1228
|
+
if (!pointerState) return;
|
|
1229
|
+
for (const [hoveredId, hoveredObj] of pointerState.hovered) {
|
|
1175
1230
|
if (!intersections.length || !intersections.find(
|
|
1176
1231
|
(hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
|
|
1177
1232
|
)) {
|
|
1178
1233
|
const eventObject = hoveredObj.eventObject;
|
|
1179
1234
|
const instance = eventObject.__r3f;
|
|
1180
|
-
|
|
1235
|
+
pointerState.hovered.delete(hoveredId);
|
|
1181
1236
|
if (instance?.eventCount) {
|
|
1182
1237
|
const handlers = instance.handlers;
|
|
1183
1238
|
const data = { ...hoveredObj, intersections };
|
|
@@ -1206,41 +1261,118 @@ function createEvents(store) {
|
|
|
1206
1261
|
instance?.handlers.onDropMissed?.(event);
|
|
1207
1262
|
}
|
|
1208
1263
|
}
|
|
1264
|
+
function cleanupPointer(pointerId) {
|
|
1265
|
+
const { internal } = store.getState();
|
|
1266
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1267
|
+
if (pointerState) {
|
|
1268
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1269
|
+
const eventObject = hoveredObj.eventObject;
|
|
1270
|
+
const instance = eventObject.__r3f;
|
|
1271
|
+
if (instance?.eventCount) {
|
|
1272
|
+
const handlers = instance.handlers;
|
|
1273
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1274
|
+
handlers.onPointerOut?.(data);
|
|
1275
|
+
handlers.onPointerLeave?.(data);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
internal.pointerMap.delete(pointerId);
|
|
1279
|
+
}
|
|
1280
|
+
internal.pointerDirty.delete(pointerId);
|
|
1281
|
+
}
|
|
1282
|
+
function processDeferredPointer(event, pointerId) {
|
|
1283
|
+
const state = store.getState();
|
|
1284
|
+
const { internal } = state;
|
|
1285
|
+
if (!state.events.enabled) return;
|
|
1286
|
+
const filter = filterPointerEvents;
|
|
1287
|
+
const hits = intersect(event, filter);
|
|
1288
|
+
cancelPointer(hits, pointerId);
|
|
1289
|
+
function onIntersect(data) {
|
|
1290
|
+
const eventObject = data.eventObject;
|
|
1291
|
+
const instance = eventObject.__r3f;
|
|
1292
|
+
if (!instance?.eventCount) return;
|
|
1293
|
+
const handlers = instance.handlers;
|
|
1294
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
1295
|
+
const id = makeId(data);
|
|
1296
|
+
const pointerState = getPointerState(internal, pointerId);
|
|
1297
|
+
const hoveredItem = pointerState.hovered.get(id);
|
|
1298
|
+
if (!hoveredItem) {
|
|
1299
|
+
pointerState.hovered.set(id, data);
|
|
1300
|
+
handlers.onPointerOver?.(data);
|
|
1301
|
+
handlers.onPointerEnter?.(data);
|
|
1302
|
+
} else if (hoveredItem.stopped) {
|
|
1303
|
+
data.stopPropagation();
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
handlers.onPointerMove?.(data);
|
|
1307
|
+
}
|
|
1308
|
+
handleIntersects(hits, event, 0, onIntersect);
|
|
1309
|
+
}
|
|
1209
1310
|
function handlePointer(name) {
|
|
1210
1311
|
switch (name) {
|
|
1211
1312
|
case "onPointerLeave":
|
|
1212
|
-
case "onPointerCancel":
|
|
1213
1313
|
case "onDragLeave":
|
|
1214
1314
|
return () => cancelPointer([]);
|
|
1315
|
+
// Global cancel of these events
|
|
1316
|
+
case "onPointerCancel":
|
|
1317
|
+
return (event) => {
|
|
1318
|
+
const pointerId = getPointerId(event);
|
|
1319
|
+
cleanupPointer(pointerId);
|
|
1320
|
+
};
|
|
1215
1321
|
case "onLostPointerCapture":
|
|
1216
1322
|
return (event) => {
|
|
1217
1323
|
const { internal } = store.getState();
|
|
1218
|
-
|
|
1324
|
+
const pointerId = getPointerId(event);
|
|
1325
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1326
|
+
if (pointerState?.captured.size) {
|
|
1219
1327
|
requestAnimationFrame(() => {
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1328
|
+
const pointerState2 = internal.pointerMap.get(pointerId);
|
|
1329
|
+
if (pointerState2?.captured.size) {
|
|
1330
|
+
pointerState2.captured.clear();
|
|
1223
1331
|
}
|
|
1332
|
+
cancelPointer([], pointerId);
|
|
1224
1333
|
});
|
|
1225
1334
|
}
|
|
1226
1335
|
};
|
|
1227
1336
|
}
|
|
1228
1337
|
return function handleEvent(event) {
|
|
1229
1338
|
const state = store.getState();
|
|
1230
|
-
const { onPointerMissed, onDragOverMissed, onDropMissed, internal } = state;
|
|
1339
|
+
const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
|
|
1340
|
+
const pointerId = getPointerId(event);
|
|
1231
1341
|
internal.lastEvent.current = event;
|
|
1232
|
-
if (!
|
|
1342
|
+
if (!events.enabled) return;
|
|
1233
1343
|
const isPointerMove = name === "onPointerMove";
|
|
1234
1344
|
const isDragOver = name === "onDragOver";
|
|
1235
1345
|
const isDrop = name === "onDrop";
|
|
1236
1346
|
const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
|
|
1347
|
+
const isPointerDown = name === "onPointerDown";
|
|
1348
|
+
const isPointerUp = name === "onPointerUp";
|
|
1349
|
+
const isWheel = name === "onWheel";
|
|
1350
|
+
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
1351
|
+
if (isPointerMove && canDeferRaycasts) {
|
|
1352
|
+
events.compute?.(event, state);
|
|
1353
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
1357
|
+
events.compute?.(event, state);
|
|
1358
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
1362
|
+
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
1363
|
+
internal.pointerDirty.delete(pointerId);
|
|
1364
|
+
processDeferredPointer(deferredEvent, pointerId);
|
|
1365
|
+
}
|
|
1237
1366
|
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
1238
1367
|
const hits = intersect(event, filter);
|
|
1239
|
-
const delta = isClickEvent ? calculateDistance(event) : 0;
|
|
1240
|
-
if (
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1368
|
+
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
1369
|
+
if (isPointerDown) {
|
|
1370
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1371
|
+
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
1372
|
+
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
1373
|
+
}
|
|
1374
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1375
|
+
const initialHits = pointerState?.initialHits ?? [];
|
|
1244
1376
|
if (isClickEvent && !hits.length) {
|
|
1245
1377
|
if (delta <= 2) {
|
|
1246
1378
|
pointerMissed(event, internal.interaction);
|
|
@@ -1255,7 +1387,9 @@ function createEvents(store) {
|
|
|
1255
1387
|
dropMissed(event, internal.interaction);
|
|
1256
1388
|
if (onDropMissed) onDropMissed(event);
|
|
1257
1389
|
}
|
|
1258
|
-
if (isPointerMove || isDragOver)
|
|
1390
|
+
if (isPointerMove || isDragOver) {
|
|
1391
|
+
cancelPointer(hits, pointerId);
|
|
1392
|
+
}
|
|
1259
1393
|
function onIntersect(data) {
|
|
1260
1394
|
const eventObject = data.eventObject;
|
|
1261
1395
|
const instance = eventObject.__r3f;
|
|
@@ -1264,9 +1398,10 @@ function createEvents(store) {
|
|
|
1264
1398
|
if (isPointerMove) {
|
|
1265
1399
|
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
1266
1400
|
const id = makeId(data);
|
|
1267
|
-
const
|
|
1401
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1402
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
1268
1403
|
if (!hoveredItem) {
|
|
1269
|
-
|
|
1404
|
+
pointerState2.hovered.set(id, data);
|
|
1270
1405
|
handlers.onPointerOver?.(data);
|
|
1271
1406
|
handlers.onPointerEnter?.(data);
|
|
1272
1407
|
} else if (hoveredItem.stopped) {
|
|
@@ -1276,9 +1411,10 @@ function createEvents(store) {
|
|
|
1276
1411
|
handlers.onPointerMove?.(data);
|
|
1277
1412
|
} else if (isDragOver) {
|
|
1278
1413
|
const id = makeId(data);
|
|
1279
|
-
const
|
|
1414
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1415
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
1280
1416
|
if (!hoveredItem) {
|
|
1281
|
-
|
|
1417
|
+
pointerState2.hovered.set(id, data);
|
|
1282
1418
|
handlers.onDragOverEnter?.(data);
|
|
1283
1419
|
} else if (hoveredItem.stopped) {
|
|
1284
1420
|
data.stopPropagation();
|
|
@@ -1289,18 +1425,18 @@ function createEvents(store) {
|
|
|
1289
1425
|
} else {
|
|
1290
1426
|
const handler = handlers[name];
|
|
1291
1427
|
if (handler) {
|
|
1292
|
-
if (!isClickEvent ||
|
|
1428
|
+
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
1293
1429
|
pointerMissed(
|
|
1294
1430
|
event,
|
|
1295
|
-
internal.interaction.filter((object) => !
|
|
1431
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
1296
1432
|
);
|
|
1297
1433
|
handler(data);
|
|
1298
1434
|
}
|
|
1299
1435
|
} else {
|
|
1300
|
-
if (isClickEvent &&
|
|
1436
|
+
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
1301
1437
|
pointerMissed(
|
|
1302
1438
|
event,
|
|
1303
|
-
internal.interaction.filter((object) => !
|
|
1439
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
1304
1440
|
);
|
|
1305
1441
|
}
|
|
1306
1442
|
}
|
|
@@ -1309,7 +1445,15 @@ function createEvents(store) {
|
|
|
1309
1445
|
handleIntersects(hits, event, delta, onIntersect);
|
|
1310
1446
|
};
|
|
1311
1447
|
}
|
|
1312
|
-
|
|
1448
|
+
function flushDeferredPointers() {
|
|
1449
|
+
const { internal, events } = store.getState();
|
|
1450
|
+
if (!events.frameTimedRaycasts) return;
|
|
1451
|
+
for (const [pointerId, event] of internal.pointerDirty) {
|
|
1452
|
+
processDeferredPointer(event, pointerId);
|
|
1453
|
+
}
|
|
1454
|
+
internal.pointerDirty.clear();
|
|
1455
|
+
}
|
|
1456
|
+
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
1313
1457
|
}
|
|
1314
1458
|
const DOM_EVENTS = {
|
|
1315
1459
|
onClick: ["click", false],
|
|
@@ -1328,10 +1472,15 @@ const DOM_EVENTS = {
|
|
|
1328
1472
|
onLostPointerCapture: ["lostpointercapture", true]
|
|
1329
1473
|
};
|
|
1330
1474
|
function createPointerEvents(store) {
|
|
1331
|
-
const { handlePointer } = createEvents(store);
|
|
1475
|
+
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
1476
|
+
let nextXRPointerId = XR_POINTER_ID_START;
|
|
1477
|
+
const xrPointers = /* @__PURE__ */ new Map();
|
|
1332
1478
|
return {
|
|
1333
1479
|
priority: 1,
|
|
1334
1480
|
enabled: true,
|
|
1481
|
+
frameTimedRaycasts: true,
|
|
1482
|
+
alwaysFireOnScroll: true,
|
|
1483
|
+
updateOnFrame: false,
|
|
1335
1484
|
compute(event, state) {
|
|
1336
1485
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
1337
1486
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
@@ -1341,11 +1490,33 @@ function createPointerEvents(store) {
|
|
|
1341
1490
|
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
1342
1491
|
{}
|
|
1343
1492
|
),
|
|
1344
|
-
update: () => {
|
|
1493
|
+
update: (pointerId) => {
|
|
1494
|
+
const { events, internal } = store.getState();
|
|
1495
|
+
if (!events.handlers) return;
|
|
1496
|
+
if (pointerId !== void 0) {
|
|
1497
|
+
const event = internal.pointerDirty.get(pointerId);
|
|
1498
|
+
if (event) {
|
|
1499
|
+
internal.pointerDirty.delete(pointerId);
|
|
1500
|
+
processDeferredPointer(event, pointerId);
|
|
1501
|
+
} else if (internal.lastEvent?.current) {
|
|
1502
|
+
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
1503
|
+
}
|
|
1504
|
+
} else {
|
|
1505
|
+
flushDeferredPointers();
|
|
1506
|
+
if (internal.lastEvent?.current) {
|
|
1507
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
},
|
|
1511
|
+
flush: () => {
|
|
1345
1512
|
const { events, internal } = store.getState();
|
|
1346
|
-
|
|
1513
|
+
flushDeferredPointers();
|
|
1514
|
+
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
1515
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1516
|
+
}
|
|
1347
1517
|
},
|
|
1348
1518
|
connect: (target) => {
|
|
1519
|
+
if (!target) return;
|
|
1349
1520
|
const { set, events } = store.getState();
|
|
1350
1521
|
events.disconnect?.();
|
|
1351
1522
|
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
@@ -1369,6 +1540,32 @@ function createPointerEvents(store) {
|
|
|
1369
1540
|
}
|
|
1370
1541
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
1371
1542
|
}
|
|
1543
|
+
},
|
|
1544
|
+
registerPointer: (config) => {
|
|
1545
|
+
const pointerId = nextXRPointerId++;
|
|
1546
|
+
xrPointers.set(pointerId, config);
|
|
1547
|
+
const { internal } = store.getState();
|
|
1548
|
+
getPointerState(internal, pointerId);
|
|
1549
|
+
return pointerId;
|
|
1550
|
+
},
|
|
1551
|
+
unregisterPointer: (pointerId) => {
|
|
1552
|
+
xrPointers.delete(pointerId);
|
|
1553
|
+
const { internal } = store.getState();
|
|
1554
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1555
|
+
if (pointerState) {
|
|
1556
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1557
|
+
const eventObject = hoveredObj.eventObject;
|
|
1558
|
+
const instance = eventObject.__r3f;
|
|
1559
|
+
if (instance?.eventCount) {
|
|
1560
|
+
const handlers = instance.handlers;
|
|
1561
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1562
|
+
handlers.onPointerOut?.(data);
|
|
1563
|
+
handlers.onPointerLeave?.(data);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
internal.pointerMap.delete(pointerId);
|
|
1567
|
+
}
|
|
1568
|
+
internal.pointerDirty.delete(pointerId);
|
|
1372
1569
|
}
|
|
1373
1570
|
};
|
|
1374
1571
|
}
|
|
@@ -1682,7 +1879,7 @@ function shouldRun(job, now) {
|
|
|
1682
1879
|
const minInterval = 1e3 / job.fps;
|
|
1683
1880
|
const lastRun = job.lastRun ?? 0;
|
|
1684
1881
|
const elapsed = now - lastRun;
|
|
1685
|
-
if (elapsed < minInterval) return false;
|
|
1882
|
+
if (elapsed < minInterval - 1) return false;
|
|
1686
1883
|
if (job.drop) {
|
|
1687
1884
|
job.lastRun = now;
|
|
1688
1885
|
} else {
|
|
@@ -2499,7 +2696,14 @@ const createStore = (invalidate, advance) => {
|
|
|
2499
2696
|
frustum: new Frustum(),
|
|
2500
2697
|
autoUpdateFrustum: true,
|
|
2501
2698
|
raycaster: null,
|
|
2502
|
-
events: {
|
|
2699
|
+
events: {
|
|
2700
|
+
priority: 1,
|
|
2701
|
+
enabled: true,
|
|
2702
|
+
connected: false,
|
|
2703
|
+
frameTimedRaycasts: true,
|
|
2704
|
+
alwaysFireOnScroll: true,
|
|
2705
|
+
updateOnFrame: false
|
|
2706
|
+
},
|
|
2503
2707
|
scene: null,
|
|
2504
2708
|
rootScene: null,
|
|
2505
2709
|
xr: null,
|
|
@@ -2590,11 +2794,13 @@ const createStore = (invalidate, advance) => {
|
|
|
2590
2794
|
},
|
|
2591
2795
|
setError: (error) => set(() => ({ error })),
|
|
2592
2796
|
error: null,
|
|
2593
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures,
|
|
2797
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
2594
2798
|
uniforms: {},
|
|
2595
2799
|
nodes: {},
|
|
2800
|
+
buffers: {},
|
|
2801
|
+
gpuStorage: {},
|
|
2596
2802
|
textures: /* @__PURE__ */ new Map(),
|
|
2597
|
-
|
|
2803
|
+
renderPipeline: null,
|
|
2598
2804
|
passes: {},
|
|
2599
2805
|
_hmrVersion: 0,
|
|
2600
2806
|
_sizeImperative: false,
|
|
@@ -2603,12 +2809,16 @@ const createStore = (invalidate, advance) => {
|
|
|
2603
2809
|
internal: {
|
|
2604
2810
|
// Events
|
|
2605
2811
|
interaction: [],
|
|
2606
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
2607
2812
|
subscribers: [],
|
|
2813
|
+
// Per-pointer state (new unified structure)
|
|
2814
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
2815
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
2816
|
+
lastEvent: React.createRef(),
|
|
2817
|
+
// Deprecated but kept for backwards compatibility
|
|
2818
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2608
2819
|
initialClick: [0, 0],
|
|
2609
2820
|
initialHits: [],
|
|
2610
2821
|
capturedMap: /* @__PURE__ */ new Map(),
|
|
2611
|
-
lastEvent: React.createRef(),
|
|
2612
2822
|
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2613
2823
|
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2614
2824
|
// Occlusion system (WebGPU only)
|
|
@@ -2696,14 +2906,16 @@ const createStore = (invalidate, advance) => {
|
|
|
2696
2906
|
oldSize = size;
|
|
2697
2907
|
oldDpr = viewport.dpr;
|
|
2698
2908
|
updateCamera(camera, size);
|
|
2699
|
-
if (canvasTarget) {
|
|
2909
|
+
if (internal.isSecondary && canvasTarget) {
|
|
2700
2910
|
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2701
|
-
|
|
2702
|
-
canvasTarget.setSize(size.width, size.height, updateStyle);
|
|
2911
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2703
2912
|
} else {
|
|
2704
2913
|
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2705
|
-
|
|
2706
|
-
|
|
2914
|
+
actualRenderer.setSize(size.width, size.height, false);
|
|
2915
|
+
if (canvasTarget) {
|
|
2916
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2917
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2918
|
+
}
|
|
2707
2919
|
}
|
|
2708
2920
|
}
|
|
2709
2921
|
if (camera !== oldCamera) {
|
|
@@ -14990,7 +15202,6 @@ function createRoot(canvas) {
|
|
|
14990
15202
|
events,
|
|
14991
15203
|
onCreated: onCreatedCallback,
|
|
14992
15204
|
shadows = false,
|
|
14993
|
-
textureColorSpace = SRGBColorSpace,
|
|
14994
15205
|
orthographic = false,
|
|
14995
15206
|
frameloop = "always",
|
|
14996
15207
|
dpr = [1, 2],
|
|
@@ -15005,6 +15216,7 @@ function createRoot(canvas) {
|
|
|
15005
15216
|
_sizeProps,
|
|
15006
15217
|
forceEven
|
|
15007
15218
|
} = props;
|
|
15219
|
+
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || SRGBColorSpace;
|
|
15008
15220
|
const state = store.getState();
|
|
15009
15221
|
const defaultGLProps = {
|
|
15010
15222
|
canvas,
|
|
@@ -15060,6 +15272,12 @@ function createRoot(canvas) {
|
|
|
15060
15272
|
} else if (!wantsGL && !state.internal.actualRenderer) {
|
|
15061
15273
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, WebGPURenderer);
|
|
15062
15274
|
if (!renderer.hasInitialized?.()) {
|
|
15275
|
+
const size2 = computeInitialSize(canvas, propsSize);
|
|
15276
|
+
if (size2.width > 0 && size2.height > 0) {
|
|
15277
|
+
const pixelRatio = calculateDpr(dpr);
|
|
15278
|
+
canvas.width = size2.width * pixelRatio;
|
|
15279
|
+
canvas.height = size2.height * pixelRatio;
|
|
15280
|
+
}
|
|
15063
15281
|
await renderer.init();
|
|
15064
15282
|
}
|
|
15065
15283
|
const backend = renderer.backend;
|
|
@@ -15169,7 +15387,7 @@ function createRoot(canvas) {
|
|
|
15169
15387
|
lastConfiguredProps.performance = performance;
|
|
15170
15388
|
}
|
|
15171
15389
|
if (!state.xr) {
|
|
15172
|
-
const handleXRFrame = (timestamp,
|
|
15390
|
+
const handleXRFrame = (timestamp, _frame) => {
|
|
15173
15391
|
const state2 = store.getState();
|
|
15174
15392
|
if (state2.frameloop === "never") return;
|
|
15175
15393
|
advance(timestamp);
|
|
@@ -15205,15 +15423,22 @@ function createRoot(canvas) {
|
|
|
15205
15423
|
const oldType = renderer.shadowMap.type;
|
|
15206
15424
|
renderer.shadowMap.enabled = !!shadows;
|
|
15207
15425
|
if (is.boo(shadows)) {
|
|
15208
|
-
renderer.shadowMap.type =
|
|
15426
|
+
renderer.shadowMap.type = PCFShadowMap;
|
|
15209
15427
|
} else if (is.str(shadows)) {
|
|
15428
|
+
if (shadows === "soft") {
|
|
15429
|
+
notifyDepreciated({
|
|
15430
|
+
heading: 'shadows="soft" is deprecated',
|
|
15431
|
+
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
15432
|
+
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
15433
|
+
});
|
|
15434
|
+
}
|
|
15210
15435
|
const types = {
|
|
15211
15436
|
basic: BasicShadowMap,
|
|
15212
15437
|
percentage: PCFShadowMap,
|
|
15213
|
-
soft:
|
|
15438
|
+
soft: PCFShadowMap,
|
|
15214
15439
|
variance: VSMShadowMap
|
|
15215
15440
|
};
|
|
15216
|
-
renderer.shadowMap.type = types[shadows] ??
|
|
15441
|
+
renderer.shadowMap.type = types[shadows] ?? PCFShadowMap;
|
|
15217
15442
|
} else if (is.obj(shadows)) {
|
|
15218
15443
|
Object.assign(renderer.shadowMap, shadows);
|
|
15219
15444
|
}
|
|
@@ -15229,13 +15454,24 @@ function createRoot(canvas) {
|
|
|
15229
15454
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
15230
15455
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
15231
15456
|
}
|
|
15457
|
+
const r3fProps = ["textureColorSpace"];
|
|
15458
|
+
const constructorOnlyProps = ["samples", "antialias", "alpha", "canvas", "powerPreference"];
|
|
15459
|
+
const nonApplyProps = [...r3fProps, ...constructorOnlyProps];
|
|
15232
15460
|
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
15233
|
-
|
|
15461
|
+
const glProps = {};
|
|
15462
|
+
for (const key in glConfig) {
|
|
15463
|
+
if (!nonApplyProps.includes(key)) glProps[key] = glConfig[key];
|
|
15464
|
+
}
|
|
15465
|
+
applyProps(renderer, glProps);
|
|
15234
15466
|
}
|
|
15235
15467
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
15236
15468
|
const currentRenderer = state.renderer;
|
|
15237
15469
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
15238
|
-
|
|
15470
|
+
const rendererProps = {};
|
|
15471
|
+
for (const key in rendererConfig) {
|
|
15472
|
+
if (!nonApplyProps.includes(key)) rendererProps[key] = rendererConfig[key];
|
|
15473
|
+
}
|
|
15474
|
+
applyProps(currentRenderer, rendererProps);
|
|
15239
15475
|
}
|
|
15240
15476
|
}
|
|
15241
15477
|
const scheduler = getScheduler();
|
|
@@ -15261,6 +15497,18 @@ function createRoot(canvas) {
|
|
|
15261
15497
|
system: true
|
|
15262
15498
|
}
|
|
15263
15499
|
);
|
|
15500
|
+
const unregisterEventsFlush = scheduler.register(
|
|
15501
|
+
() => {
|
|
15502
|
+
const state2 = store.getState();
|
|
15503
|
+
state2.events.flush?.();
|
|
15504
|
+
},
|
|
15505
|
+
{
|
|
15506
|
+
id: `${newRootId}_events`,
|
|
15507
|
+
rootId: newRootId,
|
|
15508
|
+
phase: "input",
|
|
15509
|
+
system: true
|
|
15510
|
+
}
|
|
15511
|
+
);
|
|
15264
15512
|
const unregisterFrustum = scheduler.register(
|
|
15265
15513
|
() => {
|
|
15266
15514
|
const state2 = store.getState();
|
|
@@ -15295,7 +15543,7 @@ function createRoot(canvas) {
|
|
|
15295
15543
|
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
15296
15544
|
if (userHandlesRender || state2.internal.priority) return;
|
|
15297
15545
|
try {
|
|
15298
|
-
if (state2.
|
|
15546
|
+
if (state2.renderPipeline?.render) state2.renderPipeline.render();
|
|
15299
15547
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
15300
15548
|
} catch (error) {
|
|
15301
15549
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
@@ -15320,6 +15568,7 @@ function createRoot(canvas) {
|
|
|
15320
15568
|
unregisterRoot: () => {
|
|
15321
15569
|
unregisterRoot();
|
|
15322
15570
|
unregisterCanvasTarget();
|
|
15571
|
+
unregisterEventsFlush();
|
|
15323
15572
|
unregisterFrustum();
|
|
15324
15573
|
unregisterVisibility();
|
|
15325
15574
|
unregisterRender();
|
|
@@ -15485,9 +15734,13 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15485
15734
|
const store = createWithEqualityFn((set, get) => ({ ...rest, set, get }));
|
|
15486
15735
|
const onMutate = (prev) => store.setState((state2) => inject.current(prev, state2));
|
|
15487
15736
|
onMutate(previousRoot.getState());
|
|
15488
|
-
previousRoot.subscribe(onMutate);
|
|
15489
15737
|
return store;
|
|
15490
15738
|
}, [previousRoot, container]);
|
|
15739
|
+
useIsomorphicLayoutEffect(() => {
|
|
15740
|
+
const onMutate = (prev) => usePortalStore.setState((state2) => inject.current(prev, state2));
|
|
15741
|
+
const unsubscribe = previousRoot.subscribe(onMutate);
|
|
15742
|
+
return unsubscribe;
|
|
15743
|
+
}, [previousRoot, usePortalStore]);
|
|
15491
15744
|
return (
|
|
15492
15745
|
// @ts-ignore, reconciler types are not maintained
|
|
15493
15746
|
/* @__PURE__ */ jsx(Fragment, { children: reconciler.createPortal(
|
|
@@ -15532,8 +15785,18 @@ function CanvasImpl({
|
|
|
15532
15785
|
forceEven,
|
|
15533
15786
|
...props
|
|
15534
15787
|
}) {
|
|
15535
|
-
const
|
|
15536
|
-
|
|
15788
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15789
|
+
let primaryCanvas;
|
|
15790
|
+
let scheduler;
|
|
15791
|
+
let renderer;
|
|
15792
|
+
if (isRendererConfig) {
|
|
15793
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15794
|
+
primaryCanvas = pc;
|
|
15795
|
+
scheduler = sc;
|
|
15796
|
+
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
15797
|
+
} else {
|
|
15798
|
+
renderer = rendererProp;
|
|
15799
|
+
}
|
|
15537
15800
|
React.useMemo(() => extend(THREE), []);
|
|
15538
15801
|
const Bridge = useBridge();
|
|
15539
15802
|
const backgroundProps = React.useMemo(() => {
|
|
@@ -15708,6 +15971,7 @@ function CanvasImpl({
|
|
|
15708
15971
|
queueMicrotask(() => {
|
|
15709
15972
|
const rootEntry = _roots.get(canvas);
|
|
15710
15973
|
if (rootEntry?.store) {
|
|
15974
|
+
console.log("[R3F] HMR detected \u2014 rebuilding nodes/uniforms");
|
|
15711
15975
|
rootEntry.store.setState((state) => ({
|
|
15712
15976
|
nodes: {},
|
|
15713
15977
|
uniforms: {},
|
|
@@ -15719,8 +15983,7 @@ function CanvasImpl({
|
|
|
15719
15983
|
if (typeof import.meta !== "undefined" && import.meta.hot) {
|
|
15720
15984
|
const hot = import.meta.hot;
|
|
15721
15985
|
hot.on("vite:afterUpdate", handleHMR);
|
|
15722
|
-
return () => hot.
|
|
15723
|
-
});
|
|
15986
|
+
return () => hot.off?.("vite:afterUpdate", handleHMR);
|
|
15724
15987
|
}
|
|
15725
15988
|
if (typeof module !== "undefined" && module.hot) {
|
|
15726
15989
|
const hot = module.hot;
|
|
@@ -15743,7 +16006,16 @@ function CanvasImpl({
|
|
|
15743
16006
|
...style
|
|
15744
16007
|
},
|
|
15745
16008
|
...props,
|
|
15746
|
-
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16009
|
+
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16010
|
+
"canvas",
|
|
16011
|
+
{
|
|
16012
|
+
ref: canvasRef,
|
|
16013
|
+
id,
|
|
16014
|
+
className: "r3f-canvas",
|
|
16015
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
16016
|
+
children: fallback
|
|
16017
|
+
}
|
|
16018
|
+
) })
|
|
15747
16019
|
}
|
|
15748
16020
|
);
|
|
15749
16021
|
}
|