Getting Head Position and Rotation Data

Getting all zeros as a response to position and angle of the users head. What am I missing? I tried all three of these:

XR_REFERENCE_SPACE_TYPE_VIEW
XR_REFERENCE_SPACE_TYPE_STAGE
XR_REFERENCE_SPACE_TYPE_LOCAL

Getting the success response from the functions. I am calling the functions in the renderlayer function. My app is android and displaying a cube on my quest 2. It built off the example given on the openxr-tutorial website ( android OpenGLES) . I have also a boundary set up on the quest 2. It isn’t in passthru mode.

   
    void CreateReferenceSpace()
    {
        XR_TUT_LOG("-- Create Ref Space: Start ----------------------------");
        XrReferenceSpaceCreateInfo referenceSpaceCI{XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
        referenceSpaceCI.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE; // XR_REFERENCE_SPACE_TYPE_VIEW ;// ; //XR_REFERENCE_SPACE_TYPE_LOCAL;
        referenceSpaceCI.poseInReferenceSpace = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
        OPENXR_CHECK(xrCreateReferenceSpace(m_session, &referenceSpaceCI, &m_localSpace), "Failed to create ReferenceSpace.");
        XR_TUT_LOG("- Create Ref Space: End-");
    }

    void getheadposition(float *X, float *Y, float *Z, XrTime predictedTime)
    {
        *X = 0;
        *Y = 0;
        *Z = 0;

        XrSpaceLocation headLocation{XR_TYPE_SPACE_LOCATION};

        XrResult result = xrLocateSpace(m_localSpace, m_localSpace, predictedTime, &headLocation);

        if (XR_SUCCEEDED(result))
        {
            if ((headLocation.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0)
            {
                XR_TUT_LOG("Success: Head Position");
                *X = headLocation.pose.position.x;
                *Y = headLocation.pose.position.y;
                *Z = headLocation.pose.position.z;
            }
            else
            {
                XR_TUT_LOG("Failed To Get Head Position (2)");
                *X = 0; *Y = 0; *Z = 0; // Default or error values
            }
        }
        else
        {
            XR_TUT_LOG("Failed To Get Head Position (1)");
            *X = 0; *Y = 0; *Z = 0; // Default or error values
        }
    }
    void getheadangle(float *AngleX, float *AngleY, float *AngleZ, XrTime predictedTime)
    {   
        *AngleX = 0;
        *AngleY = 0;
        *AngleZ = 0;

        XrSpaceLocation headLocation{XR_TYPE_SPACE_LOCATION};

        XrResult result = xrLocateSpace(m_localSpace, m_localSpace, predictedTime, &headLocation);

        if (XR_SUCCEEDED(result))
        {
            if  ((headLocation.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) != 0)
            {
                XrQuaternionf q = headLocation.pose.orientation;
                // Convert quaternion to Euler angles
                float qx = q.x;
                float qy = q.y;
                float qz = q.z;
                float qw = q.w;
                
                // Roll (X-axis rotation)
                float sinr_cosp = 2 * (qw * qx + qy * qz);
                float cosr_cosp = 1 - 2 * (qx * qx + qy * qy);
                *AngleX = std::atan2(sinr_cosp, cosr_cosp);

                // Pitch (Y-axis rotation)
                float sinp = 2 * (qw * qy - qz * qx);
                if (std::abs(sinp) >= 1) *AngleY = std::copysign(M_PI / 2, sinp); // use 90 degrees if out of range
                else                     *AngleY = std::asin(sinp);

                // Yaw (Z-axis rotation)
                float siny_cosp = 2 * (qw * qz + qx * qy);
                float cosy_cosp = 1 - 2 * (qy * qy + qz * qz);
                *AngleZ = std::atan2(siny_cosp, cosy_cosp);

                 XR_TUT_LOG("Success: Head Angle");
            }
            else
            {
                XR_TUT_LOG("Failed To Get Head Angle (2)");
                *AngleX = 0; *AngleY = 0; *AngleZ = 0; // Default or error values
            }
        }
        else
        {
            XR_TUT_LOG("Failed To Get Head Angle (1)");
            *AngleX = 0; *AngleY = 0; *AngleZ = 0; // Default or error values
        }
    }

You’re requesting the pose of a space relative to itself, hence the resulting pose being identity.

xrLocateSpace(m_localSpace, m_localSpace ...

What you want is something like locating VIEW against LOCAL. You will need to create 2 reference spaces then

xrLocateSpace(m_viewSpace, m_localSpace ...

Thanks for clearing that up. Creating 2 XrSpace worked.

    void CreateReferenceSpace()
    {
        XR_MESSAGE("-- Create Ref Space: Start ----------------------------");
        // Fill out an XrReferenceSpaceCreateInfo structure and create a reference XrSpace, specifying a Local space with an identity pose as the origin.
        // Create LOCAL Reference Space
        XrReferenceSpaceCreateInfo referenceSpaceCI{XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
        referenceSpaceCI.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
        referenceSpaceCI.poseInReferenceSpace = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
        OPENXR_CHECK(xrCreateReferenceSpace(m_session, &referenceSpaceCI, &m_localSpace), "Failed to create ReferenceSpace (1).");

        // Create VIEW Reference Space
        XrReferenceSpaceCreateInfo viewSpaceCreateInfo = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
        viewSpaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
        viewSpaceCreateInfo.poseInReferenceSpace = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
        OPENXR_CHECK(xrCreateReferenceSpace(m_session, &viewSpaceCreateInfo, &m_viewSpace), "Failed to create ReferenceSpace (2).");;

        XR_MESSAGE("-- Create Ref Space: End ----------------------------");
    }
1 Like