Forum Discussion
naelstrof
7 years agoHonored Guest
SteamVR Oculus driver fights with other OnPoseUpdate hooks.
Trying to make an app that lets you adjust your playspace on the fly. (Lets you climb around in other games like VRChat.)
VR Input emulator has an OnPoseUpdate hook that simply offsets the vecPosition of devices which is exactly what I need to let the player grab and move themselves around.
Though it seems as though Oculus's SteamVR driver interferes with it asynchronously, causing an extreme amount of jitter.
The exact same code running with a Vive works perfectly, and I believe this is because there isn't multiple OnPoseUpdate hooks interfering with each other.
Here's a minimal app that only requires OpenVR and VR Input Emulator as dependencies that causes the problem.
Anyone know if Oculus's SteamVR driver is modifiable so I can get it and vrinputemulator to sync on the same mutex lock?
Or should I be submitting this problem elsewhere?
VR Input emulator has an OnPoseUpdate hook that simply offsets the vecPosition of devices which is exactly what I need to let the player grab and move themselves around.
Though it seems as though Oculus's SteamVR driver interferes with it asynchronously, causing an extreme amount of jitter.
The exact same code running with a Vive works perfectly, and I believe this is because there isn't multiple OnPoseUpdate hooks interfering with each other.
Here's a minimal app that only requires OpenVR and VR Input Emulator as dependencies that causes the problem.
#include <iostream>
#include <algorithm>
#include <string>
#include <thread>
#include <openvr.h>
#include <vrinputemulator.h>
static vr::IVRSystem* m_VRSystem;
static vrinputemulator::VRInputEmulator inputEmulator;
static vr::HmdVector3d_t lastLeftPos;
static vr::HmdVector3d_t lastRightPos;
static vr::HmdVector3d_t offset;
static int currentFrame;
static vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount];
void updateOffset() {
float fSecondsSinceLastVsync;
vr::VRSystem()->GetTimeSinceLastVsync(&fSecondsSinceLastVsync, NULL);
float fDisplayFrequency = vr::VRSystem()->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float);
float fFrameDuration = 1.f / fDisplayFrequency;
float fVsyncToPhotons = vr::VRSystem()->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float);
float fPredictedSecondsFromNow = fFrameDuration - fSecondsSinceLastVsync + fVsyncToPhotons;
vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, fPredictedSecondsFromNow, devicePoses, vr::k_unMaxTrackedDeviceCount);
vr::HmdVector3d_t delta;
delta.v[0] = 0; delta.v[1] = 0; delta.v[2] = 0;
auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
if (leftId != vr::k_unTrackedDeviceIndexInvalid ) {
vr::TrackedDevicePose_t* leftPose = devicePoses + leftId;
if (leftPose->bPoseIsValid && leftPose->bDeviceIsConnected) {
vr::HmdMatrix34_t* leftMat = &(leftPose->mDeviceToAbsoluteTracking);
vr::HmdVector3d_t leftPos;
leftPos.v[0] = leftMat->m[0][3] - offset.v[0];
leftPos.v[1] = leftMat->m[1][3] - offset.v[1];
leftPos.v[2] = leftMat->m[2][3] - offset.v[2];
vr::VRControllerState_t leftButtons;
vr::VRSystem()->GetControllerState(leftId, &leftButtons, sizeof(vr::VRControllerState_t));
if (leftButtons.ulButtonPressed & (1<<7) ) {
delta.v[0] = leftPos.v[0] - lastLeftPos.v[0];
delta.v[1] = leftPos.v[1] - lastLeftPos.v[1];
delta.v[2] = leftPos.v[2] - lastLeftPos.v[2];
}
lastLeftPos.v[0] = leftPos.v[0];
lastLeftPos.v[1] = leftPos.v[1];
lastLeftPos.v[2] = leftPos.v[2];
}
}
auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
if (rightId != vr::k_unTrackedDeviceIndexInvalid ) {
vr::TrackedDevicePose_t* rightPose = devicePoses + rightId;
if (rightPose->bPoseIsValid && rightPose->bDeviceIsConnected) {
vr::HmdMatrix34_t* rightMat = &(rightPose->mDeviceToAbsoluteTracking);
vr::HmdVector3d_t rightPos;
rightPos.v[0] = rightMat->m[0][3] - offset.v[0];
rightPos.v[1] = rightMat->m[1][3] - offset.v[1];
rightPos.v[2] = rightMat->m[2][3] - offset.v[2];
vr::VRControllerState_t rightButtons;
vr::VRSystem()->GetControllerState(rightId, &rightButtons, sizeof(vr::VRControllerState_t));
if (rightButtons.ulButtonPressed & (1<<7) ) {
delta.v[0] = rightPos.v[0] - lastRightPos.v[0];
delta.v[1] = rightPos.v[1] - lastRightPos.v[1];
delta.v[2] = rightPos.v[2] - lastRightPos.v[2];
}
lastRightPos.v[0] = rightPos.v[0];
lastRightPos.v[1] = rightPos.v[1];
lastRightPos.v[2] = rightPos.v[2];
}
}
offset.v[0] -= std::clamp(delta.v[0], (double)-0.1f, (double)0.1f);
offset.v[1] -= std::clamp(delta.v[1], (double)-0.1f, (double)0.1f);
offset.v[2] -= std::clamp(delta.v[2], (double)-0.1f, (double)0.1f);
}
void viveMove() {
for (uint32_t deviceIndex = 0; deviceIndex < vr::k_unMaxTrackedDeviceCount; deviceIndex++) {
if (!vr::VRSystem()->IsTrackedDeviceConnected(deviceIndex)) {
continue;
}
vrinputemulator::DeviceInfo info;
inputEmulator.getDeviceInfo(deviceIndex, info);
if (info.offsetsEnabled == false) {
inputEmulator.enableDeviceOffsets(deviceIndex, true);
}
inputEmulator.setDriverTranslationOffset(deviceIndex, offset);
}
}
int main( int argc, char** argv ) {
// Initialize stuff
vr::EVRInitError error = vr::VRInitError_Compositor_Failed;
std::cout << "Looking for SteamVR...";
while (error != vr::VRInitError_None) {
m_VRSystem = vr::VR_Init(&error, vr::VRApplication_Background);
if (error != vr::VRInitError_None) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
std::cout << "Success!\n";
std::cout << "Looking for VR Input Emulator...";
while (true) {
try {
inputEmulator.connect();
break;
}
catch (vrinputemulator::vrinputemulator_connectionerror e) {
std::this_thread::sleep_for(std::chrono::seconds(1));
continue;
}
}
std::cout << "Success!\n";
lastLeftPos.v[0] = 0; lastLeftPos.v[1] = 0; lastLeftPos.v[2] = 0;
lastRightPos.v[0] = 0; lastRightPos.v[1] = 0; lastRightPos.v[2] = 0;
offset.v[0] = 0; offset.v[1] = 0; offset.v[2] = 0;
// Main loop
bool running = true;
while (running) {
if (vr::VRCompositor() != NULL) {
vr::Compositor_FrameTiming t;
bool hasFrame = vr::VRCompositor()->GetFrameTiming(&t, 0);
if (hasFrame && currentFrame != t.m_nFrameIndex) {
currentFrame = t.m_nFrameIndex;
updateOffset();
viveMove();
}
}
}
return 0;
}Anyone know if Oculus's SteamVR driver is modifiable so I can get it and vrinputemulator to sync on the same mutex lock?
Or should I be submitting this problem elsewhere?
1 Reply
- naelstrofHonored GuestNevermind, I figured it out. It had to do with the inter-process queue that vr input emulator was using. I enabled the "modal" parameter which kept the calls from executing out of order, and all of my problems are solved.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 10 months ago
- 4 years ago
- 3 years ago