瀏覽代碼

Merge pull request #6052 from TrevorDev/deviceOrientationDrag

option to enable horizontal dragging when orientation camera is using…
David Catuhe 6 年之前
父節點
當前提交
0569c6c5df
共有 2 個文件被更改,包括 43 次插入5 次删除
  1. 20 4
      src/Cameras/Inputs/freeCameraMouseInput.ts
  2. 23 1
      src/Cameras/deviceOrientationCamera.ts

+ 20 - 4
src/Cameras/Inputs/freeCameraMouseInput.ts

@@ -1,4 +1,4 @@
-import { Observer, EventState } from "../../Misc/observable";
+import { Observer, EventState, Observable } from "../../Misc/observable";
 import { serialize } from "../../Misc/decorators";
 import { Nullable } from "../../types";
 import { ICameraInput, CameraInputTypes } from "../../Cameras/cameraInputsManager";
@@ -32,6 +32,15 @@ export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {
     private previousPosition: Nullable<{ x: number, y: number }> = null;
 
     /**
+     * Observable for when a pointer move event occurs containing the move offset
+     */
+    public onPointerMovedObservable = new Observable<{ offsetX: number, offsetY: number }>();
+    /**
+     * @hidden
+     * If the camera should be rotated automatically based on pointer movement
+     */
+    public _allowCameraRotation = true;
+    /**
      * Manage the mouse inputs to control the movement of a free camera.
      * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
      * @param touchEnabled Defines if touch is enabled or not
@@ -105,12 +114,15 @@ export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {
                     }
 
                     var offsetX = evt.clientX - this.previousPosition.x;
+                    var offsetY = evt.clientY - this.previousPosition.y;
                     if (this.camera.getScene().useRightHandedSystem) { offsetX *= -1; }
                     if (this.camera.parent && this.camera.parent._getWorldMatrixDeterminant() < 0) { offsetX *= -1; }
-                    this.camera.cameraRotation.y += offsetX / this.angularSensibility;
 
-                    var offsetY = evt.clientY - this.previousPosition.y;
-                    this.camera.cameraRotation.x += offsetY / this.angularSensibility;
+                    if (this._allowCameraRotation) {
+                        this.camera.cameraRotation.y += offsetX / this.angularSensibility;
+                        this.camera.cameraRotation.x += offsetY / this.angularSensibility;
+                    }
+                    this.onPointerMovedObservable.notifyObservers({offsetX: offsetX, offsetY: offsetY});
 
                     this.previousPosition = {
                         x: evt.clientX,
@@ -179,6 +191,10 @@ export class FreeCameraMouseInput implements ICameraInput<FreeCamera> {
                 element.removeEventListener("contextmenu", <EventListener>this.onContextMenu);
             }
 
+            if (this.onPointerMovedObservable) {
+                this.onPointerMovedObservable.clear();
+            }
+
             this._observer = null;
             this._onMouseMove = null;
             this.previousPosition = null;

+ 23 - 1
src/Cameras/deviceOrientationCamera.ts

@@ -18,6 +18,7 @@ export class DeviceOrientationCamera extends FreeCamera {
 
     private _initialQuaternion: Quaternion;
     private _quaternionCache: Quaternion;
+    private _tmpDragQuaternion = new Quaternion();
 
     /**
      * Creates a new device orientation camera
@@ -33,11 +34,32 @@ export class DeviceOrientationCamera extends FreeCamera {
         // When the orientation sensor fires it's first event, disable mouse input
         if (this.inputs._deviceOrientationInput) {
             this.inputs._deviceOrientationInput._onDeviceOrientationChangedObservable.addOnce(() => {
-                this.inputs.removeMouse();
+                if (this.inputs._mouseInput) {
+                    this.inputs._mouseInput._allowCameraRotation = false;
+                    this.inputs._mouseInput.onPointerMovedObservable.add((e) => {
+                        if (this._dragFactor != 0) {
+                            if (!this._initialQuaternion) {
+                                this._initialQuaternion = new Quaternion();
+                            }
+                            // Rotate the initial space around the y axis to allow users to "turn around" via touch/mouse
+                            Quaternion.FromEulerAnglesToRef(0, e.offsetX * this._dragFactor, 0, this._tmpDragQuaternion);
+                            this._initialQuaternion.multiplyToRef(this._tmpDragQuaternion, this._initialQuaternion);
+                        }
+                    });
+                }
             });
         }
     }
 
+    private _dragFactor = 0;
+    /**
+     * Enabled turning on the y axis when the orientation sensor is active
+     * @param dragFactor the factor that controls the turn speed (default: 1/300)
+     */
+    public enableHorizontalDragging(dragFactor= 1 / 300) {
+        this._dragFactor = dragFactor;
+    }
+
     /**
      * Gets the current instance class name ("DeviceOrientationCamera").
      * This helps avoiding instanceof at run time.