Commit 1cb70290 authored by Philip Trettner's avatar Philip Trettner
Browse files

uniform quat, direct decompose functions

parent 2ce561cb
......@@ -7,6 +7,8 @@
#include <typed-geometry/types/size.hh>
#include <typed-geometry/types/vec.hh>
#include <typed-geometry/feature/quat.hh>
namespace tg
{
/// decomposes a transformation matrix into a translation t, rotation matrix R, and uniform scale s
......@@ -64,4 +66,63 @@ constexpr void decompose_transformation(mat<4, 4, T> const& M, vec<3, T>& transl
rotation[1] = vec<3, T>(M[1]) / s1;
rotation[2] = vec<3, T>(M[2]) / s2;
}
/// returns the translation encoded in the transformation matrix as a vector
template <class T, int D>
constexpr vec<D - 1, T> transformation_of(mat<D, D, T> const& M)
{
return vec<D - 1, T>(M[3]);
}
/// returns the scale encoded in the transformation matrix as a vector
template <class T, int D>
constexpr size<D - 1, T> scale_of(mat<D, D, T> const& M)
{
size<D - 1, T> s;
for (auto i = 0; i < D - 1; ++i)
s[i] = length(vec<D - 1, T>(M[i]));
return s;
}
/// returns the scale encoded in the transformation matrix as a scalar
/// NOTE: assumes that the matrix only has uniform scale
template <class T, int D>
constexpr T scale_uniform_of(mat<D, D, T> const& M)
{
return length(vec<D - 1, T>(M[0]));
}
/// returns the rotation part of the transformation matrix as a mat3
/// NOTE: assumes that the matrix has no shear
template <class T>
constexpr mat<3, 3, T> rotation_mat3_of(mat<4, 4, T> const& M)
{
auto const s = scale_of(M);
mat<3, 3, T> rot;
rot[0] = vec<3, T>(M[0]) / s[0];
rot[1] = vec<3, T>(M[1]) / s[1];
rot[2] = vec<3, T>(M[2]) / s[2];
return rot;
}
/// returns the rotation part of the transformation matrix as a mat4 (i.e. a valid mat4 rotation matrix)
/// NOTE: assumes that the matrix has no shear
template <class T>
constexpr mat<4, 4, T> rotation_mat4_of(mat<4, 4, T> const& M)
{
auto const s = scale_of(M);
mat<4, 4, T> rot;
rot[0] = vec<4, T>(vec<3, T>(M[0]) / s[0], T(0));
rot[1] = vec<4, T>(vec<3, T>(M[1]) / s[1], T(0));
rot[2] = vec<4, T>(vec<3, T>(M[2]) / s[2], T(0));
rot[3][3] = T(1);
return rot;
}
/// returns the rotation part of the transformation matrix as a quaternion
/// NOTE: assumes that the matrix has no shear
template <class T>
constexpr quaternion<T> rotation_quat_of(mat<4, 4, T> const& M)
{
return quaternion<T>::from_rotation_matrix(rotation_mat3_of(M));
}
}
......@@ -17,8 +17,7 @@ namespace tg
template <class T>
[[nodiscard]] constexpr mat<4, 4, T> rotation_around(dir<3, T> const& axis, angle_t<T> angle)
{
auto ca = cos(angle);
auto sa = sin(angle);
auto [sa, ca] = sin_cos(angle);
auto one_minus_ca = T(1) - ca;
auto ux = axis.x;
......@@ -50,8 +49,7 @@ template <class T>
template <class T>
[[nodiscard]] constexpr mat<4, 4, T> rotation_x(angle_t<T> a)
{
auto ca = cos(a);
auto sa = sin(a);
auto [sa, ca] = sin_cos(a);
auto m = mat<4, 4, T>::identity;
m[1][1] = ca;
......@@ -63,8 +61,7 @@ template <class T>
template <class T>
[[nodiscard]] constexpr mat<4, 4, T> rotation_y(angle_t<T> a)
{
auto ca = cos(a);
auto sa = sin(a);
auto [sa, ca] = sin_cos(a);
auto m = mat<4, 4, T>::identity;
m[0][0] = ca;
......@@ -76,8 +73,7 @@ template <class T>
template <class T>
[[nodiscard]] constexpr mat<4, 4, T> rotation_z(angle_t<T> a)
{
auto ca = cos(a);
auto sa = sin(a);
auto [sa, ca] = sin_cos(a);
auto m = mat<4, 4, T>::identity;
m[0][0] = ca;
......@@ -139,8 +135,7 @@ template <class ScalarT>
{
auto origin_to_p = p - pos<2, ScalarT>::zero;
auto ca = cos(a);
auto sa = sin(a);
auto [sa, ca] = sin_cos(a);
auto r = mat<3, 3, ScalarT>::identity;
......@@ -155,19 +150,19 @@ template <class ScalarT>
template <class ScalarT>
[[nodiscard]] constexpr vec<2, ScalarT> rotate(vec<2, ScalarT> v, angle_t<ScalarT> a)
{
auto [sin, cos] = tg::sin_cos(a);
return {cos * v.x - sin * v.y, sin * v.x + cos * v.y};
auto [sa, ca] = sin_cos(a);
return {ca * v.x - sa * v.y, sa * v.x + ca * v.y};
}
template <class ScalarT>
[[nodiscard]] constexpr dir<2, ScalarT> rotate(dir<2, ScalarT> v, angle_t<ScalarT> a)
{
auto [sin, cos] = tg::sin_cos(a);
return {cos * v.x - sin * v.y, sin * v.x + cos * v.y};
auto [sa, ca] = sin_cos(a);
return {ca * v.x - sa * v.y, sa * v.x + ca * v.y};
}
template <class ScalarT>
[[nodiscard]] constexpr pos<2, ScalarT> rotate(pos<2, ScalarT> v, angle_t<ScalarT> a)
{
auto [sin, cos] = tg::sin_cos(a);
return {cos * v.x - sin * v.y, sin * v.x + cos * v.y};
auto [sa, ca] = sin_cos(a);
return {ca * v.x - sa * v.y, sa * v.x + ca * v.y};
}
} // namespace tg
......@@ -7,6 +7,7 @@
#include <typed-geometry/types/color.hh>
#include <typed-geometry/types/pos.hh>
#include <typed-geometry/types/quat.hh>
#include <typed-geometry/types/range.hh>
#include <typed-geometry/types/scalars/scalars.hh>
......@@ -835,6 +836,22 @@ struct sampler<dir<D, ScalarT>>
}
}
};
template <class ScalarT>
struct sampler<quaternion<ScalarT>>
{
template <class Rng>
constexpr static quaternion<ScalarT> uniform(Rng& rng)
{
auto ub = aabb<4, ScalarT>::minus_one_to_one;
while (true)
{
auto p = uniform_vec(rng, ub);
auto l = length_sqr(p);
if (l > ScalarT(0) && l <= ScalarT(1))
return tg::quaternion<ScalarT>(p / sqrt(l));
}
}
};
}
} // namespace tg
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment