Browse Source

Merge pull request #3364 from TrevorDev/getViveWorking

Get vive working
David Catuhe 7 years ago
parent
commit
1fb69251cf

+ 31 - 17
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -221,7 +221,7 @@ module BABYLON {
             this._vrDeviceOrientationCamera = new BABYLON.VRDeviceOrientationFreeCamera("VRDeviceOrientationVRHelper", this._position, this._scene);
             }
             this._webVRCamera = new BABYLON.WebVRFreeCamera("WebVRHelper", this._position, this._scene, webVROptions);
-
+            this._webVRCamera.useStandingMatrix()
             // Create default button
             if (!this._useCustomVRButton) {
                 this._btnVR = <HTMLButtonElement>document.createElement("BUTTON");
@@ -305,6 +305,10 @@ module BABYLON {
             scene.getEngine().onVRRequestPresentComplete.add(this._onVRRequestPresentComplete);
             window.addEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
 
+            scene.onDisposeObservable.add(()=>{
+                this.dispose();
+            })
+
             // Gamepad connection events
             this._webVRCamera.onControllerMeshLoadedObservable.add((webVRController) => this._onDefaultMeshLoaded(webVRController));
             this._scene.gamepadManager.onGamepadConnectedObservable.add(this._onNewGamepadConnected);
@@ -642,12 +646,12 @@ module BABYLON {
                 if (gamepad.leftStick) {
                     gamepad.onleftstickchanged((stickValues) => {
                         if (this._teleportationEnabled) {
-                            this._checkTeleportBackwards(stickValues);
                             // Listening to classic/xbox gamepad only if no VR controller is active
                             if ((!this._leftLaserPointer && !this._rightLaserPointer) ||
                                 ((this._leftLaserPointer && !this._leftLaserPointer.isVisible) &&
                                     (this._rightLaserPointer && !this._rightLaserPointer.isVisible))) {
                                 this._checkTeleportWithRay(stickValues);
+                                this._checkTeleportBackwards(stickValues);
                             }
                         }
                     });
@@ -698,10 +702,17 @@ module BABYLON {
         private _enableInteractionOnController(webVRController: WebVRController) {
             var controllerMesh = 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 === "POINTING_POSE") {
+                    if (childMeshes[i].name && childMeshes[i].name.indexOf("POINTING_POSE") >= 0) {
                         controllerMesh = childMeshes[i];
                         break;
                     }
@@ -714,7 +725,6 @@ module BABYLON {
                 laserPointer.rotation.x = Math.PI / 2;
                 laserPointer.parent = controllerMesh;
                 laserPointer.position.z = -0.5;
-                laserPointer.position.y = 0;
                 laserPointer.isVisible = false;
                 if (webVRController.hand === "left") {
                     this._leftLaserPointer = laserPointer;
@@ -1101,19 +1111,23 @@ module BABYLON {
             }
 
             if(!location){
-                // Teleport the hmd to where the user is looking by moving the anchor to where they are looking minus the
-                // offset of the headset from the anchor.
-                if (this.webVRCamera.leftCamera) {
-                    this._workingVector.copyFrom(this.webVRCamera.leftCamera.globalPosition);
-                    this._workingVector.subtractInPlace(this.webVRCamera.position);
-                    this._haloCenter.subtractToRef(this._workingVector, this._workingVector);
-                } else {
-                    this._workingVector.copyFrom(this._haloCenter);
-                }
-                location = this._workingVector;
+                location = this._haloCenter;
+            }
+            // Teleport the hmd to where the user is looking by moving the anchor to where they are looking minus the
+            // offset of the headset from the anchor.
+            if (this.webVRCamera.leftCamera) {
+                this._workingVector.copyFrom(this.webVRCamera.leftCamera.globalPosition);
+                this._workingVector.subtractInPlace(this.webVRCamera.position);
+                location.subtractToRef(this._workingVector, this._workingVector);
+            } else {
+                this._workingVector.copyFrom(location);
             }
             // Add height to account for user's height offset
-            location.y += this._defaultHeight;
+            if(this.isInVRMode){
+                this._workingVector.y += this.webVRCamera.deviceDistanceToRoomGround();
+            }else{
+                this._workingVector.y += this._defaultHeight;
+            }
 
             // Create animation from the camera's position to the new location
             this.currentVRCamera.animations = [];
@@ -1124,7 +1138,7 @@ module BABYLON {
             },
             {
                 frame: 11,
-                value: location
+                value: this._workingVector
             }
             ];
 
@@ -1189,7 +1203,7 @@ module BABYLON {
                 return;
             }
 
-            var ray;
+            var ray:Ray;
             if (this._leftLaserPointer && this._leftLaserPointer.isVisible && (<any>this.currentVRCamera).leftController) {
                 ray = (<any>this.currentVRCamera).leftController.getForwardRay(this._rayLength);
             }

+ 49 - 1
src/Cameras/VR/babylon.webVRCamera.ts

@@ -56,6 +56,8 @@ module BABYLON {
         private _deviceRoomPosition = Vector3.Zero();
         private _deviceRoomRotationQuaternion = Quaternion.Identity(); 
 
+        private _standingMatrix:Nullable<Matrix> = null;
+
         // Represents device position and rotation in babylon space
         public devicePosition = Vector3.Zero();
         public deviceRotationQuaternion = Quaternion.Identity();        
@@ -73,11 +75,13 @@ module BABYLON {
 
         private _lightOnControllers: BABYLON.HemisphericLight;
 
+        private _defaultHeight = 0;
         constructor(name: string, position: Vector3, scene: Scene, private webVROptions: WebVROptions = {}) {
             super(name, position, scene);
             this._cache.position = Vector3.Zero();
             if(webVROptions.defaultHeight){
-                this.position.y = webVROptions.defaultHeight;
+                this._defaultHeight = webVROptions.defaultHeight;
+                this.position.y = this._defaultHeight;
             }
             
             this.minZ = 0.1;
@@ -160,6 +164,47 @@ module BABYLON {
             });
         }
 
+        public deviceDistanceToRoomGround = ()=>{
+            if(this._standingMatrix){
+                // Add standing matrix offset to get real offset from ground in room
+                this._standingMatrix.getTranslationToRef(this._workingVector);
+                return this._deviceRoomPosition.y+this._workingVector.y
+            }else{
+                return this._defaultHeight;
+            }
+        }
+
+        public useStandingMatrix = (callback = (bool:boolean)=>{})=>{
+            // Use standing matrix if availible
+            if(!navigator || !navigator.getVRDisplays){
+                callback(false);
+            }else{
+                navigator.getVRDisplays().then((displays:any)=>{
+                    if(!displays || !displays[0] || !displays[0].stageParameters || !displays[0].stageParameters.sittingToStandingTransform){
+                        callback(false);
+                    }else{
+                        this._standingMatrix = new BABYLON.Matrix();
+                        BABYLON.Matrix.FromFloat32ArrayToRefScaled(displays[0].stageParameters.sittingToStandingTransform, 0, 1, this._standingMatrix);
+                        if (!this.getScene().useRightHandedSystem) {
+                            [2, 6, 8, 9, 14].forEach((num) => {
+                                if(this._standingMatrix){
+                                    this._standingMatrix.m[num] *= -1;
+                                }
+                            });
+                        }
+                        // Move starting headset position by standing matrix
+                        this._deviceToWorld.multiplyToRef(this._standingMatrix, this._deviceToWorld);
+
+                        // Correct for default height added originally
+                        var pos =  this._deviceToWorld.getTranslation()
+                        pos.y -= this._defaultHeight;
+                        this._deviceToWorld.setTranslation(pos)
+                        callback(true)
+                    }
+                })
+            }
+        }
+
         public dispose(): void {
             this.getEngine().onVRRequestPresentComplete.removeCallback(this._onVREnabled);
             super.dispose();
@@ -289,6 +334,9 @@ module BABYLON {
         private _workingMatrix = Matrix.Identity();
         public _updateCache(ignoreParentClass?: boolean): void {
             if(!this.rotationQuaternion.equals(this._cache.rotationQuaternion) || !this.position.equals(this._cache.position)){
+                // Update to ensure devicePosition is up to date with most recent _deviceRoomPosition
+                this.update();
+
                 // Set working vector to the device position in room space rotated by the new rotation
                 this.rotationQuaternion.toRotationMatrix(this._workingMatrix);
                 Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._workingMatrix, this._workingVector);

+ 1 - 0
src/Gamepad/Controllers/babylon.viveController.ts

@@ -7,6 +7,7 @@ module BABYLON {
         constructor(vrGamepad: any) {
             super(vrGamepad);
             this.controllerType = PoseEnabledControllerType.VIVE;
+            this._invertLeftStickY = true;
         }
 
         public initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void) {

+ 6 - 0
src/Gamepad/Controllers/babylon.webVRController.ts

@@ -13,6 +13,8 @@ module BABYLON {
 
         protected _buttons: Array<MutableGamepadButton>;
 
+        private static handCounter = 0;
+
         private _onButtonStateChange: (controlledIndex: number, buttonIndex: number, state: ExtendedGamepadButton) => void;
 
         public onButtonStateChange(callback: (controlledIndex: number, buttonIndex: number, state: ExtendedGamepadButton) => void) {
@@ -31,6 +33,10 @@ module BABYLON {
             super(vrGamepad);
             this._buttons = new Array<ExtendedGamepadButton>(vrGamepad.buttons.length);
             this.hand = vrGamepad.hand;
+            if(!this.hand){
+                this.hand = (WebVRController.handCounter % 2 == 0) ? "left" : "right";
+                WebVRController.handCounter++;
+            }
         }
 
         public update() {

+ 5 - 0
src/Gamepad/babylon.gamepad.ts

@@ -33,6 +33,8 @@
         public static XBOX = 2;
         public static POSE_ENABLED = 3;
 
+        protected _invertLeftStickY:boolean = false;
+
         public get isConnected(): boolean {
             return this._isConnected;
         }
@@ -81,6 +83,9 @@
         public update() {
             if (this._leftStick) {
                 this.leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };
+                if(this._invertLeftStickY){
+                    this.leftStick.y *= -1;
+                }
             }
             if (this._rightStick) {
                 this.rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };