import { Observable } from "../../Misc/observable.js"; /** * This class represents a single component (for example button or thumbstick) of a motion controller */ export class WebXRControllerComponent { /** * Creates a new component for a motion controller. * It is created by the motion controller itself * * @param id the id of this component * @param type the type of the component * @param _buttonIndex index in the buttons array of the gamepad * @param _axesIndices indices of the values in the axes array of the gamepad */ constructor( /** * the id of this component */ id, /** * the type of the component */ type, _buttonIndex = -1, _axesIndices = []) { this.id = id; this.type = type; this._buttonIndex = _buttonIndex; this._axesIndices = _axesIndices; this._axes = { x: 0, y: 0, }; this._changes = {}; this._currentValue = 0; this._hasChanges = false; this._pressed = false; this._touched = false; /** * If axes are available for this component (like a touchpad or thumbstick) the observers will be notified when * the axes data changes */ this.onAxisValueChangedObservable = new Observable(); /** * Observers registered here will be triggered when the state of a button changes * State change is either pressed / touched / value */ this.onButtonStateChangedObservable = new Observable(); } /** * The current axes data. If this component has no axes it will still return an object { x: 0, y: 0 } */ get axes() { return this._axes; } /** * Get the changes. Elements will be populated only if they changed with their previous and current value */ get changes() { return this._changes; } /** * Return whether or not the component changed the last frame */ get hasChanges() { return this._hasChanges; } /** * is the button currently pressed */ get pressed() { return this._pressed; } /** * is the button currently touched */ get touched() { return this._touched; } /** * Get the current value of this component */ get value() { return this._currentValue; } /** * Dispose this component */ dispose() { this.onAxisValueChangedObservable.clear(); this.onButtonStateChangedObservable.clear(); } /** * Are there axes correlating to this component * @returns true is axes data is available */ isAxes() { return this._axesIndices.length !== 0; } /** * Is this component a button (hence - pressable) * @returns true if can be pressed */ isButton() { return this._buttonIndex !== -1; } /** * update this component using the gamepad object it is in. Called on every frame * @param nativeController the native gamepad controller object */ update(nativeController) { let buttonUpdated = false; let axesUpdate = false; this._hasChanges = false; this._changes = {}; if (this.isButton()) { const button = nativeController.buttons[this._buttonIndex]; // defensive, in case a profile was forced if (!button) { return; } if (this._currentValue !== button.value) { this.changes.value = { current: button.value, previous: this._currentValue, }; buttonUpdated = true; this._currentValue = button.value; } if (this._touched !== button.touched) { this.changes.touched = { current: button.touched, previous: this._touched, }; buttonUpdated = true; this._touched = button.touched; } if (this._pressed !== button.pressed) { this.changes.pressed = { current: button.pressed, previous: this._pressed, }; buttonUpdated = true; this._pressed = button.pressed; } } if (this.isAxes()) { if (this._axes.x !== nativeController.axes[this._axesIndices[0]]) { this.changes.axes = { current: { x: nativeController.axes[this._axesIndices[0]], y: this._axes.y, }, previous: { x: this._axes.x, y: this._axes.y, }, }; this._axes.x = nativeController.axes[this._axesIndices[0]]; axesUpdate = true; } if (this._axes.y !== nativeController.axes[this._axesIndices[1]]) { if (this.changes.axes) { this.changes.axes.current.y = nativeController.axes[this._axesIndices[1]]; } else { this.changes.axes = { current: { x: this._axes.x, y: nativeController.axes[this._axesIndices[1]], }, previous: { x: this._axes.x, y: this._axes.y, }, }; } this._axes.y = nativeController.axes[this._axesIndices[1]]; axesUpdate = true; } } if (buttonUpdated) { this._hasChanges = true; this.onButtonStateChangedObservable.notifyObservers(this); } if (axesUpdate) { this._hasChanges = true; this.onAxisValueChangedObservable.notifyObservers(this._axes); } } } /** * button component type */ WebXRControllerComponent.BUTTON_TYPE = "button"; /** * squeeze component type */ WebXRControllerComponent.SQUEEZE_TYPE = "squeeze"; /** * Thumbstick component type */ WebXRControllerComponent.THUMBSTICK_TYPE = "thumbstick"; /** * Touchpad component type */ WebXRControllerComponent.TOUCHPAD_TYPE = "touchpad"; /** * trigger component type */ WebXRControllerComponent.TRIGGER_TYPE = "trigger"; //# sourceMappingURL=webXRControllerComponent.js.map