@react-three/fiber 10.0.0-alpha.3 → 10.0.0-alpha.5
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 +143 -90
- package/dist/index.d.cts +288 -143
- package/dist/index.d.mts +288 -143
- package/dist/index.d.ts +286 -169
- package/dist/index.mjs +143 -90
- package/dist/legacy.cjs +141 -92
- package/dist/legacy.d.cts +291 -150
- package/dist/legacy.d.mts +291 -150
- package/dist/legacy.d.ts +289 -174
- package/dist/legacy.mjs +141 -92
- package/dist/webgpu/index.cjs +260 -182
- package/dist/webgpu/index.d.cts +368 -254
- package/dist/webgpu/index.d.mts +368 -254
- package/dist/webgpu/index.d.ts +366 -280
- package/dist/webgpu/index.mjs +260 -182
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
2
|
import { CubeRenderTarget, RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, Scene, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer, HalfFloatType, Color } from 'three/webgpu';
|
|
3
3
|
import { WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer } from 'three';
|
|
4
|
-
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
5
4
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
5
|
import * as React from 'react';
|
|
7
6
|
import React__default, { useRef, useMemo, useLayoutEffect, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
|
|
@@ -13,6 +12,7 @@ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
|
13
12
|
import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
|
|
14
13
|
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
15
14
|
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
15
|
+
import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
|
|
16
16
|
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
17
17
|
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
18
18
|
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
@@ -32,18 +32,22 @@ function _mergeNamespaces(n, m) {
|
|
|
32
32
|
|
|
33
33
|
const R3F_BUILD_LEGACY = true;
|
|
34
34
|
const R3F_BUILD_WEBGPU = true;
|
|
35
|
+
async function loadInspector() {
|
|
36
|
+
const { Inspector } = await import('three/addons/inspector/Inspector.js');
|
|
37
|
+
return Inspector;
|
|
38
|
+
}
|
|
35
39
|
|
|
36
40
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
37
41
|
__proto__: null,
|
|
38
42
|
CubeRenderTarget: CubeRenderTarget,
|
|
39
43
|
CubeRenderTargetCompat: CubeRenderTarget,
|
|
40
|
-
Inspector: Inspector,
|
|
41
44
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
42
45
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
43
46
|
RenderTargetCompat: RenderTarget,
|
|
44
47
|
WebGLCubeRenderTarget: WebGLCubeRenderTarget,
|
|
45
48
|
WebGLRenderTarget: WebGLRenderTarget,
|
|
46
|
-
WebGLRenderer: WebGLRenderer
|
|
49
|
+
WebGLRenderer: WebGLRenderer,
|
|
50
|
+
loadInspector: loadInspector
|
|
47
51
|
}, [webgpu]);
|
|
48
52
|
|
|
49
53
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -506,8 +510,10 @@ function hasVisibilityHandlers(handlers) {
|
|
|
506
510
|
}
|
|
507
511
|
|
|
508
512
|
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
509
|
-
function fromRef(ref) {
|
|
510
|
-
|
|
513
|
+
function fromRef(ref, transform) {
|
|
514
|
+
const marker = { [FROM_REF]: ref };
|
|
515
|
+
if (transform) marker.transform = transform;
|
|
516
|
+
return marker;
|
|
511
517
|
}
|
|
512
518
|
function isFromRef(value) {
|
|
513
519
|
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
@@ -608,11 +614,9 @@ function diffProps(instance, newProps) {
|
|
|
608
614
|
for (const prop in instance.props) {
|
|
609
615
|
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
610
616
|
const { root, key } = resolve(instance.object, prop);
|
|
611
|
-
if (
|
|
617
|
+
if (typeof root?.constructor === "function") {
|
|
612
618
|
const ctor = getMemoizedPrototype(root);
|
|
613
619
|
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
614
|
-
} else {
|
|
615
|
-
changedProps[prop] = 0;
|
|
616
620
|
}
|
|
617
621
|
}
|
|
618
622
|
return changedProps;
|
|
@@ -902,7 +906,7 @@ const createStore = (invalidate, advance) => {
|
|
|
902
906
|
size: newSize,
|
|
903
907
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
904
908
|
}));
|
|
905
|
-
|
|
909
|
+
get().invalidate();
|
|
906
910
|
}
|
|
907
911
|
}
|
|
908
912
|
return;
|
|
@@ -917,15 +921,16 @@ const createStore = (invalidate, advance) => {
|
|
|
917
921
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
918
922
|
_sizeImperative: true
|
|
919
923
|
}));
|
|
920
|
-
|
|
924
|
+
get().invalidate();
|
|
921
925
|
},
|
|
922
926
|
setDpr: (dpr) => set((state2) => {
|
|
923
927
|
const resolved = calculateDpr(dpr);
|
|
924
928
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
925
929
|
}),
|
|
926
930
|
setFrameloop: (frameloop = "always") => {
|
|
931
|
+
const rootId = get().internal.rootId;
|
|
932
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
927
933
|
set(() => ({ frameloop }));
|
|
928
|
-
getScheduler().frameloop = frameloop;
|
|
929
934
|
},
|
|
930
935
|
setError: (error) => set(() => ({ error })),
|
|
931
936
|
error: null,
|
|
@@ -1041,17 +1046,11 @@ const createStore = (invalidate, advance) => {
|
|
|
1041
1046
|
oldSize = size;
|
|
1042
1047
|
oldDpr = viewport.dpr;
|
|
1043
1048
|
updateCamera(camera, size);
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1050
|
-
if (canvasTarget) {
|
|
1051
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1052
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1049
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1050
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1051
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1052
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
1053
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
1055
1054
|
}
|
|
1056
1055
|
if (camera !== oldCamera) {
|
|
1057
1056
|
oldCamera = camera;
|
|
@@ -1113,7 +1112,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1113
1112
|
const results = cacheKeys.map(
|
|
1114
1113
|
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1115
1114
|
);
|
|
1116
|
-
|
|
1115
|
+
const stableRef = useRef(null);
|
|
1116
|
+
const previous = stableRef.current;
|
|
1117
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1118
|
+
stableRef.current = stable;
|
|
1119
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1117
1120
|
}
|
|
1118
1121
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1119
1122
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1233,6 +1236,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1233
1236
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1234
1237
|
*/
|
|
1235
1238
|
scheduler: scheduler2,
|
|
1239
|
+
/**
|
|
1240
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1241
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1242
|
+
*/
|
|
1243
|
+
get rootId() {
|
|
1244
|
+
return getScheduler().getJobRootId(id);
|
|
1245
|
+
},
|
|
1236
1246
|
/**
|
|
1237
1247
|
* Manually step this job only.
|
|
1238
1248
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1249,6 +1259,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1249
1259
|
stepAll: (timestamp) => {
|
|
1250
1260
|
getScheduler().step(timestamp);
|
|
1251
1261
|
},
|
|
1262
|
+
/**
|
|
1263
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1264
|
+
*/
|
|
1265
|
+
invalidate: (frames, stackFrames) => {
|
|
1266
|
+
const scheduler3 = getScheduler();
|
|
1267
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1268
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1269
|
+
},
|
|
1252
1270
|
/**
|
|
1253
1271
|
* Pause this job (set enabled=false).
|
|
1254
1272
|
* Job remains registered but won't run.
|
|
@@ -1278,6 +1296,11 @@ function getUrls(input) {
|
|
|
1278
1296
|
if (Array.isArray(input)) return input;
|
|
1279
1297
|
return Object.values(input);
|
|
1280
1298
|
}
|
|
1299
|
+
function inputSignature(input) {
|
|
1300
|
+
if (typeof input === "string") return input;
|
|
1301
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1302
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1303
|
+
}
|
|
1281
1304
|
function allUrlsCached(urls, textureCache) {
|
|
1282
1305
|
return urls.every((url) => textureCache.has(url));
|
|
1283
1306
|
}
|
|
@@ -1303,24 +1326,37 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1303
1326
|
const onLoadRef = useRef(onLoad);
|
|
1304
1327
|
onLoadRef.current = onLoad;
|
|
1305
1328
|
const onLoadCalledForRef = useRef(null);
|
|
1306
|
-
const
|
|
1329
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
1330
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
1331
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1307
1332
|
const cachedResult = useMemo(() => {
|
|
1308
1333
|
if (!cache) return null;
|
|
1309
1334
|
const textures = store.getState().textures;
|
|
1310
1335
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1311
|
-
return buildFromCache(
|
|
1312
|
-
}, [cache, urls,
|
|
1336
|
+
return buildFromCache(stableInput, textures);
|
|
1337
|
+
}, [cache, urls, stableInput, store]);
|
|
1313
1338
|
const loadedTextures = useLoader(
|
|
1314
1339
|
TextureLoader,
|
|
1315
|
-
IsObject(
|
|
1340
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1316
1341
|
);
|
|
1317
|
-
const
|
|
1342
|
+
const mappedTextures = useMemo(() => {
|
|
1343
|
+
if (cachedResult) return cachedResult;
|
|
1344
|
+
if (IsObject(stableInput)) {
|
|
1345
|
+
const keyed = {};
|
|
1346
|
+
const textureArray = loadedTextures;
|
|
1347
|
+
let i = 0;
|
|
1348
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1349
|
+
return keyed;
|
|
1350
|
+
} else {
|
|
1351
|
+
return loadedTextures;
|
|
1352
|
+
}
|
|
1353
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1318
1354
|
useLayoutEffect(() => {
|
|
1319
1355
|
if (cachedResult) return;
|
|
1320
1356
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
1321
1357
|
onLoadCalledForRef.current = inputKey;
|
|
1322
|
-
onLoadRef.current?.(
|
|
1323
|
-
}, [cachedResult,
|
|
1358
|
+
onLoadRef.current?.(mappedTextures);
|
|
1359
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
1324
1360
|
useEffect(() => {
|
|
1325
1361
|
if (cachedResult) return;
|
|
1326
1362
|
if ("initTexture" in renderer) {
|
|
@@ -1339,30 +1375,18 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1339
1375
|
});
|
|
1340
1376
|
}
|
|
1341
1377
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1342
|
-
const mappedTextures = useMemo(() => {
|
|
1343
|
-
if (cachedResult) return cachedResult;
|
|
1344
|
-
if (IsObject(input)) {
|
|
1345
|
-
const keyed = {};
|
|
1346
|
-
const textureArray = loadedTextures;
|
|
1347
|
-
let i = 0;
|
|
1348
|
-
for (const key in input) keyed[key] = textureArray[i++];
|
|
1349
|
-
return keyed;
|
|
1350
|
-
} else {
|
|
1351
|
-
return loadedTextures;
|
|
1352
|
-
}
|
|
1353
|
-
}, [input, loadedTextures, cachedResult]);
|
|
1354
1378
|
useEffect(() => {
|
|
1355
1379
|
if (!cache) return;
|
|
1356
1380
|
const urlTextureMap = [];
|
|
1357
|
-
if (typeof
|
|
1358
|
-
urlTextureMap.push([
|
|
1359
|
-
} else if (Array.isArray(
|
|
1381
|
+
if (typeof stableInput === "string") {
|
|
1382
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1383
|
+
} else if (Array.isArray(stableInput)) {
|
|
1360
1384
|
const textureArray = mappedTextures;
|
|
1361
|
-
|
|
1362
|
-
} else if (IsObject(
|
|
1385
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1386
|
+
} else if (IsObject(stableInput)) {
|
|
1363
1387
|
const textureRecord = mappedTextures;
|
|
1364
|
-
for (const key in
|
|
1365
|
-
const url =
|
|
1388
|
+
for (const key in stableInput) {
|
|
1389
|
+
const url = stableInput[key];
|
|
1366
1390
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1367
1391
|
}
|
|
1368
1392
|
}
|
|
@@ -1391,7 +1415,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1391
1415
|
}
|
|
1392
1416
|
return { _textureRefs: refs };
|
|
1393
1417
|
});
|
|
1394
|
-
}, [cache,
|
|
1418
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1395
1419
|
return mappedTextures;
|
|
1396
1420
|
}
|
|
1397
1421
|
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
@@ -1554,7 +1578,7 @@ function useEnvironment({
|
|
|
1554
1578
|
texture = texture.renderTarget?.texture;
|
|
1555
1579
|
}
|
|
1556
1580
|
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
1557
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1581
|
+
texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1558
1582
|
return texture;
|
|
1559
1583
|
}
|
|
1560
1584
|
const preloadDefaultOptions = {
|
|
@@ -1607,11 +1631,12 @@ function getExtension(files) {
|
|
|
1607
1631
|
const isCubemap = isArray(files) && files.length === 6;
|
|
1608
1632
|
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1609
1633
|
const firstEntry = isArray(files) ? files[0] : files;
|
|
1610
|
-
const
|
|
1634
|
+
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1635
|
+
const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
|
|
1611
1636
|
return { extension, isCubemap, isGainmap };
|
|
1612
1637
|
}
|
|
1613
1638
|
function getLoader(extension) {
|
|
1614
|
-
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1639
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1615
1640
|
return loader;
|
|
1616
1641
|
}
|
|
1617
1642
|
|
|
@@ -1662,13 +1687,19 @@ function addTail(callback) {
|
|
|
1662
1687
|
return getScheduler().onIdle(callback);
|
|
1663
1688
|
}
|
|
1664
1689
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1665
|
-
|
|
1690
|
+
const rootId = state?.internal?.rootId;
|
|
1691
|
+
const scheduler = getScheduler();
|
|
1692
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1693
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1666
1694
|
}
|
|
1667
|
-
function advance(timestamp) {
|
|
1668
|
-
|
|
1695
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1696
|
+
const rootId = state?.internal?.rootId;
|
|
1697
|
+
const scheduler = getScheduler();
|
|
1698
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1699
|
+
else scheduler.step(timestamp);
|
|
1669
1700
|
}
|
|
1670
1701
|
|
|
1671
|
-
const version = "10.0.0-alpha.
|
|
1702
|
+
const version = "10.0.0-alpha.5";
|
|
1672
1703
|
const packageData = {
|
|
1673
1704
|
version: version};
|
|
1674
1705
|
|
|
@@ -13527,7 +13558,10 @@ function extend(objects) {
|
|
|
13527
13558
|
catalogue[Component] = objects;
|
|
13528
13559
|
return Component;
|
|
13529
13560
|
} else {
|
|
13530
|
-
|
|
13561
|
+
for (const name in objects) {
|
|
13562
|
+
const object = objects[name];
|
|
13563
|
+
if (isConstructor(object)) catalogue[name] = object;
|
|
13564
|
+
}
|
|
13531
13565
|
}
|
|
13532
13566
|
}
|
|
13533
13567
|
function validateInstance(type, props) {
|
|
@@ -13875,7 +13909,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13875
13909
|
getRootHostContext: () => NO_CONTEXT,
|
|
13876
13910
|
getChildHostContext: () => NO_CONTEXT,
|
|
13877
13911
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
13878
|
-
validateInstance(type, newProps);
|
|
13912
|
+
validateInstance(instance.type, newProps);
|
|
13879
13913
|
let reconstruct = false;
|
|
13880
13914
|
if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
|
|
13881
13915
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
@@ -13902,8 +13936,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13902
13936
|
for (const prop in instance.props) {
|
|
13903
13937
|
const value = instance.props[prop];
|
|
13904
13938
|
if (isFromRef(value)) {
|
|
13905
|
-
const ref = value
|
|
13906
|
-
if (ref.current != null) resolved[prop] = ref.current;
|
|
13939
|
+
const { [FROM_REF]: ref, transform } = value;
|
|
13940
|
+
if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
|
|
13907
13941
|
}
|
|
13908
13942
|
}
|
|
13909
13943
|
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
@@ -14202,9 +14236,8 @@ function createRoot(canvas) {
|
|
|
14202
14236
|
if (!renderer.hasInitialized?.()) {
|
|
14203
14237
|
const size2 = computeInitialSize(canvas, propsSize);
|
|
14204
14238
|
if (size2.width > 0 && size2.height > 0) {
|
|
14205
|
-
|
|
14206
|
-
|
|
14207
|
-
canvas.height = size2.height * pixelRatio;
|
|
14239
|
+
renderer.setPixelRatio(calculateDpr(dpr));
|
|
14240
|
+
renderer.setSize(size2.width, size2.height, false);
|
|
14208
14241
|
}
|
|
14209
14242
|
await renderer.init();
|
|
14210
14243
|
}
|
|
@@ -14213,7 +14246,7 @@ function createRoot(canvas) {
|
|
|
14213
14246
|
state.internal.actualRenderer = renderer;
|
|
14214
14247
|
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14215
14248
|
if (canvasId && !state.internal.isSecondary) {
|
|
14216
|
-
const canvasTarget =
|
|
14249
|
+
const canvasTarget = renderer.getCanvasTarget?.();
|
|
14217
14250
|
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
14218
14251
|
state.set((prev) => ({
|
|
14219
14252
|
internal: {
|
|
@@ -14327,7 +14360,7 @@ function createRoot(canvas) {
|
|
|
14327
14360
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14328
14361
|
const state2 = store.getState();
|
|
14329
14362
|
if (state2.frameloop === "never") return;
|
|
14330
|
-
advance(timestamp);
|
|
14363
|
+
advance(timestamp, true, state2);
|
|
14331
14364
|
};
|
|
14332
14365
|
const actualRenderer = state.internal.actualRenderer;
|
|
14333
14366
|
const handleSessionChange = () => {
|
|
@@ -14335,7 +14368,7 @@ function createRoot(canvas) {
|
|
|
14335
14368
|
const renderer2 = state2.internal.actualRenderer;
|
|
14336
14369
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14337
14370
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14338
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14371
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14339
14372
|
};
|
|
14340
14373
|
const xr = {
|
|
14341
14374
|
connect() {
|
|
@@ -14417,14 +14450,23 @@ function createRoot(canvas) {
|
|
|
14417
14450
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14418
14451
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14419
14452
|
getState: () => store.getState(),
|
|
14420
|
-
onError: (err) => store.getState().setError(err)
|
|
14453
|
+
onError: (err) => store.getState().setError(err),
|
|
14454
|
+
frameloop: store.getState().frameloop,
|
|
14455
|
+
before: schedulerConfig?.before,
|
|
14456
|
+
after: schedulerConfig?.after,
|
|
14457
|
+
order: schedulerConfig?.order
|
|
14421
14458
|
});
|
|
14422
14459
|
const unregisterCanvasTarget = scheduler.register(
|
|
14423
14460
|
() => {
|
|
14424
14461
|
const state2 = store.getState();
|
|
14425
|
-
|
|
14462
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14463
|
+
if (canvasTarget) {
|
|
14426
14464
|
const renderer2 = state2.internal.actualRenderer;
|
|
14427
|
-
renderer2.setCanvasTarget(
|
|
14465
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14466
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14467
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14468
|
+
renderer2.backend?.updateSize?.();
|
|
14469
|
+
}
|
|
14428
14470
|
}
|
|
14429
14471
|
},
|
|
14430
14472
|
{
|
|
@@ -14493,8 +14535,7 @@ function createRoot(canvas) {
|
|
|
14493
14535
|
phase: "render",
|
|
14494
14536
|
system: true,
|
|
14495
14537
|
// Internal flag: this is a system job, not user-controlled
|
|
14496
|
-
//
|
|
14497
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14538
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14498
14539
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14499
14540
|
}
|
|
14500
14541
|
);
|
|
@@ -14513,8 +14554,21 @@ function createRoot(canvas) {
|
|
|
14513
14554
|
scheduler
|
|
14514
14555
|
}
|
|
14515
14556
|
}));
|
|
14557
|
+
} else {
|
|
14558
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14559
|
+
if (constraintsChanged) {
|
|
14560
|
+
scheduler.setRootConstraints(rootId, {
|
|
14561
|
+
before: schedulerConfig?.before,
|
|
14562
|
+
after: schedulerConfig?.after
|
|
14563
|
+
});
|
|
14564
|
+
}
|
|
14565
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14566
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14567
|
+
}
|
|
14516
14568
|
}
|
|
14517
|
-
|
|
14569
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14570
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14571
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14518
14572
|
onCreated = onCreatedCallback;
|
|
14519
14573
|
configured = true;
|
|
14520
14574
|
resolve();
|
|
@@ -14556,18 +14610,23 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14556
14610
|
const fiber = root?.fiber;
|
|
14557
14611
|
if (fiber) {
|
|
14558
14612
|
const state = root?.store.getState();
|
|
14559
|
-
if (state)
|
|
14613
|
+
if (state) {
|
|
14614
|
+
state.internal.active = false;
|
|
14615
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14616
|
+
if (unregisterRoot) {
|
|
14617
|
+
unregisterRoot();
|
|
14618
|
+
state.internal.unregisterRoot = void 0;
|
|
14619
|
+
}
|
|
14620
|
+
}
|
|
14560
14621
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14561
14622
|
if (state) {
|
|
14562
14623
|
setTimeout(() => {
|
|
14563
14624
|
try {
|
|
14564
14625
|
const renderer = state.internal.actualRenderer;
|
|
14565
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14566
|
-
if (unregisterRoot) unregisterRoot();
|
|
14567
14626
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14568
14627
|
if (unregisterPrimary) unregisterPrimary();
|
|
14569
14628
|
const canvasTarget = state.internal.canvasTarget;
|
|
14570
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14629
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14571
14630
|
state.events.disconnect?.();
|
|
14572
14631
|
cleanupHelperGroup(root.store);
|
|
14573
14632
|
if (state.isLegacy && renderer) {
|
|
@@ -14708,16 +14767,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14708
14767
|
const oldbg = target.background;
|
|
14709
14768
|
const oldenv = target.environment;
|
|
14710
14769
|
const oldSceneProps = {
|
|
14711
|
-
// @ts-ignore
|
|
14712
14770
|
backgroundBlurriness: target.backgroundBlurriness,
|
|
14713
|
-
// @ts-ignore
|
|
14714
14771
|
backgroundIntensity: target.backgroundIntensity,
|
|
14715
|
-
|
|
14716
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14717
|
-
// @ts-ignore
|
|
14772
|
+
backgroundRotation: target.backgroundRotation.clone(),
|
|
14718
14773
|
environmentIntensity: target.environmentIntensity,
|
|
14719
|
-
|
|
14720
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14774
|
+
environmentRotation: target.environmentRotation.clone()
|
|
14721
14775
|
};
|
|
14722
14776
|
if (background !== "only") target.environment = texture;
|
|
14723
14777
|
if (background) target.background = texture;
|
|
@@ -15011,9 +15065,9 @@ function CanvasImpl({
|
|
|
15011
15065
|
React.useMemo(() => extend(THREE), []);
|
|
15012
15066
|
const Bridge = useBridge();
|
|
15013
15067
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
15014
|
-
const
|
|
15068
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
15015
15069
|
const measureConfig = React.useMemo(() => {
|
|
15016
|
-
if (!
|
|
15070
|
+
if (!hasInitialSize) {
|
|
15017
15071
|
return {
|
|
15018
15072
|
...resize,
|
|
15019
15073
|
scroll: resize?.scroll ?? true,
|
|
@@ -15025,7 +15079,7 @@ function CanvasImpl({
|
|
|
15025
15079
|
debounce: { scroll: 50, resize: 0 },
|
|
15026
15080
|
...resize
|
|
15027
15081
|
};
|
|
15028
|
-
}, [
|
|
15082
|
+
}, [hasInitialSize, resize]);
|
|
15029
15083
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15030
15084
|
const effectiveSize = React.useMemo(() => {
|
|
15031
15085
|
let w = width ?? containerRect.width;
|
|
@@ -15041,9 +15095,7 @@ function CanvasImpl({
|
|
|
15041
15095
|
left: containerRect.left
|
|
15042
15096
|
};
|
|
15043
15097
|
}, [width, height, containerRect, forceEven]);
|
|
15044
|
-
if (!
|
|
15045
|
-
hasInitialSizeRef.current = true;
|
|
15046
|
-
}
|
|
15098
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15047
15099
|
const canvasRef = React.useRef(null);
|
|
15048
15100
|
const divRef = React.useRef(null);
|
|
15049
15101
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15157,6 +15209,7 @@ function CanvasImpl({
|
|
|
15157
15209
|
const canvas = canvasRef.current;
|
|
15158
15210
|
if (canvas) {
|
|
15159
15211
|
return () => {
|
|
15212
|
+
if (canvas.isConnected) return;
|
|
15160
15213
|
unmountComponentAtNode(canvas);
|
|
15161
15214
|
root.current = null;
|
|
15162
15215
|
};
|