From c3d97a94635f325c7f239150c3dd2e125474abff Mon Sep 17 00:00:00 2001 From: Uriel Date: Tue, 9 Apr 2024 17:54:48 -0300 Subject: [PATCH] Add support for left/right steamvr toggles (#982) --- gui/public/i18n/en/translation.ftl | 12 +- .../settings/pages/GeneralSettings.tsx | 126 ++++++++++++++---- .../rpc/settings/RPCSettingsBuilder.java | 19 +-- .../rpc/settings/RPCSettingsHandler.kt | 16 +-- .../dev/slimevr/tracking/trackers/Device.kt | 3 + .../tracking/trackers/TrackerPosition.kt | 8 +- .../slimevr/desktop/platform/SteamVRBridge.kt | 57 ++++++-- solarxr-protocol | 2 +- 8 files changed, 177 insertions(+), 66 deletions(-) diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl index 0e3f334acb..6cff670494 100644 --- a/gui/public/i18n/en/translation.ftl +++ b/gui/public/i18n/en/translation.ftl @@ -284,10 +284,14 @@ settings-general-steamvr-description = Useful for games or apps that only support certain trackers. settings-general-steamvr-trackers-waist = Waist settings-general-steamvr-trackers-chest = Chest -settings-general-steamvr-trackers-feet = Feet -settings-general-steamvr-trackers-knees = Knees -settings-general-steamvr-trackers-elbows = Elbows -settings-general-steamvr-trackers-hands = Hands +settings-general-steamvr-trackers-left_foot = Left foot +settings-general-steamvr-trackers-right_foot = Right foot +settings-general-steamvr-trackers-left_knee = Left knee +settings-general-steamvr-trackers-right_knee = Right knee +settings-general-steamvr-trackers-left_elbow = Left elbow +settings-general-steamvr-trackers-right_elbow = Right elbow +settings-general-steamvr-trackers-left_hand = Left hand +settings-general-steamvr-trackers-right_hand = Right hand settings-general-steamvr-trackers-tracker_toggling = Automatic tracker assignment settings-general-steamvr-trackers-tracker_toggling-description = Automatically handles toggling SteamVR trackers on or off depending on your current tracker assignments settings-general-steamvr-trackers-tracker_toggling-label = Automatic tracker assignment diff --git a/gui/src/components/settings/pages/GeneralSettings.tsx b/gui/src/components/settings/pages/GeneralSettings.tsx index ffd30d1822..ebc9c3057c 100644 --- a/gui/src/components/settings/pages/GeneralSettings.tsx +++ b/gui/src/components/settings/pages/GeneralSettings.tsx @@ -36,11 +36,15 @@ interface SettingsForm { trackers: { waist: boolean; chest: boolean; - feet: boolean; - knees: boolean; - elbows: boolean; - hands: boolean; automaticTrackerToggle: boolean; + leftFoot: boolean; + rightFoot: boolean; + leftKnee: boolean; + rightKnee: boolean; + leftElbow: boolean; + rightElbow: boolean; + leftHand: boolean; + rightHand: boolean; }; filtering: { type: number; @@ -95,14 +99,19 @@ interface SettingsForm { }; } -const defaultValues = { +const defaultValues: SettingsForm = { trackers: { waist: false, chest: false, - elbows: false, - knees: false, - feet: false, - hands: false, + automaticTrackerToggle: true, + leftFoot: false, + rightFoot: false, + leftElbow: false, + rightElbow: false, + leftHand: false, + rightHand: false, + leftKnee: false, + rightKnee: false, }, toggles: { extendedSpine: true, @@ -176,7 +185,11 @@ export function GeneralSettings() { defaultValues, }); const { - trackers: { automaticTrackerToggle, hands: steamVrHands }, + trackers: { + automaticTrackerToggle, + leftHand: steamVrLeftHand, + rightHand: steamVrRightHand, + }, } = watch(); const onSubmit = (values: SettingsForm) => { @@ -186,10 +199,18 @@ export function GeneralSettings() { const trackers = new SteamVRTrackersSettingT(); trackers.waist = values.trackers.waist; trackers.chest = values.trackers.chest; - trackers.feet = values.trackers.feet; - trackers.knees = values.trackers.knees; - trackers.elbows = values.trackers.elbows; - trackers.hands = values.trackers.hands; + trackers.leftFoot = values.trackers.leftFoot; + trackers.rightFoot = values.trackers.rightFoot; + + trackers.leftKnee = values.trackers.leftKnee; + trackers.rightKnee = values.trackers.rightKnee; + + trackers.leftElbow = values.trackers.leftElbow; + trackers.rightElbow = values.trackers.rightElbow; + + trackers.leftHand = values.trackers.leftHand; + trackers.rightHand = values.trackers.rightHand; + trackers.automaticTrackerToggle = values.trackers.automaticTrackerToggle; settings.steamVrTrackers = trackers; } @@ -304,7 +325,10 @@ export function GeneralSettings() { if (settings.steamVrTrackers) { formData.trackers = settings.steamVrTrackers; - if (settings.steamVrTrackers.hands) { + if ( + settings.steamVrTrackers.leftHand && + settings.steamVrTrackers.rightHand + ) { setHandsWarning(false); } } @@ -386,12 +410,15 @@ export function GeneralSettings() { }); useEffect(() => { - if (steamVrHands && handsWarning === null) { + if ((steamVrLeftHand || steamVrRightHand) && handsWarning === null) { setHandsWarning(true); - } else if (!steamVrHands && handsWarning === false) { + } else if ( + !(steamVrLeftHand || steamVrRightHand) && + handsWarning === false + ) { setHandsWarning(null); } - }, [steamVrHands, handsWarning]); + }, [steamVrLeftHand, steamVrRightHand, handsWarning]); // Handle scrolling to selected page // useEffect(() => { @@ -410,11 +437,13 @@ export function GeneralSettings() { { - setValue('trackers.hands', false); + setValue('trackers.leftHand', false); + setValue('trackers.rightHand', false); setHandsWarning(null); }} accept={() => { - setValue('trackers.hands', true); + setValue('trackers.leftHand', true); + setValue('trackers.rightHand', true); setHandsWarning(false); }} /> @@ -463,9 +492,9 @@ export function GeneralSettings() { outlined disabled={automaticTrackerToggle} control={control} - name="trackers.knees" + name="trackers.leftKnee" label={l10n.getString( - 'settings-general-steamvr-trackers-knees' + 'settings-general-steamvr-trackers-left_knee' )} /> + + + + diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java index a97144d19b..eb5e28f475 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java @@ -156,15 +156,16 @@ public static int createSteamVRSettings(FlatBufferBuilder fbb, ISteamVRBridge br fbb, bridge.getShareSetting(TrackerRole.WAIST), bridge.getShareSetting(TrackerRole.CHEST), - bridge.getShareSetting(TrackerRole.LEFT_FOOT) - && bridge.getShareSetting(TrackerRole.RIGHT_FOOT), - bridge.getShareSetting(TrackerRole.LEFT_KNEE) - && bridge.getShareSetting(TrackerRole.RIGHT_KNEE), - bridge.getShareSetting(TrackerRole.LEFT_ELBOW) - && bridge.getShareSetting(TrackerRole.RIGHT_ELBOW), - bridge.getShareSetting(TrackerRole.LEFT_HAND) - && bridge.getShareSetting(TrackerRole.RIGHT_HAND), - bridge.getAutomaticSharedTrackers() + bridge.getAutomaticSharedTrackers(), + + bridge.getShareSetting(TrackerRole.LEFT_FOOT), + bridge.getShareSetting(TrackerRole.RIGHT_FOOT), + bridge.getShareSetting(TrackerRole.LEFT_KNEE), + bridge.getShareSetting(TrackerRole.RIGHT_KNEE), + bridge.getShareSetting(TrackerRole.LEFT_ELBOW), + bridge.getShareSetting(TrackerRole.RIGHT_ELBOW), + bridge.getShareSetting(TrackerRole.LEFT_HAND), + bridge.getShareSetting(TrackerRole.RIGHT_HAND) ); } return steamvrTrackerSettings; diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt index da3f04f7c1..8ca8d79dba 100644 --- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt +++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt @@ -55,14 +55,14 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) { if (bridge != null) { bridge.changeShareSettings(TrackerRole.WAIST, req.steamVrTrackers().waist()) bridge.changeShareSettings(TrackerRole.CHEST, req.steamVrTrackers().chest()) - bridge.changeShareSettings(TrackerRole.LEFT_FOOT, req.steamVrTrackers().feet()) - bridge.changeShareSettings(TrackerRole.RIGHT_FOOT, req.steamVrTrackers().feet()) - bridge.changeShareSettings(TrackerRole.LEFT_KNEE, req.steamVrTrackers().knees()) - bridge.changeShareSettings(TrackerRole.RIGHT_KNEE, req.steamVrTrackers().knees()) - bridge.changeShareSettings(TrackerRole.LEFT_ELBOW, req.steamVrTrackers().elbows()) - bridge.changeShareSettings(TrackerRole.RIGHT_ELBOW, req.steamVrTrackers().elbows()) - bridge.changeShareSettings(TrackerRole.LEFT_HAND, req.steamVrTrackers().hands()) - bridge.changeShareSettings(TrackerRole.RIGHT_HAND, req.steamVrTrackers().hands()) + bridge.changeShareSettings(TrackerRole.LEFT_FOOT, req.steamVrTrackers().leftFoot()) + bridge.changeShareSettings(TrackerRole.RIGHT_FOOT, req.steamVrTrackers().rightFoot()) + bridge.changeShareSettings(TrackerRole.LEFT_KNEE, req.steamVrTrackers().leftKnee()) + bridge.changeShareSettings(TrackerRole.RIGHT_KNEE, req.steamVrTrackers().rightKnee()) + bridge.changeShareSettings(TrackerRole.LEFT_ELBOW, req.steamVrTrackers().leftElbow()) + bridge.changeShareSettings(TrackerRole.RIGHT_ELBOW, req.steamVrTrackers().rightElbow()) + bridge.changeShareSettings(TrackerRole.LEFT_HAND, req.steamVrTrackers().leftHand()) + bridge.changeShareSettings(TrackerRole.RIGHT_HAND, req.steamVrTrackers().rightHand()) bridge.setAutomaticSharedTrackers(req.steamVrTrackers().automaticTrackerToggle()) } } diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/Device.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/Device.kt index c94e0e87b4..71d6db17b3 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/Device.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/Device.kt @@ -21,6 +21,9 @@ open class Device { open val hardwareIdentifier: String = "Unknown" + val isOpenVrDevice: Boolean + get() = manufacturer == "OpenVR" + companion object { @JvmStatic protected val nextLocalDeviceId = AtomicInteger() diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/TrackerPosition.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/TrackerPosition.kt index d1d8244b73..559aea8995 100644 --- a/server/core/src/main/java/dev/slimevr/tracking/trackers/TrackerPosition.kt +++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/TrackerPosition.kt @@ -14,6 +14,8 @@ enum class TrackerPosition( val trackerRole: TrackerRole?, val bodyPart: Int, ) { + // If updating BodyPart of a TrackerRole, + // please also update SteamVRBridge#updateShareSettingsAutomatically() HEAD("body:head", TrackerRole.HMD, BodyPart.HEAD), NECK("body:neck", TrackerRole.NECK, BodyPart.NECK), UPPER_CHEST("body:upper_chest", TrackerRole.CHEST, BodyPart.UPPER_CHEST), @@ -50,12 +52,12 @@ enum class TrackerPosition( companion object { /** Indexed by `BodyPart` int value. EFFICIENCY FTW */ private val byBodyPart: Array = arrayOfNulls(BodyPart.names.size).apply { - for (position in values()) { + for (position in entries) { this[position.bodyPart] = position } } - private val byDesignation = values().associateBy { it.designation.lowercase() } - private val byTrackerRole = values().filter { it.trackerRole != null }.associateBy { it.trackerRole!! } + private val byDesignation = entries.associateBy { it.designation.lowercase() } + private val byTrackerRole = entries.filter { it.trackerRole != null }.associateBy { it.trackerRole!! } /** * Gets the `TrackerPosition` by its string designation. diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/platform/SteamVRBridge.kt b/server/desktop/src/main/java/dev/slimevr/desktop/platform/SteamVRBridge.kt index 027d8adc0e..ea669e91bc 100644 --- a/server/desktop/src/main/java/dev/slimevr/desktop/platform/SteamVRBridge.kt +++ b/server/desktop/src/main/java/dev/slimevr/desktop/platform/SteamVRBridge.kt @@ -55,30 +55,61 @@ abstract class SteamVRBridge( override fun updateShareSettingsAutomatically(): Boolean { if (!config.automaticSharedTrackersToggling) return false val skeleton = instance.humanPoseManager.skeleton + val isWaistSteamVr = skeleton.hipTracker?.device?.isOpenVrDevice == true || + skeleton.waistTracker?.device?.isOpenVrDevice == true // Enable waist if skeleton has an spine tracker - changeShareSettings(TrackerRole.WAIST, skeleton.hasSpineTracker) + changeShareSettings(TrackerRole.WAIST, skeleton.hasSpineTracker && !isWaistSteamVr) // hasChest if waist and/or hip is on, and chest and/or upper chest is also on val hasChest = (skeleton.hipTracker != null || skeleton.waistTracker != null) && (skeleton.upperChestTracker != null || skeleton.chestTracker != null) - changeShareSettings(TrackerRole.CHEST, hasChest) + val isChestSteamVr = skeleton.upperChestTracker?.device?.isOpenVrDevice == true || + skeleton.chestTracker?.device?.isOpenVrDevice == true + changeShareSettings( + TrackerRole.CHEST, + hasChest && !isChestSteamVr, + ) // hasFeet if lower and/or upper leg tracker is on - val hasFeet = - (skeleton.leftUpperLegTracker != null || skeleton.leftLowerLegTracker != null) && - (skeleton.rightUpperLegTracker != null || skeleton.rightLowerLegTracker != null) - changeShareSettings(TrackerRole.LEFT_FOOT, hasFeet) - changeShareSettings(TrackerRole.RIGHT_FOOT, hasFeet) + val hasLeftFoot = + (skeleton.leftUpperLegTracker != null || skeleton.leftLowerLegTracker != null) + val isLeftFootSteamVr = + skeleton.leftLowerLegTracker?.device?.isOpenVrDevice == true || + skeleton.leftFootTracker?.device?.isOpenVrDevice == true + + val hasRightFoot = + (skeleton.rightUpperLegTracker != null || skeleton.rightLowerLegTracker != null) + val isRightFootSteamVr = + skeleton.rightLowerLegTracker?.device?.isOpenVrDevice == true || + skeleton.rightFootTracker?.device?.isOpenVrDevice == true + changeShareSettings( + TrackerRole.LEFT_FOOT, + hasLeftFoot && !isLeftFootSteamVr, + ) + changeShareSettings( + TrackerRole.RIGHT_FOOT, + hasRightFoot && !isRightFootSteamVr, + ) // hasKnees if foot tracker and lower and/or upper leg tracker is on - val hasKnees = hasFeet && skeleton.hasLeftFootTracker && skeleton.hasRightFootTracker - changeShareSettings(TrackerRole.LEFT_KNEE, hasKnees) - changeShareSettings(TrackerRole.RIGHT_KNEE, hasKnees) + val hasLeftKnee = hasLeftFoot && skeleton.hasLeftFootTracker + val isLeftKneeSteamVr = skeleton.leftUpperLegTracker?.device?.isOpenVrDevice == true + + val hasRightKnee = hasRightFoot && skeleton.hasRightFootTracker + val isRightKneeSteamVr = skeleton.rightUpperLegTracker?.device?.isOpenVrDevice == true + changeShareSettings(TrackerRole.LEFT_KNEE, hasLeftKnee && !isLeftKneeSteamVr) + changeShareSettings(TrackerRole.RIGHT_KNEE, hasRightKnee && !isRightKneeSteamVr) // hasElbows if an upper arm or a lower arm tracker is on - val hasElbows = skeleton.hasLeftArmTracker && skeleton.hasRightArmTracker - changeShareSettings(TrackerRole.LEFT_ELBOW, hasElbows) - changeShareSettings(TrackerRole.RIGHT_ELBOW, hasElbows) + val hasLeftElbow = skeleton.hasLeftArmTracker + val isLeftElbowSteamVr = skeleton.leftUpperArmTracker?.device?.isOpenVrDevice == true || + skeleton.leftLowerArmTracker?.device?.isOpenVrDevice == true + + val hasRightElbow = skeleton.hasRightArmTracker + val isRightElbowSteamVr = skeleton.rightUpperArmTracker?.device?.isOpenVrDevice == true || + skeleton.rightLowerArmTracker?.device?.isOpenVrDevice == true + changeShareSettings(TrackerRole.LEFT_ELBOW, hasLeftElbow && !isLeftElbowSteamVr) + changeShareSettings(TrackerRole.RIGHT_ELBOW, hasRightElbow && !isRightElbowSteamVr) // Hands aren't touched as they will override the controller's tracking return true diff --git a/solarxr-protocol b/solarxr-protocol index d21ac81de3..b1ae56c26a 160000 --- a/solarxr-protocol +++ b/solarxr-protocol @@ -1 +1 @@ -Subproject commit d21ac81de3530c1c0c15f53a570f46f9edbc5795 +Subproject commit b1ae56c26a7b1e262bf051589620433de1eea88f