diff --git a/Apps/Playground/App.tsx b/Apps/Playground/App.tsx index c752dd368..b1169a86f 100644 --- a/Apps/Playground/App.tsx +++ b/Apps/Playground/App.tsx @@ -12,6 +12,7 @@ import { EngineView, useEngine, EngineViewCallbacks } from '@babylonjs/react-nat import { Scene, Vector3, ArcRotateCamera, Camera, WebXRSessionManager, SceneLoader, TransformNode, DeviceSourceManager, DeviceType, DeviceSource, PointerInput, WebXRTrackingState, Nullable } from '@babylonjs/core'; import '@babylonjs/loaders'; import Slider from '@react-native-community/slider'; +import * as DocumentPicker from 'react-native-document-picker'; const EngineScreen: FunctionComponent = (props: ViewProps) => { const defaultScale = 1; @@ -27,6 +28,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { const [snapshotData, setSnapshotData] = useState(); const [engineViewCallbacks, setEngineViewCallbacks] = useState(); const [trackingState, setTrackingState] = useState(); + const [modelUrl, setModelUrl] = useState('https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoxAnimated/glTF-Binary/BoxAnimated.glb'); useEffect(() => { if (engine) { @@ -62,22 +64,34 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { }); } }); + } + }, [engine]); + useEffect(() => { + if (scene && rootNode) { const transformContainer = new TransformNode('Transform Container', scene); transformContainer.parent = rootNode; transformContainer.scaling.scaleInPlace(0.2); transformContainer.position.y -= .2; - scene.beforeRender = function () { + const beforeRenderObserver = scene.onBeforeRenderObservable.add(() => { transformContainer.rotate(Vector3.Up(), 0.005 * scene.getAnimationRatio()); - }; + }); - SceneLoader.ImportMeshAsync('', 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/BoxAnimated/glTF-Binary/BoxAnimated.glb').then(result => { + const start = performance.now(); + SceneLoader.ImportMeshAsync('', modelUrl).then(result => { + const end = performance.now(); + console.log(`${modelUrl} loaded in ${end - start}ms`); const mesh = result.meshes[0]; mesh.parent = transformContainer; }); + + return () => { + scene.onBeforeRenderObservable.remove(beforeRenderObserver); + transformContainer.dispose(); + }; } - }, [engine]); + }, [modelUrl, scene, rootNode]); useEffect(() => { if (rootNode) { @@ -118,6 +132,19 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { })(); }, [rootNode, scene, xrSession]); + const onLoadModel = useCallback(() => { + (async () => { + if (rootNode && scene) { + const pickedFile = await DocumentPicker.pickSingle({copyTo: 'documentDirectory'}); + let uri = pickedFile.fileCopyUri!; + if (!(/file:\/\/.*/).test(uri)) { + uri = `file://${uri}`; + } + setModelUrl(uri); + } + })(); + }, [rootNode, scene]); + const onInitialized = useCallback(async(engineViewCallbacks: EngineViewCallbacks) => { setEngineViewCallbacks(engineViewCallbacks); }, [engine]); @@ -132,7 +159,14 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { <>