2019-03-18 05:52:32 +00:00
|
|
|
// Copyright 2019, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Base implementations for math library.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
2021-03-05 23:13:27 +00:00
|
|
|
* @author Moses Turner <mosesturner@protonmail.com>
|
2019-04-06 11:29:47 +00:00
|
|
|
* @ingroup aux_math
|
2019-03-18 05:52:32 +00:00
|
|
|
*/
|
|
|
|
|
2019-11-21 13:15:38 +00:00
|
|
|
#include "math/m_api.h"
|
|
|
|
#include "math/m_eigen_interop.hpp"
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
#include <Eigen/Core>
|
|
|
|
#include <Eigen/Geometry>
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
2021-04-30 22:23:32 +00:00
|
|
|
using namespace xrt::auxiliary::math;
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copy helpers.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static inline Eigen::Quaternionf
|
2019-09-29 10:42:53 +00:00
|
|
|
copy(const struct xrt_quat &q)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
// Eigen constructor order is different from XRT, OpenHMD and OpenXR!
|
|
|
|
// Eigen: `float w, x, y, z`.
|
|
|
|
// OpenXR: `float x, y, z, w`.
|
|
|
|
return Eigen::Quaternionf(q.w, q.x, q.y, q.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eigen::Quaternionf
|
2019-09-29 10:42:53 +00:00
|
|
|
copy(const struct xrt_quat *q)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
return copy(*q);
|
|
|
|
}
|
|
|
|
|
2021-07-29 22:56:37 +00:00
|
|
|
XRT_MAYBE_UNUSED static inline Eigen::Quaterniond
|
|
|
|
copyd(const struct xrt_quat &q)
|
|
|
|
{
|
|
|
|
// Eigen constructor order is different from XRT, OpenHMD and OpenXR!
|
|
|
|
// Eigen: `float w, x, y, z`.
|
|
|
|
// OpenXR: `float x, y, z, w`.
|
|
|
|
return Eigen::Quaterniond(q.w, q.x, q.y, q.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
XRT_MAYBE_UNUSED static inline Eigen::Quaterniond
|
|
|
|
copyd(const struct xrt_quat *q)
|
|
|
|
{
|
|
|
|
return copyd(*q);
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
static inline Eigen::Vector3f
|
2019-09-29 10:42:53 +00:00
|
|
|
copy(const struct xrt_vec3 &v)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
return Eigen::Vector3f(v.x, v.y, v.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eigen::Vector3f
|
2019-09-29 10:42:53 +00:00
|
|
|
copy(const struct xrt_vec3 *v)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
return copy(*v);
|
|
|
|
}
|
|
|
|
|
2021-07-29 22:56:37 +00:00
|
|
|
XRT_MAYBE_UNUSED static inline Eigen::Vector3d
|
|
|
|
copyd(const struct xrt_vec3 &v)
|
|
|
|
{
|
|
|
|
return Eigen::Vector3d(v.x, v.y, v.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
XRT_MAYBE_UNUSED static inline Eigen::Vector3d
|
|
|
|
copyd(const struct xrt_vec3 *v)
|
|
|
|
{
|
|
|
|
return copyd(*v);
|
|
|
|
}
|
|
|
|
|
2021-04-21 15:11:27 +00:00
|
|
|
static inline Eigen::Matrix3f
|
|
|
|
copy(const struct xrt_matrix_3x3 *m)
|
|
|
|
{
|
|
|
|
Eigen::Matrix3f res;
|
|
|
|
// clang-format off
|
|
|
|
res << m->v[0], m->v[3], m->v[6],
|
|
|
|
m->v[1], m->v[4], m->v[7],
|
|
|
|
m->v[2], m->v[5], m->v[8];
|
|
|
|
// clang-format on
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2020-05-05 12:55:03 +00:00
|
|
|
static inline Eigen::Matrix4f
|
|
|
|
copy(const struct xrt_matrix_4x4 *m)
|
|
|
|
{
|
|
|
|
Eigen::Matrix4f res;
|
|
|
|
// clang-format off
|
|
|
|
res << m->v[0], m->v[4], m->v[8], m->v[12],
|
|
|
|
m->v[1], m->v[5], m->v[9], m->v[13],
|
|
|
|
m->v[2], m->v[6], m->v[10], m->v[14],
|
|
|
|
m->v[3], m->v[7], m->v[11], m->v[15];
|
|
|
|
// clang-format on
|
|
|
|
return res;
|
|
|
|
}
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2021-07-29 22:56:37 +00:00
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Exported vector functions.
|
|
|
|
*
|
|
|
|
*/
|
2019-07-21 12:35:41 +00:00
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" bool
|
2019-09-29 10:42:53 +00:00
|
|
|
math_vec3_validate(const struct xrt_vec3 *vec3)
|
2019-07-21 12:35:41 +00:00
|
|
|
{
|
|
|
|
assert(vec3 != NULL);
|
|
|
|
|
2019-08-16 21:55:07 +00:00
|
|
|
return map_vec3(*vec3).allFinite();
|
2019-07-21 12:35:41 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2019-09-29 10:42:53 +00:00
|
|
|
math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(additional != NULL);
|
|
|
|
assert(inAndOut != NULL);
|
|
|
|
|
|
|
|
map_vec3(*inAndOut) += map_vec3(*additional);
|
|
|
|
}
|
|
|
|
|
2020-10-12 00:09:19 +00:00
|
|
|
extern "C" void
|
|
|
|
math_vec3_subtract(const struct xrt_vec3 *subtrahend, struct xrt_vec3 *inAndOut)
|
|
|
|
{
|
|
|
|
assert(subtrahend != NULL);
|
|
|
|
assert(inAndOut != NULL);
|
|
|
|
|
|
|
|
map_vec3(*inAndOut) -= map_vec3(*subtrahend);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
math_vec3_scalar_mul(float scalar, struct xrt_vec3 *inAndOut)
|
|
|
|
{
|
|
|
|
assert(inAndOut != NULL);
|
|
|
|
|
|
|
|
map_vec3(*inAndOut) *= scalar;
|
|
|
|
}
|
|
|
|
|
2019-12-29 21:00:26 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_vec3_cross(const struct xrt_vec3 *l, const struct xrt_vec3 *r, struct xrt_vec3 *result)
|
2019-12-29 21:00:26 +00:00
|
|
|
{
|
|
|
|
map_vec3(*result) = map_vec3(*l).cross(map_vec3(*r));
|
|
|
|
}
|
|
|
|
|
2020-06-19 11:38:21 +00:00
|
|
|
extern "C" void
|
|
|
|
math_vec3_normalize(struct xrt_vec3 *in)
|
|
|
|
{
|
|
|
|
map_vec3(*in) = map_vec3(*in).normalized();
|
|
|
|
}
|
2019-07-21 12:35:41 +00:00
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Exported quaternion functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-03-13 19:14:18 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_from_angle_vector(float angle_rads, const struct xrt_vec3 *vector, struct xrt_quat *result)
|
2020-03-13 19:14:18 +00:00
|
|
|
{
|
|
|
|
map_quat(*result) = Eigen::AngleAxisf(angle_rads, copy(vector));
|
|
|
|
}
|
|
|
|
|
2019-12-25 14:13:34 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_from_matrix_3x3(const struct xrt_matrix_3x3 *mat, struct xrt_quat *result)
|
2019-12-25 14:13:34 +00:00
|
|
|
{
|
|
|
|
Eigen::Matrix3f m;
|
2021-01-14 14:13:48 +00:00
|
|
|
m << mat->v[0], mat->v[1], mat->v[2], mat->v[3], mat->v[4], mat->v[5], mat->v[6], mat->v[7], mat->v[8];
|
2019-12-25 14:13:34 +00:00
|
|
|
|
|
|
|
Eigen::Quaternionf q(m);
|
|
|
|
map_quat(*result) = q;
|
|
|
|
}
|
|
|
|
|
2019-12-29 21:00:26 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_from_plus_x_z(const struct xrt_vec3 *plus_x, const struct xrt_vec3 *plus_z, struct xrt_quat *result)
|
2019-12-29 21:00:26 +00:00
|
|
|
{
|
|
|
|
xrt_vec3 plus_y;
|
|
|
|
math_vec3_cross(plus_z, plus_x, &plus_y);
|
|
|
|
|
|
|
|
xrt_matrix_3x3 m = {{
|
|
|
|
plus_x->x,
|
|
|
|
plus_y.x,
|
|
|
|
plus_z->x,
|
|
|
|
plus_x->y,
|
|
|
|
plus_y.y,
|
|
|
|
plus_z->y,
|
|
|
|
plus_x->z,
|
|
|
|
plus_y.z,
|
|
|
|
plus_z->z,
|
|
|
|
}};
|
|
|
|
|
|
|
|
math_quat_from_matrix_3x3(&m, result);
|
|
|
|
}
|
|
|
|
|
2021-01-20 13:36:08 +00:00
|
|
|
static bool
|
|
|
|
quat_validate(const float precision, const struct xrt_quat *quat)
|
2019-07-21 12:35:41 +00:00
|
|
|
{
|
|
|
|
assert(quat != NULL);
|
|
|
|
auto rot = copy(*quat);
|
|
|
|
|
2021-01-20 13:36:08 +00:00
|
|
|
|
2020-05-28 12:12:46 +00:00
|
|
|
/*
|
|
|
|
* This was originally squaredNorm, but that could result in a norm
|
|
|
|
* value that was further from 1.0f then FLOAT_EPSILON (two).
|
|
|
|
*
|
|
|
|
* Our tracking system would produce such orientations and looping those
|
|
|
|
* back into say a quad layer would cause this to fail. And even
|
|
|
|
* normalizing the quat would not fix this as normalizations uses
|
|
|
|
* non-squared "length" which does fall into the range and doesn't
|
|
|
|
* change the elements of the quat.
|
|
|
|
*/
|
|
|
|
auto norm = rot.norm();
|
2021-01-20 13:36:08 +00:00
|
|
|
if (norm > 1.0f + precision || norm < 1.0f - precision) {
|
2019-07-21 12:35:41 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Technically not yet a required check, but easier to stop problems
|
|
|
|
// now than once denormalized numbers pollute the rest of our state.
|
|
|
|
// see https://gitlab.khronos.org/openxr/openxr/issues/922
|
|
|
|
if (!rot.coeffs().allFinite()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-01-20 13:36:08 +00:00
|
|
|
extern "C" bool
|
|
|
|
math_quat_validate(const struct xrt_quat *quat)
|
|
|
|
{
|
|
|
|
const float FLOAT_EPSILON = Eigen::NumTraits<float>::epsilon();
|
|
|
|
return quat_validate(FLOAT_EPSILON, quat);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" bool
|
|
|
|
math_quat_validate_within_1_percent(const struct xrt_quat *quat)
|
|
|
|
{
|
|
|
|
return quat_validate(0.01, quat);
|
|
|
|
}
|
|
|
|
|
2020-08-30 14:25:46 +00:00
|
|
|
extern "C" void
|
|
|
|
math_quat_invert(const struct xrt_quat *quat, struct xrt_quat *out_quat)
|
|
|
|
{
|
|
|
|
map_quat(*out_quat) = map_quat(*quat).conjugate();
|
|
|
|
}
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2019-09-29 10:42:53 +00:00
|
|
|
math_quat_normalize(struct xrt_quat *inout)
|
2019-06-21 20:43:45 +00:00
|
|
|
{
|
|
|
|
assert(inout != NULL);
|
|
|
|
map_quat(*inout).normalize();
|
|
|
|
}
|
|
|
|
|
2020-06-16 13:39:16 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_rotate(const struct xrt_quat *left, const struct xrt_quat *right, struct xrt_quat *result)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(left != NULL);
|
|
|
|
assert(right != NULL);
|
|
|
|
assert(result != NULL);
|
|
|
|
|
|
|
|
auto l = copy(left);
|
|
|
|
auto r = copy(right);
|
|
|
|
|
|
|
|
auto q = l * r;
|
|
|
|
|
|
|
|
map_quat(*result) = q;
|
|
|
|
}
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_rotate_vec3(const struct xrt_quat *left, const struct xrt_vec3 *right, struct xrt_vec3 *result)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(left != NULL);
|
|
|
|
assert(right != NULL);
|
|
|
|
assert(result != NULL);
|
|
|
|
|
|
|
|
auto l = copy(left);
|
|
|
|
auto r = copy(right);
|
|
|
|
|
|
|
|
auto v = l * r;
|
|
|
|
|
|
|
|
map_vec3(*result) = v;
|
|
|
|
}
|
|
|
|
|
2020-09-03 23:33:36 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_quat_rotate_derivative(const struct xrt_quat *quat, const struct xrt_vec3 *deriv, struct xrt_vec3 *result)
|
2020-09-03 23:33:36 +00:00
|
|
|
{
|
|
|
|
assert(quat != NULL);
|
|
|
|
assert(deriv != NULL);
|
|
|
|
assert(result != NULL);
|
|
|
|
|
|
|
|
auto l = copy(quat);
|
|
|
|
auto m = Eigen::Quaternionf(0.0f, deriv->x, deriv->y, deriv->z);
|
|
|
|
auto r = l.conjugate();
|
|
|
|
|
|
|
|
auto v = l * m * r;
|
|
|
|
|
|
|
|
struct xrt_vec3 ret = {v.x(), v.y(), v.z()};
|
|
|
|
*result = ret;
|
|
|
|
}
|
|
|
|
|
2021-06-11 06:20:57 +00:00
|
|
|
extern "C" void
|
|
|
|
math_quat_slerp(const struct xrt_quat *left, const struct xrt_quat *right, float t, struct xrt_quat *result)
|
|
|
|
{
|
|
|
|
assert(left != NULL);
|
|
|
|
assert(right != NULL);
|
|
|
|
assert(result != NULL);
|
|
|
|
|
|
|
|
auto l = copy(left);
|
|
|
|
auto r = copy(right);
|
|
|
|
|
|
|
|
map_quat(*result) = l.slerp(t, r);
|
|
|
|
}
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2020-03-16 14:12:39 +00:00
|
|
|
/*
|
|
|
|
*
|
2020-05-05 12:55:03 +00:00
|
|
|
* Exported matrix functions.
|
2020-03-16 14:12:39 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-11-27 15:45:51 +00:00
|
|
|
void
|
|
|
|
math_matrix_2x2_multiply(const struct xrt_matrix_2x2 *left,
|
|
|
|
const struct xrt_matrix_2x2 *right,
|
|
|
|
struct xrt_matrix_2x2 *result)
|
|
|
|
{
|
|
|
|
result->v[0] = left->v[0] * right->v[0] + left->v[1] * right->v[2];
|
|
|
|
result->v[1] = left->v[0] * right->v[1] + left->v[1] * right->v[3];
|
|
|
|
result->v[2] = left->v[2] * right->v[0] + left->v[3] * right->v[2];
|
|
|
|
result->v[3] = left->v[2] * right->v[1] + left->v[3] * right->v[3];
|
|
|
|
}
|
|
|
|
|
2020-03-16 14:12:39 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_matrix_3x3_transform_vec3(const struct xrt_matrix_3x3 *left, const struct xrt_vec3 *right, struct xrt_vec3 *result)
|
2020-03-16 14:12:39 +00:00
|
|
|
{
|
|
|
|
Eigen::Matrix3f m;
|
|
|
|
m << left->v[0], left->v[1], left->v[2], // 1
|
|
|
|
left->v[3], left->v[4], left->v[5], // 2
|
|
|
|
left->v[6], left->v[7], left->v[8]; // 3
|
|
|
|
|
|
|
|
map_vec3(*result) = m * copy(right);
|
|
|
|
}
|
|
|
|
|
2021-03-05 23:13:27 +00:00
|
|
|
extern "C" void
|
|
|
|
math_matrix_3x3_multiply(const struct xrt_matrix_3x3 *left,
|
2021-03-05 23:17:54 +00:00
|
|
|
const struct xrt_matrix_3x3 *right,
|
|
|
|
struct xrt_matrix_3x3 *result)
|
2021-03-05 23:13:27 +00:00
|
|
|
{
|
|
|
|
result->v[0] = left->v[0] * right->v[0] + left->v[1] * right->v[3] + left->v[2] * right->v[6];
|
|
|
|
result->v[1] = left->v[0] * right->v[1] + left->v[1] * right->v[4] + left->v[2] * right->v[7];
|
|
|
|
result->v[2] = left->v[0] * right->v[2] + left->v[1] * right->v[5] + left->v[2] * right->v[8];
|
|
|
|
|
|
|
|
result->v[3] = left->v[3] * right->v[0] + left->v[4] * right->v[3] + left->v[5] * right->v[6];
|
|
|
|
result->v[4] = left->v[3] * right->v[1] + left->v[4] * right->v[4] + left->v[5] * right->v[7];
|
|
|
|
result->v[5] = left->v[3] * right->v[2] + left->v[4] * right->v[5] + left->v[5] * right->v[8];
|
|
|
|
|
|
|
|
result->v[6] = left->v[6] * right->v[0] + left->v[7] * right->v[3] + left->v[8] * right->v[6];
|
|
|
|
result->v[7] = left->v[6] * right->v[1] + left->v[7] * right->v[4] + left->v[8] * right->v[7];
|
|
|
|
result->v[8] = left->v[6] * right->v[2] + left->v[7] * right->v[5] + left->v[8] * right->v[8];
|
|
|
|
}
|
2020-03-16 14:12:39 +00:00
|
|
|
|
2021-04-21 15:11:27 +00:00
|
|
|
extern "C" void
|
|
|
|
math_matrix_3x3_inverse(const struct xrt_matrix_3x3 *in, struct xrt_matrix_3x3 *result)
|
|
|
|
{
|
|
|
|
Eigen::Matrix3f m = copy(in);
|
|
|
|
map_matrix_3x3(*result) = m.inverse();
|
|
|
|
}
|
|
|
|
|
2020-05-05 12:55:03 +00:00
|
|
|
void
|
|
|
|
math_matrix_4x4_identity(struct xrt_matrix_4x4 *result)
|
|
|
|
{
|
|
|
|
map_matrix_4x4(*result) = Eigen::Matrix4f::Identity();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
math_matrix_4x4_multiply(const struct xrt_matrix_4x4 *left,
|
|
|
|
const struct xrt_matrix_4x4 *right,
|
|
|
|
struct xrt_matrix_4x4 *result)
|
|
|
|
{
|
|
|
|
map_matrix_4x4(*result) = copy(left) * copy(right);
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:41:04 +00:00
|
|
|
void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_matrix_4x4_view_from_pose(const struct xrt_pose *pose, struct xrt_matrix_4x4 *result)
|
2020-05-07 14:41:04 +00:00
|
|
|
{
|
|
|
|
Eigen::Vector3f position = copy(&pose->position);
|
|
|
|
Eigen::Quaternionf orientation = copy(&pose->orientation);
|
|
|
|
|
|
|
|
Eigen::Translation3f translation(position);
|
|
|
|
Eigen::Affine3f transformation = translation * orientation;
|
|
|
|
|
|
|
|
map_matrix_4x4(*result) = transformation.matrix().inverse();
|
|
|
|
}
|
|
|
|
|
2020-05-15 15:51:00 +00:00
|
|
|
void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_matrix_4x4_model(const struct xrt_pose *pose, const struct xrt_vec3 *size, struct xrt_matrix_4x4 *result)
|
2020-05-15 15:51:00 +00:00
|
|
|
{
|
|
|
|
Eigen::Vector3f position = copy(&pose->position);
|
|
|
|
Eigen::Quaternionf orientation = copy(&pose->orientation);
|
|
|
|
|
2020-08-20 01:58:09 +00:00
|
|
|
auto scale = Eigen::Scaling(size->x, size->y, size->z);
|
2020-05-15 15:51:00 +00:00
|
|
|
|
|
|
|
Eigen::Translation3f translation(position);
|
|
|
|
Eigen::Affine3f transformation = translation * orientation * scale;
|
|
|
|
|
|
|
|
map_matrix_4x4(*result) = transformation.matrix();
|
|
|
|
}
|
|
|
|
|
2020-09-08 17:41:24 +00:00
|
|
|
void
|
|
|
|
math_matrix_4x4_inverse_view_projection(const struct xrt_matrix_4x4 *view,
|
|
|
|
const struct xrt_matrix_4x4 *projection,
|
|
|
|
struct xrt_matrix_4x4 *result)
|
|
|
|
{
|
|
|
|
Eigen::Matrix4f v = copy(view);
|
|
|
|
Eigen::Matrix4f v3 = Eigen::Matrix4f::Identity();
|
|
|
|
v3.block<3, 3>(0, 0) = v.block<3, 3>(0, 0);
|
|
|
|
Eigen::Matrix4f vp = copy(projection) * v3;
|
|
|
|
map_matrix_4x4(*result) = vp.inverse();
|
|
|
|
}
|
|
|
|
|
2021-07-29 22:56:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Exported Matrix 4x4 functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_identity(struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
map_matrix_4x4_f64(*result) = Eigen::Matrix4d::Identity();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_invert(const struct xrt_matrix_4x4_f64 *matrix, struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
Eigen::Matrix4d m = map_matrix_4x4_f64(*matrix);
|
|
|
|
map_matrix_4x4_f64(*result) = m.inverse();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_multiply(const struct xrt_matrix_4x4_f64 *left,
|
|
|
|
const struct xrt_matrix_4x4_f64 *right,
|
|
|
|
struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
Eigen::Matrix4d l = map_matrix_4x4_f64(*left);
|
|
|
|
Eigen::Matrix4d r = map_matrix_4x4_f64(*right);
|
|
|
|
|
|
|
|
map_matrix_4x4_f64(*result) = l * r;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_orientation(const struct xrt_quat *quat, struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
map_matrix_4x4_f64(*result) = Eigen::Affine3d(copyd(*quat)).matrix();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_model(const struct xrt_pose *pose, const struct xrt_vec3 *size, struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
Eigen::Vector3d position = copyd(pose->position);
|
|
|
|
Eigen::Quaterniond orientation = copyd(pose->orientation);
|
|
|
|
|
|
|
|
auto scale = Eigen::Scaling(copyd(size));
|
|
|
|
|
|
|
|
Eigen::Translation3d translation(position);
|
|
|
|
Eigen::Affine3d transformation = translation * orientation * scale;
|
|
|
|
|
|
|
|
map_matrix_4x4_f64(*result) = transformation.matrix();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
m_mat4_f64_view(const struct xrt_pose *pose, struct xrt_matrix_4x4_f64 *result)
|
|
|
|
{
|
|
|
|
Eigen::Vector3d position = copyd(pose->position);
|
|
|
|
Eigen::Quaterniond orientation = copyd(pose->orientation);
|
|
|
|
|
|
|
|
Eigen::Translation3d translation(position);
|
|
|
|
Eigen::Affine3d transformation = translation * orientation;
|
|
|
|
|
|
|
|
map_matrix_4x4_f64(*result) = transformation.matrix().inverse();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Exported pose functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" bool
|
2019-09-29 10:42:53 +00:00
|
|
|
math_pose_validate(const struct xrt_pose *pose)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(pose != NULL);
|
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
return math_vec3_validate(&pose->position) && math_quat_validate(&pose->orientation);
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2019-09-29 10:42:53 +00:00
|
|
|
math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(pose != NULL);
|
|
|
|
assert(outPose != NULL);
|
|
|
|
|
2020-01-11 18:59:48 +00:00
|
|
|
// Store results to temporary locals so we can do this "in-place"
|
|
|
|
// (pose == outPose) if desired. Pure copies here.
|
|
|
|
Eigen::Vector3f newPosition = position(*pose);
|
|
|
|
Eigen::Quaternionf newOrientation = orientation(*pose);
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
// Conjugate legal here since pose must be normalized/unit length.
|
2020-01-11 18:59:48 +00:00
|
|
|
newOrientation = newOrientation.conjugate();
|
|
|
|
// Use the newly inverted rotation, to rotate position.
|
|
|
|
newPosition = -(newOrientation * newPosition);
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
position(*outPose) = newPosition;
|
|
|
|
orientation(*outPose) = newOrientation;
|
|
|
|
}
|
|
|
|
|
2021-03-05 23:17:54 +00:00
|
|
|
extern "C" void
|
|
|
|
math_pose_identity(struct xrt_pose *pose)
|
|
|
|
{
|
|
|
|
pose->position.x = 0.0;
|
|
|
|
pose->position.y = 0.0;
|
|
|
|
pose->position.z = 0.0;
|
|
|
|
pose->orientation.x = 0.0;
|
|
|
|
pose->orientation.y = 0.0;
|
|
|
|
pose->orientation.z = 0.0;
|
|
|
|
pose->orientation.w = 1.0;
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
/*!
|
|
|
|
* Return the result of transforming a point by a pose/transform.
|
|
|
|
*/
|
|
|
|
static inline Eigen::Vector3f
|
2019-09-29 10:42:53 +00:00
|
|
|
transform_point(const xrt_pose &transform, const xrt_vec3 &point)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
return orientation(transform) * map_vec3(point) + position(transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Return the result of transforming a pose by a pose/transform.
|
|
|
|
*/
|
|
|
|
static inline xrt_pose
|
2019-09-29 10:42:53 +00:00
|
|
|
transform_pose(const xrt_pose &transform, const xrt_pose &pose)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
xrt_pose ret;
|
|
|
|
position(ret) = transform_point(transform, pose.position);
|
|
|
|
orientation(ret) = orientation(transform) * orientation(pose);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-07-21 12:40:00 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_pose_transform(const struct xrt_pose *transform, const struct xrt_pose *pose, struct xrt_pose *outPose)
|
2019-03-18 05:52:32 +00:00
|
|
|
{
|
|
|
|
assert(pose != NULL);
|
|
|
|
assert(transform != NULL);
|
|
|
|
assert(outPose != NULL);
|
|
|
|
|
|
|
|
xrt_pose newPose = transform_pose(*transform, *pose);
|
|
|
|
memcpy(outPose, &newPose, sizeof(xrt_pose));
|
|
|
|
}
|
|
|
|
|
2019-12-29 21:00:26 +00:00
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
math_pose_transform_point(const struct xrt_pose *transform, const struct xrt_vec3 *point, struct xrt_vec3 *out_point)
|
2019-12-29 21:00:26 +00:00
|
|
|
{
|
|
|
|
assert(transform != NULL);
|
|
|
|
assert(point != NULL);
|
|
|
|
assert(out_point != NULL);
|
|
|
|
|
|
|
|
map_vec3(*out_point) = transform_point(*transform, *point);
|
|
|
|
}
|