瀏覽代碼

Added two new VR cameras. The VRDeviceOrientionCamera can be used with a Google Cardboard or with any VR headset with mobile. The WebVRCamera is a specific camera which works with browsers compatibles with WebVR API (special builds of Firefox and Chrome)

Yannick Comte 11 年之前
父節點
當前提交
d62610038d

+ 36 - 0
Babylon/Cameras/babylon.vrDeviceOrientationCamera.js

@@ -0,0 +1,36 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var VRDeviceOrientationCamera = (function (_super) {
+        __extends(VRDeviceOrientationCamera, _super);
+        function VRDeviceOrientationCamera(name, position, scene) {
+            _super.call(this, name, position, scene);
+            this._alpha = 0;
+            this._beta = 0;
+            this._gamma = 0;
+        }
+        VRDeviceOrientationCamera.prototype._onOrientationEvent = function (evt) {
+            this._alpha = +evt.alpha | 0;
+            this._beta = +evt.beta | 0;
+            this._gamma = +evt.gamma | 0;
+
+            if (this._gamma < 0) {
+                this._gamma = 90 + this._gamma;
+            } else {
+                // Incline it in the correct angle.
+                this._gamma = 270 - this._gamma;
+            }
+
+            this.rotation.x = this._gamma / 180.0 * Math.PI;
+            this.rotation.y = -this._alpha / 180.0 * Math.PI;
+            this.rotation.z = this._beta / 180.0 * Math.PI;
+        };
+        return VRDeviceOrientationCamera;
+    })(BABYLON.OculusCamera);
+    BABYLON.VRDeviceOrientationCamera = VRDeviceOrientationCamera;
+})(BABYLON || (BABYLON = {}));

+ 29 - 0
Babylon/Cameras/babylon.vrDeviceOrientationCamera.ts

@@ -0,0 +1,29 @@
+module BABYLON {
+	export class VRDeviceOrientationCamera extends BABYLON.OculusCamera {
+		public _alpha = 0;
+		public _beta = 0;
+		public _gamma = 0;
+	
+		constructor(name: string, position: Vector3, scene: Scene) {
+			super(name, position, scene);
+		}
+
+		private _onOrientationEvent(evt: DeviceOrientationEvent): void {
+            this._alpha = +evt.alpha|0;
+            this._beta = +evt.beta|0;
+            this._gamma = +evt.gamma|0;
+
+            if (this._gamma < 0) {
+            	this._gamma = 90 + this._gamma;
+            }
+            else {
+				// Incline it in the correct angle.
+            	this._gamma = 270 - this._gamma;
+            }
+
+            this.rotation.x = this._gamma / 180.0 * Math.PI;   
+			this.rotation.y = -this._alpha / 180.0 * Math.PI;	
+			this.rotation.z	= this._beta / 180.0 * Math.PI;		
+        }
+	}
+}

+ 79 - 0
Babylon/Cameras/babylon.webVRCamera.js

