@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
210 lines • 6.63 kB
JavaScript
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