Search code examples
c++htc-viveopenvr

Why GetDeviceToAbsoluteTrackingPose(...) doesn't return the HMD position in OpenVR?


I'm trying to implement a basic OpenVR C++ app. This is my code:

#include <iostream>
#include <thread>
#include <chrono>

#include <openvr.h>


int main()
{
    vr::EVRInitError eError = vr::VRInitError_None;
    vr::IVRSystem * pvr = vr::VR_Init(&eError, vr::VRApplication_Utility);

    std::cout << "Error code: " << eError << std::endl;
    std::cout << "Is HMD present? " << vr::VR_IsHmdPresent() << std::endl;
    std::cout << "Is VR runtime installed? " << vr::VR_IsRuntimeInstalled() << std::endl;

    for (uint32_t deviceId = 0; deviceId < vr::k_unMaxTrackedDeviceCount; deviceId++) 
    {
        vr::TrackedDevicePose_t trackedDevicePose;
        vr::VRControllerState_t controllerState;

        vr::ETrackedDeviceClass deviceClass = pvr->GetTrackedDeviceClass(deviceId);

        if (!pvr->IsTrackedDeviceConnected(deviceId))
        {
            //std::cout << "Device ID " << deviceId << " is not connected." << std::endl;
            continue;
        }

        switch (deviceClass)
        {
            case vr::ETrackedDeviceClass::TrackedDeviceClass_HMD:
                std::cout << "HMD ID: " << deviceId << std::endl;
                //for (int i = 0; i < 100; ++i)
                {
                    pvr->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, &trackedDevicePose, deviceId);
                    //pvr->GetControllerStateWithPose(vr::TrackingUniverseStanding, deviceId, &controllerState, 
                    //                                sizeof(controllerState), &trackedDevicePose);

                    vr::HmdMatrix34_t & m34 = trackedDevicePose.mDeviceToAbsoluteTracking;
                    std::cout << m34.m[0][3] << " " << m34.m[1][3] << " " << m34.m[2][3] << std::endl;

                    std::this_thread::sleep_for(std::chrono::seconds(1));
                }
                break;

            default:
                break;
        }
    } 

    vr::VR_Shutdown();

    return 0;
}

The outputs are:

Error code: 0

Is HMD present? 1

Is VR runtime installed? 1

HMD ID: 0

-1.07374e+08 -1.07374e+08 -1.07374e+08

The last output doesn't change, even if I run this for a minute or more and moving my headset (HTC Vive).

I've tried to get the controller position with an other case:

            case vr::ETrackedDeviceClass::TrackedDeviceClass_Controller:
            std::cout << "Controller ID: " << deviceId << std::endl;
            //for (int i = 0; i < 100; ++i)
            {
                pvr->GetControllerStateWithPose(vr::TrackingUniverseStanding, deviceId, &controllerState, 
                                                sizeof(controllerState), &trackedDevicePose);

                vr::HmdMatrix34_t & m34 = trackedDevicePose.mDeviceToAbsoluteTracking;
                std::cout << m34.m[0][3] << " " << m34.m[1][3] << " " << m34.m[2][3] << std::endl;

                std::this_thread::sleep_for(std::chrono::seconds(1));
            }
            break;

And it outputs

Controller ID: 1

-1.07374e+08 -1.07374e+08 -1.07374e+08

When the headset or the controller is turned off, there is no output from them, so something is working but I can't figure out what's wrong.

I'm using OpenVR SDK 1.16.8

Printing out the whole matrix also gives me this weird result:

std::cout << m34.m[0][0] << " " << m34.m[1][0] << " " << m34.m[2][0] << std::endl;
std::cout << m34.m[0][1] << " " << m34.m[1][1] << " " << m34.m[2][1] << std::endl;
std::cout << m34.m[0][2] << " " << m34.m[1][2] << " " << m34.m[2][2] << std::endl;
std::cout << m34.m[0][3] << " " << m34.m[1][3] << " " << m34.m[2][3] << std::endl;

-1.07374e+08 -1.07374e+08 -1.07374e+08

-1.07374e+08 -1.07374e+08 -1.07374e+08

-1.07374e+08 -1.07374e+08 -1.07374e+08

-1.07374e+08 -1.07374e+08 -1.07374e+08


Solution

  • Okay, I've found the solution.

    pvr->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, &trackedDevicePose, 1);
    

    The last parameter should be 1 (in my case). It's an array count parameter, not the device ID.