123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- module BABYLON {
- /**
- * Defines the types of pose enabled controllers that are supported
- */
- export enum PoseEnabledControllerType {
- /**
- * HTC Vive
- */
- VIVE,
- /**
- * Oculus Rift
- */
- OCULUS,
- /**
- * Windows mixed reality
- */
- WINDOWS,
- /**
- * Samsung gear VR
- */
- GEAR_VR,
- /**
- * Google Daydream
- */
- DAYDREAM,
- /**
- * Generic
- */
- GENERIC
- }
- /**
- * Defines the MutableGamepadButton interface for the state of a gamepad button
- */
- export interface MutableGamepadButton {
- /**
- * Value of the button/trigger
- */
- value: number;
- /**
- * If the button/trigger is currently touched
- */
- touched: boolean;
- /**
- * If the button/trigger is currently pressed
- */
- pressed: boolean;
- }
- /**
- * Defines the ExtendedGamepadButton interface for a gamepad button which includes state provided by a pose controller
- * @hidden
- */
- export interface ExtendedGamepadButton extends GamepadButton {
- /**
- * If the button/trigger is currently pressed
- */
- readonly pressed: boolean;
- /**
- * If the button/trigger is currently touched
- */
- readonly touched: boolean;
- /**
- * Value of the button/trigger
- */
- readonly value: number;
- }
- /**
- * Defines the PoseEnabledControllerHelper object that is used initialize a gamepad as the controller type it is specified as (eg. windows mixed reality controller)
- */
- export class PoseEnabledControllerHelper {
- /**
- * Initializes a gamepad as the controller type it is specified as (eg. windows mixed reality controller)
- * @param vrGamepad the gamepad to initialized
- * @returns a vr controller of the type the gamepad identified as
- */
- public static InitiateController(vrGamepad: any) {
- // Oculus Touch
- if (vrGamepad.id.indexOf('Oculus Touch') !== -1) {
- return new OculusTouchController(vrGamepad);
- }
- // Windows Mixed Reality controllers
- else if (vrGamepad.id.indexOf(WindowsMotionController.GAMEPAD_ID_PREFIX) === 0) {
- return new WindowsMotionController(vrGamepad);
- }
- // HTC Vive
- else if (vrGamepad.id.toLowerCase().indexOf('openvr') !== -1) {
- return new ViveController(vrGamepad);
- }
- // Samsung/Oculus Gear VR or Oculus Go
- else if (vrGamepad.id.indexOf(GearVRController.GAMEPAD_ID_PREFIX) === 0 || vrGamepad.id.indexOf('Oculus Go') !== -1) {
- return new GearVRController(vrGamepad);
- }
- // Google Daydream
- else if (vrGamepad.id.indexOf(DaydreamController.GAMEPAD_ID_PREFIX) === 0) {
- return new DaydreamController(vrGamepad);
- }
- // Generic
- else {
- return new GenericController(vrGamepad);
- }
- }
- }
- /**
- * Defines the PoseEnabledController object that contains state of a vr capable controller
- */
- export class PoseEnabledController extends Gamepad implements PoseControlled {
- // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
- private _deviceRoomPosition = Vector3.Zero();
- private _deviceRoomRotationQuaternion = new Quaternion();
- /**
- * The device position in babylon space
- */
- public devicePosition = Vector3.Zero();
- /**
- * The device rotation in babylon space
- */
- public deviceRotationQuaternion = new Quaternion();
- /**
- * The scale factor of the device in babylon space
- */
- public deviceScaleFactor: number = 1;
- /**
- * (Likely devicePosition should be used instead) The device position in its room space
- */
- public position: Vector3;
- /**
- * (Likely deviceRotationQuaternion should be used instead) The device rotation in its room space
- */
- public rotationQuaternion: Quaternion;
- /**
- * The type of controller (Eg. Windows mixed reality)
- */
- public controllerType: PoseEnabledControllerType;
- protected _calculatedPosition: Vector3;
- private _calculatedRotation: Quaternion;
- /**
- * The raw pose from the device
- */
- public rawPose: DevicePose; //GamepadPose;
- /**
- * Internal, the mesh attached to the controller
- */
- public _mesh: Nullable<AbstractMesh>; // a node that will be attached to this Gamepad
- private _poseControlledCamera: TargetCamera;
- private _leftHandSystemQuaternion: Quaternion = new Quaternion();
- /**
- * Internal, matrix used to convert room space to babylon space
- */
- public _deviceToWorld = Matrix.Identity();
- /**
- * Node to be used when casting a ray from the controller
- */
- public _pointingPoseNode:Nullable<AbstractMesh> = null;
- /**
- * Name of the child mesh that can be used to cast a ray from the controller
- */
- public static readonly POINTING_POSE = "POINTING_POSE";
- /**
- * Creates a new PoseEnabledController from a gamepad
- * @param browserGamepad the gamepad that the PoseEnabledController should be created from
- */
- constructor(browserGamepad: any) {
- super(browserGamepad.id, browserGamepad.index, browserGamepad);
- this.type = Gamepad.POSE_ENABLED;
- this.controllerType = PoseEnabledControllerType.GENERIC;
- this.position = Vector3.Zero();
- this.rotationQuaternion = new Quaternion();
- this._calculatedPosition = Vector3.Zero();
- this._calculatedRotation = new Quaternion();
- Quaternion.RotationYawPitchRollToRef(Math.PI, 0, 0, this._leftHandSystemQuaternion);
- }
- private _workingMatrix = Matrix.Identity();
- /**
- * Updates the state of the pose enbaled controller and mesh based on the current position and rotation of the controller
- */
- public update() {
- super.update();
- var pose: GamepadPose = this.browserGamepad.pose;
- this.updateFromDevice(pose);
- Vector3.TransformCoordinatesToRef(this._calculatedPosition, this._deviceToWorld, this.devicePosition)
- this._deviceToWorld.getRotationMatrixToRef(this._workingMatrix);
- Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
- this.deviceRotationQuaternion.multiplyInPlace(this._calculatedRotation)
- if (this._mesh) {
- this._mesh.position.copyFrom(this.devicePosition);
- if (this._mesh.rotationQuaternion) {
- this._mesh.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
- }
- }
- }
- /**
- * Updates the state of the pose enbaled controller based on the raw pose data from the device
- * @param poseData raw pose fromthe device
- */
- updateFromDevice(poseData: DevicePose) {
- if (poseData) {
- this.rawPose = poseData;
- if (poseData.position) {
- this._deviceRoomPosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
- if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
- this._deviceRoomPosition.z *= -1;
- }
- this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
- this._calculatedPosition.addInPlace(this.position);
- }
- let pose = this.rawPose;
- if (poseData.orientation && pose.orientation) {
- this._deviceRoomRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
- if (this._mesh) {
- if (this._mesh.getScene().useRightHandedSystem) {
- this._deviceRoomRotationQuaternion.z *= -1;
- this._deviceRoomRotationQuaternion.w *= -1;
- } else {
- this._deviceRoomRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this._deviceRoomRotationQuaternion);
- }
- }
- // if the camera is set, rotate to the camera's rotation
- this._deviceRoomRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
- }
- }
- }
- /**
- * @hidden
- */
- public _meshAttachedObservable = new Observable<AbstractMesh>()
- /**
- * Attaches a mesh to the controller
- * @param mesh the mesh to be attached
- */
- public attachToMesh(mesh: AbstractMesh) {
- if (this._mesh) {
- this._mesh.parent = null;
- }
- this._mesh = mesh;
- if (this._poseControlledCamera) {
- this._mesh.parent = this._poseControlledCamera;
- }
- if (!this._mesh.rotationQuaternion) {
- this._mesh.rotationQuaternion = new Quaternion();
- }
- this._meshAttachedObservable.notifyObservers(mesh);
- }
- /**
- * Attaches the controllers mesh to a camera
- * @param camera the camera the mesh should be attached to
- */
- public attachToPoseControlledCamera(camera: TargetCamera) {
- this._poseControlledCamera = camera;
- if (this._mesh) {
- this._mesh.parent = this._poseControlledCamera;
- }
- }
- /**
- * Disposes of the controller
- */
- public dispose() {
- if (this._mesh) {
- this._mesh.dispose();
- }
- this._mesh = null;
- super.dispose();
- }
- /**
- * The mesh that is attached to the controller
- */
- public get mesh(): Nullable<AbstractMesh> {
- return this._mesh;
- }
- /**
- * Gets the ray of the controller in the direction the controller is pointing
- * @param length the length the resulting ray should be
- * @returns a ray in the direction the controller is pointing
- */
- public getForwardRay(length = 100): Ray {
- if (!this.mesh) {
- return new Ray(Vector3.Zero(), new Vector3(0, 0, 1), length);
- }
- var m = this._pointingPoseNode ? this._pointingPoseNode.getWorldMatrix() : this.mesh.getWorldMatrix();
- var origin = m.getTranslation();
- var forward = new Vector3(0, 0, -1);
- var forwardWorld = Vector3.TransformNormal(forward, m);
- var direction = Vector3.Normalize(forwardWorld);
- return new Ray(origin, direction, length);
- }
- }
- }
|