babylon.poseEnabledController.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. module BABYLON {
  2. export enum PoseEnabledControllerType {
  3. VIVE,
  4. OCULUS,
  5. WINDOWS,
  6. GENERIC
  7. }
  8. export interface MutableGamepadButton {
  9. value: number;
  10. touched: boolean;
  11. pressed: boolean;
  12. }
  13. export interface ExtendedGamepadButton extends GamepadButton {
  14. readonly pressed: boolean;
  15. readonly touched: boolean;
  16. readonly value: number;
  17. }
  18. export class PoseEnabledControllerHelper {
  19. public static InitiateController(vrGamepad: any) {
  20. // Oculus Touch
  21. if (vrGamepad.id.indexOf('Oculus Touch') !== -1) {
  22. return new OculusTouchController(vrGamepad);
  23. }
  24. // Windows Mixed Reality controllers
  25. else if (vrGamepad.id.indexOf(WindowsMotionController.GAMEPAD_ID_PREFIX) === 0) {
  26. return new WindowsMotionController(vrGamepad);
  27. }
  28. // HTC Vive
  29. else if (vrGamepad.id.toLowerCase().indexOf('openvr') !== -1) {
  30. return new ViveController(vrGamepad);
  31. }
  32. // Generic
  33. else {
  34. return new GenericController(vrGamepad);
  35. }
  36. }
  37. }
  38. export class PoseEnabledController extends Gamepad implements PoseControlled {
  39. devicePosition: Vector3;
  40. deviceRotationQuaternion: Quaternion;
  41. deviceScaleFactor: number = 1;
  42. public position: Vector3;
  43. public rotationQuaternion: Quaternion;
  44. public controllerType: PoseEnabledControllerType;
  45. private _calculatedPosition: Vector3;
  46. private _calculatedRotation: Quaternion;
  47. public rawPose: DevicePose; //GamepadPose;
  48. public _mesh: AbstractMesh; // a node that will be attached to this Gamepad
  49. private _poseControlledCamera: TargetCamera;
  50. private _leftHandSystemQuaternion: Quaternion = new Quaternion();
  51. constructor(browserGamepad) {
  52. super(browserGamepad.id, browserGamepad.index, browserGamepad);
  53. this.type = Gamepad.POSE_ENABLED;
  54. this.controllerType = PoseEnabledControllerType.GENERIC;
  55. this.position = Vector3.Zero();
  56. this.rotationQuaternion = new Quaternion();
  57. this.devicePosition = Vector3.Zero();
  58. this.deviceRotationQuaternion = new Quaternion();
  59. this._calculatedPosition = Vector3.Zero();
  60. this._calculatedRotation = new Quaternion();
  61. Quaternion.RotationYawPitchRollToRef(Math.PI, 0, 0, this._leftHandSystemQuaternion);
  62. }
  63. public update() {
  64. super.update();
  65. var pose: GamepadPose = this.browserGamepad.pose;
  66. this.updateFromDevice(pose);
  67. if (this._mesh) {
  68. this._mesh.position.copyFrom(this._calculatedPosition);
  69. this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
  70. }
  71. }
  72. updateFromDevice(poseData: DevicePose) {
  73. if (poseData) {
  74. this.rawPose = poseData;
  75. if (poseData.position) {
  76. this.devicePosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
  77. if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
  78. this.devicePosition.z *= -1;
  79. }
  80. this.devicePosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
  81. this._calculatedPosition.addInPlace(this.position);
  82. }
  83. if (poseData.orientation) {
  84. this.deviceRotationQuaternion.copyFromFloats(this.rawPose.orientation[0], this.rawPose.orientation[1], -this.rawPose.orientation[2], -this.rawPose.orientation[3]);
  85. if (this._mesh) {
  86. if (this._mesh.getScene().useRightHandedSystem) {
  87. this.deviceRotationQuaternion.z *= -1;
  88. this.deviceRotationQuaternion.w *= -1;
  89. } else {
  90. this.deviceRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this.deviceRotationQuaternion);
  91. }
  92. }
  93. // if the camera is set, rotate to the camera's rotation
  94. this.deviceRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
  95. }
  96. }
  97. }
  98. public attachToMesh(mesh: AbstractMesh) {
  99. if (this._mesh) {
  100. this._mesh.parent = undefined;
  101. }
  102. this._mesh = mesh;
  103. if (this._poseControlledCamera) {
  104. this._mesh.parent = this._poseControlledCamera;
  105. }
  106. if (!this._mesh.rotationQuaternion) {
  107. this._mesh.rotationQuaternion = new Quaternion();
  108. }
  109. }
  110. public attachToPoseControlledCamera(camera: TargetCamera) {
  111. this._poseControlledCamera = camera;
  112. if (this._mesh) {
  113. this._mesh.parent = this._poseControlledCamera;
  114. }
  115. }
  116. public dispose() {
  117. if (this._mesh) {
  118. this._mesh.dispose();
  119. }
  120. this._mesh = undefined;
  121. super.dispose();
  122. }
  123. public get mesh(): AbstractMesh {
  124. return this._mesh;
  125. }
  126. public getForwardRay(length = 100): Ray {
  127. if (!this.mesh) {
  128. return new Ray(Vector3.Zero(), new BABYLON.Vector3(0, 0, 1), length);
  129. }
  130. var m = this.mesh.getWorldMatrix();
  131. var origin = m.getTranslation();
  132. var forward = new BABYLON.Vector3(0, 0, -1);
  133. var forwardWorld = BABYLON.Vector3.TransformNormal(forward, m);
  134. var direction = BABYLON.Vector3.Normalize(forwardWorld);
  135. return new Ray(origin, direction, length);
  136. }
  137. }
  138. }