three-gamepad-controls 0.24.0 → 0.24.2
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 +33 -5
- package/dist/core.d.ts +9 -10
- package/dist/gamepad-arcball-controls.d.ts +5 -4
- package/dist/gamepad-arcball-controls.js +28 -13
- package/dist/gamepad-controls.d.ts +18 -11
- package/dist/gamepad-controls.js +13 -6
- package/dist/gamepad-drag-controls.d.ts +4 -6
- package/dist/gamepad-drag-controls.js +24 -15
- package/dist/gamepad-first-person-controls.d.ts +3 -4
- package/dist/gamepad-first-person-controls.js +1 -0
- package/dist/gamepad-fly-controls.d.ts +3 -4
- package/dist/gamepad-fly-controls.js +1 -0
- package/dist/gamepad-input.d.ts +26 -14
- package/dist/gamepad-input.js +15 -6
- package/dist/gamepad-manager.js +4 -2
- package/dist/gamepad-map-controls.d.ts +2 -3
- package/dist/gamepad-orbit-controls.d.ts +3 -4
- package/dist/gamepad-orbit-controls.js +22 -5
- package/dist/gamepad-pointer-lock-controls.d.ts +3 -4
- package/dist/gamepad-pointer-lock-controls.js +1 -0
- package/dist/gamepad-stick-processing.d.ts +16 -17
- package/dist/gamepad-trackball-controls.d.ts +3 -4
- package/dist/gamepad-trackball-controls.js +4 -13
- package/dist/gamepad-transform-controls.d.ts +4 -5
- package/dist/gamepad-transform-controls.js +252 -60
- package/package.json +10 -9
|
@@ -99,7 +99,18 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
99
99
|
#rotationQuaternion;
|
|
100
100
|
#rotationQuaternion2;
|
|
101
101
|
#tempQuaternion;
|
|
102
|
-
#
|
|
102
|
+
#segment = null;
|
|
103
|
+
#updating = false;
|
|
104
|
+
#ending = false;
|
|
105
|
+
#disposed = false;
|
|
106
|
+
#interrupted = false;
|
|
107
|
+
#needsNeutral = false;
|
|
108
|
+
#pointerRevision = 0;
|
|
109
|
+
#mouseDownEvent = {
|
|
110
|
+
type: "mouseDown",
|
|
111
|
+
mode: "translate"
|
|
112
|
+
};
|
|
113
|
+
#onNativeMouseDown;
|
|
103
114
|
#rotationAmount = 0;
|
|
104
115
|
#freeRotationX = 0;
|
|
105
116
|
#freeRotationY = 0;
|
|
@@ -150,6 +161,10 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
150
161
|
this.#rotationQuaternion = new Quaternion();
|
|
151
162
|
this.#rotationQuaternion2 = new Quaternion();
|
|
152
163
|
this.#tempQuaternion = new Quaternion();
|
|
164
|
+
this.#onNativeMouseDown = (event) => {
|
|
165
|
+
if (event !== this.#mouseDownEvent) this.#pointerRevision += 1;
|
|
166
|
+
};
|
|
167
|
+
controls.addEventListener("mouseDown", this.#onNativeMouseDown);
|
|
153
168
|
}
|
|
154
169
|
/**
|
|
155
170
|
* Maps the current gamepad state to `TransformControls` mode, axis,
|
|
@@ -158,38 +173,83 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
158
173
|
* @param deltaTime - Seconds since the last frame.
|
|
159
174
|
*/
|
|
160
175
|
onUpdate(deltaTime) {
|
|
176
|
+
if (this.#updating || this.#ending) return;
|
|
177
|
+
this.#updating = true;
|
|
178
|
+
this.#interrupted = false;
|
|
179
|
+
try {
|
|
180
|
+
this.#updateTransform(deltaTime);
|
|
181
|
+
} finally {
|
|
182
|
+
this.#updating = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Processes one frame of selection, reset, and movement while respecting
|
|
187
|
+
* segment ownership and the neutral input required before reacquisition.
|
|
188
|
+
*
|
|
189
|
+
* @param deltaTime - Seconds since the last frame.
|
|
190
|
+
*/
|
|
191
|
+
#updateTransform(deltaTime) {
|
|
192
|
+
const controls = this.#controls;
|
|
193
|
+
const { transformStick } = this.#options;
|
|
194
|
+
const transform = this.gamepadInput.stick(transformStick.xAxis, transformStick.yAxis, transformStick.pipeline);
|
|
195
|
+
const neutral = transform.x === 0 && transform.y === 0;
|
|
196
|
+
this.#reconcileSegment();
|
|
197
|
+
if (neutral) this.#needsNeutral = false;
|
|
198
|
+
if (!this.#canApplyInput()) return;
|
|
199
|
+
if (controls.dragging && this.#segment === null) {
|
|
200
|
+
this.#needsNeutral = !neutral;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
161
203
|
const startedButtons = this.#getStartedButtons();
|
|
162
204
|
this.#handleModeAndAxisButtons(startedButtons);
|
|
205
|
+
if (!this.#canApplyInput()) return;
|
|
163
206
|
if (startedButtons.has(this.#options.buttonReset)) this.#resetActiveTransform();
|
|
164
|
-
|
|
207
|
+
if (!this.#canApplyInput()) return;
|
|
165
208
|
const object = controls.object;
|
|
166
|
-
if (
|
|
209
|
+
if (object === void 0) {
|
|
167
210
|
this.#endTransform(true);
|
|
168
211
|
return;
|
|
169
212
|
}
|
|
170
|
-
|
|
171
|
-
if (axis === null) {
|
|
172
|
-
this.#endTransform(true);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const { transformStick } = this.#options;
|
|
176
|
-
const transform = this.gamepadInput.stick(transformStick.xAxis, transformStick.yAxis, transformStick.pipeline);
|
|
177
|
-
if (transform.x === 0 && transform.y === 0) {
|
|
213
|
+
if (neutral) {
|
|
178
214
|
this.#endTransform(false);
|
|
179
215
|
return;
|
|
180
216
|
}
|
|
181
|
-
if (
|
|
217
|
+
if (this.#needsNeutral) return;
|
|
218
|
+
const axis = this.#resolveAxis();
|
|
219
|
+
this.#setActiveAxis(axis);
|
|
220
|
+
if (!this.#canApplyInput()) return;
|
|
221
|
+
if (axis === null) return;
|
|
222
|
+
if (this.#segment === null) this.#startTransform(object, axis);
|
|
223
|
+
if (!this.#canApplyInput()) return;
|
|
224
|
+
const segment = this.#segment;
|
|
225
|
+
if (!segment.started) {
|
|
226
|
+
segment.started = true;
|
|
227
|
+
const context = this.#readContext();
|
|
228
|
+
this.#mouseDownEvent.mode = segment.mode;
|
|
229
|
+
controls.dispatchEvent(this.#mouseDownEvent);
|
|
230
|
+
this.#afterCallback(context);
|
|
231
|
+
}
|
|
232
|
+
if (!this.#canApplyInput()) return;
|
|
182
233
|
if (this.#applyCurrentTransform(object, axis, deltaTime, transform.x, transform.y)) {
|
|
234
|
+
const context = this.#readContext();
|
|
183
235
|
controls.dispatchEvent({ type: "change" });
|
|
236
|
+
if (!this.#afterCallback(context)) return;
|
|
184
237
|
controls.dispatchEvent({ type: "objectChange" });
|
|
238
|
+
this.#afterCallback(context);
|
|
185
239
|
}
|
|
186
240
|
}
|
|
187
241
|
/**
|
|
188
|
-
*
|
|
242
|
+
* Disables gamepad updates and ends only this wrapper's active transform.
|
|
189
243
|
*/
|
|
190
244
|
dispose() {
|
|
191
|
-
this.#endTransform(true);
|
|
192
245
|
super.dispose();
|
|
246
|
+
this.#disposed = true;
|
|
247
|
+
if (this.#ending) return;
|
|
248
|
+
try {
|
|
249
|
+
this.#endTransform(true);
|
|
250
|
+
} finally {
|
|
251
|
+
this.#controls.removeEventListener("mouseDown", this.#onNativeMouseDown);
|
|
252
|
+
}
|
|
193
253
|
}
|
|
194
254
|
/**
|
|
195
255
|
* Ends any active transform if the active gamepad disconnects mid-drag.
|
|
@@ -201,22 +261,108 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
201
261
|
super.onGamepadDisconnected(gamepad);
|
|
202
262
|
}
|
|
203
263
|
/**
|
|
264
|
+
* Checks whether this update can continue applying gamepad input.
|
|
265
|
+
* Native disable ends the owned segment; a wrapper pause retains it.
|
|
266
|
+
*
|
|
267
|
+
* @returns `true` when input remains enabled, a gamepad is available,
|
|
268
|
+
* and no callback has interrupted this update.
|
|
269
|
+
*/
|
|
270
|
+
#canApplyInput() {
|
|
271
|
+
if (!this.#controls.enabled) {
|
|
272
|
+
this.#endTransform(true);
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return !this.#interrupted && this.enabled && this.gamepad !== null;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Captures the native context and pointer acquisition revision without
|
|
279
|
+
* modifying the control or copying the attached object's transform.
|
|
280
|
+
*
|
|
281
|
+
* @returns A context snapshot for segment and callback validation.
|
|
282
|
+
*/
|
|
283
|
+
#readContext() {
|
|
284
|
+
const { object, mode, space, axis, dragging } = this.#controls;
|
|
285
|
+
return {
|
|
286
|
+
object,
|
|
287
|
+
mode,
|
|
288
|
+
space,
|
|
289
|
+
axis,
|
|
290
|
+
dragging,
|
|
291
|
+
pointerRevision: this.#pointerRevision
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Compares the current native context and pointer revision with a snapshot.
|
|
296
|
+
*
|
|
297
|
+
* @param context - Expected object, selection, dragging state, and pointer revision.
|
|
298
|
+
* @returns `true` when every captured context field still matches.
|
|
299
|
+
*/
|
|
300
|
+
#matchesContext(context) {
|
|
301
|
+
const controls = this.#controls;
|
|
302
|
+
return controls.object === context.object && controls.mode === context.mode && controls.space === context.space && controls.axis === context.axis && controls.dragging === context.dragging && this.#pointerRevision === context.pointerRevision;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Ends the owned segment when its context changes or its axis is disallowed.
|
|
306
|
+
* A change of attached object also requires neutral input before reacquisition.
|
|
307
|
+
*/
|
|
308
|
+
#reconcileSegment() {
|
|
309
|
+
const segment = this.#segment;
|
|
310
|
+
if (segment === null) return;
|
|
311
|
+
if (!this.#matchesContext(segment) || !this.#isAxisAllowed(segment.mode, segment.axis)) {
|
|
312
|
+
if (this.#controls.object !== segment.object) this.#needsNeutral = true;
|
|
313
|
+
this.#endTransform(false);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Revalidates context, segment ownership, and permissions after synchronous
|
|
318
|
+
* callbacks, interrupting this update if its context or segment was invalidated.
|
|
319
|
+
*
|
|
320
|
+
* @param context - Context expected after the operation that invoked callbacks.
|
|
321
|
+
* @returns `true` when this update may continue applying gamepad input.
|
|
322
|
+
*/
|
|
323
|
+
#afterCallback(context) {
|
|
324
|
+
const segment = this.#segment;
|
|
325
|
+
if (!this.#matchesContext(context)) {
|
|
326
|
+
this.#interrupted = true;
|
|
327
|
+
if (this.#controls.object !== context.object) this.#needsNeutral = true;
|
|
328
|
+
}
|
|
329
|
+
this.#reconcileSegment();
|
|
330
|
+
if (segment !== null && this.#segment !== segment) this.#interrupted = true;
|
|
331
|
+
return this.#canApplyInput();
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Writes a native property and revalidates the context after its synchronous
|
|
335
|
+
* notifications, accounting for the intended property change.
|
|
336
|
+
*
|
|
337
|
+
* @param key - Native selection or dragging property to update.
|
|
338
|
+
* @param value - Value to assign to the selected property.
|
|
339
|
+
*/
|
|
340
|
+
#writeProperty(key, value) {
|
|
341
|
+
const context = {
|
|
342
|
+
...this.#readContext(),
|
|
343
|
+
[key]: value
|
|
344
|
+
};
|
|
345
|
+
const controls = this.#controls;
|
|
346
|
+
controls[key] = value;
|
|
347
|
+
this.#afterCallback(context);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
204
350
|
* Applies mode, space, and axis button transitions from the current frame.
|
|
205
351
|
*
|
|
206
352
|
* @param startedButtons - Button indices that transitioned to pressed.
|
|
207
353
|
*/
|
|
208
354
|
#handleModeAndAxisButtons(startedButtons) {
|
|
209
355
|
const { buttonTranslate, buttonRotate, buttonScale, buttonToggleSpace, buttonAxisX, buttonAxisY, buttonAxisZ, buttonAxisComposite, buttonAxisPrevious, buttonAxisNext } = this.#options;
|
|
210
|
-
if (startedButtons.has(buttonTranslate)) this.#setMode("translate");
|
|
211
|
-
if (startedButtons.has(buttonRotate)) this.#setMode("rotate");
|
|
212
|
-
if (startedButtons.has(buttonScale)) this.#setMode("scale");
|
|
213
|
-
if (startedButtons.has(buttonToggleSpace)) this.#toggleSpace();
|
|
214
|
-
if (startedButtons.has(buttonAxisX)) this.#selectAxis("X");
|
|
215
|
-
if (startedButtons.has(buttonAxisY)) this.#selectAxis("Y");
|
|
216
|
-
if (startedButtons.has(buttonAxisZ)) this.#selectAxis("Z");
|
|
217
|
-
if (startedButtons.has(buttonAxisComposite)) this.#cycleCompositeAxis();
|
|
218
|
-
if (startedButtons.has(buttonAxisPrevious)) this.#cycleAxis(-1);
|
|
219
|
-
if (startedButtons.has(buttonAxisNext)) this.#cycleAxis(1);
|
|
356
|
+
if (startedButtons.has(buttonTranslate) && this.#canApplyInput()) this.#setMode("translate");
|
|
357
|
+
if (startedButtons.has(buttonRotate) && this.#canApplyInput()) this.#setMode("rotate");
|
|
358
|
+
if (startedButtons.has(buttonScale) && this.#canApplyInput()) this.#setMode("scale");
|
|
359
|
+
if (startedButtons.has(buttonToggleSpace) && this.#canApplyInput()) this.#toggleSpace();
|
|
360
|
+
if (startedButtons.has(buttonAxisX) && this.#canApplyInput()) this.#selectAxis("X");
|
|
361
|
+
if (startedButtons.has(buttonAxisY) && this.#canApplyInput()) this.#selectAxis("Y");
|
|
362
|
+
if (startedButtons.has(buttonAxisZ) && this.#canApplyInput()) this.#selectAxis("Z");
|
|
363
|
+
if (startedButtons.has(buttonAxisComposite) && this.#canApplyInput()) this.#cycleCompositeAxis();
|
|
364
|
+
if (startedButtons.has(buttonAxisPrevious) && this.#canApplyInput()) this.#cycleAxis(-1);
|
|
365
|
+
if (startedButtons.has(buttonAxisNext) && this.#canApplyInput()) this.#cycleAxis(1);
|
|
220
366
|
}
|
|
221
367
|
/**
|
|
222
368
|
* Switches TransformControls mode and refreshes the active axis.
|
|
@@ -226,13 +372,28 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
226
372
|
#setMode(mode) {
|
|
227
373
|
if (this.#controls.mode === mode) return;
|
|
228
374
|
this.#endTransform(false);
|
|
375
|
+
if (!this.#canApplyInput()) return;
|
|
376
|
+
const context = {
|
|
377
|
+
...this.#readContext(),
|
|
378
|
+
mode
|
|
379
|
+
};
|
|
229
380
|
this.#controls.setMode(mode);
|
|
230
|
-
this.#
|
|
381
|
+
if (this.#afterCallback(context)) this.#setActiveAxis(this.#resolveAxis(null));
|
|
231
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Ends the owned segment and toggles between local and world transform space
|
|
385
|
+
* if input remains permitted after the end notification.
|
|
386
|
+
*/
|
|
232
387
|
#toggleSpace() {
|
|
233
388
|
const nextSpace = this.#controls.space === "world" ? "local" : "world";
|
|
234
389
|
this.#endTransform(false);
|
|
390
|
+
if (!this.#canApplyInput()) return;
|
|
391
|
+
const context = {
|
|
392
|
+
...this.#readContext(),
|
|
393
|
+
space: nextSpace
|
|
394
|
+
};
|
|
235
395
|
this.#controls.setSpace(nextSpace);
|
|
396
|
+
this.#afterCallback(context);
|
|
236
397
|
}
|
|
237
398
|
/**
|
|
238
399
|
* Selects an explicit axis when it is valid for the current mode.
|
|
@@ -242,9 +403,12 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
242
403
|
#selectAxis(axis) {
|
|
243
404
|
if (!this.#isAxisAllowed(this.#controls.mode, axis)) return;
|
|
244
405
|
this.#endTransform(false);
|
|
245
|
-
this.#
|
|
246
|
-
this.#
|
|
406
|
+
if (!this.#canApplyInput()) return;
|
|
407
|
+
this.#setActiveAxis(axis);
|
|
247
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Selects the next visible composite axis available in the current mode.
|
|
411
|
+
*/
|
|
248
412
|
#cycleCompositeAxis() {
|
|
249
413
|
const validAxes = this.#getVisibleAxes(COMPOSITE_AXES[this.#controls.mode]);
|
|
250
414
|
this.#cycleThroughAxes(validAxes, 1);
|
|
@@ -264,30 +428,30 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
264
428
|
* @param direction - `1` for next axis, `-1` for previous axis.
|
|
265
429
|
*/
|
|
266
430
|
#cycleThroughAxes(axes, direction) {
|
|
431
|
+
this.#endTransform(false);
|
|
432
|
+
if (!this.#canApplyInput()) return;
|
|
267
433
|
if (axes.length === 0) {
|
|
268
434
|
this.#setActiveAxis(null);
|
|
269
435
|
return;
|
|
270
436
|
}
|
|
271
|
-
this.#
|
|
272
|
-
const
|
|
273
|
-
const currentIndex = current === null ? -1 : axes.indexOf(current);
|
|
437
|
+
const current = this.#resolveAxis();
|
|
438
|
+
const currentIndex = axes.indexOf(current);
|
|
274
439
|
const nextIndex = currentIndex === -1 ? 0 : (currentIndex + direction + axes.length) % axes.length;
|
|
275
|
-
this.#
|
|
276
|
-
this.#ensureValidAxis();
|
|
440
|
+
this.#setActiveAxis(axes[nextIndex]);
|
|
277
441
|
}
|
|
278
442
|
/**
|
|
279
|
-
*
|
|
443
|
+
* Resolves selection without writing to the native control or axis memory.
|
|
280
444
|
*
|
|
445
|
+
* @param nativeAxis - Preferred native axis, defaulting to the current selection.
|
|
446
|
+
* Pass `null` to use mode memory before the first allowed axis.
|
|
281
447
|
* @returns The active valid axis, or `null` when no axis is available.
|
|
282
448
|
*/
|
|
283
|
-
#
|
|
449
|
+
#resolveAxis(nativeAxis = this.#controls.axis) {
|
|
284
450
|
const mode = this.#controls.mode;
|
|
451
|
+
if (nativeAxis !== null && this.#isAxisAllowed(mode, nativeAxis)) return nativeAxis;
|
|
285
452
|
const current = this.#activeAxisByMode[mode];
|
|
286
453
|
const validAxes = this.#getValidAxes(mode);
|
|
287
|
-
|
|
288
|
-
this.#activeAxisByMode[mode] = nextAxis;
|
|
289
|
-
if (this.#controls.axis !== nextAxis) this.#controls.axis = nextAxis;
|
|
290
|
-
return nextAxis;
|
|
454
|
+
return current !== null && validAxes.includes(current) ? current : validAxes[0] ?? null;
|
|
291
455
|
}
|
|
292
456
|
/**
|
|
293
457
|
* Updates both the remembered axis for the current mode and the control axis.
|
|
@@ -296,7 +460,7 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
296
460
|
*/
|
|
297
461
|
#setActiveAxis(axis) {
|
|
298
462
|
this.#activeAxisByMode[this.#controls.mode] = axis;
|
|
299
|
-
if (this.#controls.axis !== axis) this.#
|
|
463
|
+
if (this.#controls.axis !== axis) this.#writeProperty("axis", axis);
|
|
300
464
|
}
|
|
301
465
|
/**
|
|
302
466
|
* Returns all visible axes supported by a TransformControls mode.
|
|
@@ -349,43 +513,71 @@ var GamepadTransformControls = class extends GamepadControls {
|
|
|
349
513
|
}
|
|
350
514
|
}
|
|
351
515
|
/**
|
|
352
|
-
*
|
|
516
|
+
* Captures a segment's transform origin and claims dragging ownership before
|
|
517
|
+
* notifying native property listeners. The update publishes `mouseDown` later.
|
|
353
518
|
*
|
|
354
519
|
* @param object - Object attached to TransformControls for this update.
|
|
520
|
+
* @param axis - Valid axis acquired for the new segment.
|
|
355
521
|
*/
|
|
356
|
-
#startTransform(object) {
|
|
357
|
-
const controls = this.#controls;
|
|
522
|
+
#startTransform(object, axis) {
|
|
358
523
|
this.#captureTransformStart(object);
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
524
|
+
this.#segment = {
|
|
525
|
+
...this.#readContext(),
|
|
526
|
+
object,
|
|
527
|
+
axis,
|
|
528
|
+
dragging: true,
|
|
529
|
+
started: false
|
|
530
|
+
};
|
|
531
|
+
this.#writeProperty("dragging", true);
|
|
365
532
|
}
|
|
366
533
|
/**
|
|
367
|
-
*
|
|
534
|
+
* Releases the owned segment and ends its published interaction once,
|
|
535
|
+
* preserving pointer ownership and context changes made by callbacks.
|
|
368
536
|
*
|
|
369
|
-
* @param clearAxis - Whether to clear the highlighted axis
|
|
537
|
+
* @param clearAxis - Whether to clear the highlighted axis if ownership
|
|
538
|
+
* and context still permit it after end notifications.
|
|
370
539
|
*/
|
|
371
540
|
#endTransform(clearAxis) {
|
|
541
|
+
const segment = this.#segment;
|
|
542
|
+
if (segment === null) return;
|
|
372
543
|
const controls = this.#controls;
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
544
|
+
const context = this.#readContext();
|
|
545
|
+
this.#segment = null;
|
|
546
|
+
this.#ending = true;
|
|
547
|
+
try {
|
|
548
|
+
if (segment.started) controls.dispatchEvent({
|
|
376
549
|
type: "mouseUp",
|
|
377
|
-
mode:
|
|
550
|
+
mode: segment.mode
|
|
378
551
|
});
|
|
379
|
-
|
|
552
|
+
const unchanged = this.#matchesContext(context);
|
|
553
|
+
if (!unchanged) {
|
|
554
|
+
this.#interrupted = true;
|
|
555
|
+
if (controls.object !== context.object) this.#needsNeutral = true;
|
|
556
|
+
}
|
|
557
|
+
const ownsDragging = this.#pointerRevision === segment.pointerRevision;
|
|
558
|
+
if (ownsDragging && controls.dragging === context.dragging) this.#writeProperty("dragging", false);
|
|
559
|
+
if (clearAxis && ownsDragging && unchanged && this.#matchesContext({
|
|
560
|
+
...context,
|
|
561
|
+
dragging: false
|
|
562
|
+
}) && controls.axis === segment.axis) this.#setActiveAxis(null);
|
|
563
|
+
} finally {
|
|
564
|
+
this.#ending = false;
|
|
565
|
+
if (this.#disposed) controls.removeEventListener("mouseDown", this.#onNativeMouseDown);
|
|
380
566
|
}
|
|
381
|
-
if (clearAxis) this.#setActiveAxis(null);
|
|
382
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* Restores the owned segment's transform origin through native reset and
|
|
570
|
+
* resets its accumulators if callbacks leave the same segment active.
|
|
571
|
+
*/
|
|
383
572
|
#resetActiveTransform() {
|
|
384
|
-
const
|
|
385
|
-
if (
|
|
573
|
+
const segment = this.#segment;
|
|
574
|
+
if (segment === null) return;
|
|
575
|
+
const context = this.#readContext();
|
|
386
576
|
this.#controls.reset();
|
|
387
|
-
this.#
|
|
388
|
-
this.#
|
|
577
|
+
this.#afterCallback(context);
|
|
578
|
+
if (this.#segment !== segment) return;
|
|
579
|
+
this.#accumulatedPosition.copy(segment.object.position);
|
|
580
|
+
this.#accumulatedScale.copy(segment.object.scale);
|
|
389
581
|
this.#rotationAmount = 0;
|
|
390
582
|
this.#freeRotationX = 0;
|
|
391
583
|
this.#freeRotationY = 0;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-gamepad-controls",
|
|
3
3
|
"description": "Gamepad support for Three.js controls.",
|
|
4
|
-
"version": "0.24.
|
|
4
|
+
"version": "0.24.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/luckasnix/three-gamepad-controls#readme",
|
|
7
7
|
"author": {
|
|
@@ -46,19 +46,20 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@biomejs/biome": "2.5.
|
|
50
|
-
"@commitlint/cli": "21.2.
|
|
51
|
-
"@commitlint/config-conventional": "21.2.
|
|
52
|
-
"@commitlint/types": "21.2.
|
|
49
|
+
"@biomejs/biome": "2.5.14",
|
|
50
|
+
"@commitlint/cli": "21.2.3",
|
|
51
|
+
"@commitlint/config-conventional": "21.2.3",
|
|
52
|
+
"@commitlint/types": "21.2.3",
|
|
53
53
|
"@types/node": "24.13.3",
|
|
54
54
|
"@types/three": "0.186.0",
|
|
55
|
-
"@vitest/
|
|
55
|
+
"@vitest/browser-playwright": "5.0.2",
|
|
56
|
+
"@vitest/coverage-v8": "5.0.2",
|
|
56
57
|
"husky": "9.1.7",
|
|
57
|
-
"
|
|
58
|
+
"playwright": "1.63.0",
|
|
58
59
|
"three": "0.186.0",
|
|
59
|
-
"tsdown": "0.
|
|
60
|
+
"tsdown": "0.23.0",
|
|
60
61
|
"typescript": "7.0.2",
|
|
61
|
-
"vitest": "5.0.
|
|
62
|
+
"vitest": "5.0.2"
|
|
62
63
|
},
|
|
63
64
|
"peerDependencies": {
|
|
64
65
|
"@types/three": "~0.186.0",
|