I have odd behaviour since this update in xrLocateHandJointsEXT:
When controller is active since start of application, xrLocateHandJointsEXT returns isActive=true, locationFlags has XR_SPACE_LOCATION_POSITION_VALID_BIT but values appear to not be initialized.
Repro code:
std::optional<std::array<xr::hand_tracker::joint, XR_HAND_JOINT_COUNT_EXT>> xr::hand_tracker::locate(XrSpace space, XrTime time)
{
if (!id || !xrLocateHandJointsEXT)
return std::nullopt;
XrHandJointsLocateInfoEXT info{
.type = XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT,
.next = nullptr,
.baseSpace = space,
.time = time,
};
std::array<XrHandJointLocationEXT, XR_HAND_JOINT_COUNT_EXT> joints_pos;
std::array<XrHandJointVelocityEXT, XR_HAND_JOINT_COUNT_EXT> joints_vel;
XrHandJointVelocitiesEXT velocities{
.type = XR_TYPE_HAND_JOINT_VELOCITIES_EXT,
.next = nullptr,
.jointCount = joints_vel.size(),
.jointVelocities = joints_vel.data(),
};
XrHandJointLocationsEXT locations{
.type = XR_TYPE_HAND_JOINT_LOCATIONS_EXT,
.next = &velocities,
.jointCount = joints_pos.size(),
.jointLocations = joints_pos.data(),
};
CHECK_XR(xrLocateHandJointsEXT(id, &info, &locations));
if (!locations.isActive)
return std::nullopt;
std::array<xr::hand_tracker::joint, XR_HAND_JOINT_COUNT_EXT> joints;
for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++)
{
joints[i] = {joints_pos[i], joints_vel[i]};
if (not (joints_pos[i].locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT))
spdlog::warn("isActive but joints_pos[{}] position invalid", i);
else
{
if (std::isnan(joints_pos[i].pose.position.x))
spdlog::warn("joints_pos[{}].x is nan", i);
if (std::isnan(joints_pos[i].pose.position.y))
spdlog::warn("joints_pos[{}].y is nan", i);
if (std::isnan(joints_pos[i].pose.position.z))
spdlog::warn("joints_pos[{}].z is nan", i);
}
if (not (joints_pos[i].locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT))
spdlog::warn("isActive but joints_pos[{}] orientation invalid", i);
else
{
if (std::isnan(joints_pos[i].pose.orientation.x))
spdlog::warn("joints_pos[{}].orientation.x is nan", i);
if (std::isnan(joints_pos[i].pose.orientation.z))
spdlog::warn("joints_pos[{}].orientation.z is nan", i);
if (std::isnan(joints_pos[i].pose.orientation.y))
spdlog::warn("joints_pos[{}].orientation.y is nan", i);
if (std::isnan(joints_pos[i].pose.orientation.w))
spdlog::warn("joints_pos[{}].orientation.w is nan", i);
}
}
return joints;
}
Sample output: