Skip to content

Commit a20fd41

Browse files
committed
Add slower lerp when tracking system swaps.
1 parent c71afcd commit a20fd41

5 files changed

Lines changed: 20 additions & 4 deletions

File tree

src/IVRDriver.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,10 @@ 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. */
100+
/** Pose lerp speed (0–1) for smoothing. From driver config file. */
101101
virtual float GetPoseLerpSpeed() = 0;
102+
/** Slower lerp speed used when swapping VD ↔ SlimeVR to smooth the transition. */
103+
virtual float GetPoseLerpSpeedOnSwap() = 0;
102104

103105
virtual inline const char *const *GetInterfaceVersions() override {
104106
return vr::k_InterfaceVersions;

src/TrackerDevice.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,22 @@ void SlimeVRDriver::TrackerDevice::Update() {
143143

144144
// Target pose: controllers use external (VD/Steam Link) when available else SlimeVR; trackers use last SlimeVR pose.
145145
vr::DriverPose_t target = last_pose_atomic_.load();
146+
bool have_external = false;
146147
if (is_controller_) {
147148
auto external = GetDriver()->GetExternalPoseForHand(is_left_hand_);
148-
if (external.has_value())
149+
have_external = external.has_value();
150+
if (have_external)
149151
target = *external;
150152
}
151-
// Lerp from current toward target to reduce jitter and smooth transitions.
153+
// Use slower lerp when swapping VD ↔ SlimeVR to smooth the transition.
154+
float lerp_t = GetDriver()->GetPoseLerpSpeed();
155+
if (is_controller_ && (have_external != last_frame_had_external_))
156+
lerp_t = GetDriver()->GetPoseLerpSpeedOnSwap();
157+
last_frame_had_external_ = have_external;
152158
if (!smoothed_pose_.has_value())
153159
smoothed_pose_ = target;
154160
else
155-
smoothed_pose_ = LerpPose(*smoothed_pose_, target, GetDriver()->GetPoseLerpSpeed());
161+
smoothed_pose_ = LerpPose(*smoothed_pose_, target, lerp_t);
156162
GetDriver()->GetDriverHost()->TrackedDevicePoseUpdated(
157163
device_index_, *smoothed_pose_, sizeof(vr::DriverPose_t));
158164
}

src/TrackerDevice.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ 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+
bool last_frame_had_external_ = false;
7374
static vr::DriverPose_t LerpPose(const vr::DriverPose_t &from,
7475
const vr::DriverPose_t &to, float t);
7576

src/VRDriver.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ void SlimeVRDriver::VRDriver::LoadDriverConfig() {
495495
if (auto v = obj["external_hand_max_radius_m"]; !v.error()) config_external_hand_max_radius_m_ = static_cast<float>(v.get_double());
496496
if (auto v = obj["stale_external_pose_frames"]; !v.error()) config_stale_external_pose_frames_ = static_cast<int>(v.get_int64());
497497
if (auto v = obj["pose_lerp_speed"]; !v.error()) config_pose_lerp_speed_ = static_cast<float>(v.get_double());
498+
if (auto v = obj["pose_lerp_speed_on_swap"]; !v.error()) config_pose_lerp_speed_on_swap_ = static_cast<float>(v.get_double());
498499
if (auto v = obj["frozen_pose_position_epsilon_m"]; !v.error()) config_frozen_pose_position_epsilon_m_ = static_cast<float>(v.get_double());
499500
logger_->Log("Loaded driver config from {}", path);
500501
} catch (const simdjson::simdjson_error &) {
@@ -506,6 +507,10 @@ float SlimeVRDriver::VRDriver::GetPoseLerpSpeed() {
506507
return config_pose_lerp_speed_;
507508
}
508509

510+
float SlimeVRDriver::VRDriver::GetPoseLerpSpeedOnSwap() {
511+
return config_pose_lerp_speed_on_swap_;
512+
}
513+
509514
SlimeVRDriver::SettingsValue
510515
SlimeVRDriver::VRDriver::GetSettingsValue(std::string key) {
511516
vr::EVRSettingsError err = vr::EVRSettingsError::VRSettingsError_None;

src/VRDriver.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ namespace SlimeVRDriver {
9191
float config_external_hand_max_radius_m_ = 1.7f;
9292
int config_stale_external_pose_frames_ = 1;
9393
float config_pose_lerp_speed_ = 0.8f;
94+
float config_pose_lerp_speed_on_swap_ = 0.25f;
9495
float config_frozen_pose_position_epsilon_m_ = 0.005f;
9596
void LoadDriverConfig();
9697
void UpdateExternalControllerPoses();
@@ -101,5 +102,6 @@ namespace SlimeVRDriver {
101102
bool ExternalHandInFrontAndInRadius(const double hand_pos[3],
102103
const vr::TrackedDevicePose_t &hmd_pose) const;
103104
virtual float GetPoseLerpSpeed() override;
105+
virtual float GetPoseLerpSpeedOnSwap() override;
104106
};
105107
}; // namespace SlimeVRDriver

0 commit comments

Comments
 (0)