Pārlūkot izejas kodu

Merge pull request #1896 from RaananW/webvr-xbox-fixes

WebVR support for rotation and position
David Catuhe 8 gadi atpakaļ
vecāks
revīzija
93a71fd6d7

+ 8 - 5
src/Cameras/VR/babylon.webVRCamera.ts

@@ -208,13 +208,16 @@ module BABYLON {
                 this._webvrViewMatrix.m[12] += parentCamera.position.x;
                 this._webvrViewMatrix.m[13] += parentCamera.position.y;
                 this._webvrViewMatrix.m[14] += parentCamera.position.z;
+
+                // is rotation offset set? 
+                if (!Quaternion.IsIdentity(this.rotationQuaternion)) {
+                    this._webvrViewMatrix.decompose(Tmp.Vector3[0], Tmp.Quaternion[0], Tmp.Vector3[1]);
+                    this.rotationQuaternion.multiplyToRef(Tmp.Quaternion[0], Tmp.Quaternion[0]);
+                    Matrix.ComposeToRef(Tmp.Vector3[0], Tmp.Quaternion[0], Tmp.Vector3[1], this._webvrViewMatrix);
+                }
+
                 this._webvrViewMatrix.invert();
             }
-            // is rotation offset set? 
-            if (!Quaternion.IsIdentity(this.rotationQuaternion)) {
-                this.rotationQuaternion.toRotationMatrix(this._tempMatrix);
-                this._tempMatrix.multiplyToRef(this._webvrViewMatrix, this._webvrViewMatrix);
-            }
 
             this._updateCameraRotationMatrix();
             Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);

+ 9 - 8
src/Cameras/babylon.camera.ts

@@ -599,31 +599,32 @@
                     this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
                     this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
 
-   
-                   if (metrics.compensateDistortion) {
+
+                    if (metrics.compensateDistortion) {
                         this._rigCameras[0]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics);
                         this._rigCameras[1]._rigPostProcess = new VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics);
                     }
                     break;
                 case Camera.RIG_MODE_WEBVR:
                     if (rigParams.vrDisplay) {
-                        //var leftEye = rigParams.vrDisplay.getEyeParameters('left');
-                        //var rightEye = rigParams.vrDisplay.getEyeParameters('right');
+                        var leftEye = rigParams.vrDisplay.getEyeParameters('left');
+                        var rightEye = rigParams.vrDisplay.getEyeParameters('right');
 
                         //Left eye
                         this._rigCameras[0].viewport = new Viewport(0, 0, 0.5, 1.0);
                         this._rigCameras[0].setCameraRigParameter("left", true);
+                        this._rigCameras[0].setCameraRigParameter("eyeParameters", leftEye);
                         this._rigCameras[0].setCameraRigParameter("frameData", rigParams.frameData);
                         this._rigCameras[0].setCameraRigParameter("parentCamera", rigParams.parentCamera);
-                        //this._rigCameras[0].setCameraRigParameter('eyeParameters', leftEye);
                         this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new Matrix();
                         this._rigCameras[0].getProjectionMatrix = this._getWebVRProjectionMatrix;
                         this._rigCameras[0]._getViewMatrix = this._getWebVRViewMatrix;
                         this._rigCameras[0]._isSynchronizedViewMatrix = this._isSynchronizedViewMatrix;
                         this._rigCameras[0]._updateCameraRotationMatrix = this._updateCameraRotationMatrix;
+
                         //Right eye
                         this._rigCameras[1].viewport = new Viewport(0.5, 0, 0.5, 1.0);
-                        //this._rigCameras[1].setCameraRigParameter('eyeParameters', rightEye);
+                        this._rigCameras[1].setCameraRigParameter('eyeParameters', rightEye);
                         this._rigCameras[1].setCameraRigParameter("frameData", rigParams.frameData);
                         this._rigCameras[1].setCameraRigParameter("parentCamera", rigParams.parentCamera);
                         this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new Matrix();
@@ -646,9 +647,9 @@
             this._cameraRigParams.vrWorkMatrix.multiplyToRef(this._cameraRigParams.vrHMatrix, this._projectionMatrix);
             return this._projectionMatrix;
         }
