zeus/src/CMatrix3f.cpp

113 lines
3.7 KiB
C++
Raw Normal View History

2016-03-04 15:03:26 -08:00
#include "zeus/CMatrix3f.hpp"
#include "zeus/CQuaternion.hpp"
#include "zeus/Global.hpp"
2015-04-19 13:39:16 -07:00
2018-12-07 17:16:50 -08:00
namespace zeus {
2015-04-19 13:39:16 -07:00
CMatrix3f::CMatrix3f(const CQuaternion& nq) {
2018-12-07 17:16:50 -08:00
float x2 = nq.x() * nq.x();
float y2 = nq.y() * nq.y();
float z2 = nq.z() * nq.z();
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
m[0][0] = 1.0 - 2.0 * y2 - 2.0 * z2;
m[1][0] = 2.0 * nq.x() * nq.y() - 2.0 * nq.z() * nq.w();
m[2][0] = 2.0 * nq.x() * nq.z() + 2.0 * nq.y() * nq.w();
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
m[0][1] = 2.0 * nq.x() * nq.y() + 2.0 * nq.z() * nq.w();
m[1][1] = 1.0 - 2.0 * x2 - 2.0 * z2;
m[2][1] = 2.0 * nq.y() * nq.z() - 2.0 * nq.x() * nq.w();
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
m[0][2] = 2.0 * nq.x() * nq.z() - 2.0 * nq.y() * nq.w();
m[1][2] = 2.0 * nq.y() * nq.z() + 2.0 * nq.x() * nq.w();
m[2][2] = 1.0 - 2.0 * x2 - 2.0 * y2;
2015-04-19 13:39:16 -07:00
}
2018-12-07 17:16:50 -08:00
void CMatrix3f::transpose() {
2015-04-19 13:39:16 -07:00
#if __SSE__
2018-12-07 17:16:50 -08:00
__m128 zero = _mm_xor_ps(m[0].mSimd.native(), m[0].mSimd.native());
__m128 T0 = _mm_unpacklo_ps(m[0].mSimd.native(), m[1].mSimd.native());
__m128 T2 = _mm_unpacklo_ps(m[2].mSimd.native(), zero);
__m128 T1 = _mm_unpackhi_ps(m[0].mSimd.native(), m[1].mSimd.native());
__m128 T3 = _mm_unpackhi_ps(m[2].mSimd.native(), zero);
m[0].mSimd = _mm_movelh_ps(T0, T2);
m[1].mSimd = _mm_movehl_ps(T2, T0);
m[2].mSimd = _mm_movelh_ps(T1, T3);
#elif __ARM_NEON
2020-05-01 16:20:31 -07:00
float32x4x2_t P0 = vzipq_f32(m[0].mSimd.native(), m[2].mSimd.native());
float32x4x2_t P1 = vzipq_f32(m[1].mSimd.native(), m[3].mSimd.native());
2018-12-07 17:16:50 -08:00
2018-12-07 21:23:50 -08:00
float32x4x2_t T0 = vzipq_f32(P0.val[0], P1.val[0]);
float32x4x2_t T1 = vzipq_f32(P0.val[1], P1.val[1]);
2018-12-07 17:16:50 -08:00
m[0].mSimd = T0.val[0];
m[1].mSimd = T0.val[1];
m[2].mSimd = T1.val[0];
2015-04-19 13:39:16 -07:00
#else
2018-12-07 17:16:50 -08:00
float tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = m[0][1];
2022-08-03 15:15:45 -07:00
m[0][1] = m[1][0].operator float();
2018-12-07 17:16:50 -08:00
m[1][0] = tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = m[0][2];
2022-08-03 15:15:45 -07:00
m[0][2] = m[2][0].operator float();
2018-12-07 17:16:50 -08:00
m[2][0] = tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = m[1][2];
2022-08-03 15:15:45 -07:00
m[1][2] = m[2][1].operator float();
2018-12-07 17:16:50 -08:00
m[2][1] = tmp;
2015-04-19 13:39:16 -07:00
#endif
}
2018-12-07 17:16:50 -08:00
CMatrix3f CMatrix3f::transposed() const {
2015-04-19 13:39:16 -07:00
#if __SSE__
2018-12-07 17:16:50 -08:00
__m128 zero = _mm_xor_ps(m[0].mSimd.native(), m[0].mSimd.native());
__m128 T0 = _mm_unpacklo_ps(m[0].mSimd.native(), m[1].mSimd.native());
__m128 T2 = _mm_unpacklo_ps(m[2].mSimd.native(), zero);
__m128 T1 = _mm_unpackhi_ps(m[0].mSimd.native(), m[1].mSimd.native());
__m128 T3 = _mm_unpackhi_ps(m[2].mSimd.native(), zero);
return CMatrix3f(_mm_movelh_ps(T0, T2), _mm_movehl_ps(T2, T0), _mm_movelh_ps(T1, T3));
#elif __ARM_NEON
2020-05-01 16:20:31 -07:00
float32x4x2_t P0 = vzipq_f32(m[0].mSimd.native(), m[2].mSimd.native());
float32x4x2_t P1 = vzipq_f32(m[1].mSimd.native(), m[3].mSimd.native());
2018-12-07 17:16:50 -08:00
2018-12-07 21:23:50 -08:00
float32x4x2_t T0 = vzipq_f32(P0.val[0], P1.val[0]);
float32x4x2_t T1 = vzipq_f32(P0.val[1], P1.val[1]);
2018-12-07 17:16:50 -08:00
return CMatrix3f(T0.val[0], T0.val[1], T1.val[0]);
2015-04-19 13:39:16 -07:00
#else
2018-12-07 17:16:50 -08:00
CMatrix3f ret(*this);
float tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = ret.m[0][1];
2022-08-03 15:15:45 -07:00
ret.m[0][1] = ret.m[1][0].operator float();
2018-12-07 17:16:50 -08:00
ret.m[1][0] = tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = m[0][2];
2022-08-03 15:15:45 -07:00
ret.m[0][2] = ret.m[2][0].operator float();
2018-12-07 17:16:50 -08:00
ret.m[2][0] = tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
tmp = m[1][2];
2022-08-03 15:15:45 -07:00
ret.m[1][2] = ret.m[2][1].operator float();
2018-12-07 17:16:50 -08:00
ret.m[2][1] = tmp;
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
return ret;
2015-04-19 13:39:16 -07:00
#endif
}
2018-12-07 17:16:50 -08:00
CMatrix3f CMatrix3f::inverted() const {
float det = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] -
m[0][2] * m[1][1] * m[2][0] - m[1][2] * m[2][1] * m[0][0] - m[2][2] * m[0][1] * m[1][0];
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
if (det == 0.0)
return CMatrix3f();
2016-07-08 11:42:42 -07:00
2018-12-07 17:16:50 -08:00
det = 1.0f / det;
return CMatrix3f((m[1][1] * m[2][2] - m[1][2] * m[2][1]) * det, -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) * det,
(m[1][0] * m[2][1] - m[1][1] * m[2][0]) * det, -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) * det,
(m[0][0] * m[2][2] - m[0][2] * m[2][0]) * det, -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) * det,
(m[0][1] * m[1][2] - m[0][2] * m[1][1]) * det, -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) * det,
(m[0][0] * m[1][1] - m[0][1] * m[1][0]) * det);
2015-04-19 13:39:16 -07:00
}
2018-12-07 21:23:50 -08:00
} // namespace zeus