From d275268a988eaeeb9d2903e384681a2a56978dfc Mon Sep 17 00:00:00 2001 From: Colton Presler Date: Tue, 17 Nov 2020 13:48:23 -0800 Subject: [PATCH 1/6] Adding configurations to make debugging in VSCode easier --- .gitignore | 4 ---- .vscode/extensions.json | 7 +++++++ .vscode/launch.json | 38 ++++++++++++++++++++++++++++++++++++++ .vscode/settings.json | 3 +++ 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 796c0d2a3..e3ec162e7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,6 @@ # .DS_Store -# Visual Studio Code -# -.vscode - # Android Studio .project .classpath diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..d8f84183b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "msjsdiag.vscode-react-native", + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..36a3c6fcc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,38 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Android", + "cwd": "${workspaceFolder}/Apps/Playground", + "type": "reactnativedirect", + "request": "launch", + "platform": "android" + }, + { + "name": "Debug iOS on Device", + "cwd": "${workspaceFolder}/Apps/Playground", + "type": "reactnativedirect", + "request": "launch", + "platform": "ios", + "port": 9221, + "target": "device" + }, + { + "name": "Attach to Android", + "cwd": "${workspaceFolder}/Apps/Playground", + "type": "reactnativedirect", + "request": "attach" + }, + { + "name": "Attach to iOS on Device", + "cwd": "${workspaceFolder}/Apps/Playground", + "type": "reactnativedirect", + "request": "attach", + "platform": "ios", + "port": 9221 + }, + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..715632548 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "react-native-tools.projectRoot": "./Apps/Playground" +} \ No newline at end of file From 61f363a2aec73a4243868dca1ed1e0042384d9f9 Mon Sep 17 00:00:00 2001 From: Colton Presler Date: Tue, 24 Nov 2020 14:55:54 -0800 Subject: [PATCH 2/6] Updating Babylon Native to latest --- .vscode/launch.json | 4 +-- Apps/Playground/App.tsx | 32 ++++++++++++++++++- Apps/Playground/ios/Podfile.lock | 2 +- .../react-native/submodules/BabylonNative | 2 +- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 36a3c6fcc..f967b0dbb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,14 +5,14 @@ "version": "0.2.0", "configurations": [ { - "name": "Debug Android", + "name": "Build & Debug Android", "cwd": "${workspaceFolder}/Apps/Playground", "type": "reactnativedirect", "request": "launch", "platform": "android" }, { - "name": "Debug iOS on Device", + "name": "Build & Debug iOS on Device", "cwd": "${workspaceFolder}/Apps/Playground", "type": "reactnativedirect", "request": "launch", diff --git a/Apps/Playground/App.tsx b/Apps/Playground/App.tsx index 9ea82066c..a07344fd4 100644 --- a/Apps/Playground/App.tsx +++ b/Apps/Playground/App.tsx @@ -9,7 +9,7 @@ import React, { useState, FunctionComponent, useEffect, useCallback } from 'reac import { SafeAreaView, StatusBar, Button, View, Text, ViewProps, Image } from 'react-native'; import { EngineView, useEngine, EngineViewCallbacks } from '@babylonjs/react-native'; -import { Scene, Vector3, Mesh, ArcRotateCamera, Camera, PBRMetallicRoughnessMaterial, Color3, TargetCamera, WebXRSessionManager, Engine } from '@babylonjs/core'; +import { Scene, Vector3, Mesh, ArcRotateCamera, Camera, PBRMetallicRoughnessMaterial, Color3, TargetCamera, WebXRSessionManager, Engine, WebXRTrackingState } from '@babylonjs/core'; import Slider from '@react-native-community/slider'; const EngineScreen: FunctionComponent = (props: ViewProps) => { @@ -25,6 +25,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { const [scale, setScale] = useState(defaultScale); const [snapshotData, setSnapshotData] = useState(); const [engineViewCallbacks, setEngineViewCallbacks] = useState(); + const [trackingState, setTrackingState] = useState(); useEffect(() => { if (engine) { @@ -55,21 +56,49 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { } }, [box, scale]); + const trackingStateToString = (trackingState: WebXRTrackingState | undefined) : string => + { + if (trackingState == undefined) { + return "" + } + + switch(trackingState) { + case WebXRTrackingState.NOT_TRACKING: + return "Not Tracking"; + break; + case WebXRTrackingState.TRACKING: + return "Tracking"; + break; + case WebXRTrackingState.TRACKING_LOST: + return "Tracking Lost"; + break; + } + } + const onToggleXr = useCallback(() => { (async () => { if (xrSession) { await xrSession.exitXRAsync(); setXrSession(undefined); + setTrackingState(undefined); } else { if (box !== undefined && scene !== undefined) { const xr = await scene.createDefaultXRExperienceAsync({ disableDefaultUI: true, disableTeleportation: true }) const session = await xr.baseExperience.enterXRAsync("immersive-ar", "unbounded", xr.renderTarget); setXrSession(session); + + setTrackingState(xr.baseExperience.camera.trackingState); + xr.baseExperience.camera.onTrackingStateChanged.add((newTrackingState) =>{ + setTrackingState(newTrackingState); + }) + // TODO: Figure out why getFrontPosition stopped working //box.position = (scene.activeCamera as TargetCamera).getFrontPosition(2); const cameraRay = scene.activeCamera!.getForwardRay(1); box.position = cameraRay.origin.add(cameraRay.direction.scale(cameraRay.length)); box.rotate(Vector3.Up(), 3.14159); + + //CreateSpheres(scene, 10); } } })(); @@ -100,6 +129,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { } + {trackingStateToString(trackingState)} } { toggleView && diff --git a/Apps/Playground/ios/Podfile.lock b/Apps/Playground/ios/Podfile.lock index dd8e80386..770b6fe32 100644 --- a/Apps/Playground/ios/Podfile.lock +++ b/Apps/Playground/ios/Podfile.lock @@ -466,7 +466,7 @@ SPEC CHECKSUMS: React-jsi: b32a31da32e030f30bbf9a8d3a9c8325df9e793f React-jsiexecutor: 7ab9cdcdd18d57652fb041f8a147fe9658d4e00a React-jsinspector: 2e28bb487e42dda6c94dbfa0c648d1343767a0fb - react-native-babylon: cbcec38c3e3d9fc1aee538508a1f751619bb335b + react-native-babylon: 05685525bfa89aae82b2fccd0a56351e954df545 react-native-slider: b34d943dc60deb96d952ba6b6b249aa8091e86da React-RCTActionSheet: 1702a1a85e550b5c36e2e03cb2bd3adea053de95 React-RCTAnimation: ddda576010a878865a4eab83a78acd92176ef6a1 diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index d9042b8ff..1a8b34e55 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit d9042b8ff52fad2c9bcbc27f4999ba944c68d57d +Subproject commit 1a8b34e55d043830ac404715f84781521ec01ba2 From 4b00044a07860c2f642e1a43dd1cfced309ca396 Mon Sep 17 00:00:00 2001 From: Colton Presler Date: Tue, 24 Nov 2020 15:04:21 -0800 Subject: [PATCH 3/6] Merging master --- Apps/Playground/App.tsx | 55 +++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/Apps/Playground/App.tsx b/Apps/Playground/App.tsx index a07344fd4..24faf7d00 100644 --- a/Apps/Playground/App.tsx +++ b/Apps/Playground/App.tsx @@ -9,7 +9,8 @@ import React, { useState, FunctionComponent, useEffect, useCallback } from 'reac import { SafeAreaView, StatusBar, Button, View, Text, ViewProps, Image } from 'react-native'; import { EngineView, useEngine, EngineViewCallbacks } from '@babylonjs/react-native'; -import { Scene, Vector3, Mesh, ArcRotateCamera, Camera, PBRMetallicRoughnessMaterial, Color3, TargetCamera, WebXRSessionManager, Engine, WebXRTrackingState } from '@babylonjs/core'; +import { Scene, Vector3, ArcRotateCamera, Camera, WebXRSessionManager, SceneLoader, TransformNode, DeviceSourceManager, DeviceType, DeviceSource, PointerInput, WebXRTrackingState } from '@babylonjs/core'; +import '@babylonjs/loaders'; import Slider from '@react-native-community/slider'; const EngineScreen: FunctionComponent = (props: ViewProps) => { @@ -19,7 +20,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { const engine = useEngine(); const [toggleView, setToggleView] = useState(false); const [camera, setCamera] = useState(); - const [box, setBox] = useState(); + const [rootNode, setRootNode] = useState(); const [scene, setScene] = useState(); const [xrSession, setXrSession] = useState(); const [scale, setScale] = useState(defaultScale); @@ -35,26 +36,44 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { (scene.activeCamera as ArcRotateCamera).beta -= Math.PI / 8; setCamera(scene.activeCamera!); scene.createDefaultLight(true); + const rootNode = new TransformNode("Root Container", scene); + setRootNode(rootNode); + + const deviceSourceManager = new DeviceSourceManager(engine); + deviceSourceManager.onDeviceConnectedObservable.add(device => { + if (device.deviceType === DeviceType.Touch) { + const touch: DeviceSource = deviceSourceManager.getDeviceSource(device.deviceType, device.deviceSlot)!; + touch.onInputChangedObservable.add(touchEvent => { + if (touchEvent.inputIndex === PointerInput.Horizontal) { + if (touchEvent.currentState && touchEvent.previousState) { + rootNode.rotate(Vector3.Down(), (touchEvent.currentState - touchEvent.previousState) * 0.005); + } + } + }) + } + }) - const box = Mesh.CreateBox("box", 0.3, scene); - setBox(box); - const mat = new PBRMetallicRoughnessMaterial("mat", scene); - mat.metallic = 1; - mat.roughness = 0.5; - mat.baseColor = Color3.Red(); - box.material = mat; + const transformContainer = new TransformNode("Transform Container", scene); + transformContainer.parent = rootNode; + transformContainer.scaling.scaleInPlace(0.2); + transformContainer.position.y -= .2; scene.beforeRender = function () { - box.rotate(Vector3.Up(), 0.005 * scene.getAnimationRatio()); + 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 mesh = result.meshes[0]; + mesh.parent = transformContainer; + }); } }, [engine]); useEffect(() => { - if (box) { - box.scaling = new Vector3(scale, scale, scale); + if (rootNode) { + rootNode.scaling = new Vector3(scale, scale, scale); } - }, [box, scale]); + }, [rootNode, scale]); const trackingStateToString = (trackingState: WebXRTrackingState | undefined) : string => { @@ -82,7 +101,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { setXrSession(undefined); setTrackingState(undefined); } else { - if (box !== undefined && scene !== undefined) { + if (rootNode !== undefined && scene !== undefined) { const xr = await scene.createDefaultXRExperienceAsync({ disableDefaultUI: true, disableTeleportation: true }) const session = await xr.baseExperience.enterXRAsync("immersive-ar", "unbounded", xr.renderTarget); setXrSession(session); @@ -95,14 +114,12 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { // TODO: Figure out why getFrontPosition stopped working //box.position = (scene.activeCamera as TargetCamera).getFrontPosition(2); const cameraRay = scene.activeCamera!.getForwardRay(1); - box.position = cameraRay.origin.add(cameraRay.direction.scale(cameraRay.length)); - box.rotate(Vector3.Up(), 3.14159); - - //CreateSpheres(scene, 10); + rootNode.position = cameraRay.origin.add(cameraRay.direction.scale(cameraRay.length)); + rootNode.rotate(Vector3.Up(), 3.14159); } } })(); - }, [box, scene, xrSession]); + }, [rootNode, scene, xrSession]); const onInitialized = useCallback(async(engineViewCallbacks: EngineViewCallbacks) => { setEngineViewCallbacks(engineViewCallbacks); From ad8fc39bcbe5a0c51ffe44a629726a361eae2ba4 Mon Sep 17 00:00:00 2001 From: Colton Presler Date: Tue, 24 Nov 2020 15:19:21 -0800 Subject: [PATCH 4/6] Update babylon native to actual latest --- Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index 1a8b34e55..23f066b56 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit 1a8b34e55d043830ac404715f84781521ec01ba2 +Subproject commit 23f066b567d5eb7054c984a0726e6bc59fe74d06 From 611ce073568cf2627bddc9fb38859fa7a0b30084 Mon Sep 17 00:00:00 2001 From: CoPrez <40213616+CoPrez@users.noreply.github.com> Date: Mon, 30 Nov 2020 15:30:23 -0800 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Alex-MSFT Co-authored-by: Ryan Tremblay --- Apps/Playground/App.tsx | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/Apps/Playground/App.tsx b/Apps/Playground/App.tsx index 24faf7d00..b6c73a137 100644 --- a/Apps/Playground/App.tsx +++ b/Apps/Playground/App.tsx @@ -75,23 +75,8 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { } }, [rootNode, scale]); - const trackingStateToString = (trackingState: WebXRTrackingState | undefined) : string => - { - if (trackingState == undefined) { - return "" - } - - switch(trackingState) { - case WebXRTrackingState.NOT_TRACKING: - return "Not Tracking"; - break; - case WebXRTrackingState.TRACKING: - return "Tracking"; - break; - case WebXRTrackingState.TRACKING_LOST: - return "Tracking Lost"; - break; - } + const trackingStateToString = (trackingState: WebXRTrackingState | undefined) : string => { + return trackingState === undefined ? "" : WebXRTrackingState[trackingState]; } const onToggleXr = useCallback(() => { @@ -107,9 +92,9 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { setXrSession(session); setTrackingState(xr.baseExperience.camera.trackingState); - xr.baseExperience.camera.onTrackingStateChanged.add((newTrackingState) =>{ + xr.baseExperience.camera.onTrackingStateChanged.add((newTrackingState) => { setTrackingState(newTrackingState); - }) + }); // TODO: Figure out why getFrontPosition stopped working //box.position = (scene.activeCamera as TargetCamera).getFrontPosition(2); From 83baa87ed8a88a89dc842d880068a32b8640fd61 Mon Sep 17 00:00:00 2001 From: CoPrez <40213616+CoPrez@users.noreply.github.com> Date: Mon, 30 Nov 2020 15:30:54 -0800 Subject: [PATCH 6/6] Update Apps/Playground/App.tsx Co-authored-by: Alex-MSFT --- Apps/Playground/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Playground/App.tsx b/Apps/Playground/App.tsx index b6c73a137..14197b12a 100644 --- a/Apps/Playground/App.tsx +++ b/Apps/Playground/App.tsx @@ -77,7 +77,7 @@ const EngineScreen: FunctionComponent = (props: ViewProps) => { const trackingStateToString = (trackingState: WebXRTrackingState | undefined) : string => { return trackingState === undefined ? "" : WebXRTrackingState[trackingState]; - } + }; const onToggleXr = useCallback(() => { (async () => {