From 389bd8baad8c1e735f4fc946ca9cbb9ded9bc018 Mon Sep 17 00:00:00 2001 From: hooke Date: Fri, 20 Mar 2020 00:12:21 +0800 Subject: [PATCH] fix[scene]: some scene props not working. (#52) * fix: interface error * fix[scene]: scene props not work --- .gitignore | 1 + package-lock.json | 181 ++++++++---------- src/CreatedInstance.ts | 6 +- src/ReactBabylonJSHostConfig.ts | 2 +- src/Scene.tsx | 325 +++++++++++++++++--------------- 5 files changed, 262 insertions(+), 253 deletions(-) diff --git a/.gitignore b/.gitignore index 35166ff6..4d5c3c66 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ compiled dist storybook-static *.lock +debug/ diff --git a/package-lock.json b/package-lock.json index cf929b70..17af8f51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1427,6 +1427,34 @@ "react-lifecycles-compat": "^3.0.4" } }, + "@rollup/plugin-json": { + "version": "4.0.2", + "resolved": "http://r.cnpmjs.org/@rollup/plugin-json/download/@rollup/plugin-json-4.0.2.tgz", + "integrity": "sha1-SCGF7jasfdIcNG4tvMIv/tDG8tY=", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.4" + } + }, + "@rollup/plugin-typescript": { + "version": "4.0.0", + "resolved": "http://r.cnpmjs.org/@rollup/plugin-typescript/download/@rollup/plugin-typescript-4.0.0.tgz", + "integrity": "sha1-ek97KETShmnljAPIgPbtDW6SZoU=", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.1", + "resolve": "^1.14.1" + } + }, + "@rollup/pluginutils": { + "version": "3.0.8", + "resolved": "http://r.cnpmjs.org/@rollup/pluginutils/download/@rollup/pluginutils-3.0.8.tgz", + "integrity": "sha1-TpTRKNlLkGmeUX7wRUIpYNGMj94=", + "dev": true, + "requires": { + "estree-walker": "^1.0.1" + } + }, "@samverschueren/stream-to-observable": { "version": "0.3.0", "resolved": "http://r.cnpmjs.org/@samverschueren/stream-to-observable/download/@samverschueren/stream-to-observable-0.3.0.tgz", @@ -2834,12 +2862,6 @@ "integrity": "sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=", "dev": true }, - "@types/estree": { - "version": "0.0.42", - "resolved": "http://r.cnpmjs.org/@types/estree/download/@types/estree-0.0.42.tgz", - "integrity": "sha1-jQwfSAM57+2z5GBw4i3WPgQw3RE=", - "dev": true - }, "@types/events": { "version": "3.0.0", "resolved": "http://r.cnpmjs.org/@types/events/download/@types/events-3.0.0.tgz", @@ -3015,15 +3037,6 @@ "@types/react": "*" } }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "http://r.cnpmjs.org/@types/resolve/download/@types/resolve-0.0.8.tgz", - "integrity": "sha1-8mB00jjgJlnjI84aE9BB7uKA4ZQ=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/retry": { "version": "0.12.0", "resolved": "http://r.cnpmjs.org/@types/retry/download/@types/retry-0.12.0.tgz", @@ -5931,12 +5944,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "builtin-modules": { - "version": "3.1.0", - "resolved": "http://r.cnpmjs.org/builtin-modules/download/builtin-modules-3.1.0.tgz", - "integrity": "sha1-qtl8FRMet2tltQ7yCOdYTNdqdIQ=", - "dev": true - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "http://r.cnpmjs.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz", @@ -8087,6 +8094,12 @@ "stream-shift": "^1.0.0" } }, + "earcut": { + "version": "2.2.2", + "resolved": "http://r.cnpmjs.org/earcut/download/earcut-2.2.2.tgz", + "integrity": "sha1-QbC8NfY+D+gNp83f8oUR5+LoDRE=", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "http://r.cnpmjs.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz", @@ -8386,9 +8399,9 @@ "dev": true }, "estree-walker": { - "version": "0.6.1", - "resolved": "http://r.cnpmjs.org/estree-walker/download/estree-walker-0.6.1.tgz", - "integrity": "sha1-UwSRQ/QMbrkYsjZx0f4yGfOhs2I=", + "version": "1.0.1", + "resolved": "http://r.cnpmjs.org/estree-walker/download/estree-walker-1.0.1.tgz", + "integrity": "sha1-MbxdYSyWtwQQa0d+bdXYqhOMtwA=", "dev": true }, "esutils": { @@ -11529,12 +11542,6 @@ "integrity": "sha1-Ug2vxDB7uOvDO4E95c58lADWRKE=", "dev": true }, - "is-module": { - "version": "1.0.0", - "resolved": "http://r.cnpmjs.org/is-module/download/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, "is-negated-glob": { "version": "1.0.0", "resolved": "http://r.cnpmjs.org/is-negated-glob/download/is-negated-glob-1.0.0.tgz", @@ -14570,15 +14577,6 @@ "integrity": "sha1-6xkwsDbAgArevM1fF7xMEt6Ltx8=", "dev": true }, - "magic-string": { - "version": "0.25.6", - "resolved": "http://r.cnpmjs.org/magic-string/download/magic-string-0.25.6.tgz", - "integrity": "sha1-VYY4fRJC+RnG0iNXnMk4vxQgeV4=", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, "make-dir": { "version": "2.1.0", "resolved": "http://r.cnpmjs.org/make-dir/download/make-dir-2.1.0.tgz", @@ -22447,71 +22445,27 @@ } }, "rollup": { - "version": "1.31.1", - "resolved": "http://r.cnpmjs.org/rollup/download/rollup-1.31.1.tgz", - "integrity": "sha1-QXDW+HFI1G5fvim0k/jz6jRTyW8=", + "version": "2.1.0", + "resolved": "http://r.cnpmjs.org/rollup/download/rollup-2.1.0.tgz", + "integrity": "sha1-VS4kjjl6BrnG24eMBWTKTuBnKck=", "dev": true, "requires": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" + "fsevents": "~2.1.2" }, "dependencies": { - "acorn": { - "version": "7.1.0", - "resolved": "http://r.cnpmjs.org/acorn/download/acorn-7.1.0.tgz", - "integrity": "sha1-lJ028sKSU12mAig1hsJHfFfrLWw=", - "dev": true + "fsevents": { + "version": "2.1.2", + "resolved": "http://r.cnpmjs.org/fsevents/download/fsevents-2.1.2.tgz", + "integrity": "sha1-TAofs0vGjlQ7S4Kp7Dkr+9qECAU=", + "dev": true, + "optional": true } } }, - "rollup-plugin-commonjs": { - "version": "9.3.4", - "resolved": "http://r.cnpmjs.org/rollup-plugin-commonjs/download/rollup-plugin-commonjs-9.3.4.tgz", - "integrity": "sha1-Kz3du73tg9RcNv8QHN0p6ST9I7w=", - "dev": true, - "requires": { - "estree-walker": "^0.6.0", - "magic-string": "^0.25.2", - "resolve": "^1.10.0", - "rollup-pluginutils": "^2.6.0" - } - }, - "rollup-plugin-json": { - "version": "3.1.0", - "resolved": "http://r.cnpmjs.org/rollup-plugin-json/download/rollup-plugin-json-3.1.0.tgz", - "integrity": "sha1-fB2vYMRrwhAh6gFr0AhjVhoDMhs=", - "dev": true, - "requires": { - "rollup-pluginutils": "^2.3.1" - } - }, - "rollup-plugin-node-resolve": { - "version": "4.2.4", - "resolved": "http://r.cnpmjs.org/rollup-plugin-node-resolve/download/rollup-plugin-node-resolve-4.2.4.tgz", - "integrity": "sha1-fTcPjW/TAxAGoAMsOCYt2b48YlA=", - "dev": true, - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.10.0" - } - }, - "rollup-plugin-sourcemaps": { - "version": "0.4.2", - "resolved": "http://r.cnpmjs.org/rollup-plugin-sourcemaps/download/rollup-plugin-sourcemaps-0.4.2.tgz", - "integrity": "sha1-YhJaqUCHqt97g+9N+vYptHMTXoc=", - "dev": true, - "requires": { - "rollup-pluginutils": "^2.0.1", - "source-map-resolve": "^0.5.0" - } - }, "rollup-plugin-terser": { - "version": "5.2.0", - "resolved": "http://r.cnpmjs.org/rollup-plugin-terser/download/rollup-plugin-terser-5.2.0.tgz", - "integrity": "sha1-unWK33aTR7fx6vnvNZeNLiB9zMc=", + "version": "5.3.0", + "resolved": "http://r.cnpmjs.org/rollup-plugin-terser/download/rollup-plugin-terser-5.3.0.tgz", + "integrity": "sha1-nA3TPVdx35YwzQJ9aiVZGH9liF4=", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", @@ -22542,6 +22496,27 @@ } } }, + "rollup-plugin-typescript2": { + "version": "0.26.0", + "resolved": "http://r.cnpmjs.org/rollup-plugin-typescript2/download/rollup-plugin-typescript2-0.26.0.tgz", + "integrity": "sha1-zuK0TVHZYjaGZW123DCnPE3pFnI=", + "dev": true, + "requires": { + "find-cache-dir": "^3.2.0", + "fs-extra": "8.1.0", + "resolve": "1.15.1", + "rollup-pluginutils": "2.8.2", + "tslib": "1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.10.0", + "resolved": "http://r.cnpmjs.org/tslib/download/tslib-1.10.0.tgz", + "integrity": "sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo=", + "dev": true + } + } + }, "rollup-pluginutils": { "version": "2.8.2", "resolved": "http://r.cnpmjs.org/rollup-pluginutils/download/rollup-pluginutils-2.8.2.tgz", @@ -22549,6 +22524,14 @@ "dev": true, "requires": { "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "http://r.cnpmjs.org/estree-walker/download/estree-walker-0.6.1.tgz", + "integrity": "sha1-UwSRQ/QMbrkYsjZx0f4yGfOhs2I=", + "dev": true + } } }, "rsvp": { @@ -23681,12 +23664,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "http://r.cnpmjs.org/sourcemap-codec/download/sourcemap-codec-1.4.8.tgz", - "integrity": "sha1-6oBL2UhXQC5pktBaOO8a41qatMQ=", - "dev": true - }, "space-separated-tokens": { "version": "1.1.5", "resolved": "http://r.cnpmjs.org/space-separated-tokens/download/space-separated-tokens-1.1.5.tgz", diff --git a/src/CreatedInstance.ts b/src/CreatedInstance.ts index dcb3f1d7..61c4e24b 100644 --- a/src/CreatedInstance.ts +++ b/src/CreatedInstance.ts @@ -89,7 +89,7 @@ export interface CreatedInstance { state?: any customProps: CustomProps // TODO: Consider merging these last 2 into a single class/container. - propsHandlers?: HasPropsHandlers // These are mostly generated + propsHandlers?: HasPropsHandlers // These are mostly generated lifecycleListener?: LifecycleListener // Only custom types currently support LifecycleListeners (ie: AttachesToParent) deferredCreationProps?: any // deferred props for instance with delayed creation (ie: ShadowGenerator that needs Light). } @@ -99,10 +99,10 @@ export class CreatedInstanceImpl implements CreatedInstance { public readonly metadata: CreatedInstanceMetadata public parent: CreatedInstance | null = null // Not the same as parent in BabylonJS, this is for internal reconciler structure. ie: graph walking public children: CreatedInstance[] = [] - public propsHandlers: HasPropsHandlers + public propsHandlers: HasPropsHandlers public customProps: CustomProps - constructor(hostInstance: T, metadata: CreatedInstanceMetadata, fiberObject: HasPropsHandlers, customProps: CustomProps) { + constructor(hostInstance: T, metadata: CreatedInstanceMetadata, fiberObject: HasPropsHandlers, customProps: CustomProps) { this.hostInstance = hostInstance this.metadata = metadata this.propsHandlers = fiberObject diff --git a/src/ReactBabylonJSHostConfig.ts b/src/ReactBabylonJSHostConfig.ts index e3f20254..42b2cb33 100644 --- a/src/ReactBabylonJSHostConfig.ts +++ b/src/ReactBabylonJSHostConfig.ts @@ -275,7 +275,7 @@ const ReactBabylonJSHostConfig: HostConfig< }, parent: null, children: [], - propsHandlers: new FiberModel(), + propsHandlers: new FiberModel() as any, lifecycleListener: new CUSTOM_COMPONENTS.ModelLifecycleListener(scene! /* should always be available */, props), customProps: {} } diff --git a/src/Scene.tsx b/src/Scene.tsx index 76ac95fb..52a88dec 100644 --- a/src/Scene.tsx +++ b/src/Scene.tsx @@ -5,17 +5,26 @@ * LICENSE.txt file in the root directory of this source tree. */ -import React, { createContext, useContext, useEffect, useState, useRef } from 'react'; -import ReactReconciler, { Reconciler } from "react-reconciler"; - -import { WithBabylonJSContext, withBabylonJS, BabylonJSContext } from './Engine'; -import { Scene as BabylonJSScene, Engine as BabylonJSEngine, Nullable, AbstractMesh, PointerInfo, PointerEventTypes, SceneOptions, Observer, EventState } from '@babylonjs/core'; - -import { applyUpdateToInstance } from "./UpdateInstance"; -import ReactBabylonJSHostConfig, { Container } from './ReactBabylonJSHostConfig'; -import { FiberScenePropsHandler } from './generatedCode'; -import { FiberSceneProps } from './generatedProps'; -import { UpdatePayload } from './PropsHandler'; +import React, {createContext, useContext, useEffect, useRef, useState,} from 'react'; +import ReactReconciler, {Reconciler} from "react-reconciler"; + +import {BabylonJSContext, withBabylonJS, WithBabylonJSContext} from './Engine'; +import { + AbstractMesh, + Engine as BabylonJSEngine, + Nullable, + Observer, + PointerEventTypes, + PointerInfo, + Scene as BabylonJSScene, + SceneOptions +} from '@babylonjs/core'; + +import {applyUpdateToInstance} from "./UpdateInstance"; +import ReactBabylonJSHostConfig, {Container} from './ReactBabylonJSHostConfig'; +import {FiberScenePropsHandler} from './generatedCode'; +import {FiberSceneProps} from './generatedProps'; +import {UpdatePayload} from './PropsHandler'; export interface WithSceneContext { engine: Nullable @@ -41,16 +50,14 @@ export const useBabylonScene = () => useContext(SceneContext).scene type Omit = Pick>; -export function withScene< - P extends { sceneContext: WithSceneContext }, - R = Omit - >( +export function withScene

>( Component: React.ComponentClass

| React.FunctionComponent

- ): React.FunctionComponent { +): React.FunctionComponent { return function BoundComponent(props: R) { return ( - {ctx => } + {ctx => } ); }; @@ -69,170 +76,194 @@ type SceneProps = { const usePrevious = (value: T) => { const ref = useRef(); + useEffect(() => { ref.current = value; - }); + }, [value]); + return ref.current; }; const Scene: React.FC = (props: SceneProps, context?: any) => { - const { engine } = useContext(BabylonJSContext) + const {engine} = useContext(BabylonJSContext) - const [propsHandler]= useState(new FiberScenePropsHandler()); + const [propsHandler] = useState(new FiberScenePropsHandler()); const [sceneReady, setSceneReady] = useState(false); const [scene, setScene] = useState>(null) const [fiberRoot, setFiberRoot] = useState(null); // TODO: make this strongly typed const [renderer, setRenderer] = useState>>(null); - const prevProps = usePrevious(props); - useEffect(() => { - if (engine === null || scene === null || renderer === null || prevProps === undefined) { - return; - } - const updates : UpdatePayload = propsHandler.getPropertyUpdates(prevProps, props) - if (updates !== null) { - updates.forEach(propertyUpdate => { - applyUpdateToInstance(scene, propertyUpdate, 'scene') - }) - } - - renderer.updateContainer( - - {props.children} - , - fiberRoot, - undefined, - () => { /* called after container is updated. we may want an external observable here */ } - ) - }) + const prevPropsRef = useRef({}); + // initialize babylon scene useEffect(() => { - // const onSceneReady = (eventData: BabylonJSScene, eventState: EventState) => { - // setSceneReady(true); - // } - - const scene = new BabylonJSScene(engine!, props.sceneOptions) - - // const onReadyObservable: Nullable> = scene.onReadyObservable.add(onSceneReady); - if (scene.isReady()) { - // scene.onReadyObservable.remove(onReadyObservable); - setSceneReady(true) - } else { - console.error('Scene is not ready. Report issue in react-babylonjs repo') - } - - setScene(scene); - - const isAsync = false // Disables experimental async rendering - - const container: Container = { - engine: props.babylonJSContext.engine, - canvas: props.babylonJSContext.canvas, - scene: scene, - rootInstance: { - hostInstance: null, - children: [], - parent: null, - metadata: { - className: "root" - }, - customProps: {} + // const onSceneReady = (eventData: BabylonJSScene, eventState: EventState) => { + // setSceneReady(true); + // } + + const scene = new BabylonJSScene(engine!, props.sceneOptions) + // const onReadyObservable: Nullable> = scene.onReadyObservable.add(onSceneReady); + if (scene.isReady()) { + // scene.onReadyObservable.remove(onReadyObservable); + setSceneReady(true) + } else { + console.error('Scene is not ready. Report issue in react-babylonjs repo') } - } - const renderer = ReactReconciler(ReactBabylonJSHostConfig); - setRenderer(renderer) - const fiberRoot = renderer.createContainer(container, isAsync, false /* hydrate true == better HMR? */) - setFiberRoot(fiberRoot); - - renderer.injectIntoDevTools({ - bundleType: process.env.NODE_ENV === 'production' ? 0 : 1, - version: '2.0.0', - rendererPackageName: 'react-babylonjs' - }) - - const pointerDownObservable: Nullable> = scene.onPointerObservable.add( - (evt: PointerInfo) => { - if(typeof props.onScenePointerDown === 'function') { - props.onScenePointerDown(evt, scene) + setScene(scene); + + const isAsync = false // Disables experimental async rendering + + const container: Container = { + engine: props.babylonJSContext.engine, + canvas: props.babylonJSContext.canvas, + scene: scene, + rootInstance: { + hostInstance: null, + children: [], + parent: null, + metadata: { + className: "root" + }, + customProps: {} } + } + + const renderer = ReactReconciler(ReactBabylonJSHostConfig); + setRenderer(renderer) + const fiberRoot = renderer.createContainer(container, isAsync, false /* hydrate true == better HMR? */) + setFiberRoot(fiberRoot); + + renderer.injectIntoDevTools({ + bundleType: process.env.NODE_ENV === 'production' ? 0 : 1, + version: '2.0.0', + rendererPackageName: 'react-babylonjs' + }) - if (evt && evt.pickInfo && evt.pickInfo.hit && evt.pickInfo.pickedMesh) { - let mesh = evt.pickInfo.pickedMesh - if (typeof props.onMeshPicked === 'function') { - props.onMeshPicked(mesh, scene) - } else { - // console.log('onMeshPicked not being called') + const pointerDownObservable: Nullable> = scene.onPointerObservable.add( + (evt: PointerInfo) => { + if (typeof props.onScenePointerDown === 'function') { + props.onScenePointerDown(evt, scene) } - } - }, - PointerEventTypes.POINTERDOWN - ); - // can only be assigned on init - let pointerUpObservable: Nullable> = null; - if(typeof props.onScenePointerUp === 'function') { - pointerUpObservable = scene.onPointerObservable.add( - (evt: PointerInfo) => { - props.onScenePointerUp!(evt, scene) - }, - PointerEventTypes.POINTERUP - ) - }; - - // can only be assigned on init - let pointerMoveObservable: Nullable> = null; - if(typeof props.onScenePointerMove === 'function') { - pointerMoveObservable = scene.onPointerObservable.add( - (evt: PointerInfo) => { - props.onScenePointerMove!(evt, scene) + if (evt && evt.pickInfo && evt.pickInfo.hit && evt.pickInfo.pickedMesh) { + let mesh = evt.pickInfo.pickedMesh + if (typeof props.onMeshPicked === 'function') { + props.onMeshPicked(mesh, scene) + } else { + // console.log('onMeshPicked not being called') + } + } }, - PointerEventTypes.POINTERMOVE) - }; + PointerEventTypes.POINTERDOWN + ); + + // can only be assigned on init + let pointerUpObservable: Nullable> = null; + if (typeof props.onScenePointerUp === 'function') { + pointerUpObservable = scene.onPointerObservable.add( + (evt: PointerInfo) => { + props.onScenePointerUp!(evt, scene) + }, + PointerEventTypes.POINTERUP + ) + } + ; + + // can only be assigned on init + let pointerMoveObservable: Nullable> = null; + if (typeof props.onScenePointerMove === 'function') { + pointerMoveObservable = scene.onPointerObservable.add( + (evt: PointerInfo) => { + props.onScenePointerMove!(evt, scene) + }, + PointerEventTypes.POINTERMOVE) + } + ; - if (typeof props.onSceneMount === 'function') { - props.onSceneMount({ + if (typeof props.onSceneMount === 'function') { + props.onSceneMount({ scene: scene, canvas: scene.getEngine().getRenderingCanvas()! - }); - // TODO: console.error if canvas is not attached. runRenderLoop() is expected to be part of onSceneMount(). + }); + // TODO: console.error if canvas is not attached. runRenderLoop() is expected to be part of onSceneMount(). + } + + // TODO: change enable physics to 'usePhysics' taking an object with a Vector3 and 'any'. + // NOTE: must be enabled for updating container (cannot add impostors w/o physics enabled) + if (Array.isArray(props.enablePhysics)) { + scene.enablePhysics(props.enablePhysics[0], props.enablePhysics[1]); + } + + // update the root Container + renderer.updateContainer( + + {props.children} + , fiberRoot, undefined, () => { /* empty */ + } + ) + + return () => { + if (pointerDownObservable) { + scene.onPointerObservable.remove(pointerDownObservable); + } + + if (pointerUpObservable) { + scene.onPointerObservable.remove(pointerUpObservable); + } + + if (pointerMoveObservable) { + scene.onPointerObservable.remove(pointerMoveObservable); + } + + scene.dispose(); + } + }, + [/* no deps, so called only on un/mount */] + ); + + + // update babylon scene + useEffect(() => { + if (engine === null || scene === null || renderer === null) { + return; } - // TODO: change enable physics to 'usePhysics' taking an object with a Vector3 and 'any'. - // NOTE: must be enabled for updating container (cannot add impostors w/o physics enabled) - if (Array.isArray(props.enablePhysics)) { - scene.enablePhysics(props.enablePhysics[0], props.enablePhysics[1]); + const prevProps = prevPropsRef.current; + const updates: UpdatePayload = propsHandler.getPropertyUpdates(prevProps, props); + + if (updates !== null) { + updates.forEach(propertyUpdate => { + applyUpdateToInstance(scene, propertyUpdate, 'scene') + }) } - // update the root Container renderer.updateContainer( - + {props.children} - , fiberRoot, undefined, () => { /* empty */} - ) - - return () => { - if (pointerDownObservable) { - scene.onPointerObservable.remove(pointerDownObservable); - } - - if (pointerUpObservable) { - scene.onPointerObservable.remove(pointerUpObservable); - } - - if (pointerMoveObservable) { - scene.onPointerObservable.remove(pointerMoveObservable); + , + fiberRoot, + undefined, + () => { /* called after container is updated. we may want an external observable here */ } + ) - scene.dispose(); - } - }, - [/* no deps, so called only on un/mount */] - ) + prevPropsRef.current = props; + }); return null; -} +}; -export default withBabylonJS(Scene) \ No newline at end of file +export default withBabylonJS(Scene)