Skip to content

Commit 2af0873

Browse files
committed
Add config file resource for hand tracking/slimevr skeleton ratios.
1 parent 9e01483 commit 2af0873

6 files changed

Lines changed: 56 additions & 18 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"external_hand_max_radius_m": 1.7,
3+
"stale_external_pose_frames": 1,
4+
"pose_lerp_speed": 0.8,
5+
"frozen_pose_position_epsilon_m": 0.005
6+
}

src/IVRDriver.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class IVRDriver : protected vr::IServerTrackedDeviceProvider {
9797
virtual std::optional<vr::DriverPose_t>
9898
GetExternalPoseForHand(bool left_hand) = 0;
9999

100+
/** Pose lerp speed (0–1) for smoothing VD/SlimeVR transitions. From driver config file. */
101+
virtual float GetPoseLerpSpeed() = 0;
102+
100103
virtual inline const char *const *GetInterfaceVersions() override {
101104
return vr::k_InterfaceVersions;
102105
};

src/TrackerDevice.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void SlimeVRDriver::TrackerDevice::Update() {
152152
if (!smoothed_pose_.has_value())
153153
smoothed_pose_ = target;
154154
else
155-
smoothed_pose_ = LerpPose(*smoothed_pose_, target, kPoseLerpSpeed);
155+
smoothed_pose_ = LerpPose(*smoothed_pose_, target, GetDriver()->GetPoseLerpSpeed());
156156
GetDriver()->GetDriverHost()->TrackedDevicePoseUpdated(
157157
device_index_, *smoothed_pose_, sizeof(vr::DriverPose_t));
158158
}

src/TrackerDevice.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class TrackerDevice : public IVRDevice {
7070
std::atomic<vr::DriverPose_t> last_pose_atomic_ =
7171
IVRDevice::MakeDefaultPose();
7272
std::optional<vr::DriverPose_t> smoothed_pose_;
73-
static constexpr float kPoseLerpSpeed = 0.8f;
7473
static vr::DriverPose_t LerpPose(const vr::DriverPose_t &from,
7574
const vr::DriverPose_t &to, float t);
7675

src/VRDriver.cpp

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ SlimeVRDriver::VRDriver::Init(vr::IVRDriverContext *pDriverContext) {
3232

3333
logger_->Log("SlimeVR Driver Loaded Successfully");
3434

35+
LoadDriverConfig();
36+
3537
bridge_ = std::make_shared<BridgeClient>(
3638
std::static_pointer_cast<Logger>(std::make_shared<VRLogger>("Bridge")),
3739
std::bind(&SlimeVRDriver::VRDriver::OnBridgeMessage, this,
@@ -349,6 +351,32 @@ bool SlimeVRDriver::VRDriver::AddDevice(std::shared_ptr<IVRDevice> device) {
349351
return true;
350352
}
351353

354+
void SlimeVRDriver::VRDriver::LoadDriverConfig() {
355+
vr::IVRResources *res = vr::VRResources();
356+
if (!res) return;
357+
char path[1024];
358+
uint32_t len = res->GetResourceFullPath(
359+
"slimevr_driver_config.json", "", path, sizeof(path));
360+
if (len == 0 || len >= sizeof(path)) return;
361+
path[len] = '\0';
362+
try {
363+
auto json = simdjson::padded_string::load(path);
364+
simdjson::ondemand::document doc = json_parser_.iterate(json);
365+
auto obj = doc.get_object();
366+
if (auto v = obj["external_hand_max_radius_m"]; !v.error()) config_external_hand_max_radius_m_ = static_cast<float>(v.get_double());
367+
if (auto v = obj["stale_external_pose_frames"]; !v.error()) config_stale_external_pose_frames_ = static_cast<int>(v.get_int64());
368+
if (auto v = obj["pose_lerp_speed"]; !v.error()) config_pose_lerp_speed_ = static_cast<float>(v.get_double());
369+
if (auto v = obj["frozen_pose_position_epsilon_m"]; !v.error()) config_frozen_pose_position_epsilon_m_ = static_cast<float>(v.get_double());
370+
logger_->Log("Loaded driver config from {}", path);
371+
} catch (const simdjson::simdjson_error &) {
372+
// Use defaults; config file missing or invalid
373+
}
374+
}
375+
376+
float SlimeVRDriver::VRDriver::GetPoseLerpSpeed() {
377+
return config_pose_lerp_speed_;
378+
}
379+
352380
SlimeVRDriver::SettingsValue
353381
SlimeVRDriver::VRDriver::GetSettingsValue(std::string key) {
354382
vr::EVRSettingsError err = vr::EVRSettingsError::VRSettingsError_None;
@@ -555,9 +583,8 @@ vr::DriverPose_t SlimeVRDriver::VRDriver::DriverPoseFromTrackedDevicePose(
555583
}
556584

557585
bool SlimeVRDriver::VRDriver::ExternalPoseEquals(const vr::DriverPose_t &a,
558-
const vr::DriverPose_t &b) {
559-
// Position only; rotation ignored so small rotation jitter doesn't block frozen detection.
560-
const float pos_eps = 0.005f; // ~5 mm
586+
const vr::DriverPose_t &b) const {
587+
float pos_eps = config_frozen_pose_position_epsilon_m_;
561588
for (int i = 0; i < 3; i++) {
562589
if (std::fabs(a.vecPosition[i] - b.vecPosition[i]) > pos_eps)
563590
return false;
@@ -566,14 +593,15 @@ bool SlimeVRDriver::VRDriver::ExternalPoseEquals(const vr::DriverPose_t &a,
566593
}
567594

568595
bool SlimeVRDriver::VRDriver::ExternalHandInFrontAndInRadius(
569-
const double hand_pos[3], const vr::TrackedDevicePose_t &hmd_pose) {
596+
const double hand_pos[3], const vr::TrackedDevicePose_t &hmd_pose) const {
570597
if (!hmd_pose.bPoseIsValid)
571598
return false;
599+
double r = static_cast<double>(config_external_hand_max_radius_m_);
572600
const auto &m = hmd_pose.mDeviceToAbsoluteTracking.m;
573601
double hx = m[0][3], hy = m[1][3], hz = m[2][3];
574602
double dx = hand_pos[0] - hx, dy = hand_pos[1] - hy, dz = hand_pos[2] - hz;
575603
double dist_sq = dx * dx + dy * dy + dz * dz;
576-
if (dist_sq > static_cast<double>(kExternalHandMaxRadius) * kExternalHandMaxRadius)
604+
if (dist_sq > r * r)
577605
return false;
578606
// Forward = -Z in OpenVR (third column of rotation)
579607
double fx = -m[0][2], fy = -m[1][2], fz = -m[2][2];
@@ -640,7 +668,7 @@ void SlimeVRDriver::VRDriver::UpdateExternalControllerPoses() {
640668
if (last_external_left_pose_.has_value() &&
641669
ExternalPoseEquals(driver_pose, *last_external_left_pose_)) {
642670
stale_external_left_frames_++;
643-
if (stale_external_left_frames_ >= kStaleExternalPoseFrames)
671+
if (stale_external_left_frames_ >= config_stale_external_pose_frames_)
644672
external_left_pose_ = std::nullopt; // swap to SlimeVR
645673
else
646674
external_left_pose_ = driver_pose;
@@ -653,7 +681,7 @@ void SlimeVRDriver::VRDriver::UpdateExternalControllerPoses() {
653681
if (last_external_right_pose_.has_value() &&
654682
ExternalPoseEquals(driver_pose, *last_external_right_pose_)) {
655683
stale_external_right_frames_++;
656-
if (stale_external_right_frames_ >= kStaleExternalPoseFrames)
684+
if (stale_external_right_frames_ >= config_stale_external_pose_frames_)
657685
external_right_pose_ = std::nullopt; // swap to SlimeVR
658686
else
659687
external_right_pose_ = driver_pose;

src/VRDriver.hpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,19 @@ class VRDriver : public IVRDriver {
8787
std::optional<vr::DriverPose_t> last_external_right_pose_;
8888
int stale_external_left_frames_ = 0;
8989
int stale_external_right_frames_ = 0;
90-
static constexpr int kStaleExternalPoseFrames = 1;
91-
/// Max distance (meters) from HMD for using external hand; beyond this or behind HMD → SlimeVR. 1.7f = 170 cm.
92-
static constexpr float kExternalHandMaxRadius = 1.7f;
90+
// Values from slimevr_driver_config.json (fallbacks if file missing)
91+
float config_external_hand_max_radius_m_ = 1.7f;
92+
int config_stale_external_pose_frames_ = 1;
93+
float config_pose_lerp_speed_ = 0.8f;
94+
float config_frozen_pose_position_epsilon_m_ = 0.005f;
95+
void LoadDriverConfig();
9396
void UpdateExternalControllerPoses();
9497
static vr::DriverPose_t
9598
DriverPoseFromTrackedDevicePose(const vr::TrackedDevicePose_t &raw);
96-
static bool ExternalPoseEquals(const vr::DriverPose_t &a,
97-
const vr::DriverPose_t &b);
98-
/// True if hand position is in front of HMD and within kExternalHandMaxRadius.
99-
static bool
100-
ExternalHandInFrontAndInRadius(const double hand_pos[3],
101-
const vr::TrackedDevicePose_t &hmd_pose);
99+
bool ExternalPoseEquals(const vr::DriverPose_t &a,
100+
const vr::DriverPose_t &b) const;
101+
bool ExternalHandInFrontAndInRadius(const double hand_pos[3],
102+
const vr::TrackedDevicePose_t &hmd_pose) const;
103+
virtual float GetPoseLerpSpeed() override;
102104
};
103105
}; // namespace SlimeVRDriver

0 commit comments

Comments
 (0)