@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/legacy.mjs
CHANGED
|
@@ -11,6 +11,7 @@ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
|
11
11
|
import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
|
|
12
12
|
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
13
13
|
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
14
|
+
import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
|
|
14
15
|
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
15
16
|
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
16
17
|
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
@@ -30,16 +31,14 @@ function _mergeNamespaces(n, m) {
|
|
|
30
31
|
|
|
31
32
|
const R3F_BUILD_LEGACY = true;
|
|
32
33
|
const R3F_BUILD_WEBGPU = false;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
const WebGPURenderer = class WebGPURenderer2 {
|
|
34
|
+
async function loadInspector() {
|
|
35
|
+
throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
36
|
+
}
|
|
37
|
+
class WebGPURenderer {
|
|
39
38
|
constructor() {
|
|
40
39
|
throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
41
40
|
}
|
|
42
|
-
}
|
|
41
|
+
}
|
|
43
42
|
const RenderTarget = null;
|
|
44
43
|
const CubeRenderTarget = null;
|
|
45
44
|
|
|
@@ -47,12 +46,12 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
47
46
|
__proto__: null,
|
|
48
47
|
CubeRenderTarget: CubeRenderTarget,
|
|
49
48
|
CubeRenderTargetCompat: WebGLCubeRenderTarget,
|
|
50
|
-
Inspector: Inspector,
|
|
51
49
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
52
50
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
53
51
|
RenderTarget: RenderTarget,
|
|
54
52
|
RenderTargetCompat: WebGLRenderTarget,
|
|
55
|
-
WebGPURenderer: WebGPURenderer
|
|
53
|
+
WebGPURenderer: WebGPURenderer,
|
|
54
|
+
loadInspector: loadInspector
|
|
56
55
|
}, [three]);
|
|
57
56
|
|
|
58
57
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -515,8 +514,10 @@ function hasVisibilityHandlers(handlers) {
|
|
|
515
514
|
}
|
|
516
515
|
|
|
517
516
|
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
518
|
-
function fromRef(ref) {
|
|
519
|
-
|
|
517
|
+
function fromRef(ref, transform) {
|
|
518
|
+
const marker = { [FROM_REF]: ref };
|
|
519
|
+
if (transform) marker.transform = transform;
|
|
520
|
+
return marker;
|
|
520
521
|
}
|
|
521
522
|
function isFromRef(value) {
|
|
522
523
|
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
@@ -617,11 +618,9 @@ function diffProps(instance, newProps) {
|
|
|
617
618
|
for (const prop in instance.props) {
|
|
618
619
|
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
619
620
|
const { root, key } = resolve(instance.object, prop);
|
|
620
|
-
if (
|
|
621
|
+
if (typeof root?.constructor === "function") {
|
|
621
622
|
const ctor = getMemoizedPrototype(root);
|
|
622
623
|
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
623
|
-
} else {
|
|
624
|
-
changedProps[prop] = 0;
|
|
625
624
|
}
|
|
626
625
|
}
|
|
627
626
|
return changedProps;
|
|
@@ -911,7 +910,7 @@ const createStore = (invalidate, advance) => {
|
|
|
911
910
|
size: newSize,
|
|
912
911
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
913
912
|
}));
|
|
914
|
-
|
|
913
|
+
get().invalidate();
|
|
915
914
|
}
|
|
916
915
|
}
|
|
917
916
|
return;
|
|
@@ -926,15 +925,16 @@ const createStore = (invalidate, advance) => {
|
|
|
926
925
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
927
926
|
_sizeImperative: true
|
|
928
927
|
}));
|
|
929
|
-
|
|
928
|
+
get().invalidate();
|
|
930
929
|
},
|
|
931
930
|
setDpr: (dpr) => set((state2) => {
|
|
932
931
|
const resolved = calculateDpr(dpr);
|
|
933
932
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
934
933
|
}),
|
|
935
934
|
setFrameloop: (frameloop = "always") => {
|
|
935
|
+
const rootId = get().internal.rootId;
|
|
936
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
936
937
|
set(() => ({ frameloop }));
|
|
937
|
-
getScheduler().frameloop = frameloop;
|
|
938
938
|
},
|
|
939
939
|
setError: (error) => set(() => ({ error })),
|
|
940
940
|
error: null,
|
|
@@ -1050,17 +1050,11 @@ const createStore = (invalidate, advance) => {
|
|
|
1050
1050
|
oldSize = size;
|
|
1051
1051
|
oldDpr = viewport.dpr;
|
|
1052
1052
|
updateCamera(camera, size);
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1059
|
-
if (canvasTarget) {
|
|
1060
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1061
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1053
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1054
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1055
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1056
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
1057
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
1064
1058
|
}
|
|
1065
1059
|
if (camera !== oldCamera) {
|
|
1066
1060
|
oldCamera = camera;
|
|
@@ -1122,7 +1116,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1122
1116
|
const results = cacheKeys.map(
|
|
1123
1117
|
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1124
1118
|
);
|
|
1125
|
-
|
|
1119
|
+
const stableRef = useRef(null);
|
|
1120
|
+
const previous = stableRef.current;
|
|
1121
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1122
|
+
stableRef.current = stable;
|
|
1123
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1126
1124
|
}
|
|
1127
1125
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1128
1126
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1242,6 +1240,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1242
1240
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1243
1241
|
*/
|
|
1244
1242
|
scheduler: scheduler2,
|
|
1243
|
+
/**
|
|
1244
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1245
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1246
|
+
*/
|
|
1247
|
+
get rootId() {
|
|
1248
|
+
return getScheduler().getJobRootId(id);
|
|
1249
|
+
},
|
|
1245
1250
|
/**
|
|
1246
1251
|
* Manually step this job only.
|
|
1247
1252
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1258,6 +1263,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1258
1263
|
stepAll: (timestamp) => {
|
|
1259
1264
|
getScheduler().step(timestamp);
|
|
1260
1265
|
},
|
|
1266
|
+
/**
|
|
1267
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1268
|
+
*/
|
|
1269
|
+
invalidate: (frames, stackFrames) => {
|
|
1270
|
+
const scheduler3 = getScheduler();
|
|
1271
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1272
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1273
|
+
},
|
|
1261
1274
|
/**
|
|
1262
1275
|
* Pause this job (set enabled=false).
|
|
1263
1276
|
* Job remains registered but won't run.
|
|
@@ -1287,6 +1300,11 @@ function getUrls(input) {
|
|
|
1287
1300
|
if (Array.isArray(input)) return input;
|
|
1288
1301
|
return Object.values(input);
|
|
1289
1302
|
}
|
|
1303
|
+
function inputSignature(input) {
|
|
1304
|
+
if (typeof input === "string") return input;
|
|
1305
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1306
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1307
|
+
}
|
|
1290
1308
|
function allUrlsCached(urls, textureCache) {
|
|
1291
1309
|
return urls.every((url) => textureCache.has(url));
|
|
1292
1310
|
}
|
|
@@ -1312,24 +1330,37 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1312
1330
|
const onLoadRef = useRef(onLoad);
|
|
1313
1331
|
onLoadRef.current = onLoad;
|
|
1314
1332
|
const onLoadCalledForRef = useRef(null);
|
|
1315
|
-
const
|
|
1333
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
1334
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
1335
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1316
1336
|
const cachedResult = useMemo(() => {
|
|
1317
1337
|
if (!cache) return null;
|
|
1318
1338
|
const textures = store.getState().textures;
|
|
1319
1339
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1320
|
-
return buildFromCache(
|
|
1321
|
-
}, [cache, urls,
|
|
1340
|
+
return buildFromCache(stableInput, textures);
|
|
1341
|
+
}, [cache, urls, stableInput, store]);
|
|
1322
1342
|
const loadedTextures = useLoader(
|
|
1323
1343
|
TextureLoader,
|
|
1324
|
-
IsObject(
|
|
1344
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1325
1345
|
);
|
|
1326
|
-
const
|
|
1346
|
+
const mappedTextures = useMemo(() => {
|
|
1347
|
+
if (cachedResult) return cachedResult;
|
|
1348
|
+
if (IsObject(stableInput)) {
|
|
1349
|
+
const keyed = {};
|
|
1350
|
+
const textureArray = loadedTextures;
|
|
1351
|
+
let i = 0;
|
|
1352
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1353
|
+
return keyed;
|
|
1354
|
+
} else {
|
|
1355
|
+
return loadedTextures;
|
|
1356
|
+
}
|
|
1357
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1327
1358
|
useLayoutEffect(() => {
|
|
1328
1359
|
if (cachedResult) return;
|
|
1329
1360
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
1330
1361
|
onLoadCalledForRef.current = inputKey;
|
|
1331
|
-
onLoadRef.current?.(
|
|
1332
|
-
}, [cachedResult,
|
|
1362
|
+
onLoadRef.current?.(mappedTextures);
|
|
1363
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
1333
1364
|
useEffect(() => {
|
|
1334
1365
|
if (cachedResult) return;
|
|
1335
1366
|
if ("initTexture" in renderer) {
|
|
@@ -1348,30 +1379,18 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1348
1379
|
});
|
|
1349
1380
|
}
|
|
1350
1381
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1351
|
-
const mappedTextures = useMemo(() => {
|
|
1352
|
-
if (cachedResult) return cachedResult;
|
|
1353
|
-
if (IsObject(input)) {
|
|
1354
|
-
const keyed = {};
|
|
1355
|
-
const textureArray = loadedTextures;
|
|
1356
|
-
let i = 0;
|
|
1357
|
-
for (const key in input) keyed[key] = textureArray[i++];
|
|
1358
|
-
return keyed;
|
|
1359
|
-
} else {
|
|
1360
|
-
return loadedTextures;
|
|
1361
|
-
}
|
|
1362
|
-
}, [input, loadedTextures, cachedResult]);
|
|
1363
1382
|
useEffect(() => {
|
|
1364
1383
|
if (!cache) return;
|
|
1365
1384
|
const urlTextureMap = [];
|
|
1366
|
-
if (typeof
|
|
1367
|
-
urlTextureMap.push([
|
|
1368
|
-
} else if (Array.isArray(
|
|
1385
|
+
if (typeof stableInput === "string") {
|
|
1386
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1387
|
+
} else if (Array.isArray(stableInput)) {
|
|
1369
1388
|
const textureArray = mappedTextures;
|
|
1370
|
-
|
|
1371
|
-
} else if (IsObject(
|
|
1389
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1390
|
+
} else if (IsObject(stableInput)) {
|
|
1372
1391
|
const textureRecord = mappedTextures;
|
|
1373
|
-
for (const key in
|
|
1374
|
-
const url =
|
|
1392
|
+
for (const key in stableInput) {
|
|
1393
|
+
const url = stableInput[key];
|
|
1375
1394
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1376
1395
|
}
|
|
1377
1396
|
}
|
|
@@ -1400,7 +1419,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1400
1419
|
}
|
|
1401
1420
|
return { _textureRefs: refs };
|
|
1402
1421
|
});
|
|
1403
|
-
}, [cache,
|
|
1422
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1404
1423
|
return mappedTextures;
|
|
1405
1424
|
}
|
|
1406
1425
|
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
@@ -1561,7 +1580,7 @@ function useEnvironment({
|
|
|
1561
1580
|
texture = texture.renderTarget?.texture;
|
|
1562
1581
|
}
|
|
1563
1582
|
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
1564
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1583
|
+
texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1565
1584
|
return texture;
|
|
1566
1585
|
}
|
|
1567
1586
|
const preloadDefaultOptions = {
|
|
@@ -1614,11 +1633,12 @@ function getExtension(files) {
|
|
|
1614
1633
|
const isCubemap = isArray(files) && files.length === 6;
|
|
1615
1634
|
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1616
1635
|
const firstEntry = isArray(files) ? files[0] : files;
|
|
1617
|
-
const
|
|
1636
|
+
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1637
|
+
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;
|
|
1618
1638
|
return { extension, isCubemap, isGainmap };
|
|
1619
1639
|
}
|
|
1620
1640
|
function getLoader(extension) {
|
|
1621
|
-
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1641
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1622
1642
|
return loader;
|
|
1623
1643
|
}
|
|
1624
1644
|
|
|
@@ -1669,13 +1689,19 @@ function addTail(callback) {
|
|
|
1669
1689
|
return getScheduler().onIdle(callback);
|
|
1670
1690
|
}
|
|
1671
1691
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1672
|
-
|
|
1692
|
+
const rootId = state?.internal?.rootId;
|
|
1693
|
+
const scheduler = getScheduler();
|
|
1694
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1695
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1673
1696
|
}
|
|
1674
|
-
function advance(timestamp) {
|
|
1675
|
-
|
|
1697
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1698
|
+
const rootId = state?.internal?.rootId;
|
|
1699
|
+
const scheduler = getScheduler();
|
|
1700
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1701
|
+
else scheduler.step(timestamp);
|
|
1676
1702
|
}
|
|
1677
1703
|
|
|
1678
|
-
const version = "10.0.0-alpha.
|
|
1704
|
+
const version = "10.0.0-alpha.5";
|
|
1679
1705
|
const packageData = {
|
|
1680
1706
|
version: version};
|
|
1681
1707
|
|
|
@@ -13534,7 +13560,10 @@ function extend(objects) {
|
|
|
13534
13560
|
catalogue[Component] = objects;
|
|
13535
13561
|
return Component;
|
|
13536
13562
|
} else {
|
|
13537
|
-
|
|
13563
|
+
for (const name in objects) {
|
|
13564
|
+
const object = objects[name];
|
|
13565
|
+
if (isConstructor(object)) catalogue[name] = object;
|
|
13566
|
+
}
|
|
13538
13567
|
}
|
|
13539
13568
|
}
|
|
13540
13569
|
function validateInstance(type, props) {
|
|
@@ -13882,7 +13911,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13882
13911
|
getRootHostContext: () => NO_CONTEXT,
|
|
13883
13912
|
getChildHostContext: () => NO_CONTEXT,
|
|
13884
13913
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
13885
|
-
validateInstance(type, newProps);
|
|
13914
|
+
validateInstance(instance.type, newProps);
|
|
13886
13915
|
let reconstruct = false;
|
|
13887
13916
|
if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
|
|
13888
13917
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
@@ -13909,8 +13938,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13909
13938
|
for (const prop in instance.props) {
|
|
13910
13939
|
const value = instance.props[prop];
|
|
13911
13940
|
if (isFromRef(value)) {
|
|
13912
|
-
const ref = value
|
|
13913
|
-
if (ref.current != null) resolved[prop] = ref.current;
|
|
13941
|
+
const { [FROM_REF]: ref, transform } = value;
|
|
13942
|
+
if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
|
|
13914
13943
|
}
|
|
13915
13944
|
}
|
|
13916
13945
|
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
@@ -14287,7 +14316,7 @@ function createRoot(canvas) {
|
|
|
14287
14316
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14288
14317
|
const state2 = store.getState();
|
|
14289
14318
|
if (state2.frameloop === "never") return;
|
|
14290
|
-
advance(timestamp);
|
|
14319
|
+
advance(timestamp, true, state2);
|
|
14291
14320
|
};
|
|
14292
14321
|
const actualRenderer = state.internal.actualRenderer;
|
|
14293
14322
|
const handleSessionChange = () => {
|
|
@@ -14295,7 +14324,7 @@ function createRoot(canvas) {
|
|
|
14295
14324
|
const renderer2 = state2.internal.actualRenderer;
|
|
14296
14325
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14297
14326
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14298
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14327
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14299
14328
|
};
|
|
14300
14329
|
const xr = {
|
|
14301
14330
|
connect() {
|
|
@@ -14377,14 +14406,23 @@ function createRoot(canvas) {
|
|
|
14377
14406
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14378
14407
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14379
14408
|
getState: () => store.getState(),
|
|
14380
|
-
onError: (err) => store.getState().setError(err)
|
|
14409
|
+
onError: (err) => store.getState().setError(err),
|
|
14410
|
+
frameloop: store.getState().frameloop,
|
|
14411
|
+
before: schedulerConfig?.before,
|
|
14412
|
+
after: schedulerConfig?.after,
|
|
14413
|
+
order: schedulerConfig?.order
|
|
14381
14414
|
});
|
|
14382
14415
|
const unregisterCanvasTarget = scheduler.register(
|
|
14383
14416
|
() => {
|
|
14384
14417
|
const state2 = store.getState();
|
|
14385
|
-
|
|
14418
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14419
|
+
if (canvasTarget) {
|
|
14386
14420
|
const renderer2 = state2.internal.actualRenderer;
|
|
14387
|
-
renderer2.setCanvasTarget(
|
|
14421
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14422
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14423
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14424
|
+
renderer2.backend?.updateSize?.();
|
|
14425
|
+
}
|
|
14388
14426
|
}
|
|
14389
14427
|
},
|
|
14390
14428
|
{
|
|
@@ -14453,8 +14491,7 @@ function createRoot(canvas) {
|
|
|
14453
14491
|
phase: "render",
|
|
14454
14492
|
system: true,
|
|
14455
14493
|
// Internal flag: this is a system job, not user-controlled
|
|
14456
|
-
//
|
|
14457
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14494
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14458
14495
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14459
14496
|
}
|
|
14460
14497
|
);
|
|
@@ -14473,8 +14510,21 @@ function createRoot(canvas) {
|
|
|
14473
14510
|
scheduler
|
|
14474
14511
|
}
|
|
14475
14512
|
}));
|
|
14513
|
+
} else {
|
|
14514
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14515
|
+
if (constraintsChanged) {
|
|
14516
|
+
scheduler.setRootConstraints(rootId, {
|
|
14517
|
+
before: schedulerConfig?.before,
|
|
14518
|
+
after: schedulerConfig?.after
|
|
14519
|
+
});
|
|
14520
|
+
}
|
|
14521
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14522
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14523
|
+
}
|
|
14476
14524
|
}
|
|
14477
|
-
|
|
14525
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14526
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14527
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14478
14528
|
onCreated = onCreatedCallback;
|
|
14479
14529
|
configured = true;
|
|
14480
14530
|
resolve();
|
|
@@ -14516,18 +14566,23 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14516
14566
|
const fiber = root?.fiber;
|
|
14517
14567
|
if (fiber) {
|
|
14518
14568
|
const state = root?.store.getState();
|
|
14519
|
-
if (state)
|
|
14569
|
+
if (state) {
|
|
14570
|
+
state.internal.active = false;
|
|
14571
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14572
|
+
if (unregisterRoot) {
|
|
14573
|
+
unregisterRoot();
|
|
14574
|
+
state.internal.unregisterRoot = void 0;
|
|
14575
|
+
}
|
|
14576
|
+
}
|
|
14520
14577
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14521
14578
|
if (state) {
|
|
14522
14579
|
setTimeout(() => {
|
|
14523
14580
|
try {
|
|
14524
14581
|
const renderer = state.internal.actualRenderer;
|
|
14525
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14526
|
-
if (unregisterRoot) unregisterRoot();
|
|
14527
14582
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14528
14583
|
if (unregisterPrimary) unregisterPrimary();
|
|
14529
14584
|
const canvasTarget = state.internal.canvasTarget;
|
|
14530
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14585
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14531
14586
|
state.events.disconnect?.();
|
|
14532
14587
|
cleanupHelperGroup(root.store);
|
|
14533
14588
|
if (state.isLegacy && renderer) {
|
|
@@ -14668,16 +14723,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14668
14723
|
const oldbg = target.background;
|
|
14669
14724
|
const oldenv = target.environment;
|
|
14670
14725
|
const oldSceneProps = {
|
|
14671
|
-
// @ts-ignore
|
|
14672
14726
|
backgroundBlurriness: target.backgroundBlurriness,
|
|
14673
|
-
// @ts-ignore
|
|
14674
14727
|
backgroundIntensity: target.backgroundIntensity,
|
|
14675
|
-
|
|
14676
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14677
|
-
// @ts-ignore
|
|
14728
|
+
backgroundRotation: target.backgroundRotation.clone(),
|
|
14678
14729
|
environmentIntensity: target.environmentIntensity,
|
|
14679
|
-
|
|
14680
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14730
|
+
environmentRotation: target.environmentRotation.clone()
|
|
14681
14731
|
};
|
|
14682
14732
|
if (background !== "only") target.environment = texture;
|
|
14683
14733
|
if (background) target.background = texture;
|
|
@@ -14971,9 +15021,9 @@ function CanvasImpl({
|
|
|
14971
15021
|
React.useMemo(() => extend(THREE), []);
|
|
14972
15022
|
const Bridge = useBridge();
|
|
14973
15023
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
14974
|
-
const
|
|
15024
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
14975
15025
|
const measureConfig = React.useMemo(() => {
|
|
14976
|
-
if (!
|
|
15026
|
+
if (!hasInitialSize) {
|
|
14977
15027
|
return {
|
|
14978
15028
|
...resize,
|
|
14979
15029
|
scroll: resize?.scroll ?? true,
|
|
@@ -14985,7 +15035,7 @@ function CanvasImpl({
|
|
|
14985
15035
|
debounce: { scroll: 50, resize: 0 },
|
|
14986
15036
|
...resize
|
|
14987
15037
|
};
|
|
14988
|
-
}, [
|
|
15038
|
+
}, [hasInitialSize, resize]);
|
|
14989
15039
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
14990
15040
|
const effectiveSize = React.useMemo(() => {
|
|
14991
15041
|
let w = width ?? containerRect.width;
|
|
@@ -15001,9 +15051,7 @@ function CanvasImpl({
|
|
|
15001
15051
|
left: containerRect.left
|
|
15002
15052
|
};
|
|
15003
15053
|
}, [width, height, containerRect, forceEven]);
|
|
15004
|
-
if (!
|
|
15005
|
-
hasInitialSizeRef.current = true;
|
|
15006
|
-
}
|
|
15054
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15007
15055
|
const canvasRef = React.useRef(null);
|
|
15008
15056
|
const divRef = React.useRef(null);
|
|
15009
15057
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15117,6 +15165,7 @@ function CanvasImpl({
|
|
|
15117
15165
|
const canvas = canvasRef.current;
|
|
15118
15166
|
if (canvas) {
|
|
15119
15167
|
return () => {
|
|
15168
|
+
if (canvas.isConnected) return;
|
|
15120
15169
|
unmountComponentAtNode(canvas);
|
|
15121
15170
|
root.current = null;
|
|
15122
15171
|
};
|