Browse Source

Merge pull request #3806 from TrevorDev/useControllerWhileMeshLoading

use empty mesh while controller is loading and enable input while mes…
Trevor Baron 7 years ago
parent
commit
28cc3df32b

+ 1 - 0
dist/preview release/what's new.md

@@ -81,6 +81,7 @@
 - Support depth maps for multiple active cameras for post processes like depth of field ([trevordev](https://github.com/trevordev))
 - Integrates depth texture support in the engine ([sebavan](https://github.com/sebavan))
 - NPM package now has a dependency system, updated during build. ([RaananW](https://github.com/RaananW))
+- WebVRExperienceHelper will create an empty controller model so that controller interactions can be used while the actual model is still loading ([trevordev](https://github.com/trevordev))
 - Default fragment shader will clamp negative values to avoid underflow, webVR post processing will render to eye texture size ([trevordev](https://github.com/trevordev))
 
 ## Bug fixes

+ 38 - 23
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -116,7 +116,17 @@ module BABYLON {
             this._laserPointer.rotation.x = Math.PI / 2;
             this._laserPointer.position.z = -0.5;
             this._laserPointer.isVisible = false;
-            this._laserPointer.parent = webVRController.mesh;
+
+            if(!webVRController.mesh){
+                // Create an empty mesh that is used prior to loading the high quality model
+                var preloadMesh = new Mesh("preloadControllerMesh", scene);
+                var preloadPointerPose = new Mesh(PoseEnabledController.POINTING_POSE, scene);
+                preloadPointerPose.rotation.x = -0.7;
+                preloadMesh.addChild(preloadPointerPose);
+                webVRController.attachToMesh(preloadMesh);
+            }
+
+            this._setLaserPointerParent(webVRController.mesh!);
         }
 
         _getForwardRay(length:number):Ray{
@@ -138,6 +148,22 @@ module BABYLON {
         }
 
         public _setLaserPointerParent(mesh:AbstractMesh){
+            var makeNotPick = (root: AbstractMesh) => {
+                root.name += " laserPointer";
+                root.getChildMeshes().forEach((c) => {
+                    makeNotPick(c);
+                });
+            }
+            makeNotPick(mesh);
+            var childMeshes = mesh.getChildMeshes();
+
+            for (var i = 0; i < childMeshes.length; i++) {
+                if (childMeshes[i].name && childMeshes[i].name.indexOf(PoseEnabledController.POINTING_POSE) >= 0) {
+                    mesh = childMeshes[i];
+                    this.webVRController._pointingPoseNode = mesh;
+                    break;
+                }
+            }
             this._laserPointer.parent = mesh;
         }
 
@@ -532,6 +558,8 @@ module BABYLON {
             }
             this._webVRCamera = new WebVRFreeCamera("WebVRHelper", this._position, this._scene, webVROptions);
             this._webVRCamera.useStandingMatrix()
+
+            this._cameraGazer = new VRExperienceHelperCameraGazer(()=>{return this.currentVRCamera;}, scene);
             // Create default button
             if (!this._useCustomVRButton) {
                 this._btnVR = <HTMLButtonElement>document.createElement("BUTTON");
@@ -629,17 +657,19 @@ module BABYLON {
             //create easing functions
             this._circleEase = new CircleEase();
             this._circleEase.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);
-
-            this._cameraGazer = new VRExperienceHelperCameraGazer(()=>{return this.currentVRCamera;}, scene)
         }
 
         // Raised when one of the controller has loaded successfully its associated default mesh
         private _onDefaultMeshLoaded(webVRController: WebVRController) {
             if(this.leftController && this.leftController.webVRController == webVRController){
-                this._tryEnableInteractionOnController(this.leftController);
+                if(webVRController.mesh){
+                    this.leftController._setLaserPointerParent(webVRController.mesh)
+                }
             }
             if(this.rightController && this.rightController.webVRController == webVRController){
-                this._tryEnableInteractionOnController(this.rightController);
+                if(webVRController.mesh){
+                    this.rightController._setLaserPointerParent(webVRController.mesh)
+                }
             }
             
             try {
@@ -1058,22 +1088,7 @@ module BABYLON {
         private _enableInteractionOnController(controller: VRExperienceHelperControllerGazer) {
             var controllerMesh = controller.webVRController.mesh;
             if (controllerMesh) {
-                var makeNotPick = (root: AbstractMesh) => {
-                    root.name += " laserPointer";
-                    root.getChildMeshes().forEach((c) => {
-                        makeNotPick(c);
-                    });
-                }
-                makeNotPick(controllerMesh);
-                var childMeshes = controllerMesh.getChildMeshes();
-
-                for (var i = 0; i < childMeshes.length; i++) {
-                    if (childMeshes[i].name && childMeshes[i].name.indexOf("POINTING_POSE") >= 0) {
-                        controllerMesh = childMeshes[i];
-                        break;
-                    }
-                }
-                controller._setLaserPointerParent(controllerMesh);
+                
                 controller._interactionsEnabled = true;
                 controller._activatePointer();
                 controller.webVRController.onMainButtonStateChangedObservable.add((stateObject) => {
@@ -1679,7 +1694,7 @@ module BABYLON {
             if (this.isInVRMode) {
                 this.exitVR();
             }
-
+            
             if (this._postProcessMove) {
                 this._postProcessMove.dispose();
             }
@@ -1742,4 +1757,4 @@ module BABYLON {
             return "VRExperienceHelper";
         }
     }
-}
+}

+ 10 - 1
src/Gamepad/Controllers/babylon.poseEnabledController.ts

@@ -80,6 +80,15 @@ module BABYLON {
 
         public _deviceToWorld = Matrix.Identity();
 
+        /**
+         * Node to be used when casting a ray from the controller
+         */
+        public _pointingPoseNode:Nullable<AbstractMesh> = null;
+        /**
+         * Name of the child mesh that can be used to cast a ray from the controller
+         */
+        public static readonly POINTING_POSE = "POINTING_POSE";
+
         constructor(browserGamepad: any) {
             super(browserGamepad.id, browserGamepad.index, browserGamepad);
             this.type = Gamepad.POSE_ENABLED;
@@ -181,7 +190,7 @@ module BABYLON {
                 return new Ray(Vector3.Zero(), new Vector3(0, 0, 1), length);
             }
 
-            var m = this.mesh.getWorldMatrix();
+            var m = this._pointingPoseNode ? this._pointingPoseNode.getWorldMatrix() : this.mesh.getWorldMatrix();
             var origin = m.getTranslation();
 
             var forward = new Vector3(0, 0, -1);

+ 9 - 10
src/Gamepad/Controllers/babylon.windowsMotionController.ts

@@ -62,7 +62,7 @@ module BABYLON {
                 'TOUCHPAD_TOUCH_X',
                 'TOUCHPAD_TOUCH_Y'
             ],
-            pointingPoseMeshName: 'POINTING_POSE'
+            pointingPoseMeshName: PoseEnabledController.POINTING_POSE
         };
 
         public onTrackpadChangedObservable = new Observable<ExtendedGamepadButton>();
@@ -104,15 +104,14 @@ module BABYLON {
          */
         public update() {
             super.update();
-
-            // Only need to animate axes if there is a loaded mesh
-            if (this._loadedMeshInfo) {
-                if (this.browserGamepad.axes) {
-                    if (this.browserGamepad.axes[2] != this.trackpad.x || this.browserGamepad.axes[3] != this.trackpad.y) {
-                        this.trackpad.x = this.browserGamepad["axes"][2];
-                        this.trackpad.y = this.browserGamepad["axes"][3];
-                        this.onTrackpadValuesChangedObservable.notifyObservers(this.trackpad);
-                    }
+            if (this.browserGamepad.axes) {
+                if (this.browserGamepad.axes[2] != this.trackpad.x || this.browserGamepad.axes[3] != this.trackpad.y) {
+                    this.trackpad.x = this.browserGamepad["axes"][2];
+                    this.trackpad.y = this.browserGamepad["axes"][3];
+                    this.onTrackpadValuesChangedObservable.notifyObservers(this.trackpad);
+                }
+                // Only need to animate axes if there is a loaded mesh
+                if (this._loadedMeshInfo) {
                     for (let axis = 0; axis < this._mapping.axisMeshNames.length; axis++) {
                         this.lerpAxisTransform(axis, this.browserGamepad.axes[axis]);
                     }