17#include <Eigen/Eigenvalues>
31 __m128
A0 = _mm_load_ps(a[0]);
32 __m128
A1 = _mm_load_ps(a[1]);
33 __m128
A2 = _mm_load_ps(a[2]);
34 __m128 A3 = _mm_load_ps(a[3]);
36 for (
int i = 0;
i < 4;
i++) {
37 __m128 B0 = _mm_set1_ps(
b[
i][0]);
38 __m128 B1 = _mm_set1_ps(
b[
i][1]);
39 __m128 B2 = _mm_set1_ps(
b[
i][2]);
40 __m128 B3 = _mm_set1_ps(
b[
i][3]);
42 __m128
sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0,
A0), _mm_mul_ps(B1,
A1)),
43 _mm_add_ps(_mm_mul_ps(B2,
A2), _mm_mul_ps(B3, A3)));
48 result[0][0] =
b[0][0] * a[0][0] +
b[0][1] * a[1][0] +
b[0][2] * a[2][0] +
b[0][3] * a[3][0];
49 result[0][1] =
b[0][0] * a[0][1] +
b[0][1] * a[1][1] +
b[0][2] * a[2][1] +
b[0][3] * a[3][1];
50 result[0][2] =
b[0][0] * a[0][2] +
b[0][1] * a[1][2] +
b[0][2] * a[2][2] +
b[0][3] * a[3][2];
51 result[0][3] =
b[0][0] * a[0][3] +
b[0][1] * a[1][3] +
b[0][2] * a[2][3] +
b[0][3] * a[3][3];
53 result[1][0] =
b[1][0] * a[0][0] +
b[1][1] * a[1][0] +
b[1][2] * a[2][0] +
b[1][3] * a[3][0];
54 result[1][1] =
b[1][0] * a[0][1] +
b[1][1] * a[1][1] +
b[1][2] * a[2][1] +
b[1][3] * a[3][1];
55 result[1][2] =
b[1][0] * a[0][2] +
b[1][1] * a[1][2] +
b[1][2] * a[2][2] +
b[1][3] * a[3][2];
56 result[1][3] =
b[1][0] * a[0][3] +
b[1][1] * a[1][3] +
b[1][2] * a[2][3] +
b[1][3] * a[3][3];
58 result[2][0] =
b[2][0] * a[0][0] +
b[2][1] * a[1][0] +
b[2][2] * a[2][0] +
b[2][3] * a[3][0];
59 result[2][1] =
b[2][0] * a[0][1] +
b[2][1] * a[1][1] +
b[2][2] * a[2][1] +
b[2][3] * a[3][1];
60 result[2][2] =
b[2][0] * a[0][2] +
b[2][1] * a[1][2] +
b[2][2] * a[2][2] +
b[2][3] * a[3][2];
61 result[2][3] =
b[2][0] * a[0][3] +
b[2][1] * a[1][3] +
b[2][2] * a[2][3] +
b[2][3] * a[3][3];
63 result[3][0] =
b[3][0] * a[0][0] +
b[3][1] * a[1][0] +
b[3][2] * a[2][0] +
b[3][3] * a[3][0];
64 result[3][1] =
b[3][0] * a[0][1] +
b[3][1] * a[1][1] +
b[3][2] * a[2][1] +
b[3][3] * a[3][1];
65 result[3][2] =
b[3][0] * a[0][2] +
b[3][1] * a[1][2] +
b[3][2] * a[2][2] +
b[3][3] * a[3][2];
66 result[3][3] =
b[3][0] * a[0][3] +
b[3][1] * a[1][3] +
b[3][2] * a[2][3] +
b[3][3] * a[3][3];
78 __m128
A0 = _mm_set_ps(0, a[0][2], a[0][1], a[0][0]);
79 __m128
A1 = _mm_set_ps(0, a[1][2], a[1][1], a[1][0]);
80 __m128
A2 = _mm_set_ps(0, a[2][2], a[2][1], a[2][0]);
82 for (
int i = 0;
i < 2;
i++) {
83 __m128 B0 = _mm_set1_ps(
b[
i][0]);
84 __m128 B1 = _mm_set1_ps(
b[
i][1]);
85 __m128 B2 = _mm_set1_ps(
b[
i][2]);
86 __m128
sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0,
A0), _mm_mul_ps(B1,
A1)),
94 sum[2] = _mm_shuffle_ps(
sum[2],
sum[2], _MM_SHUFFLE(3, 2, 1, 1));
96 sum[2] = _mm_shuffle_ps(
sum[2],
sum[2], _MM_SHUFFLE(3, 2, 1, 2));
101 result[0][0] =
b[0][0] * a[0][0] +
b[0][1] * a[1][0] +
b[0][2] * a[2][0];
102 result[0][1] =
b[0][0] * a[0][1] +
b[0][1] * a[1][1] +
b[0][2] * a[2][1];
103 result[0][2] =
b[0][0] * a[0][2] +
b[0][1] * a[1][2] +
b[0][2] * a[2][2];
105 result[1][0] =
b[1][0] * a[0][0] +
b[1][1] * a[1][0] +
b[1][2] * a[2][0];
106 result[1][1] =
b[1][0] * a[0][1] +
b[1][1] * a[1][1] +
b[1][2] * a[2][1];
107 result[1][2] =
b[1][0] * a[0][2] +
b[1][1] * a[1][2] +
b[1][2] * a[2][2];
109 result[2][0] =
b[2][0] * a[0][0] +
b[2][1] * a[1][0] +
b[2][2] * a[2][0];
110 result[2][1] =
b[2][0] * a[0][1] +
b[2][1] * a[1][1] +
b[2][2] * a[2][1];
111 result[2][2] =
b[2][0] * a[0][2] +
b[2][1] * a[1][2] +
b[2][2] * a[2][2];
133 return Eigen::Map<const Eigen::Matrix<T, Size, Size>>(mat.
base_ptr()).determinant();
150 return Eigen::Map<const Eigen::Matrix<T, 3, 3>, 0, Eigen::Stride<4, 1>>(mat.
base_ptr())
151 .determinant() <
T(0);
174 if (m_c != c && m_r != r) {
175 int d_c = (m_c < c) ? m_c : (m_c - 1);
176 int d_r = (m_r < r) ? m_r : (m_r - 1);
177 tmp[d_c][d_r] = mat[m_c][m_r];
183 adj[r][c] = ((c + r) & 1) ? -minor : minor;
202template<
typename T,
int Size>
206 Eigen::Map<const Eigen::Matrix<T, Size, Size>>
M(mat.
base_ptr());
207 Eigen::Map<Eigen::Matrix<T, Size, Size>>
R(
result.base_ptr());
208 M.computeInverseWithCheck(
R, r_success, 0.0f);
222template<
typename T,
int Size>
243 using namespace Eigen;
244 using MatrixT = Eigen::Matrix<T, Size, Size>;
245 using VectorT = Eigen::Matrix<T, Size, 1>;
253 using MatrixDynamicT = Eigen::Matrix<T, Dynamic, Dynamic>;
254 JacobiSVD<MatrixDynamicT, NoQRPreconditioner> svd(
255 Eigen::Map<const MatrixDynamicT>(mat.
base_ptr(), Size, Size), ComputeThinU | ComputeThinV);
257 Eigen::Map<MatrixT>(
U.base_ptr()) = svd.matrixU();
258 (Eigen::Map<VectorT>(S_val)) = svd.singularValues();
259 Eigen::Map<MatrixT>(
V.base_ptr()) = svd.matrixV();
263 unroll<Size>([&](
auto i) { S_val[
i] = (S_val[
i] < epsilon) ?
T(0) : (
T(1) / S_val[
i]); });
304 using namespace Eigen;
305 using MatrixT = Eigen::Matrix<T, 3, 3>;
306 using VectorT = Eigen::Matrix<T, 3, 1>;
313 using MatrixDynamicT = Eigen::Matrix<T, Dynamic, Dynamic>;
314 JacobiSVD<MatrixDynamicT, NoQRPreconditioner> svd(
315 Eigen::Map<const MatrixDynamicT>(mat3.
base_ptr(), 3, 3), ComputeThinU | ComputeThinV);
317 Eigen::Map<MatrixT>(
W.base_ptr()) = svd.matrixU();
318 (Eigen::Map<VectorT>(S_val)) = svd.singularValues();
319 Eigen::Map<MatrixT>(
V.base_ptr()) = svd.matrixV();
402 Vec3T a_scale, b_scale;
403 QuaternionT a_quat, b_quat;
408 const QuaternionT rotation =
interpolate(a_quat, b_quat, t);
422 Vec3T a_scale, b_scale;
423 QuaternionT a_quat, b_quat;
427 const Vec3T location =
interpolate(a_loc, b_loc, t);
429 const QuaternionT rotation =
interpolate(a_quat, b_quat, t);
459 float ha2 = 0.5f *
math::atan2(x_axis.y, x_axis.x);
473template void normalized_to_eul2(
const float3x3 &mat,
474 Euler3Base<float> &eul1,
475 Euler3Base<float> &eul2);
476template void normalized_to_eul2(
const float3x3 &mat,
477 EulerXYZBase<float> &eul1,
478 EulerXYZBase<float> &eul2);
479template void normalized_to_eul2(
const double3x3 &mat,
480 EulerXYZBase<double> &eul1,
481 EulerXYZBase<double> &eul2);
483template QuaternionBase<float> normalized_to_quat_with_checks(
const float3x3 &mat);
484template QuaternionBase<double> normalized_to_quat_with_checks(
const double3x3 &mat);
508namespace projection {
511 float left,
float right,
float bottom,
float top,
float near_clip,
float far_clip);
513 float left,
float right,
float bottom,
float top,
float near_clip,
float far_clip);
515 float left,
float right,
float bottom,
float top,
float near_clip);
540 if (
math::abs(length_0 - length_1) > epsilon) {
543 if (
math::abs(length_0 - length_2) > epsilon) {
546 if (
math::abs(length_1 - length_2) > epsilon) {
561 for (float3 &normal : normals.slice(range)) {
562 normal = normalized_transform * normal;
568 for (float3 &normal : normals.slice(range)) {
569 normal = math::normalize(normal_transform * normal);
585 for (const int i : range) {
586 dst[i] = normalized_transform * src[i];
592 for (const int i : range) {
593 dst[i] = math::normalize(normal_transform * src[i]);
616 const bool use_threading)
624 transform_points_no_threading(src.slice(range), transform, dst.slice(range));
635 for (
float3 &position : points) {
642 const bool use_threading)
649 transform_points_no_threading(transform, points.slice(range));
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
btMatrix3x3 adjoint() const
Return the adjoint of the matrix.
btScalar determinant() const
Return the determinant of the matrix.
static T sum(const btAlignedObjectArray< T > &items)
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr IndexRange index_range() const
static float normals[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
MatBase< R, C > transpose(MatBase< C, R >) RET
VecBase< float, 3 > float3
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
MatBase< T, 4, 4 > perspective_infinite(T left, T right, T bottom, T top, T near_clip)
Create a perspective projection matrix using OpenGL coordinate convention: Maps each axis range to [-...
QuaternionBase< T > conjugate(const QuaternionBase< T > &a)
QuaternionBase< float > Quaternion
T length_squared(const VecBase< T, Size > &a)
T cos(const AngleRadianBase< T > &a)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
bool is_negative(const MatBase< T, 3, 3 > &mat)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
static bool skip_transform(const float4x4 &transform)
Quaternion to_quaternion_legacy(const float3x3 &mat)
static void transform_points_no_threading(const Span< float3 > src, const float4x4 &transform, MutableSpan< float3 > dst)
MatBase< T, Size, Size > pseudo_invert(const MatBase< T, Size, Size > &mat, T epsilon=1e-8)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
T interpolate(const T &a, const T &b, const FactorT &t)
void transform_normals(const float3x3 &transform, MutableSpan< float3 > normals)
bool is_similarity_transform(const MatBase< T, 3, 3 > &matrix, const T &epsilon=1e-6)
T atan2(const T &y, const T &x)
MatBase< T, 3, 3 > interpolate_fast(const MatBase< T, 3, 3 > &a, const MatBase< T, 3, 3 > &b, T t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
static void polar_decompose(const MatBase< T, 3, 3 > &mat3, MatBase< T, 3, 3 > &r_U, MatBase< T, 3, 3 > &r_P)
bool is_equal(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, const T epsilon=T(0))
T sin(const AngleRadianBase< T > &a)
void to_rot_scale(const MatBase< T, 2, 2 > &mat, AngleRadianBase< T > &r_rotation, VecBase< T, 2 > &r_scale)
MatBase< T, NumCol, NumRow > interpolate_linear(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, T t)
void to_loc_rot_scale(const MatBase< T, 3, 3 > &mat, VecBase< T, 2 > &r_location, AngleRadianBase< T > &r_rotation, VecBase< T, 2 > &r_scale)
MatT from_rot_scale(const RotationT &rotation, const VectorT &scale)
MatT from_rotation(const RotationT &rotation)
void transform_points(const float4x4 &transform, MutableSpan< float3 > points, bool use_threading=true)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 2, 2 > float2x2
MatBase< float, 4, 4 > float4x4
MatBase< double, 3, 3 > double3x3
MatBase< double, 2, 2 > double2x2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
MatBase< T, B_NumCol, A_NumRow > operator*(const MatBase< T, A_NumCol, A_NumRow > &a, const MatBase< T, B_NumCol, B_NumRow > &b)
MatBase< double, 4, 4 > double4x4
VecBase< T, 3 > vec3_type
const T * base_ptr() const
static MatBase identity()
CCL_NAMESPACE_BEGIN struct Window V