Compare commits

...

13 Commits

Author SHA1 Message Date
Butterscotch!
340cff8be5 Minimize ProGuard rules & enable optimization 2026-03-06 01:43:02 -05:00
Sapphire
0236a05f26 Allow showing 'Up to date' version for third-party trackers (#1756) 2026-02-25 23:08:31 +01:00
Butterscotch!
28deb357da Revert TrackerResetsHandler & add comments (#1748) 2026-02-20 11:26:23 +01:00
jabberrock
4d93f87a01 Clarify AI policy on contributions (#1752) 2026-02-17 03:59:11 +03:00
Sapphire
88adfce242 Hide tracker firmware version when board type is unknown (#1721) 2026-02-09 21:58:36 +01:00
Sapphire
3d02795dbc Don't trigger timeout when Wi-Fi provisioning is done (#1725)
Co-authored-by: lucas lelievre <loucass003@gmail.com>
2026-02-09 21:57:56 +01:00
Sapphire
7ff50f78eb Don't ask for full reset on timeout with manual or saved mounting (#1727) 2026-02-02 18:06:38 +01:00
Sapphire
0e3aaf105c Display more accurate info for OpenVR devices (#1731) 2026-02-02 18:06:17 +01:00
sctanf
f638540886 TrackerBattery disable tooltip while charging (#1733) 2026-02-02 18:05:50 +01:00
Sapphire
343d69d690 Support feet mounting reset over Protobuf bridge (#1737) 2026-02-02 18:05:31 +01:00
H3
e2d7d354c6 Add ESP32-S2 to USB-Serial Accept-List (#1730)
Co-authored-by: unlogisch04 <98281608+unlogisch04@users.noreply.github.com>
2026-01-29 22:54:37 +03:00
sctanf
cc6f297b92 Re-add missing battery runtime estimate to DataFeedBuilder (#1732) 2026-01-29 14:00:18 +04:00
H114514191981
2add43e71a add CH343 support (#1568)
Co-authored-by: unlogisch04 <98281608+unlogisch04@users.noreply.github.com>
2026-01-28 10:39:25 +02:00
15 changed files with 343 additions and 175 deletions

View File

@@ -116,3 +116,9 @@ licensed under `GPL-v3`.
## Discord
We use discord *a lot* to coordinate and discuss development. Come join us at
https://discord.gg/SlimeVR!
## Use of AI
We DO NOT accept contributions that are generated with AI (for example, "vibe-coding").
If you do use AI, and you believe your usage of AI is reasonable, you must clearly disclose
how you used AI in your submission.

View File

@@ -18,6 +18,8 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="7522", MODE="0660
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="7523", MODE="0660", TAG+="uaccess"
# CH341
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="5523", MODE="0660", TAG+="uaccess"
# CH343
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="55D3", MODE="0660", TAG+="uaccess"
# CH9102x
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="55D4", MODE="0660", TAG+="uaccess"
@@ -26,8 +28,10 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="1A86", ATTRS{idProduct}=="55D4", MODE="0660
SUBSYSTEMS=="usb", ATTRS{idVendor}=="10C4", ATTRS{idProduct}=="EA60", MODE="0660", TAG+="uaccess"
## Espressif
# ESP32-C3
# ESP32-S3 / ESP32-C3 / ESP32-C5 / ESP32-C6 / ESP32-C61 / ESP32-H2 / ESP32-P4
SUBSYSTEMS=="usb", ATTRS{idVendor}=="303A", ATTRS{idProduct}=="1001", MODE="0660", TAG+="uaccess"
# ESP32-S2
SUBSYSTEMS=="usb", ATTRS{idVendor}=="303A", ATTRS{idProduct}=="0002", MODE="0660", TAG+="uaccess"
## FTDI
# FT232BM/L/Q, FT245BM/L/Q

View File

@@ -38,7 +38,7 @@ export function TrackerBattery({
return (
<Tooltip
disabled={!charging && (!runtime || debug)}
disabled={charging || !runtime || debug}
preferedDirection="left"
content=<Typography>{percentFormatter.format(value)}</Typography>
>

View File

@@ -199,7 +199,7 @@ export function TrackerSettingsPage() {
shakeHighlight={false}
/>
)}
{
{tracker?.device?.hardwareInfo?.hardwareIdentifier != 'Unknown' && (
<div className="flex flex-col bg-background-70 p-3 rounded-lg gap-2">
<Typography
variant="section-title"
@@ -223,34 +223,38 @@ export function TrackerSettingsPage() {
whitespace="whitespace-pre-wrap"
textAlign="text-end"
>
v{tracker?.device?.hardwareInfo?.firmwareVersion}
{tracker?.device?.hardwareInfo?.firmwareVersion
? `v${tracker?.device?.hardwareInfo?.firmwareVersion}`
: '--'}
</Typography>
</div>
<div className="flex justify-between gap-2">
<Typography id="tracker-settings-latest-version" />
{!updateUnavailable && (
<>
{currentFirmwareRelease && (
<Typography
color={
needUpdate === 'updated'
? undefined
: 'text-accent-background-10'
}
textAlign="text-end"
whitespace="whitespace-pre-wrap"
>
{currentFirmwareRelease.name}
</Typography>
)}
</>
)}
{updateUnavailable && (
<Typography id="tracker-settings-update-unavailable-v2">
No releases found
</Typography>
)}
</div>
{!!tracker?.device?.hardwareInfo?.officialBoardType && (
<div className="flex justify-between gap-2">
<Typography id="tracker-settings-latest-version" />
{!updateUnavailable && (
<>
{currentFirmwareRelease && (
<Typography
color={
needUpdate === 'updated'
? undefined
: 'text-accent-background-10'
}
textAlign="text-end"
whitespace="whitespace-pre-wrap"
>
{currentFirmwareRelease.name}
</Typography>
)}
</>
)}
{updateUnavailable && (
<Typography id="tracker-settings-update-unavailable-v2">
No releases found
</Typography>
)}
</div>
)}
</div>
{!updateUnavailable && (
<Tooltip
@@ -289,7 +293,7 @@ export function TrackerSettingsPage() {
</Tooltip>
)}
</div>
}
)}
<div className="flex flex-col bg-background-70 p-3 rounded-lg gap-2 overflow-x-auto">
<div className="flex justify-between">
@@ -317,10 +321,11 @@ export function TrackerSettingsPage() {
<div className="flex justify-between">
<Typography>{l10n.getString('tracker-infos-url')}</Typography>
<Typography>
udp://
{IPv4.fromNumber(
tracker?.device?.hardwareInfo?.ipAddress?.addr || 0
).toString()}
{tracker?.device?.hardwareInfo?.ipAddress?.addr
? `udp://${IPv4.fromNumber(
tracker?.device?.hardwareInfo?.ipAddress?.addr || 0
).toString()}`
: '--'}
</Typography>
</div>
<div className="flex justify-between">

View File

@@ -129,9 +129,6 @@ export function checkForUpdate(
if (
!device.hardwareInfo?.officialBoardType ||
![BoardType.SLIMEVR, BoardType.SLIMEVR_V1_2].includes(
device.hardwareInfo.officialBoardType
) ||
!semver.valid(currentFirmwareRelease.version) ||
!semver.valid(device.hardwareInfo.firmwareVersion?.toString() ?? 'none')
) {
@@ -143,6 +140,14 @@ export function checkForUpdate(
currentFirmwareRelease.version
);
if (
![BoardType.SLIMEVR, BoardType.SLIMEVR_V1_2].includes(
device.hardwareInfo.officialBoardType
)
) {
return canUpdate ? 'unavailable' : 'updated';
}
if (
canUpdate &&
device.hardwareStatus?.batteryPctEstimate != null &&

View File

@@ -1,62 +1,29 @@
-dontwarn java.awt.Color
-dontwarn java.beans.BeanInfo
-dontwarn java.beans.IntrospectionException
-dontwarn java.beans.Introspector
-dontwarn java.beans.PropertyDescriptor
-dontwarn java.lang.management.ManagementFactory
-dontwarn java.lang.management.RuntimeMXBean
-dontwarn org.apache.logging.log4j.Level
-dontwarn org.apache.logging.log4j.LogManager
-dontwarn org.apache.logging.log4j.Logger
-dontwarn org.apache.logging.log4j.message.MessageFactory
-dontwarn org.apache.logging.log4j.spi.ExtendedLogger
-dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper
-dontwarn org.apache.log4j.Level
-dontwarn org.apache.log4j.Logger
-dontwarn org.apache.log4j.Priority
-dontwarn org.conscrypt.BufferAllocator
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.HandshakeListener
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ClientProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$Provider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ServerProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego
-dontwarn org.jetbrains.annotations.Async$Execute
-dontwarn org.jetbrains.annotations.Async$Schedule
-dontwarn reactor.blockhound.integration.BlockHoundIntegration
-keep class io.ktor.** { *; }
-keep class io.netty.** { *; }
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.atomicfu.**
-dontwarn java.beans.**
-dontwarn io.netty.**
-dontwarn com.typesafe.**
-dontwarn org.slf4j.**
-keep class io.netty.** { *; }
# Proguard configuration for Jackson 2.x
# Jackson 2.x
# https://github.com/FasterXML/jackson-docs/wiki/JacksonOnAndroid
#-keep class java.beans.** { *; }
#-dontwarn java.beans.**
#
#-keep class com.fasterxml.jackson.** { *; }
#-dontwarn com.fasterxml.jackson.databind.**
#
#-keep class com.github.jonpeterson.jackson.** { *; }
#
#-keepclassmembers class * {
# @com.fasterxml.jackson.annotation.* *;
#}
-keepattributes *Annotation*,Signature,EnclosingMethod
# Proguard configuration for SnakeYAML 2.X
#-keep class org.yaml.snakeyaml.** { *; }
#-dontwarn org.yaml.snakeyaml.**
-keep class com.fasterxml.jackson.**
-keepclassmembers class * {
@com.fasterxml.jackson.annotation.* *;
}
# Jackson 2.x Model Versioning Module
-keep class com.github.jonpeterson.jackson.**
# SnakeYAML 2.X
-keep class org.yaml.snakeyaml.**
# Don't mess with SlimeVR config, the class structure is essential for serialization
-keep class dev.slimevr.config.** { *; }
# Obfuscation is fine but it makes crash logs unreadable, we don't really need it for our app
-dontobfuscate
# Temporary measure to keep config functional, beware Jackson issues if removing!!
-dontoptimize

View File

@@ -349,6 +349,9 @@ fun createDeviceData(
if (tracker.packetsReceived != null) {
HardwareStatus.addPacketsReceived(fbb, tracker.packetsReceived!!)
}
if (tracker.batteryRemainingRuntime != null) {
HardwareStatus.addBatteryRuntimeEstimate(fbb, tracker.batteryRemainingRuntime!!)
}
val hardwareDataOffset = HardwareStatus.endHardwareStatus(fbb)
val hardwareInfoOffset = createHardwareInfo(fbb, device)

View File

@@ -36,7 +36,7 @@ public class ProvisioningHandler implements SerialListener {
this.provisioningTickTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (!isRunning)
if (!isRunning || provisioningStatus == ProvisioningStatus.DONE)
return;
provisioningTick();
}

View File

@@ -30,14 +30,18 @@ abstract class SerialHandler {
Pair(0x1A86, 0x7523),
// CH341
Pair(0x1A86, 0x5523),
// CH343
Pair(0x1A86, 0x55D3),
// CH9102x
Pair(0x1A86, 0x55D4),
// / Silabs
// CP210x
Pair(0x10C4, 0xEA60),
// / Espressif
// ESP32-C3
// ESP32-S3 / ESP32-C3 / ESP32-C5 / ESP32-C6 / ESP32-C61 / ESP32-H2 / ESP32-P4
Pair(0x303A, 0x1001),
// ESP32-S2
Pair(0x303A, 0x0002),
// / FTDI
// FT232BM/L/Q, FT245BM/L/Q
// FT232RL/Q, FT245RL/Q

View File

@@ -24,8 +24,6 @@ class TrackerResetsHandler(val tracker: Tracker) {
Math.PI.toFloat(),
0f,
).toQuaternion()
private val QuarterPitch = Quaternion.rotationAroundXAxis(FastMath.HALF_PI)
private var driftAmount = 0f
private var averagedDriftQuat = Quaternion.IDENTITY
private var rotationSinceReset = Quaternion.IDENTITY
@@ -54,6 +52,16 @@ class TrackerResetsHandler(val tracker: Tracker) {
// Reference adjustment quats
/**
* Gyro fix is set by full reset. This sets the current y rotation to 0, correcting
* for initial yaw rotation and the rotation incurred by mounting orientation. This
* is a local offset in rotation and does not affect the axes of rotation.
*
* This rotation is only used to compute [attachmentFix], otherwise [yawFix] would
* correct for the same rotation.
*/
private var gyroFix = Quaternion.IDENTITY
/**
* Attachment fix is set by full reset. This sets the current x and z rotations to
* 0, correcting for initial pitch and roll rotation. This is a global offset in
@@ -180,9 +188,12 @@ class TrackerResetsHandler(val tracker: Tracker) {
/**
* Get the reference adjusted accel.
*/
// All IMU axis corrections are inverse to undo `adjustToReference` after local yaw offsets are added
// Order is VERY important here! Please be extremely careful! >~>
fun getReferenceAdjustedAccel(rawRot: Quaternion, accel: Vector3): Vector3 = (adjustToReference(rawRot) * (attachmentFix * mountingOrientation * mountRotFix * tposeDownFix).inv()).sandwich(accel)
// TODO: Make this actually adjusted to the corrected IMU heading. The current
// implementation for heading correction doesn't appear to be correct and may simply
// make acceleration worse, so I'm just leaving this until we work that out. The
// output of this will be world space, but with an unknown offset to heading (yaw).
// - Butterscotch
fun getReferenceAdjustedAccel(rawRot: Quaternion, accel: Vector3): Vector3 = rawRot.sandwich(accel)
/**
* Converts raw or filtered rotation into reference- and
@@ -191,17 +202,22 @@ class TrackerResetsHandler(val tracker: Tracker) {
*/
private fun adjustToReference(rotation: Quaternion): Quaternion {
var rot = rotation
// Correct for global pitch/roll offset
rot *= attachmentFix
// Correct for global yaw offset without affecting local yaw so we can change this
// later without invalidating local yaw offset corrections
// Align heading axis with bone space
if (!tracker.isHmd || tracker.trackerPosition != TrackerPosition.HEAD) {
rot = mountingOrientation.inv() * rot * mountingOrientation
rot *= mountingOrientation
}
rot = mountRotFix.inv() * rot * mountRotFix
// T-pose global correction
// Heading correction assuming manual orientation is correct
rot = gyroFix * rot
// Align attitude axes with bone space
rot *= attachmentFix
// Secondary heading axis alignment with bone space for automatic mounting
// Note: Applying an inverse amount of heading correction corresponding to the
// axis alignment quaternion will leave the correction to another variable
rot = mountRotFix.inv() * (rot * mountRotFix)
// More attitude axes alignment specifically for the t-pose configuration, this
// probably shouldn't be a separate variable from attachmentFix?
rot *= tposeDownFix
// Align local yaw with reference
// More heading correction
rot = yawFix * rot
rot = constraintFix * rot
return rot
@@ -211,6 +227,8 @@ class TrackerResetsHandler(val tracker: Tracker) {
* Converts raw or filtered rotation into zero-reference-adjusted by
* applying quaternions produced after full reset and yaw reset only
*/
// This is essentially just adjustToReference but aligning to quaternion identity
// rather than to the bone.
private fun adjustToIdentity(rotation: Quaternion): Quaternion {
var rot = rotation
rot = gyroFixNoMounting * rot
@@ -265,23 +283,15 @@ class TrackerResetsHandler(val tracker: Tracker) {
lastResetQuaternion = oldRot
// Adjust raw rotation to mountingOrientation
val rotation = tracker.getRawRotation()
val mountingAdjustedRotation = tracker.getRawRotation() * mountingOrientation
// Gyrofix
val gyroFix = if (tracker.allowMounting || (tracker.trackerPosition == TrackerPosition.HEAD && !tracker.isHmd)) {
if (tracker.isComputed) {
fixGyroscope(rotation)
if (tracker.allowMounting || (tracker.trackerPosition == TrackerPosition.HEAD && !tracker.isHmd)) {
gyroFix = if (tracker.isComputed) {
fixGyroscope(tracker.getRawRotation())
} else {
if (tracker.trackerPosition.isFoot()) {
// Feet are rotated by 90 deg pitch, this means we're relying on IMU rotation
// to be set correctly here.
fixGyroscope(rotation * tposeDownFix * QuarterPitch)
} else {
fixGyroscope(rotation * tposeDownFix)
}
fixGyroscope(mountingAdjustedRotation * tposeDownFix)
}
} else {
Quaternion.IDENTITY
}
// Mounting for computed trackers
@@ -296,7 +306,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
if (resetHmdPitch) {
// Reset the HMD's pitch if it's assigned to head and resetHmdPitch is true
// Get rotation without yaw (make sure to use the raw rotation directly!)
val rotBuf = getYawQuaternion(rotation).inv() * rotation
val rotBuf = getYawQuaternion(tracker.getRawRotation()).inv() * tracker.getRawRotation()
// Isolate pitch
Quaternion(rotBuf.w, -rotBuf.x, 0f, 0f).unit()
} else {
@@ -304,7 +314,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
Quaternion.IDENTITY
}
} else {
(gyroFix * rotation).inv()
fixAttachment(mountingAdjustedRotation)
}
// Rotate attachmentFix by 180 degrees as a workaround for t-pose (down)
@@ -316,7 +326,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
// Don't adjust yaw if head and computed
if (tracker.trackerPosition != TrackerPosition.HEAD || !tracker.isComputed) {
yawFix = gyroFix * reference.project(Vector3.POS_Y).unit()
yawFix = fixYaw(mountingAdjustedRotation, reference)
tracker.yawResetSmoothing.reset()
}
@@ -360,7 +370,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
lastResetQuaternion = oldRot
val yawFixOld = yawFix
yawFix = fixYaw(tracker.getRawRotation(), reference)
yawFix = fixYaw(tracker.getRawRotation() * mountingOrientation, reference)
tracker.yawResetSmoothing.reset()
makeIdentityAdjustmentQuatsYaw()
@@ -399,9 +409,9 @@ class TrackerResetsHandler(val tracker: Tracker) {
constraintFix = Quaternion.IDENTITY
// Get the current calibrated rotation
var rotBuf = adjustToDrift(tracker.getRawRotation())
var rotBuf = adjustToDrift(tracker.getRawRotation() * mountingOrientation)
rotBuf = gyroFix * rotBuf
rotBuf *= attachmentFix
rotBuf = mountingOrientation.inv() * rotBuf * mountingOrientation
rotBuf = yawFix * rotBuf
// Adjust buffer to reference
@@ -457,22 +467,14 @@ class TrackerResetsHandler(val tracker: Tracker) {
mountRotFix = Quaternion.IDENTITY
}
// EulerOrder.YXZ is actually better for gyroscope fix, as it can get yaw at any roll.
// Consequentially, instead of the roll being limited, the pitch is limited to
// 90 degrees from the yaw plane. This means trackers may be mounted upside down
// or with incorrectly configured IMU rotation, but we will need to compensate for
// the pitch.
private fun fixGyroscope(sensorRotation: Quaternion): Quaternion = getYawQuaternion(sensorRotation, EulerOrder.YXZ).inv()
private fun fixGyroscope(sensorRotation: Quaternion): Quaternion = getYawQuaternion(sensorRotation).inv()
private fun fixAttachment(sensorRotation: Quaternion): Quaternion = (gyroFix * sensorRotation).inv()
private fun fixYaw(sensorRotation: Quaternion, reference: Quaternion): Quaternion {
var rot = sensorRotation * attachmentFix
// We need to fix the global yaw offset for the euler yaw calculation
if (!tracker.isHmd || tracker.trackerPosition != TrackerPosition.HEAD) {
rot = mountingOrientation.inv() * rot * mountingOrientation
}
rot = mountRotFix.inv() * rot * mountRotFix
// TODO: Get diff from ref to rot, use euler angle (YZX) yaw as output.
// This prevents pitch and roll from affecting the alignment.
var rot = gyroFix * sensorRotation
rot *= attachmentFix
rot = mountRotFix.inv() * (rot * mountRotFix)
rot = getYawQuaternion(rot)
return rot.inv() * reference.project(Vector3.POS_Y).unit()
}
@@ -483,7 +485,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
// In both cases, the isolated yaw value changes
// with the tracker's roll when pointing forward.
// calling twinNearest() makes sure this rotation has the wanted polarity (+-).
private fun getYawQuaternion(rot: Quaternion, order: EulerOrder = EulerOrder.YZX): Quaternion = EulerAngles(order, 0f, rot.toEulerAngles(order).y, 0f).toQuaternion().twinNearest(rot)
private fun getYawQuaternion(rot: Quaternion): Quaternion = EulerAngles(EulerOrder.YZX, 0f, rot.toEulerAngles(EulerOrder.YZX).y, 0f).toQuaternion().twinNearest(rot)
private fun makeIdentityAdjustmentQuatsFull() {
val sensorRotation = tracker.getRawRotation()

View File

@@ -11,6 +11,7 @@ import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.tracking.trackers.TrackerUtils
import dev.slimevr.tracking.trackers.udp.TrackerDataType
import io.github.axisangles.ktmath.Quaternion
import solarxr_protocol.datatypes.DeviceIdT
import solarxr_protocol.datatypes.TrackerIdT
import solarxr_protocol.rpc.*
@@ -199,7 +200,8 @@ class TrackingChecklistManager(private val vrServer: VRServer) : VRCConfigListen
}
// We ask for a full reset if you need to do mounting calibration but cant because you haven't done full reset in a while
// or if you have trackers that need reset after re-assigning
val needFullReset = (!resetMountingCompleted && !vrServer.serverGuards.canDoMounting) || trackerRequireReset.isNotEmpty()
val usingSavedCalibration = vrServer.configManager.vrConfig.resetsConfig.saveMountingReset && imuTrackers.all { it.resetsHandler.mountRotFix != Quaternion.IDENTITY }
val needFullReset = (vrServer.configManager.vrConfig.resetsConfig.lastMountingMethod == MountingMethods.AUTOMATIC && !usingSavedCalibration && !resetMountingCompleted && !vrServer.serverGuards.canDoMounting) || trackerRequireReset.isNotEmpty()
updateValidity(TrackingChecklistStepId.FULL_RESET, !needFullReset) {
it.enabled = imuTrackers.isNotEmpty()
if (trackerRequireReset.isNotEmpty()) {

View File

@@ -93,13 +93,13 @@ class SkeletonResetTests {
TrackerPosition.HIP,
TrackerPosition.LEFT_LOWER_LEG,
TrackerPosition.RIGHT_LOWER_LEG,
-> mountRot
-> mountRot * Quaternion.SLIMEVR.FRONT
TrackerPosition.LEFT_UPPER_LEG,
TrackerPosition.RIGHT_UPPER_LEG,
-> mountRot * Quaternion.SLIMEVR.FRONT
-> mountRot
else -> mountRot * Quaternion.SLIMEVR.FRONT
else -> mountRot
}
val actualMounting = tracker.resetsHandler.mountRotFix

View File

@@ -7,6 +7,7 @@ import dev.slimevr.desktop.platform.ProtobufMessages.*
import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.tracking.trackers.TrackerStatus.Companion.getById
import dev.slimevr.tracking.trackers.TrackerUtils
import dev.slimevr.util.ann.VRServerThread
import io.eiren.util.ann.Synchronize
import io.eiren.util.ann.ThreadSafe
@@ -218,6 +219,11 @@ abstract class ProtobufBridge(@JvmField protected val bridgeName: String) : ISte
"mounting_reset" -> instance.resetTrackersMounting(resetSourceName)
"feet_mounting_reset" -> instance.resetTrackersMounting(
resetSourceName,
TrackerUtils.feetsBodyParts,
)
"pause_tracking" ->
instance
.togglePauseTracking(resetSourceName)

View File

@@ -3558,6 +3558,20 @@ public final class ProtobufMessages {
* @return The trackerRole.
*/
int getTrackerRole();
/**
* <code>string manufacturer = 5;</code>
*
* @return The manufacturer.
*/
java.lang.String getManufacturer();
/**
* <code>string manufacturer = 5;</code>
*
* @return The bytes for manufacturer.
*/
com.google.protobuf.ByteString getManufacturerBytes();
}
/**
@@ -3588,6 +3602,7 @@ public final class ProtobufMessages {
private TrackerAdded() {
trackerSerial_ = "";
trackerName_ = "";
manufacturer_ = "";
}
public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
@@ -3713,6 +3728,48 @@ public final class ProtobufMessages {
return trackerRole_;
}
public static final int MANUFACTURER_FIELD_NUMBER = 5;
@SuppressWarnings("serial")
private volatile java.lang.Object manufacturer_ = "";
/**
* <code>string manufacturer = 5;</code>
*
* @return The manufacturer.
*/
@java.lang.Override
public java.lang.String getManufacturer() {
java.lang.Object ref = manufacturer_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
manufacturer_ = s;
return s;
}
}
/**
* <code>string manufacturer = 5;</code>
*
* @return The bytes for manufacturer.
*/
@java.lang.Override
public com.google.protobuf.ByteString getManufacturerBytes() {
java.lang.Object ref = manufacturer_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b = com.google.protobuf.ByteString
.copyFromUtf8(
(java.lang.String) ref
);
manufacturer_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
@@ -3742,6 +3799,9 @@ public final class ProtobufMessages {
if (trackerRole_ != 0) {
output.writeInt32(4, trackerRole_);
}
if (!com.google.protobuf.GeneratedMessage.isStringEmpty(manufacturer_)) {
com.google.protobuf.GeneratedMessage.writeString(output, 5, manufacturer_);
}
getUnknownFields().writeTo(output);
}
@@ -3766,6 +3826,9 @@ public final class ProtobufMessages {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(4, trackerRole_);
}
if (!com.google.protobuf.GeneratedMessage.isStringEmpty(manufacturer_)) {
size += com.google.protobuf.GeneratedMessage.computeStringSize(5, manufacturer_);
}
size += getUnknownFields().getSerializedSize();
memoizedSize = size;
return size;
@@ -3801,6 +3864,11 @@ public final class ProtobufMessages {
!= other.getTrackerRole()
)
return false;
if (
!getManufacturer()
.equals(other.getManufacturer())
)
return false;
if (!getUnknownFields().equals(other.getUnknownFields()))
return false;
return true;
@@ -3821,6 +3889,8 @@ public final class ProtobufMessages {
hash = (53 * hash) + getTrackerName().hashCode();
hash = (37 * hash) + TRACKER_ROLE_FIELD_NUMBER;
hash = (53 * hash) + getTrackerRole();
hash = (37 * hash) + MANUFACTURER_FIELD_NUMBER;
hash = (53 * hash) + getManufacturer().hashCode();
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
@@ -3993,6 +4063,7 @@ public final class ProtobufMessages {
trackerSerial_ = "";
trackerName_ = "";
trackerRole_ = 0;
manufacturer_ = "";
return this;
}
@@ -4044,6 +4115,9 @@ public final class ProtobufMessages {
if (((from_bitField0_ & 0x00000008) != 0)) {
result.trackerRole_ = trackerRole_;
}
if (((from_bitField0_ & 0x00000010) != 0)) {
result.manufacturer_ = manufacturer_;
}
}
@java.lang.Override
@@ -4083,6 +4157,11 @@ public final class ProtobufMessages {
if (other.getTrackerRole() != 0) {
setTrackerRole(other.getTrackerRole());
}
if (!other.getManufacturer().isEmpty()) {
manufacturer_ = other.manufacturer_;
bitField0_ |= 0x00000010;
onChanged();
}
this.mergeUnknownFields(other.getUnknownFields());
onChanged();
return this;
@@ -4130,6 +4209,11 @@ public final class ProtobufMessages {
bitField0_ |= 0x00000008;
break;
} // case 32
case 42: {
manufacturer_ = input.readStringRequireUtf8();
bitField0_ |= 0x00000010;
break;
} // case 42
default: {
if (!super.parseUnknownField(input, extensionRegistry, tag)) {
done = true; // was an endgroup tag
@@ -4398,6 +4482,93 @@ public final class ProtobufMessages {
return this;
}
private java.lang.Object manufacturer_ = "";
/**
* <code>string manufacturer = 5;</code>
*
* @return The manufacturer.
*/
public java.lang.String getManufacturer() {
java.lang.Object ref = manufacturer_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
manufacturer_ = s;
return s;
} else {
return (java.lang.String) ref;
}
}
/**
* <code>string manufacturer = 5;</code>
*
* @return The bytes for manufacturer.
*/
public com.google.protobuf.ByteString getManufacturerBytes() {
java.lang.Object ref = manufacturer_;
if (ref instanceof String) {
com.google.protobuf.ByteString b = com.google.protobuf.ByteString
.copyFromUtf8(
(java.lang.String) ref
);
manufacturer_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
* <code>string manufacturer = 5;</code>
*
* @param value The manufacturer to set.
* @return This builder for chaining.
*/
public Builder setManufacturer(
java.lang.String value
) {
if (value == null) {
throw new NullPointerException();
}
manufacturer_ = value;
bitField0_ |= 0x00000010;
onChanged();
return this;
}
/**
* <code>string manufacturer = 5;</code>
*
* @return This builder for chaining.
*/
public Builder clearManufacturer() {
manufacturer_ = getDefaultInstance().getManufacturer();
bitField0_ = (bitField0_ & ~0x00000010);
onChanged();
return this;
}
/**
* <code>string manufacturer = 5;</code>
*
* @param value The bytes for manufacturer to set.
* @return This builder for chaining.
*/
public Builder setManufacturerBytes(
com.google.protobuf.ByteString value
) {
if (value == null) {
throw new NullPointerException();
}
checkByteStringIsUtf8(value);
manufacturer_ = value;
bitField0_ |= 0x00000010;
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:messages.TrackerAdded)
}
@@ -8872,53 +9043,55 @@ public final class ProtobufMessages {
+
"ctionArgumentsEntry\0326\n\024ActionArgumentsEn"
+
"try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"f\n\014T"
"try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"|\n\014T"
+
"rackerAdded\022\022\n\ntracker_id\030\001 \001(\005\022\026\n\016track"
+
"er_serial\030\002 \001(\t\022\024\n\014tracker_name\030\003 \001(\t\022\024\n"
+
"\014tracker_role\030\004 \001(\005\"\374\002\n\rTrackerStatus\022\022\n"
"\014tracker_role\030\004 \001(\005\022\024\n\014manufacturer\030\005 \001("
+
"\ntracker_id\030\001 \001(\005\022.\n\006status\030\002 \001(\0162\036.mess"
"\t\"\374\002\n\rTrackerStatus\022\022\n\ntracker_id\030\001 \001(\005\022"
+
"ages.TrackerStatus.Status\0221\n\005extra\030\003 \003(\013"
".\n\006status\030\002 \001(\0162\036.messages.TrackerStatus"
+
"2\".messages.TrackerStatus.ExtraEntry\022;\n\n"
".Status\0221\n\005extra\030\003 \003(\0132\".messages.Tracke"
+
"confidence\030\004 \001(\0162\".messages.TrackerStatu"
"rStatus.ExtraEntry\022;\n\nconfidence\030\004 \001(\0162\""
+
"s.ConfidenceH\000\210\001\001\032,\n\nExtraEntry\022\013\n\003key\030\001"
".messages.TrackerStatus.ConfidenceH\000\210\001\001\032"
+
" \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"E\n\006Status\022\020\n\014DIS"
",\n\nExtraEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001("
+
"CONNECTED\020\000\022\006\n\002OK\020\001\022\010\n\004BUSY\020\002\022\t\n\005ERROR\020\003"
"\t:\0028\001\"E\n\006Status\022\020\n\014DISCONNECTED\020\000\022\006\n\002OK\020"
+
"\022\014\n\010OCCLUDED\020\004\"3\n\nConfidence\022\006\n\002NO\020\000\022\007\n\003"
"\001\022\010\n\004BUSY\020\002\022\t\n\005ERROR\020\003\022\014\n\010OCCLUDED\020\004\"3\n\n"
+
"LOW\020\001\022\n\n\006MEDIUM\020\005\022\010\n\004HIGH\020\nB\r\n\013_confiden"
"Confidence\022\006\n\002NO\020\000\022\007\n\003LOW\020\001\022\n\n\006MEDIUM\020\005\022"
+
"ce\"I\n\007Battery\022\022\n\ntracker_id\030\001 \001(\005\022\025\n\rbat"
"\010\n\004HIGH\020\nB\r\n\013_confidence\"I\n\007Battery\022\022\n\nt"
+
"tery_level\030\002 \001(\002\022\023\n\013is_charging\030\003 \001(\010\"\241\002"
"racker_id\030\001 \001(\005\022\025\n\rbattery_level\030\002 \001(\002\022\023"
+
"\n\017ProtobufMessage\022&\n\010position\030\001 \001(\0132\022.me"
"\n\013is_charging\030\003 \001(\010\"\241\002\n\017ProtobufMessage\022"
+
"ssages.PositionH\000\022+\n\013user_action\030\002 \001(\0132\024"
"&\n\010position\030\001 \001(\0132\022.messages.PositionH\000\022"
+
".messages.UserActionH\000\022/\n\rtracker_added\030"
"+\n\013user_action\030\002 \001(\0132\024.messages.UserActi"
+
"\003 \001(\0132\026.messages.TrackerAddedH\000\0221\n\016track"
"onH\000\022/\n\rtracker_added\030\003 \001(\0132\026.messages.T"
+
"er_status\030\004 \001(\0132\027.messages.TrackerStatus"
"rackerAddedH\000\0221\n\016tracker_status\030\004 \001(\0132\027."
+
"H\000\022$\n\007battery\030\005 \001(\0132\021.messages.BatteryH\000"
"messages.TrackerStatusH\000\022$\n\007battery\030\005 \001("
+
"\022$\n\007version\030\006 \001(\0132\021.messages.VersionH\000B\t"
"\0132\021.messages.BatteryH\000\022$\n\007version\030\006 \001(\0132"
+
"\n\007messageB2\n\034dev.slimevr.desktop.platfor"
"\021.messages.VersionH\000B\t\n\007messageB2\n\034dev.s"
+
"mB\020ProtobufMessagesH\003b\006proto3"
"limevr.desktop.platformB\020ProtobufMessage"
+
"sH\003b\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(
@@ -8957,7 +9130,8 @@ public final class ProtobufMessages {
internal_static_messages_TrackerAdded_descriptor = getDescriptor().getMessageTypes().get(4);
internal_static_messages_TrackerAdded_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_messages_TrackerAdded_descriptor,
new java.lang.String[] { "TrackerId", "TrackerSerial", "TrackerName", "TrackerRole", }
new java.lang.String[] { "TrackerId", "TrackerSerial", "TrackerName", "TrackerRole",
"Manufacturer", }
);
internal_static_messages_TrackerStatus_descriptor = getDescriptor()
.getMessageTypes()

View File

@@ -147,23 +147,13 @@ abstract class SteamVRBridge(
val device = instance.deviceManager
.createDevice(
trackerAdded.trackerName,
trackerAdded.trackerSerial,
"OpenVR", // TODO : We need the manufacturer
null,
trackerAdded.manufacturer.ifEmpty { "OpenVR" },
)
// Display name, needsReset and isHmd
val displayName: String
val isHmd = if (trackerAdded.trackerId == 0) {
displayName = if (trackerAdded.trackerName == "HMD") {
"SteamVR Driver HMD"
} else {
"Feeder App HMD"
}
true
} else {
displayName = trackerAdded.trackerName
false
}
val displayName: String = trackerAdded.trackerName
val isHmd = trackerAdded.trackerId == 0
// trackerPosition
val role = getById(trackerAdded.trackerRole)