mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-06 15:16:13 +00:00
st/oxr: Ensure quaternion is normalized in xrLocateViews()
In rare cases the state tracker's pose transformations resulted in a quaternion that accumulated float precision errors such that the norm of the quaternion was not within float precision of 1.0 anymore. Introduce a function math_quat_ensure_normalized() that can be used after multiple operations have been performed on a quaternion.
This commit is contained in:
parent
876c8bc5d7
commit
7a1dbbe8a1
|
@ -166,6 +166,18 @@ math_quat_validate(const struct xrt_quat *quat);
|
||||||
void
|
void
|
||||||
math_quat_normalize(struct xrt_quat *inout);
|
math_quat_normalize(struct xrt_quat *inout);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Normalizes a quaternion if it has accumulated float precision errors.
|
||||||
|
* Returns true if the quaternion was already normalized or was normalized after
|
||||||
|
* being found within a small float precision tolerance.
|
||||||
|
* Returns false if the quaternion was not at all normalized.
|
||||||
|
*
|
||||||
|
* @relates xrt_quat
|
||||||
|
* @ingroup aux_math
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
math_quat_ensure_normalized(struct xrt_quat *inout);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Rotate a vector.
|
* Rotate a vector.
|
||||||
*
|
*
|
||||||
|
|
|
@ -183,6 +183,28 @@ math_quat_normalize(struct xrt_quat *inout)
|
||||||
map_quat(*inout).normalize();
|
map_quat(*inout).normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" bool
|
||||||
|
math_quat_ensure_normalized(struct xrt_quat *inout)
|
||||||
|
{
|
||||||
|
assert(inout != NULL);
|
||||||
|
|
||||||
|
if (math_quat_validate(inout))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const float FLOAT_EPSILON = Eigen::NumTraits<float>::epsilon();
|
||||||
|
const float TOLERANCE = FLOAT_EPSILON * 5;
|
||||||
|
|
||||||
|
auto rot = copy(*inout);
|
||||||
|
auto norm = rot.norm();
|
||||||
|
if (norm > 1.0f + TOLERANCE || norm < 1.0f - TOLERANCE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_quat(*inout).normalize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
math_quat_rotate(const struct xrt_quat *left,
|
math_quat_rotate(const struct xrt_quat *left,
|
||||||
const struct xrt_quat *right,
|
const struct xrt_quat *right,
|
||||||
|
|
|
@ -389,6 +389,13 @@ oxr_session_views(struct oxr_logger *log,
|
||||||
safe_copy.xrt = xdev->hmd->views[i].fov;
|
safe_copy.xrt = xdev->hmd->views[i].fov;
|
||||||
views[i].fov = safe_copy.oxr;
|
views[i].fov = safe_copy.oxr;
|
||||||
|
|
||||||
|
if (!math_quat_ensure_normalized(
|
||||||
|
&((struct xrt_pose *)&views[i].pose)->orientation)) {
|
||||||
|
return oxr_error(
|
||||||
|
log, XR_ERROR_RUNTIME_FAILURE,
|
||||||
|
"Quaternion in xrLocateViews was invalid");
|
||||||
|
}
|
||||||
|
|
||||||
print_view_fov(sess, i, (struct xrt_fov *)&views[i].fov);
|
print_view_fov(sess, i, (struct xrt_fov *)&views[i].fov);
|
||||||
print_view_pose(sess, i, (struct xrt_pose *)&views[i].pose);
|
print_view_pose(sess, i, (struct xrt_pose *)&views[i].pose);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue