webXRControllerModelLoader.ts 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { Quaternion, Vector3 } from '../../Maths/math.vector';
  2. import { WindowsMotionController } from '../../Gamepads/Controllers/windowsMotionController';
  3. import { OculusTouchController } from '../../Gamepads/Controllers/oculusTouchController';
  4. import { WebXRInput } from './webXRInput';
  5. import { ViveController } from '../../Gamepads/Controllers/viveController';
  6. import { WebVRController } from '../../Gamepads/Controllers/webVRController';
  7. import { Observable } from '../../Misc/observable';
  8. import { WebXRController } from './webXRController';
  9. /**
  10. * Loads a controller model and adds it as a child of the WebXRControllers grip when the controller is created
  11. */
  12. export class WebXRControllerModelLoader {
  13. /**
  14. * an observable that triggers when a new model (the mesh itself) was initialized.
  15. * To know when the mesh was loaded use the controller's own modelLoaded() method
  16. */
  17. public onControllerModelLoaded = new Observable<WebXRController>();
  18. /**
  19. * Creates the WebXRControllerModelLoader
  20. * @param input xr input that creates the controllers
  21. */
  22. constructor(input: WebXRInput) {
  23. input.onControllerAddedObservable.add((c) => {
  24. if (!c.inputSource.gamepad) {
  25. return;
  26. }
  27. let controllerModel: WebVRController;
  28. let rotation: Quaternion;
  29. const position = new Vector3();
  30. switch (c.inputSource.gamepad.id) {
  31. case "htc-vive": {
  32. controllerModel = new ViveController(c.inputSource.gamepad);
  33. rotation = Quaternion.FromEulerAngles(0, Math.PI, 0);
  34. break;
  35. }
  36. case "oculus-touch": {
  37. controllerModel = new OculusTouchController(c.inputSource.gamepad);
  38. rotation = Quaternion.FromEulerAngles(0, Math.PI, 0);
  39. position.y = 0.034;
  40. position.z = 0.052;
  41. break;
  42. }
  43. case "oculus-quest": {
  44. OculusTouchController._IsQuest = true;
  45. controllerModel = new OculusTouchController(c.inputSource.gamepad);
  46. rotation = Quaternion.FromEulerAngles(Math.PI / -4, Math.PI, 0);
  47. break;
  48. }
  49. default: {
  50. controllerModel = new WindowsMotionController(c.inputSource.gamepad);
  51. rotation = Quaternion.FromEulerAngles(0, Math.PI, 0);
  52. break;
  53. }
  54. }
  55. controllerModel.hand = c.inputSource.handedness;
  56. controllerModel.isXR = true;
  57. controllerModel.initControllerMesh(c.getScene(), (m) => {
  58. controllerModel.mesh!.parent = c.grip || input.baseExperience.container;
  59. controllerModel.mesh!.rotationQuaternion = rotation;
  60. controllerModel.mesh!.position = position;
  61. m.isPickable = false;
  62. m.getChildMeshes(false).forEach((m) => {
  63. m.isPickable = false;
  64. });
  65. this.onControllerModelLoaded.notifyObservers(c);
  66. });
  67. c.gamepadController = controllerModel;
  68. });
  69. }
  70. }