UNPKG

ive-connect

Version:

A universal haptic device control library for interactive experiences

94 lines (93 loc) 4.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertScriptPositionToDevicePosition = convertScriptPositionToDevicePosition; exports.createDeviceCommandExecutor = createDeviceCommandExecutor; exports.createMultiDeviceCommandExecutor = createMultiDeviceCommandExecutor; /** * Convert script position (0-100) to device position (0.0-1.0) */ function convertScriptPositionToDevicePosition(scriptPos, strokeMin = 0.0, strokeMax = 1.0, invert = false) { // Normalize scriptPos to 0.0-1.0 range let normalized = Math.min(1, Math.max(0, scriptPos / 100)); // Apply script inversion first if enabled if (invert) { normalized = 1.0 - normalized; } // Scale to stroke range return strokeMin + normalized * (strokeMax - strokeMin); } /** * Create a command executor for a specific device */ function createDeviceCommandExecutor(api, deviceInfo, preferences, invertScript = false) { // If device is disabled, return a no-op executor if (!preferences.enabled) { return { executeAction: async () => { /* No-op */ }, }; } // Track last position to detect unchanged positions let lastPos = -1; return { executeAction: async (pos, prevPos, durationMs, strokeRange = { min: 0, max: 1 }) => { try { // Convert position to device range with stroke range applied const position = convertScriptPositionToDevicePosition(pos, strokeRange.min, strokeRange.max, invertScript); // Apply device-specific intensity scaling if configured const intensity = preferences.intensity !== undefined ? preferences.intensity : 1.0; // For vibration and rotation: based on position directly // If position hasn't changed from last position, set to 0 let speed = Math.min(1.0, Math.max(0, pos / 100)) * intensity; // If position hasn't changed, set speed to 0 if (Math.abs(pos - lastPos) < 0.00001 && lastPos >= 0) { speed = 0; } // Save position for next time lastPos = pos; console.log(`Device ${deviceInfo.name} command:`, { speed, position, durationMs, strokeRange, }); // Send appropriate commands based on device capabilities and preferences if (deviceInfo.canLinear && preferences.useLinear) { await api.linearDevice(deviceInfo.index, position, durationMs); } if (deviceInfo.canVibrate && preferences.useVibrate) { await api.vibrateDevice(deviceInfo.index, invertScript ? 1 - speed : speed); } if (deviceInfo.canRotate && preferences.useRotate) { await api.rotateDevice(deviceInfo.index, speed, invertScript ? false : true); } } catch (error) { console.error(`Error executing command for device ${deviceInfo.name}:`, error); } }, }; } /** * Create a command executor for multiple devices */ function createMultiDeviceCommandExecutor(api, devices, preferences, invertScript = false) { // Create executors for all enabled devices const deviceExecutors = devices .filter((device) => { const devicePrefs = preferences.get(device.index); return devicePrefs && devicePrefs.enabled; }) .map((device) => { const devicePrefs = preferences.get(device.index); return createDeviceCommandExecutor(api, device, devicePrefs, invertScript); }); // Create a combined executor that will send commands to all devices return { executeAction: async (pos, prevPos, durationMs, strokeRange = { min: 0, max: 1 }) => { // Execute on all devices in parallel await Promise.all(deviceExecutors.map((executor) => executor.executeAction(pos, prevPos, durationMs, strokeRange))); }, }; }