three-gamepad-controls 0.19.0 → 0.20.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/dist/gamepad-stick-processing.d.ts +31 -4
- package/dist/gamepad-stick-processing.js +82 -66
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
//#region src/gamepad-stick-processing.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Geometry used when processing two-dimensional stick values.
|
|
4
|
+
*
|
|
5
|
+
* Axial processing transforms each component independently. Radial processing
|
|
6
|
+
* transforms vector magnitude while preserving direction.
|
|
7
|
+
*/
|
|
8
|
+
type GamepadStickProcessingMode = "axial" | "radial";
|
|
9
|
+
/**
|
|
10
|
+
* Built-in response curve applied to stick components or magnitude.
|
|
4
11
|
*/
|
|
5
|
-
type
|
|
12
|
+
type GamepadResponseCurve = "linear" | "quadratic" | "cubic";
|
|
6
13
|
/**
|
|
7
14
|
* Two-dimensional gamepad stick value.
|
|
8
15
|
*/
|
|
@@ -53,13 +60,26 @@ type GamepadDeadzoneProcessorOptions = {
|
|
|
53
60
|
* Whether to process each component or the vector magnitude.
|
|
54
61
|
* @default "axial"
|
|
55
62
|
*/
|
|
56
|
-
mode?:
|
|
63
|
+
mode?: GamepadStickProcessingMode;
|
|
57
64
|
/**
|
|
58
65
|
* Whether to remap values outside the dead zone to the full output range.
|
|
59
66
|
* @default false
|
|
60
67
|
*/
|
|
61
68
|
rescale?: boolean;
|
|
62
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Options for {@link createGamepadResponseCurveProcessor}.
|
|
72
|
+
*/
|
|
73
|
+
type GamepadResponseCurveProcessorOptions = {
|
|
74
|
+
/**
|
|
75
|
+
* Curve used to transform values in the normalized input range.
|
|
76
|
+
*/
|
|
77
|
+
curve: GamepadResponseCurve;
|
|
78
|
+
/**
|
|
79
|
+
* Whether to process each component or the vector magnitude.
|
|
80
|
+
*/
|
|
81
|
+
mode: GamepadStickProcessingMode;
|
|
82
|
+
};
|
|
63
83
|
/**
|
|
64
84
|
* Options for {@link createGamepadInversionProcessor}.
|
|
65
85
|
*/
|
|
@@ -115,6 +135,13 @@ declare const createGamepadStickPipeline: (...processors: readonly GamepadStickP
|
|
|
115
135
|
* @returns Stateless dead zone processor.
|
|
116
136
|
*/
|
|
117
137
|
declare const createGamepadDeadzoneProcessor: (options?: GamepadDeadzoneProcessorOptions) => GamepadStickProcessor;
|
|
138
|
+
/**
|
|
139
|
+
* Creates an axial or radial response curve processor.
|
|
140
|
+
*
|
|
141
|
+
* @param options - Response curve configuration.
|
|
142
|
+
* @returns Stateless response curve processor.
|
|
143
|
+
*/
|
|
144
|
+
declare const createGamepadResponseCurveProcessor: (options: GamepadResponseCurveProcessorOptions) => GamepadStickProcessor;
|
|
118
145
|
/**
|
|
119
146
|
* Creates a processor that independently inverts stick components.
|
|
120
147
|
*
|
|
@@ -135,4 +162,4 @@ declare const DEFAULT_GAMEPAD_STICK_PIPELINE: GamepadStickPipeline;
|
|
|
135
162
|
*/
|
|
136
163
|
declare const resolveGamepadStickBinding: (defaults: GamepadStickBinding, options?: GamepadStickBindingOptions) => GamepadStickBinding;
|
|
137
164
|
//#endregion
|
|
138
|
-
export { DEFAULT_GAMEPAD_STICK_PIPELINE,
|
|
165
|
+
export { DEFAULT_GAMEPAD_STICK_PIPELINE, GamepadDeadzoneProcessorOptions, GamepadInversionProcessorOptions, GamepadResponseCurve, GamepadResponseCurveProcessorOptions, GamepadStick, GamepadStickBinding, GamepadStickBindingOptions, GamepadStickPipeline, GamepadStickProcessingMode, GamepadStickProcessor, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
|
@@ -9,6 +9,51 @@ const DEFAULT_INVERSION_PROCESSOR_OPTIONS = {
|
|
|
9
9
|
invertY: false
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
+
* Returns a canonical stick result and preserves the original value when
|
|
13
|
+
* processing produced no change.
|
|
14
|
+
*
|
|
15
|
+
* @param source - Original stick value.
|
|
16
|
+
* @param x - Processed horizontal component.
|
|
17
|
+
* @param y - Processed vertical component.
|
|
18
|
+
* @returns Canonical processed stick value.
|
|
19
|
+
*/
|
|
20
|
+
const createGamepadStickResult = (source, x, y) => {
|
|
21
|
+
const canonicalX = x === 0 ? 0 : x;
|
|
22
|
+
const canonicalY = y === 0 ? 0 : y;
|
|
23
|
+
if (canonicalX === source.x && canonicalY === source.y && !Object.is(source.x, -0) && !Object.is(source.y, -0)) return source;
|
|
24
|
+
return {
|
|
25
|
+
x: canonicalX,
|
|
26
|
+
y: canonicalY
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Transforms the magnitude of a signed scalar while preserving its sign.
|
|
31
|
+
*
|
|
32
|
+
* @param value - Signed scalar value.
|
|
33
|
+
* @param mapMagnitude - Magnitude transformation.
|
|
34
|
+
* @returns Transformed signed value.
|
|
35
|
+
*/
|
|
36
|
+
const mapGamepadSignedMagnitude = (value, mapMagnitude) => {
|
|
37
|
+
if (value === 0) return 0;
|
|
38
|
+
return Math.sign(value) * mapMagnitude(Math.abs(value));
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Transforms stick magnitude while preserving vector direction.
|
|
42
|
+
*
|
|
43
|
+
* @param value - Stick value to transform.
|
|
44
|
+
* @param mapMagnitude - Magnitude transformation.
|
|
45
|
+
* @returns Stick with transformed magnitude.
|
|
46
|
+
*/
|
|
47
|
+
const mapGamepadStickMagnitude = (value, mapMagnitude) => {
|
|
48
|
+
const magnitude = Math.hypot(value.x, value.y);
|
|
49
|
+
if (magnitude === 0) return createGamepadStickResult(value, 0, 0);
|
|
50
|
+
const mappedMagnitude = mapMagnitude(magnitude);
|
|
51
|
+
if (mappedMagnitude === magnitude) return createGamepadStickResult(value, value.x, value.y);
|
|
52
|
+
if (mappedMagnitude === 0) return createGamepadStickResult(value, 0, 0);
|
|
53
|
+
const scale = mappedMagnitude / magnitude;
|
|
54
|
+
return createGamepadStickResult(value, value.x * scale, value.y * scale);
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
12
57
|
* Applies a dead zone and remaps the remaining magnitude to `[0, 1]`.
|
|
13
58
|
*
|
|
14
59
|
* @param magnitude - Non-negative input magnitude.
|
|
@@ -20,21 +65,22 @@ const rescaleGamepadDeadzoneMagnitude = (magnitude, threshold) => {
|
|
|
20
65
|
return Math.min((magnitude - threshold) / (1 - threshold), 1);
|
|
21
66
|
};
|
|
22
67
|
/**
|
|
23
|
-
* Applies
|
|
68
|
+
* Applies a built-in curve to a normalized magnitude.
|
|
24
69
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
70
|
+
* Magnitudes above `1` remain unchanged so response curves do not implicitly
|
|
71
|
+
* clamp or normalize custom processor output.
|
|
72
|
+
*
|
|
73
|
+
* @param magnitude - Non-negative component or vector magnitude.
|
|
74
|
+
* @param curve - Curve to apply.
|
|
75
|
+
* @returns Curved magnitude.
|
|
29
76
|
*/
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return Math.sign(value) * rescaledMagnitude;
|
|
77
|
+
const applyGamepadResponseCurve = (magnitude, curve) => {
|
|
78
|
+
if (magnitude > 1) return magnitude;
|
|
79
|
+
switch (curve) {
|
|
80
|
+
case "linear": return magnitude;
|
|
81
|
+
case "quadratic": return magnitude ** 2;
|
|
82
|
+
case "cubic": return magnitude ** 3;
|
|
83
|
+
}
|
|
38
84
|
};
|
|
39
85
|
/**
|
|
40
86
|
* Creates an ordered pipeline from stateless stick processors.
|
|
@@ -67,47 +113,27 @@ const createGamepadDeadzoneProcessor = (options) => {
|
|
|
67
113
|
...DEFAULT_DEADZONE_PROCESSOR_OPTIONS,
|
|
68
114
|
...options
|
|
69
115
|
};
|
|
116
|
+
const mapMagnitude = (magnitude) => {
|
|
117
|
+
if (magnitude < threshold) return 0;
|
|
118
|
+
return rescale ? rescaleGamepadDeadzoneMagnitude(magnitude, threshold) : magnitude;
|
|
119
|
+
};
|
|
70
120
|
return Object.freeze({ process(value) {
|
|
71
|
-
if (mode === "axial")
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
if (!rescale) {
|
|
89
|
-
if (!Object.is(value.x, -0) && !Object.is(value.y, -0)) return value;
|
|
90
|
-
return {
|
|
91
|
-
x: value.x === 0 ? 0 : value.x,
|
|
92
|
-
y: value.y === 0 ? 0 : value.y
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
const rescaledMagnitude = rescaleGamepadDeadzoneMagnitude(magnitude, threshold);
|
|
96
|
-
if (rescaledMagnitude === 0 || magnitude === 0) {
|
|
97
|
-
if (value.x === 0 && value.y === 0 && !Object.is(value.x, -0) && !Object.is(value.y, -0)) return value;
|
|
98
|
-
return {
|
|
99
|
-
x: 0,
|
|
100
|
-
y: 0
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
const scale = rescaledMagnitude / magnitude;
|
|
104
|
-
const x = value.x === 0 ? 0 : value.x * scale;
|
|
105
|
-
const y = value.y === 0 ? 0 : value.y * scale;
|
|
106
|
-
if (x === value.x && y === value.y && !Object.is(value.x, -0) && !Object.is(value.y, -0)) return value;
|
|
107
|
-
return {
|
|
108
|
-
x,
|
|
109
|
-
y
|
|
110
|
-
};
|
|
121
|
+
if (mode === "axial") return createGamepadStickResult(value, mapGamepadSignedMagnitude(value.x, mapMagnitude), mapGamepadSignedMagnitude(value.y, mapMagnitude));
|
|
122
|
+
return mapGamepadStickMagnitude(value, mapMagnitude);
|
|
123
|
+
} });
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Creates an axial or radial response curve processor.
|
|
127
|
+
*
|
|
128
|
+
* @param options - Response curve configuration.
|
|
129
|
+
* @returns Stateless response curve processor.
|
|
130
|
+
*/
|
|
131
|
+
const createGamepadResponseCurveProcessor = (options) => {
|
|
132
|
+
const { curve, mode } = options;
|
|
133
|
+
const mapMagnitude = (magnitude) => applyGamepadResponseCurve(magnitude, curve);
|
|
134
|
+
return Object.freeze({ process(value) {
|
|
135
|
+
if (mode === "axial") return createGamepadStickResult(value, mapGamepadSignedMagnitude(value.x, mapMagnitude), mapGamepadSignedMagnitude(value.y, mapMagnitude));
|
|
136
|
+
return mapGamepadStickMagnitude(value, mapMagnitude);
|
|
111
137
|
} });
|
|
112
138
|
};
|
|
113
139
|
/**
|
|
@@ -122,20 +148,10 @@ const createGamepadInversionProcessor = (options) => {
|
|
|
122
148
|
...options
|
|
123
149
|
};
|
|
124
150
|
return Object.freeze({ process(value) {
|
|
125
|
-
if (!invertX && !invertY)
|
|
126
|
-
if (!Object.is(value.x, -0) && !Object.is(value.y, -0)) return value;
|
|
127
|
-
return {
|
|
128
|
-
x: value.x === 0 ? 0 : value.x,
|
|
129
|
-
y: value.y === 0 ? 0 : value.y
|
|
130
|
-
};
|
|
131
|
-
}
|
|
151
|
+
if (!invertX && !invertY) return createGamepadStickResult(value, value.x, value.y);
|
|
132
152
|
const x = value.x === 0 ? 0 : invertX ? -value.x : value.x;
|
|
133
153
|
const y = value.y === 0 ? 0 : invertY ? -value.y : value.y;
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
x,
|
|
137
|
-
y
|
|
138
|
-
};
|
|
154
|
+
return createGamepadStickResult(value, x, y);
|
|
139
155
|
} });
|
|
140
156
|
};
|
|
141
157
|
/**
|
|
@@ -157,4 +173,4 @@ const resolveGamepadStickBinding = (defaults, options) => {
|
|
|
157
173
|
};
|
|
158
174
|
};
|
|
159
175
|
//#endregion
|
|
160
|
-
export { DEFAULT_GAMEPAD_STICK_PIPELINE, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
|
176
|
+
export { DEFAULT_GAMEPAD_STICK_PIPELINE, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX } from "./core.js";
|
|
2
|
-
import { DEFAULT_GAMEPAD_STICK_PIPELINE,
|
|
2
|
+
import { DEFAULT_GAMEPAD_STICK_PIPELINE, GamepadDeadzoneProcessorOptions, GamepadInversionProcessorOptions, GamepadResponseCurve, GamepadResponseCurveProcessorOptions, GamepadStick, GamepadStickBinding, GamepadStickBindingOptions, GamepadStickPipeline, GamepadStickProcessingMode, GamepadStickProcessor, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding } from "./gamepad-stick-processing.js";
|
|
3
3
|
import { GamepadAxisOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions } from "./gamepad-input.js";
|
|
4
4
|
import { GamepadControls, GamepadControlsEventMap, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
5
5
|
import { GamepadArcballControls, GamepadArcballControlsOptions } from "./gamepad-arcball-controls.js";
|
|
@@ -11,4 +11,4 @@ import { GamepadMapControls } from "./gamepad-map-controls.js";
|
|
|
11
11
|
import { GamepadPointerLockControls, GamepadPointerLockControlsOptions } from "./gamepad-pointer-lock-controls.js";
|
|
12
12
|
import { GamepadTrackballControls, GamepadTrackballControlsOptions } from "./gamepad-trackball-controls.js";
|
|
13
13
|
import { GamepadTransformControls, GamepadTransformControlsOptions } from "./gamepad-transform-controls.js";
|
|
14
|
-
export { DEFAULT_GAMEPAD_STICK_PIPELINE, GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadArcballControlsOptions, GamepadAxisKey, GamepadAxisOptions, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, GamepadControls, GamepadControlsEventMap, GamepadControlsOptions,
|
|
14
|
+
export { DEFAULT_GAMEPAD_STICK_PIPELINE, GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadArcballControlsOptions, GamepadAxisKey, GamepadAxisOptions, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, GamepadControls, GamepadControlsEventMap, GamepadControlsOptions, GamepadDeadzoneProcessorOptions, GamepadDragControls, GamepadDragControlsOptions, GamepadFirstPersonControls, GamepadFirstPersonControlsOptions, GamepadFlyControls, GamepadFlyControlsOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadInversionProcessorOptions, GamepadMapControls, GamepadOrbitControls, GamepadOrbitControlsOptions, GamepadPointerLockControls, GamepadPointerLockControlsOptions, GamepadResponseCurve, GamepadResponseCurveProcessorOptions, GamepadStick, GamepadStickBinding, GamepadStickBindingOptions, GamepadStickPipeline, GamepadStickProcessingMode, GamepadStickProcessor, GamepadTrackballControls, GamepadTrackballControlsOptions, GamepadTransformControls, GamepadTransformControlsOptions, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX } from "./core.js";
|
|
2
|
-
import { DEFAULT_GAMEPAD_STICK_PIPELINE, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadStickPipeline, resolveGamepadStickBinding } from "./gamepad-stick-processing.js";
|
|
2
|
+
import { DEFAULT_GAMEPAD_STICK_PIPELINE, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding } from "./gamepad-stick-processing.js";
|
|
3
3
|
import { GamepadInput } from "./gamepad-input.js";
|
|
4
4
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
5
5
|
import { GamepadArcballControls } from "./gamepad-arcball-controls.js";
|
|
@@ -11,4 +11,4 @@ import { GamepadMapControls } from "./gamepad-map-controls.js";
|
|
|
11
11
|
import { GamepadPointerLockControls } from "./gamepad-pointer-lock-controls.js";
|
|
12
12
|
import { GamepadTrackballControls } from "./gamepad-trackball-controls.js";
|
|
13
13
|
import { GamepadTransformControls } from "./gamepad-transform-controls.js";
|
|
14
|
-
export { DEFAULT_GAMEPAD_STICK_PIPELINE, GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadControls, GamepadDragControls, GamepadFirstPersonControls, GamepadFlyControls, GamepadInput, GamepadMapControls, GamepadOrbitControls, GamepadPointerLockControls, GamepadTrackballControls, GamepadTransformControls, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
|
14
|
+
export { DEFAULT_GAMEPAD_STICK_PIPELINE, GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadControls, GamepadDragControls, GamepadFirstPersonControls, GamepadFlyControls, GamepadInput, GamepadMapControls, GamepadOrbitControls, GamepadPointerLockControls, GamepadTrackballControls, GamepadTransformControls, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX, createGamepadDeadzoneProcessor, createGamepadInversionProcessor, createGamepadResponseCurveProcessor, createGamepadStickPipeline, resolveGamepadStickBinding };
|
package/package.json
CHANGED