babylon.webVRController.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. module BABYLON {
  2. export abstract class WebVRController extends PoseEnabledController {
  3. protected _defaultModel: AbstractMesh;
  4. // Observables
  5. public onTriggerStateChangedObservable = new Observable<ExtendedGamepadButton>();
  6. public onMainButtonStateChangedObservable = new Observable<ExtendedGamepadButton>();
  7. public onSecondaryButtonStateChangedObservable = new Observable<ExtendedGamepadButton>();
  8. public onPadStateChangedObservable = new Observable<ExtendedGamepadButton>();
  9. public onPadValuesChangedObservable = new Observable<StickValues>();
  10. protected _buttons: Array<MutableGamepadButton>;
  11. private _onButtonStateChange: (controlledIndex: number, buttonIndex: number, state: ExtendedGamepadButton) => void;
  12. public onButtonStateChange(callback: (controlledIndex: number, buttonIndex: number, state: ExtendedGamepadButton) => void) {
  13. this._onButtonStateChange = callback;
  14. }
  15. public pad: StickValues = { x: 0, y: 0 };
  16. public hand: string; // 'left' or 'right', see https://w3c.github.io/gamepad/extensions.html#gamepadhand-enum
  17. public get defaultModel(): AbstractMesh {
  18. return this._defaultModel;
  19. }
  20. constructor(vrGamepad: any) {
  21. super(vrGamepad);
  22. this._buttons = new Array<ExtendedGamepadButton>(vrGamepad.buttons.length);
  23. this.hand = vrGamepad.hand;
  24. }
  25. public update() {
  26. super.update();
  27. for (var index = 0; index < this._buttons.length; index++) {
  28. this._setButtonValue(this.browserGamepad.buttons[index], this._buttons[index], index);
  29. };
  30. if (this.leftStick.x !== this.pad.x || this.leftStick.y !== this.pad.y) {
  31. this.pad.x = this.leftStick.x;
  32. this.pad.y = this.leftStick.y;
  33. this.onPadValuesChangedObservable.notifyObservers(this.pad);
  34. }
  35. }
  36. protected abstract handleButtonChange(buttonIdx: number, value: ExtendedGamepadButton, changes: GamepadButtonChanges): void;
  37. public abstract initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void): void;
  38. private _setButtonValue(newState: ExtendedGamepadButton, currentState: ExtendedGamepadButton, buttonIndex: number) {
  39. if (!newState) {
  40. newState = {
  41. pressed: false,
  42. touched: false,
  43. value: 0
  44. };
  45. }
  46. if (!currentState) {
  47. this._buttons[buttonIndex] = {
  48. pressed: newState.pressed,
  49. touched: newState.touched,
  50. value: newState.value
  51. }
  52. return;
  53. }
  54. this._checkChanges(newState, currentState);
  55. if (this._changes.changed) {
  56. this._onButtonStateChange && this._onButtonStateChange(this.index, buttonIndex, newState);
  57. this.handleButtonChange(buttonIndex, newState, this._changes);
  58. }
  59. this._buttons[buttonIndex].pressed = newState.pressed;
  60. this._buttons[buttonIndex].touched = newState.touched;
  61. // oculus triggers are never 0, thou not touched.
  62. this._buttons[buttonIndex].value = newState.value < 0.00000001 ? 0 : newState.value;
  63. }
  64. // avoid GC, store state in a tmp object
  65. private _changes: GamepadButtonChanges = {
  66. pressChanged: false,
  67. touchChanged: false,
  68. valueChanged: false,
  69. changed: false
  70. };
  71. private _checkChanges(newState: ExtendedGamepadButton, currentState: ExtendedGamepadButton) {
  72. this._changes.pressChanged = newState.pressed !== currentState.pressed;
  73. this._changes.touchChanged = newState.touched !== currentState.touched;
  74. this._changes.valueChanged = newState.value !== currentState.value;
  75. this._changes.changed = this._changes.pressChanged || this._changes.touchChanged || this._changes.valueChanged;
  76. return this._changes;
  77. }
  78. public dispose(): void {
  79. super.dispose();
  80. this.onTriggerStateChangedObservable.clear();
  81. this.onMainButtonStateChangedObservable.clear();
  82. this.onSecondaryButtonStateChangedObservable.clear();
  83. this.onPadStateChangedObservable.clear();
  84. this.onPadValuesChangedObservable.clear();
  85. }
  86. }
  87. }