浏览代码

Merge pull request #3218 from BabylonJS/davrous

Adding interactivity support / simulatePointerDown
David Rousset 7 年之前
父节点
当前提交
cd73dd39a5
共有 2 个文件被更改,包括 10957 次插入10867 次删除
  1. 10816 10811
      dist/preview release/babylon.d.ts
  2. 141 56
      src/Cameras/VR/babylon.vrExperienceHelper.ts

文件差异内容过多而无法显示
+ 10816 - 10811
dist/preview release/babylon.d.ts


+ 141 - 56
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -55,16 +55,20 @@ module BABYLON {
         private _rotationAngle: number = 0;
         private _haloCenter = new Vector3(0, 0, 0);
         private _gazeTracker: BABYLON.Mesh;
-        private _padSensibilityUp = 0.7;
-        private _padSensibilityDown = 0.3;
-        private _leftLaserPointer: Mesh;
-        private _rightLaserPointer: Mesh;
+        private _padSensibilityUp = 0.65;
+        private _padSensibilityDown = 0.35;
+        private _leftLaserPointer: Nullable<Mesh>;
+        private _rightLaserPointer: Nullable<Mesh>;
         private _currentMeshSelected: Nullable<AbstractMesh>;
         public onNewMeshSelected = new Observable<AbstractMesh>();
 
         private _meshSelectionPredicate: (mesh: AbstractMesh) => boolean;
         public meshSelectionPredicate: (mesh: AbstractMesh) => boolean;
 
+        private _currentHit: Nullable<PickingInfo>;
+        private _pointerDownOnMeshAsked = false;
+        private _isActionableMesh = false;
+
         public get deviceOrientationCamera(): DeviceOrientationCamera {
             return this._deviceOrientationCamera;
         }
@@ -92,7 +96,7 @@ module BABYLON {
 
             if (!this._scene.activeCamera || isNaN(this._scene.activeCamera.position.x)) {
                 this._position = new BABYLON.Vector3(0, 2, 0);
-                this._deviceOrientationCamera = new BABYLON.DeviceOrientationCamera("deviceOrientationVRHelper", new BABYLON.Vector3(0, 2, 0), scene);
+                this._deviceOrientationCamera = new BABYLON.DeviceOrientationCamera("deviceOrientationVRHelper", new BABYLON.Vector3(0, 1.7, 0), scene);
             }
             else {
                 this._position = this._scene.activeCamera.position.clone();
@@ -508,10 +512,10 @@ module BABYLON {
                     if (stateObject.value === 1) {
                         laserPointer.isVisible = !laserPointer.isVisible;
                         // Laser pointer can only be active on left or right, not both at the same time
-                        if (webVRController.hand === "left") {
+                        if (webVRController.hand === "left" && this._rightLaserPointer) {
                             this._rightLaserPointer.isVisible = false;
                         }
-                        else {
+                        else if (this._leftLaserPointer) {
                             this._leftLaserPointer.isVisible = false;
                         }
                     }
@@ -520,21 +524,25 @@ module BABYLON {
                     if (!this._teleportationRequestInitiated) {
                         if (stateObject.y < -this._padSensibilityUp) {
                             // If laser pointer wasn't enabled yet
-                            if (webVRController.hand === "left") {
+                            if (webVRController.hand === "left" &&  this._leftLaserPointer) {
                                 this._leftLaserPointer.isVisible = true;
-                                this._rightLaserPointer.isVisible = false;
+                                if (this._rightLaserPointer) {
+                                    this._rightLaserPointer.isVisible = false;
+                                }
                             }
-                            else {
-                                this._leftLaserPointer.isVisible = false;
+                            else if (this._rightLaserPointer) {
                                 this._rightLaserPointer.isVisible = true;
+                                if (this._leftLaserPointer) {
+                                    this._leftLaserPointer.isVisible = false;
+                                }
                             }
                             this._teleportationRequestInitiated = true;
                         }
                     }
                     else {
                         // Listening to the proper controller values changes to confirm teleportation
-                        if ((webVRController.hand === "left" && this._leftLaserPointer.isVisible) 
-                            || (webVRController.hand === "right" && this._rightLaserPointer.isVisible)) {
+                        if ((webVRController.hand === "left" && this._leftLaserPointer && this._leftLaserPointer.isVisible) 
+                            || (webVRController.hand === "right" && this._rightLaserPointer && this._rightLaserPointer.isVisible)) {
                             if (stateObject.y > -this._padSensibilityDown) {
                                 if (this._teleportationAllowed) {
                                     this._teleportationAllowed = false;
@@ -572,6 +580,22 @@ module BABYLON {
                         }
                     }
                 });
+                webVRController.onTriggerStateChangedObservable.add((stateObject) => {
+                    if (!this._pointerDownOnMeshAsked) {
+                        if (stateObject.value > this._padSensibilityUp) {
+                            this._pointerDownOnMeshAsked = true;
+                            if (this._currentMeshSelected && this._currentHit) {
+                                this._scene.simulatePointerDown(this._currentHit);
+                            }
+                        }
+                    }
+                    else if (stateObject.value < this._padSensibilityDown) {
+                        if (this._currentMeshSelected && this._currentHit) {
+                            this._scene.simulatePointerUp(this._currentHit);
+                        }
+                        this._pointerDownOnMeshAsked = false;
+                    }
+                });
             }
         }
 
@@ -583,7 +607,7 @@ module BABYLON {
 
             var targetMat = new BABYLON.StandardMaterial("targetMat", this._scene);
             targetMat.specularColor = BABYLON.Color3.Black();
-            targetMat.emissiveColor = BABYLON.Color3.White();
+            targetMat.emissiveColor = new BABYLON.Color3(0.7, 0.7, 0.7)
             targetMat.backFaceCulling = false;
             this._gazeTracker.material = targetMat;
         }
@@ -746,61 +770,83 @@ module BABYLON {
             this._scene.beginAnimation(this.currentVRCamera, 0, 6, false, 1);
         }
 
-        private _moveTeleportationSelectorTo(coordinates: Vector3) {
-            this._teleportationAllowed = true;
-            if (this._teleportationRequestInitiated) {
-                this._displayTeleportationCircle();
-            }
-            else {
-                this._hideTeleportationCircle();
+        private _moveTeleportationSelectorTo(hit: PickingInfo) {
+            if (hit.pickedPoint) {
+                this._teleportationAllowed = true;
+                if (this._teleportationRequestInitiated) {
+                    this._displayTeleportationCircle();
+                }
+                else {
+                    this._hideTeleportationCircle();
+                }
+                this._haloCenter.copyFrom(hit.pickedPoint);
+                this._teleportationCircle.position.copyFrom(hit.pickedPoint);
+                var pickNormal = hit.getNormal();
+                if (pickNormal) {
+                    var axis1 = BABYLON.Vector3.Cross(BABYLON.Axis.Y, pickNormal);
+                    var axis2 = BABYLON.Vector3.Cross(pickNormal, axis1);
+                    BABYLON.Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, this._teleportationCircle.rotation);
+                }
+                this._teleportationCircle.position.y += 0.1;
             }
-            this._haloCenter.copyFrom(coordinates);
-            this._teleportationCircle.position = coordinates;
-            this._teleportationCircle.position.y += 0.001;
         }
 
         private _teleportCamera() {
             this.currentVRCamera.animations = [];
         
-            var animationCameraTeleportation = new BABYLON.Animation("animationCameraTeleportation", "position.x", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
+            var animationCameraTeleportationX = new BABYLON.Animation("animationCameraTeleportationX", "position.x", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                 BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
         
-            var animationCameraTeleportationKeys = [];
-            animationCameraTeleportationKeys.push({
+            var animationCameraTeleportationXKeys = [];
+            animationCameraTeleportationXKeys.push({
                 frame: 0,
                 value: this.currentVRCamera.position.x
             });
-            animationCameraTeleportationKeys.push({
+            animationCameraTeleportationXKeys.push({
                 frame: 11,
                 value: this._haloCenter.x
             });
         
-            animationCameraTeleportation.setKeys(animationCameraTeleportationKeys);
-        
             var easingFunction = new BABYLON.CircleEase();
             easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
-            animationCameraTeleportation.setEasingFunction(easingFunction);
+
+            animationCameraTeleportationX.setKeys(animationCameraTeleportationXKeys);
+            animationCameraTeleportationX.setEasingFunction(easingFunction);
+            this.currentVRCamera.animations.push(animationCameraTeleportationX);
+
+            var animationCameraTeleportationY = new BABYLON.Animation("animationCameraTeleportationY", "position.y", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
+            BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
+    
+            var animationCameraTeleportationYKeys = [];
+            animationCameraTeleportationYKeys.push({
+                frame: 0,
+                value: this.currentVRCamera.position.y
+            });
+            animationCameraTeleportationYKeys.push({
+                frame: 11,
+                value: this._haloCenter.y+1.7
+            });
         
-            this.currentVRCamera.animations.push(animationCameraTeleportation);
+            animationCameraTeleportationY.setKeys(animationCameraTeleportationYKeys);
+            animationCameraTeleportationY.setEasingFunction(easingFunction);
+            this.currentVRCamera.animations.push(animationCameraTeleportationY);
         
-            var animationZoomIn2 = new BABYLON.Animation("animationZoomIn", "position.z", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
+            var animationCameraTeleportationZ = new BABYLON.Animation("animationCameraTeleportationZ", "position.z", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                 BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
         
-            var keys2 = [];
-            keys2.push({
+            var animationCameraTeleportationZKeys = [];
+            animationCameraTeleportationZKeys.push({
                 frame: 0,
                 value: this.currentVRCamera.position.z
             });
-            keys2.push({
+            animationCameraTeleportationZKeys.push({
                 frame: 11,
                 value: this._haloCenter.z
             });
         
-            animationZoomIn2.setKeys(keys2);
-        
-            animationZoomIn2.setEasingFunction(easingFunction);
-        
-            this.currentVRCamera.animations.push(animationZoomIn2);
+            animationCameraTeleportationZ.setKeys(animationCameraTeleportationZKeys);
+            animationCameraTeleportationZ.setEasingFunction(easingFunction);
+            this.currentVRCamera.animations.push(animationCameraTeleportationZ);
         
             this._postProcessMove.animations = [];
         
@@ -856,9 +902,11 @@ module BABYLON {
 
         private _castRayAndSelectObject () {
             var ray;
-            if (!(<WebVRFreeCamera>this.currentVRCamera).rightController || !(<WebVRFreeCamera>this.currentVRCamera).leftController || 
-                ((this._leftLaserPointer && !this._leftLaserPointer.isVisible) && (this._rightLaserPointer && !this._rightLaserPointer.isVisible))) {
-                ray = this.currentVRCamera.getForwardRay();
+            if ((!(<WebVRFreeCamera>this.currentVRCamera).rightController && !(<WebVRFreeCamera>this.currentVRCamera).leftController) || 
+                (this._leftLaserPointer && !this._leftLaserPointer.isVisible && !this._rightLaserPointer) || 
+                (this._rightLaserPointer && !this._rightLaserPointer.isVisible && !this._leftLaserPointer) || 
+                (this._rightLaserPointer && this._leftLaserPointer && !this._rightLaserPointer.isVisible && !this._leftLaserPointer.isVisible)) {
+                    ray = this.currentVRCamera.getForwardRay();
                 
             } else {
                 if (this._leftLaserPointer && this._leftLaserPointer.isVisible) {
@@ -873,9 +921,13 @@ module BABYLON {
 
             // Moving the gazeTracker on the mesh face targetted
             if (hit && hit.pickedPoint) {
-                this._gazeTracker.scaling.x = hit.distance;
-                this._gazeTracker.scaling.y = hit.distance;
-                this._gazeTracker.scaling.z = hit.distance;
+                var multiplier = 1;
+                if (this._isActionableMesh) {
+                    multiplier = 3;
+                }
+                this._gazeTracker.scaling.x = hit.distance * multiplier;
+                this._gazeTracker.scaling.y = hit.distance * multiplier;
+                this._gazeTracker.scaling.z = hit.distance * multiplier;
         
                 var pickNormal = hit.getNormal();
                 // To avoid z-fighting
@@ -883,7 +935,7 @@ module BABYLON {
                 
                 if (pickNormal) {
                     var axis1 = BABYLON.Vector3.Cross(BABYLON.Axis.Y, pickNormal);
-                    var axis2 = BABYLON.Vector3.Cross( pickNormal, axis1);
+                    var axis2 = BABYLON.Vector3.Cross(pickNormal, axis1);
                     BABYLON.Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, this._gazeTracker.rotation);
                 }
                 this._gazeTracker.position.copyFrom(hit.pickedPoint);
@@ -906,7 +958,7 @@ module BABYLON {
                 else {
                     this._gazeTracker.position.z -= deltaFighting;
                 }
-                ray.length = hit.distance;
+
                 // Changing the size of the laser pointer based on the distance from the targetted point
                 if (this._rightLaserPointer && this._rightLaserPointer.isVisible) {
                     this._rightLaserPointer.scaling.y = hit.distance;
@@ -919,27 +971,60 @@ module BABYLON {
             }
         
             if (hit && hit.pickedMesh) {
+                this._currentHit = hit;
                 // The object selected is the floor, we're in a teleportation scenario
                 if (hit.pickedMesh.name.indexOf(this._floorMeshName) !== -1 && hit.pickedPoint) {
                     // Moving the teleportation area to this targetted point
-                    this._moveTeleportationSelectorTo(hit.pickedPoint)
+                    this._moveTeleportationSelectorTo(hit)
                     return;
                 }
                 // If not, we're in a selection scenario
                 this._hideTeleportationCircle();
                 this._teleportationAllowed = false;
-                if (hit.pickedMesh !== this._currentMeshSelected && this.meshSelectionPredicate(hit.pickedMesh)) {
-                    this._currentMeshSelected = hit.pickedMesh;
-                    this.onNewMeshSelected.notifyObservers(this._currentMeshSelected);
-                }
-                else {
-                    this._currentMeshSelected = null;
+                if (hit.pickedMesh !== this._currentMeshSelected) {
+                    if (this.meshSelectionPredicate(hit.pickedMesh)) {
+                        this._currentMeshSelected = hit.pickedMesh;
+                        if (hit.pickedMesh.isPickable && hit.pickedMesh.actionManager) {
+                            this.changeGazeColor(new BABYLON.Color3(0,0,1));
+                            this.changeLaserColor(new BABYLON.Color3(0.2,0.2,1));
+                            this._isActionableMesh = true;
+                        }
+                        else {
+                            this.changeGazeColor(new BABYLON.Color3(0.7,0.7,0.7));
+                            this.changeLaserColor(new BABYLON.Color3(0.7,0.7,0.7));
+                            this._isActionableMesh = false;
+                        }
+                        this.onNewMeshSelected.notifyObservers(this._currentMeshSelected);
+                    }
+                    else {
+                        this._currentMeshSelected = null;
+                        this.changeGazeColor(new BABYLON.Color3(0.7,0.7,0.7));
+                        this.changeLaserColor(new BABYLON.Color3(0.7,0.7,0.7));
+                    }
                 }
             }
             else {
+                this._currentHit = null;
                 this._currentMeshSelected = null;
                 this._teleportationAllowed = false;
                 this._hideTeleportationCircle();
+                this.changeGazeColor(new BABYLON.Color3(0.7,0.7,0.7));
+                this.changeLaserColor(new BABYLON.Color3(0.7,0.7,0.7));
+            }
+        }
+
+        public changeLaserColor(color: Color3) {
+            if (this._leftLaserPointer && this._leftLaserPointer.material) {
+                (<StandardMaterial>this._leftLaserPointer.material).emissiveColor = color;
+            }
+            if (this._rightLaserPointer && this._rightLaserPointer.material) {
+                (<StandardMaterial>this._rightLaserPointer.material).emissiveColor = color;
+            }
+        }
+
+        public changeGazeColor(color: Color3) {
+            if (this._gazeTracker.material) {
+                (<StandardMaterial>this._gazeTracker.material).emissiveColor = color;
             }
         }