The project a is stage reference space that allows the player to walk around, but I need a way to move with the thumbsticks as well. I have an created an extra XrPosef called m_Local that is the amount the player as moved and rotated with the thumbsticks. To get my position I use m_HMD + m_Local and for rotation use a QuaternionMultiply function on m_HMD and m_Local.
My movement code works, but is this the right way to move with the thumbstick in OpenXR?
void movelocalz(float Time, XrTime predictedDisplayTime)
{
// Move The Direction The Player Is Facing
if (m_Move.z != 0.0f)
{
float Distance = m_Move.z;
m_Move.z = 0.0f;
XrSpaceLocation viewSpaceLocation = {XR_TYPE_SPACE_LOCATION};
XrResult result;
// Locate the view space relative to the world space at the predicted display time
result = xrLocateSpace(m_viewSpace, m_worldSpace, predictedDisplayTime, &viewSpaceLocation);
if (XR_SUCCEEDED(result) &&
(viewSpaceLocation.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) &&
(viewSpaceLocation.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT))
{
// Calculate forward vector based on the orientation
XrQuaternionf RightHandedOrientation = viewSpaceLocation.pose.orientation;
XrQuaternionf LeftHandedOrientation;
// Convert right-handed to left-handed coordinate system
RightToLeftCoordinateSystem(RightHandedOrientation.w, RightHandedOrientation.x, RightHandedOrientation.y, RightHandedOrientation.z,
LeftHandedOrientation.w, LeftHandedOrientation.x, LeftHandedOrientation.y, LeftHandedOrientation.z);
// Define the initial forward vector in a left-handed coordinate system
// Assuming forward is along +Z axis
float initialForwardX = 0.0f, initialForwardY = 0.0f, initialForwardZ = 1.0f;
XrVector3f forwardDirection;
// Rotate initial forward vector by the quaternion
RotateVectorByQuaternion(LeftHandedOrientation.w, LeftHandedOrientation.x, LeftHandedOrientation.y, LeftHandedOrientation.z,
initialForwardX, initialForwardY, initialForwardZ,
forwardDirection.x, forwardDirection.y, forwardDirection.z);
// Calculate speed (distance over time)
float speed = Distance / Time;
// Update position based on speed and forward direction
m_Local.position.x += forwardDirection.x * speed;
if (m_FollowHMDPitch) m_Local.position.y += forwardDirection.y * speed;
m_Local.position.z += forwardDirection.z * speed;
}
}
}
Now as for rotation, I cannot get this to work correctly. The HMD tilt is off when I start rotating the m_Local with the thumbsticks.
void rotatelocaly(float Time, XrTime predictedDisplayTime)
{
if (m_Rotate.y != 0.0f)
{
float angleRadians = m_Rotate.y; // Assuming m_Rotate.y is in radians as noted.
m_Rotate.y = 0.0f; // Reset the rotation amount after applying it.
// Components of the quaternion for a rotation around the Y-axis
float qw = cos(angleRadians / 2.0f);
float qx = 0.0f;
float qy = sin(angleRadians / 2.0f);
float qz = 0.0f;
// Assuming m_Local.orientation represents the current orientation as a quaternion
XrQuaternionf currentOrientation = m_Local.orientation;
XrQuaternionf newOrientation;
// Quaternion multiplication (current orientation * rotation quaternion)
newOrientation.w = currentOrientation.w * qw - currentOrientation.y * qy;
newOrientation.x = currentOrientation.x * qw + currentOrientation.z * qy;
newOrientation.y = currentOrientation.y * qw + currentOrientation.w * qy;
newOrientation.z = currentOrientation.z * qw - currentOrientation.x * qy;
// Update the local orientation with the new orientation
m_Local.orientation = newOrientation;
}
}
I also read to destroy and recreate the stage reference space to update the pose. I could get rid of m_Local completely if I done this. Not sure which is the correct path.