@kelnishi/satmouse-client 0.9.4 → 0.9.5
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/react/index.cjs +66 -3
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +31 -1
- package/dist/react/index.d.ts +31 -1
- package/dist/react/index.js +66 -3
- package/dist/react/index.js.map +1 -1
- package/dist/utils/index.cjs +80 -3
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +43 -2
- package/dist/utils/index.d.ts +43 -2
- package/dist/utils/index.js +77 -4
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -119,6 +119,29 @@ type AxisMap = {
|
|
|
119
119
|
rz: keyof Vec3;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
/** Input axis identifier */
|
|
123
|
+
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
|
|
124
|
+
/** A single action binding — maps one input axis to a named output */
|
|
125
|
+
interface ActionBinding {
|
|
126
|
+
/** Which input axis drives this action */
|
|
127
|
+
source: InputAxis;
|
|
128
|
+
/** Scale multiplier (default: 1) */
|
|
129
|
+
scale?: number;
|
|
130
|
+
/** Invert the value (default: false) */
|
|
131
|
+
invert?: boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* ActionMap defines how raw 6DOF axes map to named output actions.
|
|
135
|
+
*
|
|
136
|
+
* Client apps declare the actions they support and how device axes
|
|
137
|
+
* feed into them. Users can reassign axes via the settings UI.
|
|
138
|
+
*
|
|
139
|
+
* Default: 6 actions matching the 6 input axes (passthrough).
|
|
140
|
+
*/
|
|
141
|
+
type ActionMap = Record<string, ActionBinding>;
|
|
142
|
+
/** Result of applying an ActionMap to spatial data */
|
|
143
|
+
type ActionValues = Record<string, number>;
|
|
144
|
+
|
|
122
145
|
/** Per-device transform overrides. Any field left undefined inherits from global defaults. */
|
|
123
146
|
interface DeviceConfig {
|
|
124
147
|
sensitivity?: Partial<SensitivityConfig>;
|
|
@@ -126,6 +149,7 @@ interface DeviceConfig {
|
|
|
126
149
|
deadZone?: number;
|
|
127
150
|
dominant?: boolean;
|
|
128
151
|
axisRemap?: Partial<AxisMap>;
|
|
152
|
+
actionMap?: ActionMap;
|
|
129
153
|
lockPosition?: boolean;
|
|
130
154
|
lockRotation?: boolean;
|
|
131
155
|
}
|
|
@@ -138,6 +162,8 @@ interface InputConfig {
|
|
|
138
162
|
axisRemap: AxisMap;
|
|
139
163
|
lockPosition: boolean;
|
|
140
164
|
lockRotation: boolean;
|
|
165
|
+
/** Action map — maps input axes to named output actions. Default: passthrough. */
|
|
166
|
+
actionMap: ActionMap;
|
|
141
167
|
/**
|
|
142
168
|
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
143
169
|
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
@@ -152,8 +178,10 @@ interface StorageAdapter {
|
|
|
152
178
|
}
|
|
153
179
|
|
|
154
180
|
interface InputManagerEvents {
|
|
155
|
-
/** Processed spatial data (after all transforms) */
|
|
181
|
+
/** Processed spatial data (after all transforms + action map) */
|
|
156
182
|
spatialData: (data: SpatialData) => void;
|
|
183
|
+
/** Named action values from the action map */
|
|
184
|
+
actionValues: (values: ActionValues) => void;
|
|
157
185
|
/** Raw spatial data (before transforms) */
|
|
158
186
|
rawSpatialData: (data: SpatialData) => void;
|
|
159
187
|
/** Button event (pass-through from connection) */
|
|
@@ -209,6 +237,8 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
209
237
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
210
238
|
/** Register a callback for button events. Returns unsubscribe function. */
|
|
211
239
|
onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
|
|
240
|
+
/** Register a callback for action values. Returns unsubscribe function. */
|
|
241
|
+
onActionValues(callback: (values: ActionValues) => void): () => void;
|
|
212
242
|
private wireConnection;
|
|
213
243
|
private processSpatialData;
|
|
214
244
|
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -119,6 +119,29 @@ type AxisMap = {
|
|
|
119
119
|
rz: keyof Vec3;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
/** Input axis identifier */
|
|
123
|
+
type InputAxis = "tx" | "ty" | "tz" | "rx" | "ry" | "rz";
|
|
124
|
+
/** A single action binding — maps one input axis to a named output */
|
|
125
|
+
interface ActionBinding {
|
|
126
|
+
/** Which input axis drives this action */
|
|
127
|
+
source: InputAxis;
|
|
128
|
+
/** Scale multiplier (default: 1) */
|
|
129
|
+
scale?: number;
|
|
130
|
+
/** Invert the value (default: false) */
|
|
131
|
+
invert?: boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* ActionMap defines how raw 6DOF axes map to named output actions.
|
|
135
|
+
*
|
|
136
|
+
* Client apps declare the actions they support and how device axes
|
|
137
|
+
* feed into them. Users can reassign axes via the settings UI.
|
|
138
|
+
*
|
|
139
|
+
* Default: 6 actions matching the 6 input axes (passthrough).
|
|
140
|
+
*/
|
|
141
|
+
type ActionMap = Record<string, ActionBinding>;
|
|
142
|
+
/** Result of applying an ActionMap to spatial data */
|
|
143
|
+
type ActionValues = Record<string, number>;
|
|
144
|
+
|
|
122
145
|
/** Per-device transform overrides. Any field left undefined inherits from global defaults. */
|
|
123
146
|
interface DeviceConfig {
|
|
124
147
|
sensitivity?: Partial<SensitivityConfig>;
|
|
@@ -126,6 +149,7 @@ interface DeviceConfig {
|
|
|
126
149
|
deadZone?: number;
|
|
127
150
|
dominant?: boolean;
|
|
128
151
|
axisRemap?: Partial<AxisMap>;
|
|
152
|
+
actionMap?: ActionMap;
|
|
129
153
|
lockPosition?: boolean;
|
|
130
154
|
lockRotation?: boolean;
|
|
131
155
|
}
|
|
@@ -138,6 +162,8 @@ interface InputConfig {
|
|
|
138
162
|
axisRemap: AxisMap;
|
|
139
163
|
lockPosition: boolean;
|
|
140
164
|
lockRotation: boolean;
|
|
165
|
+
/** Action map — maps input axes to named output actions. Default: passthrough. */
|
|
166
|
+
actionMap: ActionMap;
|
|
141
167
|
/**
|
|
142
168
|
* Per-device overrides, keyed by device ID (e.g., "spacemouse-c635")
|
|
143
169
|
* or device family pattern (e.g., "spacemouse-*", "hid-054c-*").
|
|
@@ -152,8 +178,10 @@ interface StorageAdapter {
|
|
|
152
178
|
}
|
|
153
179
|
|
|
154
180
|
interface InputManagerEvents {
|
|
155
|
-
/** Processed spatial data (after all transforms) */
|
|
181
|
+
/** Processed spatial data (after all transforms + action map) */
|
|
156
182
|
spatialData: (data: SpatialData) => void;
|
|
183
|
+
/** Named action values from the action map */
|
|
184
|
+
actionValues: (values: ActionValues) => void;
|
|
157
185
|
/** Raw spatial data (before transforms) */
|
|
158
186
|
rawSpatialData: (data: SpatialData) => void;
|
|
159
187
|
/** Button event (pass-through from connection) */
|
|
@@ -209,6 +237,8 @@ declare class InputManager extends TypedEmitter<InputManagerEvents> {
|
|
|
209
237
|
onSpatialData(callback: (data: SpatialData) => void): () => void;
|
|
210
238
|
/** Register a callback for button events. Returns unsubscribe function. */
|
|
211
239
|
onButtonEvent(callback: (data: ButtonEvent) => void): () => void;
|
|
240
|
+
/** Register a callback for action values. Returns unsubscribe function. */
|
|
241
|
+
onActionValues(callback: (values: ActionValues) => void): () => void;
|
|
212
242
|
private wireConnection;
|
|
213
243
|
private processSpatialData;
|
|
214
244
|
}
|
package/dist/react/index.js
CHANGED
|
@@ -425,6 +425,57 @@ function launchSatMouse(options) {
|
|
|
425
425
|
});
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
// src/utils/action-map.ts
|
|
429
|
+
var DEFAULT_ACTION_MAP = {
|
|
430
|
+
tx: { source: "tx" },
|
|
431
|
+
ty: { source: "ty" },
|
|
432
|
+
tz: { source: "tz" },
|
|
433
|
+
rx: { source: "rx" },
|
|
434
|
+
ry: { source: "ry" },
|
|
435
|
+
rz: { source: "rz" }
|
|
436
|
+
};
|
|
437
|
+
function readAxis(data, axis) {
|
|
438
|
+
switch (axis) {
|
|
439
|
+
case "tx":
|
|
440
|
+
return data.translation.x;
|
|
441
|
+
case "ty":
|
|
442
|
+
return data.translation.y;
|
|
443
|
+
case "tz":
|
|
444
|
+
return data.translation.z;
|
|
445
|
+
case "rx":
|
|
446
|
+
return data.rotation.x;
|
|
447
|
+
case "ry":
|
|
448
|
+
return data.rotation.y;
|
|
449
|
+
case "rz":
|
|
450
|
+
return data.rotation.z;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function applyActionMap(data, map) {
|
|
454
|
+
const result = {};
|
|
455
|
+
for (const [action, binding] of Object.entries(map)) {
|
|
456
|
+
let value = readAxis(data, binding.source);
|
|
457
|
+
if (binding.invert) value = -value;
|
|
458
|
+
value *= binding.scale ?? 1;
|
|
459
|
+
result[action] = value;
|
|
460
|
+
}
|
|
461
|
+
return result;
|
|
462
|
+
}
|
|
463
|
+
function actionValuesToSpatialData(values, timestamp) {
|
|
464
|
+
return {
|
|
465
|
+
translation: {
|
|
466
|
+
x: values.tx ?? 0,
|
|
467
|
+
y: values.ty ?? 0,
|
|
468
|
+
z: values.tz ?? 0
|
|
469
|
+
},
|
|
470
|
+
rotation: {
|
|
471
|
+
x: values.rx ?? 0,
|
|
472
|
+
y: values.ry ?? 0,
|
|
473
|
+
z: values.rz ?? 0
|
|
474
|
+
},
|
|
475
|
+
timestamp
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
428
479
|
// src/utils/config.ts
|
|
429
480
|
var DEFAULT_CONFIG = {
|
|
430
481
|
sensitivity: { translation: 1e-3, rotation: 1e-3 },
|
|
@@ -434,6 +485,7 @@ var DEFAULT_CONFIG = {
|
|
|
434
485
|
axisRemap: { tx: "x", ty: "y", tz: "z", rx: "x", ry: "y", rz: "z" },
|
|
435
486
|
lockPosition: false,
|
|
436
487
|
lockRotation: false,
|
|
488
|
+
actionMap: { ...DEFAULT_ACTION_MAP },
|
|
437
489
|
devices: {}
|
|
438
490
|
};
|
|
439
491
|
function mergeConfig(base, partial) {
|
|
@@ -443,6 +495,7 @@ function mergeConfig(base, partial) {
|
|
|
443
495
|
sensitivity: { ...base.sensitivity, ...partial.sensitivity },
|
|
444
496
|
flip: { ...base.flip, ...partial.flip },
|
|
445
497
|
axisRemap: { ...base.axisRemap, ...partial.axisRemap },
|
|
498
|
+
actionMap: partial.actionMap ? { ...base.actionMap, ...partial.actionMap } : { ...base.actionMap },
|
|
446
499
|
devices: { ...base.devices }
|
|
447
500
|
};
|
|
448
501
|
if (partial.devices) {
|
|
@@ -482,6 +535,7 @@ function resolveDeviceConfig(config, deviceId) {
|
|
|
482
535
|
deadZone: deviceOverride.deadZone ?? config.deadZone,
|
|
483
536
|
dominant: deviceOverride.dominant ?? config.dominant,
|
|
484
537
|
axisRemap: { ...config.axisRemap, ...deviceOverride.axisRemap },
|
|
538
|
+
actionMap: deviceOverride.actionMap ? { ...config.actionMap, ...deviceOverride.actionMap } : config.actionMap,
|
|
485
539
|
lockPosition: deviceOverride.lockPosition ?? config.lockPosition,
|
|
486
540
|
lockRotation: deviceOverride.lockRotation ?? config.lockRotation
|
|
487
541
|
};
|
|
@@ -648,6 +702,7 @@ var InputManager = class extends TypedEmitter {
|
|
|
648
702
|
deadZone: resolved.deadZone,
|
|
649
703
|
dominant: resolved.dominant,
|
|
650
704
|
axisRemap: resolved.axisRemap,
|
|
705
|
+
actionMap: resolved.actionMap,
|
|
651
706
|
lockPosition: resolved.lockPosition,
|
|
652
707
|
lockRotation: resolved.lockRotation
|
|
653
708
|
};
|
|
@@ -677,11 +732,17 @@ var InputManager = class extends TypedEmitter {
|
|
|
677
732
|
this.on("buttonEvent", callback);
|
|
678
733
|
return () => this.off("buttonEvent", callback);
|
|
679
734
|
}
|
|
735
|
+
/** Register a callback for action values. Returns unsubscribe function. */
|
|
736
|
+
onActionValues(callback) {
|
|
737
|
+
this.on("actionValues", callback);
|
|
738
|
+
return () => this.off("actionValues", callback);
|
|
739
|
+
}
|
|
680
740
|
wireConnection(connection) {
|
|
681
741
|
connection.on("spatialData", (raw) => {
|
|
682
742
|
this.emit("rawSpatialData", raw);
|
|
683
|
-
const
|
|
684
|
-
if (
|
|
743
|
+
const { spatial, actions } = this.processSpatialData(raw);
|
|
744
|
+
if (spatial) this.emit("spatialData", spatial);
|
|
745
|
+
if (actions) this.emit("actionValues", actions);
|
|
685
746
|
});
|
|
686
747
|
connection.on("buttonEvent", (event) => this.emit("buttonEvent", event));
|
|
687
748
|
connection.on("stateChange", (state, proto) => this.emit("stateChange", state, proto));
|
|
@@ -705,7 +766,9 @@ var InputManager = class extends TypedEmitter {
|
|
|
705
766
|
if (cfg.lockRotation) {
|
|
706
767
|
data = { ...data, rotation: { x: 0, y: 0, z: 0 } };
|
|
707
768
|
}
|
|
708
|
-
|
|
769
|
+
const actions = applyActionMap(data, cfg.actionMap);
|
|
770
|
+
const spatial = actionValuesToSpatialData(actions, data.timestamp);
|
|
771
|
+
return { spatial, actions };
|
|
709
772
|
}
|
|
710
773
|
};
|
|
711
774
|
var SatMouseContext = createContext(null);
|