From 5c9544f2be71dc7a05187025fa9d63f2643cc9ac Mon Sep 17 00:00:00 2001 From: Cody Bennett Date: Fri, 29 Jul 2022 10:44:54 -0500 Subject: [PATCH] [v9] refactor(core)!: always set colormanagement, use r141 WebXR types (#2377) --- docs/tutorials/v8-migration-guide.mdx | 6 ++--- package.json | 4 +-- packages/fiber/package.json | 2 +- packages/fiber/src/core/index.tsx | 12 +++------ packages/fiber/src/core/loop.ts | 9 ++----- packages/fiber/src/core/stages.ts | 27 +++++++++---------- packages/fiber/src/core/store.ts | 4 +-- packages/fiber/src/core/utils.ts | 15 ----------- .../web/__snapshots__/canvas.test.tsx.snap | 2 +- packages/test-renderer/package.json | 2 +- yarn.lock | 22 +++++++++++---- 11 files changed, 46 insertions(+), 59 deletions(-) diff --git a/docs/tutorials/v8-migration-guide.mdx b/docs/tutorials/v8-migration-guide.mdx index f9d18c7541..1e6bf7081c 100644 --- a/docs/tutorials/v8-migration-guide.mdx +++ b/docs/tutorials/v8-migration-guide.mdx @@ -198,7 +198,7 @@ The `vr` prop was removed in favor of automatic WebXR switching. Whenever a sess In addition to the automatic rendering, useFrame will expose the current [`XRFrame`](https://developer.mozilla.org/en-US/docs/Web/API/XRFrame) obtained via [XRSession#requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/XRSession/requestAnimationFrame). ```ts -useFrame((state: RootState, delta: number, frame?: THREE.XRFrame) => { ... }) +useFrame((state: RootState, delta: number, frame?: XRFrame) => { ... }) ``` This removes the need for custom rendering loops when using WebXR pose data and abstractions like `useXRFrame` of [@react-three/xr](https://github.com/pmndrs/react-xr). @@ -218,7 +218,7 @@ This is also supported by all cameras that you create, be it a THREE.Perspective ```jsx import { PerspectiveCamera } from '@react-three/drei' - +; ``` @@ -333,7 +333,7 @@ window.addEventListener('resize', () => { root.configure({ events, camera: { position: [0, 0, 50], fov: 50 }, - size: { width: window.innerWidth, height: window.innerHeight } + size: { width: window.innerWidth, height: window.innerHeight }, }) root.render() }) diff --git a/package.json b/package.json index 774e561a15..66adc6259f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@types/react-native": "0.67.4", "@types/react-test-renderer": "^17.0.1", "@types/scheduler": "^0.16.2", - "@types/three": "^0.139.0", + "@types/three": "^0.141.0", "@typescript-eslint/eslint-plugin": "^5.17.0", "@typescript-eslint/parser": "^5.17.0", "eslint": "^8.12.0", @@ -78,7 +78,7 @@ "react-native": "0.67.4", "react-test-renderer": "^18.0.0", "regenerator-runtime": "^0.13.9", - "three": "^0.139.0", + "three": "^0.141.0", "three-stdlib": "^2.8.11", "ts-jest": "^27.1.4", "typescript": "^4.6.3" diff --git a/packages/fiber/package.json b/packages/fiber/package.json index ff19207a9e..5e34a2eb8c 100644 --- a/packages/fiber/package.json +++ b/packages/fiber/package.json @@ -57,7 +57,7 @@ "react": ">=18.0", "react-dom": ">=18.0", "react-native": ">=0.64", - "three": ">=0.133" + "three": ">=0.141" }, "peerDependenciesMeta": { "react-dom": { diff --git a/packages/fiber/src/core/index.tsx b/packages/fiber/src/core/index.tsx index af7033a78a..da473102bd 100644 --- a/packages/fiber/src/core/index.tsx +++ b/packages/fiber/src/core/index.tsx @@ -31,7 +31,6 @@ import { useIsomorphicLayoutEffect, Camera, updateCamera, - setDeep, } from './utils' import { useStore } from './hooks' import { Stage, Lifecycle, Stages } from './stages' @@ -136,7 +135,7 @@ const createStages = (stages: Stage[] | undefined, store: UseBoundStore { + current: (state: RootState, delta: number, frame?: XRFrame | undefined) => { subscribers = state.internal.subscribers for (let i = 0; i < subscribers.length; i++) { subscription = subscribers[i] @@ -248,7 +247,7 @@ function createRoot(canvas: TCanvas): ReconcilerRoot { + const handleXRFrame: XRFrameRequestCallback = (timestamp: number, frame?: XRFrame) => { const state = store.getState() if (state.frameloop === 'never') return advance(timestamp, true, state, frame) @@ -294,11 +293,8 @@ function createRoot(canvas: TCanvas): ReconcilerRoot, timestamp: number) { effects.forEach(({callback}) => callback(timestamp)) } -function update(timestamp: number, state: RootState, frame?: THREE.XRFrame) { +function update(timestamp: number, state: RootState, frame?: XRFrame) { // Run local effects let delta = state.clock.getDelta() // In frameloop='never' mode, clock times are updated using the provided timestamp @@ -112,12 +112,7 @@ export function createLoop(roots: Map) { } } - function advance( - timestamp: number, - runGlobalEffects: boolean = true, - state?: RootState, - frame?: THREE.XRFrame, - ): void { + function advance(timestamp: number, runGlobalEffects: boolean = true, state?: RootState, frame?: XRFrame): void { if (runGlobalEffects) run(globalEffects, timestamp) if (!state) roots.forEach((root) => update(timestamp, root.store.getState())) else update(timestamp, state, frame) diff --git a/packages/fiber/src/core/stages.ts b/packages/fiber/src/core/stages.ts index 03efad94d4..98a97341b7 100644 --- a/packages/fiber/src/core/stages.ts +++ b/packages/fiber/src/core/stages.ts @@ -3,7 +3,7 @@ import { StoreApi, UseBoundStore } from 'zustand' import { RootState } from './store' export interface UpdateCallback { - (state: RootState, delta: number, frame?: THREE.XRFrame | undefined): void + (state: RootState, delta: number, frame?: XRFrame): void } export type UpdateCallbackRef = MutableRefObject @@ -28,10 +28,10 @@ export class Stage { /** * Executes all callback subscriptions on the stage. - * @param {number} delta - Delta time between frame calls. - * @param {THREE.XRFrame | undefined} [frame] - The XR frame if it exists. + * @param delta - Delta time between frame calls. + * @param [frame] - The XR frame if it exists. */ - frame(delta: number, frame?: THREE.XRFrame | undefined) { + frame(delta: number, frame?: XRFrame) { const subs = this.subscribers const initialTime = performance.now() @@ -44,9 +44,9 @@ export class Stage { /** * Adds a callback subscriber to the stage. - * @param {UpdateCallbackRef} ref - The mutable callback reference. - * @param {Store} store - The store to be used with the callback execution. - * @returns {() => void} A function to remove the subscription. + * @param ref - The mutable callback reference. + * @param store - The store to be used with the callback execution. + * @returns A function to remove the subscription. */ add(ref: UpdateCallbackRef, store: Store) { this.subscribers.push({ ref, store }) @@ -68,10 +68,9 @@ const FPS_50 = 1 / 50 /** * Class representing a stage that updates every frame at a fixed rate. - * @param {string} name - Name of the stage. - * @param {number} [fixedStep] - Fixed step rate. - * @param {number} [maxSubsteps] - Maximum number of substeps. - * @extends Stage + * @param name - Name of the stage. + * @param [fixedStep] - Fixed step rate. + * @param [maxSubsteps] - Maximum number of substeps. */ export class FixedStage extends Stage { private _fixedStep: number @@ -94,10 +93,10 @@ export class FixedStage extends Stage { /** * Executes all callback subscriptions on the stage. - * @param {number} delta - Delta time between frame calls. - * @param {THREE.XRFrame | undefined} [frame] - The XR frame if it exists. + * @param delta - Delta time between frame calls. + * @param [frame] - The XR frame if it exists. */ - frame(delta: number, frame?: THREE.XRFrame | undefined) { + frame(delta: number, frame?: XRFrame) { const initialTime = performance.now() let substeps = 0 this._substepTimes = [] diff --git a/packages/fiber/src/core/store.ts b/packages/fiber/src/core/store.ts index bb9b88670c..b1a17881bf 100644 --- a/packages/fiber/src/core/store.ts +++ b/packages/fiber/src/core/store.ts @@ -47,7 +47,7 @@ export type Viewport = Size & { aspect: number } -export type RenderCallback = (state: RootState, delta: number, frame?: THREE.XRFrame) => void +export type RenderCallback = (state: RootState, delta: number, frame?: XRFrame) => void type LegacyAlways = 'always' export type FrameloopMode = LegacyAlways | 'auto' | 'demand' | 'never' @@ -170,7 +170,7 @@ const context = React.createContext>(null!) const createStore = ( invalidate: (state?: RootState, frames?: number) => void, - advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: THREE.XRFrame) => void, + advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: XRFrame) => void, ): UseBoundStore => { const rootState = create((set, get) => { const position = new THREE.Vector3() diff --git a/packages/fiber/src/core/utils.ts b/packages/fiber/src/core/utils.ts index fd7402b78b..737c2a1f05 100644 --- a/packages/fiber/src/core/utils.ts +++ b/packages/fiber/src/core/utils.ts @@ -321,11 +321,6 @@ export function applyProps(instance: Instance, data: InstanceProps | DiffSet) { else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask // Otherwise just set ... else targetProp.set(value) - // For versions of three which don't support THREE.ColorManagement, - // Auto-convert sRGB colors - // https://github.com/pmndrs/react-three-fiber/issues/344 - const supportsColorManagement = 'ColorManagement' in THREE - if (!supportsColorManagement && !rootState.linear && isColor) targetProp.convertSRGBToLinear() } // Else, just overwrite the value } else { @@ -381,13 +376,3 @@ export function updateCamera(camera: Camera & { manual?: boolean }, size: Size) camera.updateMatrixWorld() } } - -/** - * Safely sets a deeply-nested value on an object. - */ -export function setDeep(obj: any, value: any, keys: string[]) { - const key = keys.pop()! - const target = keys.reduce((acc, key) => acc[key], obj) - - return (target[key] = value) -} diff --git a/packages/fiber/tests/web/__snapshots__/canvas.test.tsx.snap b/packages/fiber/tests/web/__snapshots__/canvas.test.tsx.snap index 56d34347fe..560516675d 100644 --- a/packages/fiber/tests/web/__snapshots__/canvas.test.tsx.snap +++ b/packages/fiber/tests/web/__snapshots__/canvas.test.tsx.snap @@ -9,7 +9,7 @@ exports[`web Canvas should correctly mount 1`] = ` style="width: 100%; height: 100%;" > =18.0", "@react-three/fiber": ">=9.0.0", - "three": ">=0.133" + "three": ">=0.141" } } diff --git a/yarn.lock b/yarn.lock index 3304bc5413..738950b3ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2263,10 +2263,17 @@ "@types/react" "*" csstype "^3.0.2" -"@types/three@^0.139.0": - version "0.139.0" - resolved "https://registry.yarnpkg.com/@types/three/-/three-0.139.0.tgz#69af1f0c52f8eea390f513e05478af1dd7f49e6f" - integrity sha512-4V/jZhyq7Mv05coUzxL3bz8AuBOSi/1F0RY7ujisHTV0Amy/fnYJ+s7TSJ1/hXjZukSkpuFRgV+wvWUEMbsMbQ== +"@types/three@^0.141.0": + version "0.141.0" + resolved "https://registry.yarnpkg.com/@types/three/-/three-0.141.0.tgz#d9d81a54b28ebc2a56931dfd4d9c54d25c20d6c8" + integrity sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA== + dependencies: + "@types/webxr" "*" + +"@types/webxr@*": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.4.0.tgz#ad06c96a324293e0d5175d13dd5ded5931f90ba3" + integrity sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg== "@types/yargs-parser@*": version "21.0.0" @@ -8660,11 +8667,16 @@ three-stdlib@^2.8.11, three-stdlib@^2.8.12, three-stdlib@^2.9.1: potpack "^1.0.1" zstddec "^0.0.2" -three@^0.139.0, three@^0.139.2: +three@^0.139.2: version "0.139.2" resolved "https://registry.yarnpkg.com/three/-/three-0.139.2.tgz#b110799a15736df673b9293e31653a4ac73648dd" integrity sha512-gV7q7QY8rogu7HLFZR9cWnOQAUedUhu2WXAnpr2kdXZP9YDKsG/0ychwQvWkZN5PlNw9mv5MoCTin6zNTXoONg== +three@^0.141.0: + version "0.141.0" + resolved "https://registry.yarnpkg.com/three/-/three-0.141.0.tgz#16677a12b9dd0c3e1568ebad0fd09de15d5a8216" + integrity sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA== + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"