three-gamepad-controls 0.10.6 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/gamepad-arcball-controls.d.ts +1 -2
- package/dist/gamepad-arcball-controls.js +75 -16
- package/dist/gamepad-controls.d.ts +25 -12
- package/dist/gamepad-controls.js +58 -51
- package/dist/gamepad-drag-controls.d.ts +1 -2
- package/dist/gamepad-drag-controls.js +86 -13
- package/dist/gamepad-first-person-controls.d.ts +1 -2
- package/dist/gamepad-first-person-controls.js +38 -13
- package/dist/gamepad-fly-controls.d.ts +1 -2
- package/dist/gamepad-fly-controls.js +9 -10
- package/dist/gamepad-input.d.ts +156 -0
- package/dist/gamepad-input.js +310 -0
- package/dist/gamepad-orbit-controls.d.ts +1 -2
- package/dist/gamepad-orbit-controls.js +8 -9
- package/dist/gamepad-pointer-lock-controls.d.ts +1 -2
- package/dist/gamepad-pointer-lock-controls.js +6 -7
- package/dist/gamepad-trackball-controls.d.ts +1 -2
- package/dist/gamepad-trackball-controls.js +45 -15
- package/dist/gamepad-transform-controls.d.ts +1 -2
- package/dist/gamepad-transform-controls.js +317 -21
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +3 -3
- package/dist/utils.js +0 -41
package/README.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Gamepad support for [Three.js](https://threejs.org) controls, built on top of [Web Gamepad API](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API).
|
|
4
4
|
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
flowchart TD
|
|
9
|
+
GamepadManager["GamepadManager<br/>(internal polling and active device lifecycle)"]
|
|
10
|
+
GamepadInput["GamepadInput<br/>(public low-level input state)"]
|
|
11
|
+
GamepadControls["GamepadControls<br/>(abstract Three.js wrapper base)"]
|
|
12
|
+
Wrappers["Specific wrappers<br/>(Orbit, Map, Fly, Transform, etc.)"]
|
|
13
|
+
|
|
14
|
+
GamepadManager --> GamepadInput
|
|
15
|
+
GamepadInput --> GamepadControls
|
|
16
|
+
GamepadControls --> Wrappers
|
|
17
|
+
```
|
|
18
|
+
|
|
5
19
|
## 📦 Installation
|
|
6
20
|
|
|
7
21
|
npm:
|
|
@@ -37,6 +51,7 @@ bun add three-gamepad-controls
|
|
|
37
51
|
## 📖 Documentation
|
|
38
52
|
|
|
39
53
|
- [Core](./docs/core.md) — The fundamental building blocks.
|
|
54
|
+
- [GamepadInput](./docs/gamepad-input.md) - Low-level reader for gamepad buttons, axes, sticks, and transitions.
|
|
40
55
|
- [GamepadControls](./docs/gamepad-controls.md) — Abstract base class for custom gamepad controls.
|
|
41
56
|
- [GamepadArcballControls](./docs/gamepad-arcball-controls.md) - Gamepad support for `ArcballControls`.
|
|
42
57
|
- [GamepadDragControls](./docs/gamepad-drag-controls.md) - Gamepad support for `DragControls`.
|
|
@@ -99,9 +99,8 @@ declare class GamepadArcballControls extends GamepadControls {
|
|
|
99
99
|
* z-rotation, and center focus.
|
|
100
100
|
*
|
|
101
101
|
* @param deltaTime - Seconds since the last frame.
|
|
102
|
-
* @param gamepad - Fresh gamepad snapshot provided by the base class.
|
|
103
102
|
*/
|
|
104
|
-
protected onUpdate(deltaTime: number
|
|
103
|
+
protected onUpdate(deltaTime: number): void;
|
|
105
104
|
}
|
|
106
105
|
//#endregion
|
|
107
106
|
export { GamepadArcballControls, GamepadArcballControlsOptions };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
-
import { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue } from "./utils.js";
|
|
4
3
|
import { Vector2, Vector3 } from "three";
|
|
5
4
|
//#region src/gamepad-arcball-controls.ts
|
|
6
5
|
/**
|
|
@@ -40,7 +39,6 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
40
39
|
#cameraForward;
|
|
41
40
|
#cameraRight;
|
|
42
41
|
#previousUp;
|
|
43
|
-
#focusButtonPressed = false;
|
|
44
42
|
#wasInteracting = false;
|
|
45
43
|
/**
|
|
46
44
|
* @param controls - A Three.js `ArcballControls` instance.
|
|
@@ -67,22 +65,22 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
67
65
|
* z-rotation, and center focus.
|
|
68
66
|
*
|
|
69
67
|
* @param deltaTime - Seconds since the last frame.
|
|
70
|
-
* @param gamepad - Fresh gamepad snapshot provided by the base class.
|
|
71
68
|
*/
|
|
72
|
-
onUpdate(deltaTime
|
|
69
|
+
onUpdate(deltaTime) {
|
|
73
70
|
const controls = this.#controls;
|
|
74
71
|
const { rotateSpeed, panSpeed, zoomSpeed, zRotateSpeed, deadzone, axisRotateX, axisRotateY, axisPanX, axisPanY, buttonZoomIn, buttonZoomOut, buttonZRotateLeft, buttonZRotateRight, buttonFocus } = this.#options;
|
|
75
|
-
const
|
|
72
|
+
const input = this.gamepadInput;
|
|
73
|
+
const focusPoint = this.#consumeFocusPoint(buttonFocus);
|
|
76
74
|
if (!controls.enabled) {
|
|
77
75
|
this.#endInteraction();
|
|
78
76
|
return;
|
|
79
77
|
}
|
|
80
|
-
const rotateX = controls.enableRotate ?
|
|
81
|
-
const rotateY = controls.enableRotate ?
|
|
82
|
-
const panX = controls.enablePan ?
|
|
83
|
-
const panY = controls.enablePan ?
|
|
84
|
-
const zoom = controls.enableZoom ?
|
|
85
|
-
const zRotation = controls.enableRotate ?
|
|
78
|
+
const rotateX = controls.enableRotate ? input.axis(axisRotateX, { deadzone }) : 0;
|
|
79
|
+
const rotateY = controls.enableRotate ? input.axis(axisRotateY, { deadzone }) : 0;
|
|
80
|
+
const panX = controls.enablePan ? input.axis(axisPanX, { deadzone }) : 0;
|
|
81
|
+
const panY = controls.enablePan ? input.axis(axisPanY, { deadzone }) : 0;
|
|
82
|
+
const zoom = controls.enableZoom ? input.buttonValue(buttonZoomIn) - input.buttonValue(buttonZoomOut) : 0;
|
|
83
|
+
const zRotation = controls.enableRotate ? input.buttonValue(buttonZRotateLeft) - input.buttonValue(buttonZRotateRight) : 0;
|
|
86
84
|
const activeInput = rotateX !== 0 || rotateY !== 0 || panX !== 0 || panY !== 0 || Math.abs(zoom) > deadzone || Math.abs(zRotation) > deadzone;
|
|
87
85
|
if (!activeInput && focusPoint === null) {
|
|
88
86
|
this.#endInteraction();
|
|
@@ -103,6 +101,15 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
103
101
|
this.#wasInteracting = activeInput;
|
|
104
102
|
if (!activeInput) this.#endInteraction();
|
|
105
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Applies gamepad stick rotation through Arcball's runtime rotation helper.
|
|
106
|
+
*
|
|
107
|
+
* @param deltaTime - Seconds since the last frame.
|
|
108
|
+
* @param rotateX - Horizontal rotation input after dead zone processing.
|
|
109
|
+
* @param rotateY - Vertical rotation input after dead zone processing.
|
|
110
|
+
* @param rotateSpeed - User-configured rotation speed multiplier.
|
|
111
|
+
* @returns `true` when a rotation was applied.
|
|
112
|
+
*/
|
|
106
113
|
#applyRotation(deltaTime, rotateX, rotateY, rotateSpeed) {
|
|
107
114
|
if (rotateX === 0 && rotateY === 0) return false;
|
|
108
115
|
const controls = this.#controls;
|
|
@@ -119,6 +126,13 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
119
126
|
}
|
|
120
127
|
return changed;
|
|
121
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Applies an Arcball rotation around a specific world axis.
|
|
131
|
+
*
|
|
132
|
+
* @param axis - World axis to rotate around.
|
|
133
|
+
* @param angle - Rotation amount in radians.
|
|
134
|
+
* @returns `true` when ArcballControls produced and applied a transform.
|
|
135
|
+
*/
|
|
122
136
|
#applyRotationAroundAxis(axis, angle) {
|
|
123
137
|
if (axis.lengthSq() === 0 || angle === 0) return false;
|
|
124
138
|
const controls = this.#controls;
|
|
@@ -128,6 +142,15 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
128
142
|
if (changed) controls.object.up.copy(this.#previousUp).applyAxisAngle(axis, -angle);
|
|
129
143
|
return changed;
|
|
130
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Applies gamepad pan by converting stick input to Arcball trackball points.
|
|
147
|
+
*
|
|
148
|
+
* @param deltaTime - Seconds since the last frame.
|
|
149
|
+
* @param panX - Horizontal pan input after dead zone processing.
|
|
150
|
+
* @param panY - Vertical pan input after dead zone processing.
|
|
151
|
+
* @param panSpeed - User-configured pan speed multiplier.
|
|
152
|
+
* @returns `true` when a pan transform was applied.
|
|
153
|
+
*/
|
|
131
154
|
#applyPan(deltaTime, panX, panY, panSpeed) {
|
|
132
155
|
if (panX === 0 && panY === 0) return false;
|
|
133
156
|
const controls = this.#controls;
|
|
@@ -137,6 +160,15 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
137
160
|
this.#panEnd.set(panX * distance, panY * distance, 0);
|
|
138
161
|
return this.#applyTransform(controls.pan(this.#panStart, this.#panEnd));
|
|
139
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Applies trigger-driven zoom around Arcball's gizmo center.
|
|
165
|
+
*
|
|
166
|
+
* @param deltaTime - Seconds since the last frame.
|
|
167
|
+
* @param zoom - Signed zoom input from the configured trigger pair.
|
|
168
|
+
* @param zoomSpeed - User-configured zoom speed multiplier.
|
|
169
|
+
* @param deadzone - Trigger dead zone threshold.
|
|
170
|
+
* @returns `true` when a zoom transform was applied.
|
|
171
|
+
*/
|
|
140
172
|
#applyZoom(deltaTime, zoom, zoomSpeed, deadzone) {
|
|
141
173
|
if (Math.abs(zoom) <= deadzone || this.#controls.scaleFactor <= 0) return false;
|
|
142
174
|
const controls = this.#controls;
|
|
@@ -145,6 +177,15 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
145
177
|
controls.updateMatrixState();
|
|
146
178
|
return this.#applyTransform(controls.scale(size, controls._gizmos.position));
|
|
147
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Applies shoulder-button rotation around the current camera view axis.
|
|
182
|
+
*
|
|
183
|
+
* @param deltaTime - Seconds since the last frame.
|
|
184
|
+
* @param zRotation - Signed z-rotation input from the configured buttons.
|
|
185
|
+
* @param zRotateSpeed - User-configured z-rotation speed multiplier.
|
|
186
|
+
* @param deadzone - Button value dead zone threshold.
|
|
187
|
+
* @returns `true` when a z-rotation transform was applied.
|
|
188
|
+
*/
|
|
148
189
|
#applyZRotation(deltaTime, zRotation, zRotateSpeed, deadzone) {
|
|
149
190
|
if (Math.abs(zRotation) <= deadzone) return false;
|
|
150
191
|
const controls = this.#controls;
|
|
@@ -156,6 +197,12 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
156
197
|
if (changed) controls.object.up.copy(this.#previousUp).applyAxisAngle(controls._rotationAxis, angle);
|
|
157
198
|
return changed;
|
|
158
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Focuses ArcballControls on the given point when one was consumed.
|
|
202
|
+
*
|
|
203
|
+
* @param point - World-space focus point, or `null` when no focus is pending.
|
|
204
|
+
* @returns `true` when focus was applied.
|
|
205
|
+
*/
|
|
159
206
|
#applyFocus(point) {
|
|
160
207
|
if (point === null) return false;
|
|
161
208
|
const controls = this.#controls;
|
|
@@ -164,20 +211,32 @@ var GamepadArcballControls = class extends GamepadControls {
|
|
|
164
211
|
controls.updateMatrixState();
|
|
165
212
|
return true;
|
|
166
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Applies a transformation returned by an Arcball runtime helper.
|
|
216
|
+
*
|
|
217
|
+
* @param transformation - Arcball transformation matrices, if any.
|
|
218
|
+
* @returns `true` when a transformation was applied.
|
|
219
|
+
*/
|
|
167
220
|
#applyTransform(transformation) {
|
|
168
221
|
if (transformation === void 0) return false;
|
|
169
222
|
this.#controls.applyTransformMatrix(transformation);
|
|
170
223
|
this.#controls.updateMatrixState();
|
|
171
224
|
return true;
|
|
172
225
|
}
|
|
173
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Consumes a focus-button press and resolves the viewport center hit point.
|
|
228
|
+
*
|
|
229
|
+
* @param buttonFocus - Button index configured for focus.
|
|
230
|
+
* @returns The center hit point, or `null` when focus should not run.
|
|
231
|
+
*/
|
|
232
|
+
#consumeFocusPoint(buttonFocus) {
|
|
174
233
|
const controls = this.#controls;
|
|
175
|
-
|
|
176
|
-
const shouldFocus = focusPressed && !this.#focusButtonPressed;
|
|
177
|
-
this.#focusButtonPressed = focusPressed;
|
|
178
|
-
if (!shouldFocus || !controls.enabled || !controls.enablePan || !controls.enableFocus || controls.scene === null) return null;
|
|
234
|
+
if (!this.gamepadInput.wasPressed(buttonFocus) || !controls.enabled || !controls.enablePan || !controls.enableFocus || controls.scene === null) return null;
|
|
179
235
|
return controls.unprojectOnObj(this.#centerNdc, controls.object);
|
|
180
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Dispatches Arcball's `end` event when an active gamepad interaction stops.
|
|
239
|
+
*/
|
|
181
240
|
#endInteraction() {
|
|
182
241
|
if (!this.#wasInteracting) return;
|
|
183
242
|
this.#controls.dispatchEvent({ type: "end" });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GamepadInput } from "./gamepad-input.js";
|
|
1
2
|
import { EventDispatcher } from "three";
|
|
2
3
|
|
|
3
4
|
//#region src/gamepad-controls.d.ts
|
|
@@ -12,20 +13,26 @@ type GamepadControlsEventMap = {
|
|
|
12
13
|
* Fired when a gamepad is connected and set as the active gamepad.
|
|
13
14
|
*/
|
|
14
15
|
connected: {
|
|
16
|
+
/**
|
|
17
|
+
* Gamepad snapshot that became active.
|
|
18
|
+
*/
|
|
15
19
|
gamepad: Gamepad;
|
|
16
20
|
};
|
|
17
21
|
/**
|
|
18
22
|
* Fired when the active gamepad is disconnected.
|
|
19
23
|
*/
|
|
20
24
|
disconnected: {
|
|
25
|
+
/**
|
|
26
|
+
* Gamepad snapshot that was active before disconnection.
|
|
27
|
+
*/
|
|
21
28
|
gamepad: Gamepad;
|
|
22
29
|
};
|
|
23
30
|
};
|
|
24
31
|
/**
|
|
25
32
|
* Abstract base class for Three.js gamepad controls.
|
|
26
33
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
34
|
+
* Delegates gamepad connection lifecycle and input polling to {@link GamepadInput}
|
|
35
|
+
* so subclasses can focus on mapping input to the wrapped Three.js control.
|
|
29
36
|
*/
|
|
30
37
|
declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEventMap> {
|
|
31
38
|
#private;
|
|
@@ -38,7 +45,16 @@ declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEv
|
|
|
38
45
|
* The currently active gamepad, or `null` if no gamepad is connected.
|
|
39
46
|
*/
|
|
40
47
|
gamepad: Gamepad | null;
|
|
48
|
+
/**
|
|
49
|
+
* Creates the base input reader and attaches lifecycle listeners.
|
|
50
|
+
*/
|
|
41
51
|
constructor();
|
|
52
|
+
/**
|
|
53
|
+
* Low-level gamepad input reader used by subclasses.
|
|
54
|
+
*
|
|
55
|
+
* @returns The shared input reader for the active gamepad.
|
|
56
|
+
*/
|
|
57
|
+
protected get gamepadInput(): GamepadInput;
|
|
42
58
|
/**
|
|
43
59
|
* Advances the controller by one frame. Call this inside your render loop.
|
|
44
60
|
*
|
|
@@ -53,25 +69,22 @@ declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEv
|
|
|
53
69
|
* Called every frame when a gamepad is available and `enabled` is `true`.
|
|
54
70
|
*
|
|
55
71
|
* @param deltaTime - Seconds since the last frame.
|
|
56
|
-
* @param gamepad - A fresh snapshot of the currently active gamepad.
|
|
57
72
|
*/
|
|
58
|
-
protected abstract onUpdate(deltaTime: number
|
|
73
|
+
protected abstract onUpdate(deltaTime: number): void;
|
|
59
74
|
/**
|
|
60
|
-
* Called when
|
|
75
|
+
* Called when a gamepad becomes active through the shared input reader.
|
|
61
76
|
*
|
|
62
|
-
* The default
|
|
63
|
-
* Override to customize selection behavior.
|
|
77
|
+
* The default dispatches a `connected` event.
|
|
64
78
|
*
|
|
65
|
-
* @param gamepad - The gamepad that
|
|
79
|
+
* @param gamepad - The gamepad that became active.
|
|
66
80
|
*/
|
|
67
81
|
protected onGamepadConnected(gamepad: Gamepad): void;
|
|
68
82
|
/**
|
|
69
|
-
* Called when
|
|
83
|
+
* Called when the active gamepad disconnects through the shared input reader.
|
|
70
84
|
*
|
|
71
|
-
* The default
|
|
72
|
-
* disconnecting gamepad was the active one. Override to add custom cleanup.
|
|
85
|
+
* The default dispatches a `disconnected` event.
|
|
73
86
|
*
|
|
74
|
-
* @param gamepad - The gamepad that
|
|
87
|
+
* @param gamepad - The gamepad that was active before disconnection.
|
|
75
88
|
*/
|
|
76
89
|
protected onGamepadDisconnected(gamepad: Gamepad): void;
|
|
77
90
|
}
|
package/dist/gamepad-controls.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GamepadInput } from "./gamepad-input.js";
|
|
2
2
|
import { EventDispatcher } from "three";
|
|
3
3
|
//#region src/gamepad-controls.ts
|
|
4
4
|
/**
|
|
5
5
|
* Abstract base class for Three.js gamepad controls.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Delegates gamepad connection lifecycle and input polling to {@link GamepadInput}
|
|
8
|
+
* so subclasses can focus on mapping input to the wrapped Three.js control.
|
|
9
9
|
*/
|
|
10
10
|
var GamepadControls = class extends EventDispatcher {
|
|
11
11
|
/**
|
|
@@ -17,20 +17,51 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
17
17
|
* The currently active gamepad, or `null` if no gamepad is connected.
|
|
18
18
|
*/
|
|
19
19
|
gamepad = null;
|
|
20
|
-
#
|
|
20
|
+
#gamepadInput;
|
|
21
|
+
/**
|
|
22
|
+
* Bound input connection listener kept so it can be removed in {@link dispose}.
|
|
23
|
+
*/
|
|
21
24
|
#onGamepadConnected;
|
|
25
|
+
/**
|
|
26
|
+
* Bound input disconnection listener kept so it can be removed in {@link dispose}.
|
|
27
|
+
*/
|
|
22
28
|
#onGamepadDisconnected;
|
|
29
|
+
/**
|
|
30
|
+
* Creates the base input reader and attaches lifecycle listeners.
|
|
31
|
+
*/
|
|
23
32
|
constructor() {
|
|
24
33
|
super();
|
|
25
|
-
this.#
|
|
26
|
-
this.#onGamepadConnected = (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.#onGamepadDisconnected
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
this.#gamepadInput = new GamepadInput();
|
|
35
|
+
this.#onGamepadConnected = this.#handleGamepadConnected.bind(this);
|
|
36
|
+
this.#onGamepadDisconnected = this.#handleGamepadDisconnected.bind(this);
|
|
37
|
+
this.#gamepadInput.addEventListener("connected", this.#onGamepadConnected);
|
|
38
|
+
this.#gamepadInput.addEventListener("disconnected", this.#onGamepadDisconnected);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Low-level gamepad input reader used by subclasses.
|
|
42
|
+
*
|
|
43
|
+
* @returns The shared input reader for the active gamepad.
|
|
44
|
+
*/
|
|
45
|
+
get gamepadInput() {
|
|
46
|
+
return this.#gamepadInput;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Forwards an input connection event to the overridable lifecycle hook.
|
|
50
|
+
*
|
|
51
|
+
* @param event - Input event containing the connected gamepad snapshot.
|
|
52
|
+
*/
|
|
53
|
+
#handleGamepadConnected(event) {
|
|
54
|
+
this.gamepad = this.#gamepadInput.gamepad;
|
|
55
|
+
this.onGamepadConnected(event.gamepad);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Forwards an input disconnection event to the overridable lifecycle hook.
|
|
59
|
+
*
|
|
60
|
+
* @param event - Input event containing the disconnected gamepad snapshot.
|
|
61
|
+
*/
|
|
62
|
+
#handleGamepadDisconnected(event) {
|
|
63
|
+
this.gamepad = this.#gamepadInput.gamepad;
|
|
64
|
+
this.onGamepadDisconnected(event.gamepad);
|
|
34
65
|
}
|
|
35
66
|
/**
|
|
36
67
|
* Advances the controller by one frame. Call this inside your render loop.
|
|
@@ -39,69 +70,45 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
39
70
|
*/
|
|
40
71
|
update(deltaTime) {
|
|
41
72
|
if (!this.enabled) return;
|
|
42
|
-
this.#
|
|
43
|
-
|
|
44
|
-
if (connected !== null) {
|
|
45
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
46
|
-
this.onGamepadConnected(connected);
|
|
47
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
48
|
-
} else if (disconnected !== null) {
|
|
49
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
50
|
-
this.onGamepadDisconnected(disconnected);
|
|
51
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
52
|
-
return;
|
|
53
|
-
} else {
|
|
54
|
-
this.gamepad = gamepad;
|
|
55
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
56
|
-
}
|
|
73
|
+
this.#gamepadInput.update();
|
|
74
|
+
this.gamepad = this.#gamepadInput.gamepad;
|
|
57
75
|
if (this.gamepad === null) return;
|
|
58
|
-
this.onUpdate(deltaTime
|
|
76
|
+
this.onUpdate(deltaTime);
|
|
59
77
|
}
|
|
60
78
|
/**
|
|
61
79
|
* Removes all event listeners attached by this controller. Call when no longer needed.
|
|
62
80
|
*/
|
|
63
81
|
dispose() {
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
this.#gamepadInput.removeEventListener("connected", this.#onGamepadConnected);
|
|
83
|
+
this.#gamepadInput.removeEventListener("disconnected", this.#onGamepadDisconnected);
|
|
84
|
+
this.#gamepadInput.dispose();
|
|
66
85
|
this.gamepad = null;
|
|
67
|
-
this.#manager.activeGamepad = null;
|
|
68
86
|
this.enabled = false;
|
|
69
87
|
}
|
|
70
88
|
/**
|
|
71
|
-
* Called when
|
|
89
|
+
* Called when a gamepad becomes active through the shared input reader.
|
|
72
90
|
*
|
|
73
|
-
* The default
|
|
74
|
-
* Override to customize selection behavior.
|
|
91
|
+
* The default dispatches a `connected` event.
|
|
75
92
|
*
|
|
76
|
-
* @param gamepad - The gamepad that
|
|
93
|
+
* @param gamepad - The gamepad that became active.
|
|
77
94
|
*/
|
|
78
95
|
onGamepadConnected(gamepad) {
|
|
79
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
80
|
-
if (!this.#manager.connect(gamepad)) return;
|
|
81
|
-
const connectedGamepad = this.#manager.activeGamepad;
|
|
82
|
-
if (connectedGamepad === null) return;
|
|
83
|
-
this.gamepad = connectedGamepad;
|
|
84
96
|
this.dispatchEvent({
|
|
85
97
|
type: "connected",
|
|
86
|
-
gamepad
|
|
98
|
+
gamepad
|
|
87
99
|
});
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
90
|
-
* Called when
|
|
102
|
+
* Called when the active gamepad disconnects through the shared input reader.
|
|
91
103
|
*
|
|
92
|
-
* The default
|
|
93
|
-
* disconnecting gamepad was the active one. Override to add custom cleanup.
|
|
104
|
+
* The default dispatches a `disconnected` event.
|
|
94
105
|
*
|
|
95
|
-
* @param gamepad - The gamepad that
|
|
106
|
+
* @param gamepad - The gamepad that was active before disconnection.
|
|
96
107
|
*/
|
|
97
108
|
onGamepadDisconnected(gamepad) {
|
|
98
|
-
this.#manager.activeGamepad = this.gamepad;
|
|
99
|
-
const disconnectedGamepad = this.#manager.disconnect(gamepad);
|
|
100
|
-
if (disconnectedGamepad === null) return;
|
|
101
|
-
this.gamepad = this.#manager.activeGamepad;
|
|
102
109
|
this.dispatchEvent({
|
|
103
110
|
type: "disconnected",
|
|
104
|
-
gamepad
|
|
111
|
+
gamepad
|
|
105
112
|
});
|
|
106
113
|
}
|
|
107
114
|
};
|
|
@@ -68,9 +68,8 @@ declare class GamepadDragControls extends GamepadControls {
|
|
|
68
68
|
* and rotate behavior.
|
|
69
69
|
*
|
|
70
70
|
* @param deltaTime - Seconds since the last frame.
|
|
71
|
-
* @param gamepad - Fresh gamepad snapshot provided by the base class.
|
|
72
71
|
*/
|
|
73
|
-
protected onUpdate(deltaTime: number
|
|
72
|
+
protected onUpdate(deltaTime: number): void;
|
|
74
73
|
/**
|
|
75
74
|
* Releases any selected object and removes hover state before disposing the
|
|
76
75
|
* gamepad lifecycle listeners.
|