-        
+
         protected _updateCameraRotationMatrix() {
-           // only here for webvr
+            // only here for webvr
         }
         /**
          * This function MUST be overwritten by the different WebVR cameras available.

+ 8 - 0
src/Cameras/babylon.targetCamera.ts

@@ -177,6 +177,14 @@ module BABYLON {
                 this.rotation.x += this.cameraRotation.x;
                 this.rotation.y += this.cameraRotation.y;
 
+                //rotate, if quaternion is set and rotation was used
+                if (this.rotationQuaternion) {
+                    var len = this.rotation.length();
+                    if (len) {
+                        Quaternion.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this.rotationQuaternion);
+                    }
+                }
+
 
                 if (!this.noRotationConstraint) {
                     var limit = (Math.PI / 2) * 0.95;

+ 25 - 12
src/Tools/babylon.extendedGamepad.ts

@@ -39,7 +39,7 @@ module BABYLON {
         public rawPose: DevicePose; //GamepadPose;
 
         private _mesh: AbstractMesh; // a node that will be attached to this Gamepad
-        private _poseControlledCamera: PoseControlled;
+        private _poseControlledCamera: TargetCamera;
 
         constructor(public vrGamepad) {
             super(vrGamepad.id, vrGamepad.index, vrGamepad);
@@ -57,11 +57,11 @@ module BABYLON {
         public update() {
             super.update();
             // update this device's offset position from the attached camera, if provided
-            if (this._poseControlledCamera && this._poseControlledCamera.deviceScaleFactor) {
-                //this.position.copyFrom(this._poseControlledCamera.position);
-                //this.rotationQuaternion.copyFrom(this._poseControlledCamera.rotationQuaternion);
-                this.deviceScaleFactor = this._poseControlledCamera.deviceScaleFactor;
-            }
+            //if (this._poseControlledCamera && this._poseControlledCamera.deviceScaleFactor) {
+            //this.position.copyFrom(this._poseControlledCamera.position);
+            //this.rotationQuaternion.copyFrom(this._poseControlledCamera.rotationQuaternion);
+            //this.deviceScaleFactor = this._poseControlledCamera.deviceScaleFactor;
+            //}
             var pose: GamepadPose = this.vrGamepad.pose;
             this.updateFromDevice(pose);
 
@@ -84,10 +84,10 @@ module BABYLON {
                     this._calculatedPosition.addInPlace(this.position);
 
                     // scale the position using the scale factor, add the device's position
-                    if (this._poseControlledCamera) {
+                    /*if (this._poseControlledCamera) {
                         // this allows total positioning freedom - the device, the camera and the mesh can be individually controlled.
                         this._calculatedPosition.addInPlace(this._poseControlledCamera.position);
-                    }
+                    }*/
                 }
                 if (poseData.orientation) {
                     this.deviceRotationQuaternion.copyFromFloats(this.rawPose.orientation[0], this.rawPose.orientation[1], -this.rawPose.orientation[2], -this.rawPose.orientation[3]);
@@ -99,7 +99,22 @@ module BABYLON {
                     // if the camera is set, rotate to the camera's rotation
                     this.rotationQuaternion.multiplyToRef(this.deviceRotationQuaternion, this._calculatedRotation);
                     if (this._poseControlledCamera) {
-                        this._calculatedRotation.multiplyToRef(this._poseControlledCamera.rotationQuaternion, this._calculatedRotation);
+
+                        Matrix.ScalingToRef(1, 1, 1, Tmp.Matrix[1]);
+                        this._calculatedRotation.toRotationMatrix(Tmp.Matrix[0]);
+                        Matrix.TranslationToRef(this._calculatedPosition.x, this._calculatedPosition.y, this._calculatedPosition.z, Tmp.Matrix[2]);
+
+                        //Matrix.Identity().multiplyToRef(Tmp.Matrix[1], Tmp.Matrix[4]);
+                        Tmp.Matrix[1].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[5]);
+
+                        this._poseControlledCamera.getWorldMatrix().getTranslationToRef(Tmp.Vector3[0])
+
+                        Matrix.ComposeToRef(new Vector3(this.deviceScaleFactor, this.deviceScaleFactor, this.deviceScaleFactor), this._poseControlledCamera.rotationQuaternion, Tmp.Vector3[0], Tmp.Matrix[4]);
+                        Tmp.Matrix[5].multiplyToRef(Tmp.Matrix[2], Tmp.Matrix[1]);
+
+                        Tmp.Matrix[1].multiplyToRef(Tmp.Matrix[4], Tmp.Matrix[2]);
+                        Tmp.Matrix[2].decompose(Tmp.Vector3[0], this._calculatedRotation, this._calculatedPosition);
+
                     }
                 }
             }
@@ -107,15 +122,13 @@ module BABYLON {
 
 
         public attachToMesh(mesh: AbstractMesh) {
-            this._mesh = mesh;
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new Quaternion();
             }
         }
 
-        public attachToPoseControlledCamera(camera: PoseControlled) {
+        public attachToPoseControlledCamera(camera: TargetCamera) {
             this._poseControlledCamera = camera;
-            this.deviceScaleFactor = camera.deviceScaleFactor;
         }
 
         public detachMesh() {