@@ -0,0 +1,79 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var WebVRCamera = (function (_super) {
+        __extends(WebVRCamera, _super);
+        function WebVRCamera(name, position, scene) {
+            _super.call(this, name, position, scene);
+            this._hmdDevice = null;
+            this._sensorDevice = null;
+            this._cacheState = null;
+            this._cacheQuaternion = new BABYLON.Quaternion();
+            this._cacheRotation = BABYLON.Vector3.Zero();
+            this._vrEnabled = false;
+            this._getWebVRDevices = this._getWebVRDevices.bind(this);
+        }
+        WebVRCamera.prototype._getWebVRDevices = function (devices) {
+            var size = devices.length;
+            var i = 0;
+
+            // Reset devices.
+            this._sensorDevice = null;
+            this._hmdDevice = null;
+
+            while (i > 0 && this._hmdDevice === null) {
+                if (devices[i] instanceof HMDVRDevice) {
+                    this._hmdDevice = devices[i];
+                }
+                i++;
+            }
+
+            i = 0;
+
+            while (i > 0 && this._sensorDevice === null) {
+                if (devices[i] instanceof PositionSensorVRDevice && (!this._hmdDevice || devices[i].hardwareUnitId === hmdDevice.hardwareUnitId)) {
+                    this._sensorDevice = devices[i];
+                }
+                i++;
+            }
+
+            this._vrEnabled = this._sensorDevice && this._hmdDevice ? true : false;
+        };
+
+        WebVRCamera.prototype._update = function () {
+            if (this._vrEnabled) {
+                this._cacheState = this._sensorDevice.getState();
+                this._cacheQuaternion.copyFromFloats(this._cacheState.orientation.x, this._cacheState.orientation.y, this._cacheState.orientation.z, this._cacheState.orientation.w);
+                this._cacheQuaternion.toEulerAnglesToRef(this._cacheRotation);
+
+                this.rotation.x = -this._cacheRotation.z;
+                this.rotation.y = -this._cacheRotation.y;
+                this.rotation.z = this._cacheRotation.x;
+            }
+
+            _super.prototype._update.call(this);
+        };
+
+        WebVRCamera.prototype.attachControl = function (element, noPreventDefault) {
+            _super.prototype.attachControl.call(this, element, noPreventDefault);
+
+            if (navigator.getVRDevices) {
+                navigator.getVRDevices().then(this._getWebVRDevices);
+            } else if (navigator.mozGetVRDevices) {
+                navigator.mozGetVRDevices(this._getWebVRDevices);
+            }
+        };
+
+        WebVRCamera.prototype.detachControl = function (element) {
+            _super.prototype.detachControl.call(this, element);
+            this._vrEnabled = false;
+        };
+        return WebVRCamera;
+    })(BABYLON.OculusCamera);
+    BABYLON.WebVRCamera = WebVRCamera;
+})(BABYLON || (BABYLON = {}));

+ 74 - 0
Babylon/Cameras/babylon.webVRCamera.ts

@@ -0,0 +1,74 @@
+module BABYLON {
+	export class WebVRCamera extends BABYLON.OculusCamera {
+		public _hmdDevice = null;
+		public _sensorDevice = null;
+		public _cacheState = null;
+		public _cacheQuaternion = new BABYLON.Quaternion();
+		public _cacheRotation = BABYLON.Vector3.Zero();
+		public _vrEnabled = false;
+	
+		constructor(name: string, position: Vector3, scene: Scene) {
+			super(name, position, scene);
+			this._getWebVRDevices = this._getWebVRDevices.bind(this);
+		}
+
+		private _getWebVRDevices(devices: Array):void {
+			var size = devices.length;
+			var i = 0;
+
+			// Reset devices.
+			this._sensorDevice = null;
+			this._hmdDevice = null;
+
+			// Search for a HmdDevice.
+			while (i > 0 && this._hmdDevice === null) {
+				if (devices[i] instanceof HMDVRDevice) {
+					this._hmdDevice = devices[i];       
+				}
+				i++;
+			}
+
+			i = 0;
+
+			// Search for a
+			while (i > 0 && this._sensorDevice === null) {
+				if (devices[i] instanceof PositionSensorVRDevice && (!this._hmdDevice || devices[i].hardwareUnitId === hmdDevice.hardwareUnitId)) {
+					this._sensorDevice = devices[i];
+				}
+				i++;
+			}
+
+			this._vrEnabled = this._sensorDevice && this._hmdDevice ? true : false;
+		}
+
+		public _update(): void {
+			if (this._vrEnabled) {
+				this._cacheState = this._sensorDevice.getState();
+				this._cacheQuaternion.copyFromFloats(this._cacheState.orientation.x, this._cacheState.orientation.y, this._cacheState.orientation.z, this._cacheState.orientation.w);
+				this._cacheQuaternion.toEulerAnglesToRef(this._cacheRotation);
+
+				this.rotation.x = -this._cacheRotation.z;
+				this.rotation.y = -this._cacheRotation.y;
+				this.rotation.z = this._cacheRotation.x;
+			}
+
+			super._update();
+		}
+
+		public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
+			super.attachControl(element, noPreventDefault);
+
+			if (navigator.getVRDevices) {
+				navigator.getVRDevices().then(this._getWebVRDevices);
+			} 
+			else if (navigator.mozGetVRDevices) {
+				navigator.mozGetVRDevices(this._getWebVRDevices);
+			}
+		}
+
+		public detachControl(element: HTMLElement): void {
+			super.detachControl(element);
+			this._vrEnabled = false;
+		}
+	}
+}