mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-02 19:58:01 +03:00
2320 lines
63 KiB
C++
2320 lines
63 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
Matrix Inverse algo: https://github.com/niswegmann/small-matrix-inverse
|
|
*/
|
|
|
|
#include "mat.hpp"
|
|
|
|
const mat3 mat3_identity = {
|
|
{ 1.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 1.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 1.0f },
|
|
};
|
|
|
|
const mat3 mat3_null = {
|
|
{ 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f },
|
|
};
|
|
|
|
const mat4 mat4_identity = {
|
|
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
|
};
|
|
|
|
const mat4 mat4_null = {
|
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
};
|
|
|
|
inline void mat3_add(const mat3* x, const mat3* y, mat3* z) {
|
|
z->row0 = x->row0 + y->row0;
|
|
z->row1 = x->row1 + y->row1;
|
|
z->row2 = x->row2 + y->row2;
|
|
}
|
|
|
|
inline void mat3_sub(const mat3* x, const mat3* y, mat3* z) {
|
|
z->row0 = x->row0 - y->row0;
|
|
z->row1 = x->row1 - y->row1;
|
|
z->row2 = x->row2 - y->row2;
|
|
}
|
|
|
|
inline void mat3_mult(const mat3* x, const mat3* y, mat3* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 xt0;
|
|
__m128 xt1;
|
|
__m128 xt2;
|
|
*(vec3*)&xt0 = x->row0;
|
|
*(vec3*)&xt1 = x->row1;
|
|
*(vec3*)&xt2 = x->row2;
|
|
*(vec3*)&yt = y->row0;
|
|
t0 = _mm_mul_ps(xt0, _mm_shuffle_ps(yt, yt, 0x00));
|
|
t1 = _mm_mul_ps(xt1, _mm_shuffle_ps(yt, yt, 0x55));
|
|
t2 = _mm_mul_ps(xt2, _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt = _mm_add_ps(_mm_add_ps(t0, t1), t2);
|
|
z->row0 = *(vec3*)&zt;
|
|
*(vec3*)&yt = y->row1;
|
|
t0 = _mm_mul_ps(xt0, _mm_shuffle_ps(yt, yt, 0x00));
|
|
t1 = _mm_mul_ps(xt1, _mm_shuffle_ps(yt, yt, 0x55));
|
|
t2 = _mm_mul_ps(xt2, _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt = _mm_add_ps(_mm_add_ps(t0, t1), t2);
|
|
z->row1 = *(vec3*)&zt;
|
|
*(vec3*)&yt = y->row2;
|
|
t0 = _mm_mul_ps(xt0, _mm_shuffle_ps(yt, yt, 0x00));
|
|
t1 = _mm_mul_ps(xt1, _mm_shuffle_ps(yt, yt, 0x55));
|
|
t2 = _mm_mul_ps(xt2, _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt = _mm_add_ps(_mm_add_ps(t0, t1), t2);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_mult_vec2(const mat3* x, const vec2* y, vec2* z) {
|
|
__m128 xt;
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
*(vec2*)&yt = *y;
|
|
*(vec3*)&xt = x->row0;
|
|
zt0 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x00));
|
|
*(vec3*)&xt = x->row1;
|
|
zt1 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt = _mm_add_ps(zt0, zt1);
|
|
*z = *(vec2*)&zt;
|
|
}
|
|
|
|
inline void mat3_mult_vec(const mat3* x, const vec3* y, vec3* z) {
|
|
__m128 xt;
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
*(vec3*)&yt = *y;
|
|
*(vec3*)&xt = x->row0;
|
|
zt0 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x00));
|
|
*(vec3*)&xt = x->row1;
|
|
zt1 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0x55));
|
|
*(vec3*)&xt = x->row2;
|
|
zt2 = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt = _mm_add_ps(_mm_add_ps(zt0, zt1), zt2);
|
|
*z = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_mult_scalar(const mat3* x, float_t y, mat3* z) {
|
|
__m128 xt;
|
|
__m128 yt;
|
|
__m128 zt;
|
|
yt = vec4::load_xmm(y);
|
|
*(vec3*)&xt = x->row0;
|
|
zt = _mm_mul_ps(xt, yt);
|
|
z->row0 = *(vec3*)&zt;
|
|
*(vec3*)&xt = x->row1;
|
|
zt = _mm_mul_ps(xt, yt);
|
|
z->row1 = *(vec3*)&zt;
|
|
*(vec3*)&xt = x->row2;
|
|
zt = _mm_mul_ps(xt, yt);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_transpose(const mat3* x, mat3* z) {
|
|
__m128 xt0;
|
|
__m128 xt1;
|
|
__m128 xt2;
|
|
__m128 xt3;
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
__m128 yt2;
|
|
__m128 yt3;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
xt0 = vec3::load_xmm(x->row0);
|
|
xt1 = vec3::load_xmm(x->row1);
|
|
xt2 = vec3::load_xmm(x->row2);
|
|
xt3 = vec4::load_xmm(0.0f);
|
|
yt0 = _mm_unpacklo_ps(xt0, xt1);
|
|
yt1 = _mm_unpackhi_ps(xt0, xt1);
|
|
yt2 = _mm_unpacklo_ps(xt2, xt3);
|
|
yt3 = _mm_unpackhi_ps(xt2, xt3);
|
|
zt0 = _mm_movelh_ps(yt0, yt2);
|
|
zt1 = _mm_movehl_ps(yt2, yt0);
|
|
zt2 = _mm_movelh_ps(yt1, yt3);
|
|
z->row0 = *(vec3*)&zt0;
|
|
z->row1 = *(vec3*)&zt1;
|
|
z->row2 = *(vec3*)&zt2;
|
|
}
|
|
|
|
void mat3_inverse(const mat3* x, mat3* z) {
|
|
vec3 xt0;
|
|
vec3 xt1;
|
|
vec3 xt2;
|
|
__m128 yt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
__m128 wt;
|
|
xt0 = x->row0;
|
|
xt1 = x->row1;
|
|
xt2 = x->row2;
|
|
zt0 = _mm_sub_ps(
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.y, xt0.z, xt1.y),
|
|
_mm_set_ps(0.0f, xt1.z, xt2.y, xt2.z)
|
|
),
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.z, xt0.y, xt1.z),
|
|
_mm_set_ps(0.0f, xt1.y, xt2.z, xt2.y)
|
|
)
|
|
);
|
|
zt1 = _mm_sub_ps(
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.z, xt0.x, xt1.z),
|
|
_mm_set_ps(0.0f, xt1.x, xt2.z, xt2.x)
|
|
),
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.x, xt0.z, xt1.x),
|
|
_mm_set_ps(0.0f, xt1.z, xt2.x, xt2.z)
|
|
)
|
|
);
|
|
zt2 = _mm_sub_ps(
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.x, xt0.y, xt1.x),
|
|
_mm_set_ps(0.0f, xt1.y, xt2.x, xt2.y)
|
|
),
|
|
_mm_mul_ps(
|
|
_mm_set_ps(0.0f, xt0.y, xt0.x, xt1.y),
|
|
_mm_set_ps(0.0f, xt1.x, xt2.y, xt2.x)
|
|
)
|
|
);
|
|
|
|
wt = _mm_movelh_ps(_mm_unpacklo_ps(zt0, zt1), zt2);
|
|
yt = vec3::load_xmm(xt0);
|
|
wt = _mm_mul_ps(yt, wt);
|
|
wt = _mm_hadd_ps(wt, wt);
|
|
wt = _mm_hadd_ps(wt, wt);
|
|
if (_mm_cvtss_f32(wt) != 0.0f)
|
|
wt = _mm_div_ss(_mm_set_ss(1.0f), wt);
|
|
wt = _mm_shuffle_ps(wt, wt, 0);
|
|
yt = _mm_mul_ps(zt0, wt);
|
|
z->row0 = *(vec3*)&yt;
|
|
yt = _mm_mul_ps(zt1, wt);
|
|
z->row1 = *(vec3*)&yt;
|
|
yt = _mm_mul_ps(zt2, wt);
|
|
z->row2 = *(vec3*)&yt;
|
|
}
|
|
|
|
inline void mat3_invtrans(const mat3* x, mat3* z) {
|
|
mat3 t = *x;
|
|
mat3_inverse(&t, &t);
|
|
mat3_transpose(&t, &t);
|
|
*z = t;
|
|
}
|
|
|
|
inline void mat3_inverse_normalized(const mat3* x, mat3* z) {
|
|
mat3_transpose(x, z);
|
|
}
|
|
|
|
inline void mat3_normalize(const mat3* x, mat3* z) {
|
|
__m128 det;
|
|
__m128 xt0;
|
|
__m128 xt1;
|
|
__m128 xt2;
|
|
det = _mm_set_ss(mat3_determinant(x));
|
|
if (_mm_cvtss_f32(det) != 0.0f)
|
|
det = _mm_div_ss(_mm_set_ss(1.0f), det);
|
|
det = _mm_shuffle_ps(det, det, 0);
|
|
*(vec3*)&xt0 = x->row0;
|
|
*(vec3*)&xt1 = x->row1;
|
|
*(vec3*)&xt2 = x->row2;
|
|
xt0 = _mm_mul_ps(xt0, det);
|
|
xt1 = _mm_mul_ps(xt1, det);
|
|
xt2 = _mm_mul_ps(xt2, det);
|
|
z->row0 = *(vec3*)&xt0;
|
|
z->row1 = *(vec3*)&xt1;
|
|
z->row2 = *(vec3*)&xt2;
|
|
}
|
|
|
|
inline void mat3_normalize_rotation(const mat3* x, mat3* z) {
|
|
z->row0 = vec3::normalize(x->row0);
|
|
z->row1 = vec3::normalize(x->row1);
|
|
z->row2 = vec3::normalize(x->row2);
|
|
}
|
|
|
|
inline float_t mat3_determinant(const mat3* x) {
|
|
vec3 xt0;
|
|
vec3 xt1;
|
|
vec3 xt2;
|
|
xt0 = x->row0;
|
|
xt1 = x->row1;
|
|
xt2 = x->row2;
|
|
float_t b00 = xt0.x * xt1.y * xt2.z;
|
|
float_t b01 = xt0.y * xt1.z * xt2.x;
|
|
float_t b02 = xt0.z * xt1.x * xt2.y;
|
|
float_t b03 = xt0.z * xt1.y * xt2.x;
|
|
float_t b04 = xt0.x * xt1.z * xt2.y;
|
|
float_t b05 = xt0.y * xt1.x * xt2.z;
|
|
return b00 + b01 + b02 - b03 - b04 - b05;
|
|
}
|
|
|
|
inline void mat3_rotate_xyz(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (x != 0.0f)
|
|
mat3_rotate_x(x, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (x != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat3_rotate_y(y, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (y != 0.0f || x != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat3_rotate_z(z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_xzy(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (x != 0.0f)
|
|
mat3_rotate_x(x, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (x != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat3_rotate_z(z, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (z != 0.0f || x != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat3_rotate_y(y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_yxz(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (y != 0.0f)
|
|
mat3_rotate_y(y, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (y != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat3_rotate_x(x, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (x != 0.0f || y != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat3_rotate_z(z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_yzx(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (y != 0.0f)
|
|
mat3_rotate_y(y, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (y != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat3_rotate_z(z, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (z != 0.0f || y != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat3_rotate_x(x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_zxy(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (z != 0.0f)
|
|
mat3_rotate_z(z, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (z != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat3_rotate_x(x, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (x != 0.0f || z != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat3_rotate_y(y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_zyx(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (z != 0.0f)
|
|
mat3_rotate_z(z, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (z != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat3_rotate_y(y, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (y != 0.0f || z != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat3_rotate_x(x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_x_sin_cos(float_t sin_val, float_t cos_val, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row1.y = cos_val;
|
|
yt.row1.z = sin_val;
|
|
yt.row2.y = -sin_val;
|
|
yt.row2.z = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_y_sin_cos(float_t sin_val, float_t cos_val, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row0.x = cos_val;
|
|
yt.row0.z = -sin_val;
|
|
yt.row2.x = sin_val;
|
|
yt.row2.z = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_z_sin_cos(float_t sin_val, float_t cos_val, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row0.x = cos_val;
|
|
yt.row0.y = sin_val;
|
|
yt.row1.x = -sin_val;
|
|
yt.row1.y = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_x_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) {
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
z->row0 = *(vec3*)&y0;
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(cos_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(sin_val));
|
|
zt = _mm_add_ps(t1, t2);
|
|
z->row1 = *(vec3*)&zt;
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(-sin_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(cos_val));
|
|
zt = _mm_add_ps(t1, t2);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_rotate_y_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) {
|
|
__m128 t0;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(cos_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(-sin_val));
|
|
zt = _mm_add_ps(t0, t2);
|
|
z->row0 = *(vec3*)&zt;
|
|
z->row1 = *(vec3*)&y1;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(sin_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(cos_val));
|
|
zt = _mm_add_ps(t0, t2);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_rotate_z_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(cos_val));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(sin_val));
|
|
zt = _mm_add_ps(t0, t1);
|
|
z->row0 = *(vec3*)&zt;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(-sin_val));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(cos_val));
|
|
zt = _mm_add_ps(t0, t1);
|
|
z->row1 = *(vec3*)&zt;
|
|
z->row2 = *(vec3*)&y2;
|
|
}
|
|
|
|
inline void mat3_rotate_x(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat3_identity;
|
|
yt.row1.y = x_cos;
|
|
yt.row1.z = x_sin;
|
|
yt.row2.y = -x_sin;
|
|
yt.row2.z = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_y(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat3_identity;
|
|
yt.row0.x = x_cos;
|
|
yt.row0.z = -x_sin;
|
|
yt.row2.x = x_sin;
|
|
yt.row2.z = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_z(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat3_identity;
|
|
yt.row0.x = x_cos;
|
|
yt.row0.y = x_sin;
|
|
yt.row1.x = -x_sin;
|
|
yt.row1.y = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_rotate_xyz_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_xzy_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_yxz_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_yzx_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_zxy_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_zyx_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = *s;
|
|
if (z != 0.0f)
|
|
mat3_rotate_z_mult(&dt, z, &dt);
|
|
if (y != 0.0f)
|
|
mat3_rotate_y_mult(&dt, y, &dt);
|
|
if (x != 0.0f)
|
|
mat3_rotate_x_mult(&dt, x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_rotate_x_mult(const mat3* x, float_t y, mat3* z) {
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
z->row0 = *(vec3*)&y0;
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_cos));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_sin));
|
|
zt = _mm_add_ps(t1, t2);
|
|
z->row1 = *(vec3*)&zt;
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(-y_sin));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_cos));
|
|
zt = _mm_add_ps(t1, t2);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_rotate_y_mult(const mat3* x, float_t y, mat3* z) {
|
|
__m128 t0;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_cos));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(-y_sin));
|
|
zt = _mm_add_ps(t0, t2);
|
|
z->row0 = *(vec3*)&zt;
|
|
z->row1 = *(vec3*)&y1;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_sin));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_cos));
|
|
zt = _mm_add_ps(t0, t2);
|
|
z->row2 = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat3_rotate_z_mult(const mat3* x, float_t y, mat3* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 zt;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
*(vec3*)&y0 = x->row0;
|
|
*(vec3*)&y1 = x->row1;
|
|
*(vec3*)&y2 = x->row2;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_cos));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_sin));
|
|
zt = _mm_add_ps(t0, t1);
|
|
z->row0 = *(vec3*)&zt;
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(-y_sin));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_cos));
|
|
zt = _mm_add_ps(t0, t1);
|
|
z->row1 = *(vec3*)&zt;
|
|
z->row2 = *(vec3*)&y2;
|
|
}
|
|
|
|
inline void mat3_scale(float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 dt;
|
|
dt = mat3_identity;
|
|
if (x != 1.0f)
|
|
dt.row0.x = x;
|
|
if (y != 1.0f)
|
|
dt.row1.y = y;
|
|
if (z != 1.0f)
|
|
dt.row2.z = z;
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat3_scale_x(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row0.x = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_scale_y(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row1.y = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_scale_z(float_t x, mat3* y) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row2.z = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat3_scale_mult(const mat3* s, float_t x, float_t y, float_t z, mat3* d) {
|
|
mat3 st;
|
|
mat3 dt;
|
|
if (x != 1.0f || y != 1.0f || z != 1.0f) {
|
|
st = *s;
|
|
dt = mat3_identity;
|
|
dt.row0.x = x;
|
|
dt.row1.y = y;
|
|
dt.row2.z = z;
|
|
mat3_mult(&st, &dt, &dt);
|
|
*d = dt;
|
|
}
|
|
else
|
|
*d = *s;
|
|
}
|
|
|
|
inline void mat3_scale_x_mult(const mat3* x, float_t y, mat3* z) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row0.x = y;
|
|
mat3_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat3_scale_y_mult(const mat3* x, float_t y, mat3* z) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row1.y = y;
|
|
mat3_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat3_scale_z_mult(const mat3* x, float_t y, mat3* z) {
|
|
mat3 yt;
|
|
yt = mat3_identity;
|
|
yt.row2.z = y;
|
|
mat3_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat3_from_quat(const quat* quat, mat3* mat) {
|
|
float_t y;
|
|
float_t x;
|
|
float_t z;
|
|
float_t w;
|
|
float_t len;
|
|
float_t xy;
|
|
float_t yy;
|
|
float_t xx;
|
|
float_t wx;
|
|
float_t wy;
|
|
float_t zz;
|
|
float_t xz;
|
|
float_t wz;
|
|
float_t yz;
|
|
|
|
x = quat->x;
|
|
y = quat->y;
|
|
z = quat->z;
|
|
w = quat->w;
|
|
len = quat::length_squared(*quat);
|
|
len = len > 0.0f ? 2.0f / len : 0.0f;
|
|
xx = x * x * len;
|
|
xy = x * y * len;
|
|
xz = x * z * len;
|
|
yy = y * y * len;
|
|
zz = z * z * len;
|
|
yz = y * z * len;
|
|
wx = w * x * len;
|
|
wy = w * y * len;
|
|
wz = w * z * len;
|
|
mat->row0.x = 1.0f - zz - yy;
|
|
mat->row0.y = xy + wz;
|
|
mat->row0.z = xz - wy;
|
|
mat->row1.x = xy - wz;
|
|
mat->row1.y = 1.0f - zz - xx;
|
|
mat->row1.z = yz + wx;
|
|
mat->row2.x = xz + wy;
|
|
mat->row2.y = yz - wx;
|
|
mat->row2.z = 1.0f - yy - xx;
|
|
}
|
|
|
|
inline void mat3_from_axis_angle(const vec3* axis, float_t angle, mat3* mat) {
|
|
float_t angle_sin;
|
|
float_t angle_cos;
|
|
float_t angle_cos_1;
|
|
vec3 _axis;
|
|
vec3 _axis_sin;
|
|
vec3 temp;
|
|
|
|
angle_sin = sinf(angle);
|
|
angle_cos = cosf(angle);
|
|
angle_cos_1 = 1.0f - angle_cos;
|
|
|
|
_axis = vec3::normalize(*axis);
|
|
|
|
_axis_sin = _axis * angle_sin;
|
|
temp = _axis * (_axis.x * angle_cos_1);
|
|
mat->row0.x = temp.x + angle_cos;
|
|
mat->row1.x = temp.y - _axis_sin.z;
|
|
mat->row2.x = temp.z + _axis_sin.y;
|
|
temp = _axis * (_axis.y * angle_cos_1);
|
|
mat->row0.y = temp.x + _axis_sin.z;
|
|
mat->row1.y = temp.y + angle_cos;
|
|
mat->row2.y = temp.z - _axis_sin.x;
|
|
temp = _axis * (_axis.z * angle_cos_1);
|
|
mat->row0.z = temp.x - _axis_sin.y;
|
|
mat->row1.z = temp.y + _axis_sin.x;
|
|
mat->row2.z = temp.z + angle_cos;
|
|
}
|
|
|
|
inline void mat3_from_axis_angle_sin_cos(const vec3* axis, float_t sin_val, float_t cos_val, mat3* mat) {
|
|
float_t cos_val_1;
|
|
vec3 _axis;
|
|
vec3 _axis_sin;
|
|
vec3 temp;
|
|
|
|
cos_val_1 = 1.0f - cos_val;
|
|
|
|
_axis = vec3::normalize(*axis);
|
|
|
|
_axis_sin = _axis * sin_val;
|
|
temp = _axis * (_axis.x * cos_val_1);
|
|
mat->row0.x = temp.x + cos_val;
|
|
mat->row1.x = temp.y - _axis_sin.z;
|
|
mat->row2.x = temp.z + _axis_sin.y;
|
|
temp = _axis * (_axis.y * cos_val_1);
|
|
mat->row0.y = temp.x + _axis_sin.z;
|
|
mat->row1.y = temp.y + cos_val;
|
|
mat->row2.y = temp.z - _axis_sin.x;
|
|
temp = _axis * (_axis.z * cos_val_1);
|
|
mat->row0.z = temp.x - _axis_sin.y;
|
|
mat->row1.z = temp.y + _axis_sin.x;
|
|
mat->row2.z = temp.z + cos_val;
|
|
}
|
|
|
|
inline void mat3_from_mat4(const mat4* x, mat3* z) {
|
|
z->row0 = *(vec3*)&x->row0;
|
|
z->row1 = *(vec3*)&x->row1;
|
|
z->row2 = *(vec3*)&x->row2;
|
|
}
|
|
|
|
inline void mat3_from_mat4_inverse(const mat4* x, mat3* z) {
|
|
mat4 yt;
|
|
|
|
mat4_inverse(x, &yt);
|
|
z->row0 = *(vec3*)&yt.row0;
|
|
z->row1 = *(vec3*)&yt.row1;
|
|
z->row2 = *(vec3*)&yt.row2;
|
|
}
|
|
|
|
inline void mat3_get_rotation(const mat3* x, vec3* z) {
|
|
if (-x->row0.z >= 1.0f)
|
|
z->y = (float_t)M_PI_2;
|
|
else if (-x->row0.z <= -1.0f)
|
|
z->y = (float_t)-M_PI_2;
|
|
else
|
|
z->y = asinf(-x->row0.z);
|
|
if (fabs(x->row0.z) < 0.99999899f) {
|
|
z->x = atan2f(x->row1.z, x->row2.z);
|
|
z->z = atan2f(x->row0.y, x->row0.x);
|
|
}
|
|
else {
|
|
z->x = 0.0f;
|
|
z->z = atan2f(x->row2.y, x->row1.y);
|
|
if (-x->row0.z < 0.0f)
|
|
z->z = -z->z;
|
|
}
|
|
}
|
|
|
|
inline void mat3_get_scale(const mat3* x, vec3* z) {
|
|
z->x = vec3::length(x->row0);
|
|
z->y = vec3::length(x->row1);
|
|
z->z = vec3::length(x->row2);
|
|
}
|
|
|
|
inline float_t mat3_get_max_scale(const mat3* x) {
|
|
mat3 mat;
|
|
mat3_transpose(x, &mat);
|
|
|
|
float_t length;
|
|
float_t max = 0.0f;
|
|
length = vec3::length(mat.row0);
|
|
if (max < length)
|
|
max = length;
|
|
length = vec3::length(mat.row1);
|
|
if (max < length)
|
|
max = length;
|
|
length = vec3::length(mat.row2);
|
|
if (max < length)
|
|
max = length;
|
|
return max;
|
|
}
|
|
|
|
inline void mat3_mult_axis_angle(const mat3* x, const vec3* axis, const float_t angle, mat3* z) {
|
|
quat q1;
|
|
quat q2;
|
|
quat q3;
|
|
quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y,
|
|
x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1);
|
|
quat_from_axis_angle(axis, angle, &q2);
|
|
quat_mult(&q2, &q1, &q3);
|
|
mat3_from_quat(&q3, z);
|
|
}
|
|
|
|
inline void mat4_add(const mat4* x, const mat4* y, mat4* z) {
|
|
z->row0 = x->row0 + y->row0;
|
|
z->row1 = x->row1 + y->row1;
|
|
z->row2 = x->row2 + y->row2;
|
|
z->row3 = x->row3 + y->row3;
|
|
}
|
|
|
|
inline void mat4_sub(const mat4* x, const mat4* y, mat4* z) {
|
|
z->row0 = x->row0 - y->row0;
|
|
z->row1 = x->row1 - y->row1;
|
|
z->row2 = x->row2 - y->row2;
|
|
z->row3 = x->row3 - y->row3;
|
|
}
|
|
|
|
inline void mat4_mult(const mat4* x, const mat4* y, mat4* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 t3;
|
|
__m128 xt;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
y0 = vec4::load_xmm(y->row0);
|
|
y1 = vec4::load_xmm(y->row1);
|
|
y2 = vec4::load_xmm(y->row2);
|
|
y3 = vec4::load_xmm(y->row3);
|
|
xt = vec4::load_xmm(x->row0);
|
|
t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00));
|
|
t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55));
|
|
t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA));
|
|
t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF));
|
|
z->row0 = vec4::store_xmm(_mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)));
|
|
xt = vec4::load_xmm(x->row1);
|
|
t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00));
|
|
t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55));
|
|
t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA));
|
|
t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF));
|
|
z->row1 = vec4::store_xmm(_mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)));
|
|
xt = vec4::load_xmm(x->row2);
|
|
t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00));
|
|
t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55));
|
|
t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA));
|
|
t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF));
|
|
z->row2 = vec4::store_xmm(_mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)));
|
|
xt = vec4::load_xmm(x->row3);
|
|
t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00));
|
|
t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55));
|
|
t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA));
|
|
t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF));
|
|
z->row3 = vec4::store_xmm(_mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)));
|
|
}
|
|
|
|
inline void mat4_mult_vec2(const mat4* x, const vec2* y, vec2* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
*(vec2*)&yt = *y;
|
|
zt0 = _mm_mul_ps(vec4::load_xmm(x->row0), _mm_shuffle_ps(yt, yt, 0x00));
|
|
zt1 = _mm_mul_ps(vec4::load_xmm(x->row1), _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt = _mm_add_ps(zt0, zt1);
|
|
*z = *(vec2*)&zt;
|
|
}
|
|
|
|
inline void mat4_mult_vec2_trans(const mat4* x, const vec2* y, vec2* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
*(vec2*)&yt = *y;
|
|
zt0 = _mm_mul_ps(vec4::load_xmm(x->row0), _mm_shuffle_ps(yt, yt, 0x00));
|
|
zt1 = _mm_mul_ps(vec4::load_xmm(x->row1), _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt2 = vec4::load_xmm(x->row3);
|
|
zt = _mm_add_ps(_mm_add_ps(zt0, zt1), zt2);
|
|
*z = *(vec2*)&zt;
|
|
}
|
|
|
|
inline void mat4_mult_vec3(const mat4* x, const vec3* y, vec3* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
*(vec3*)&yt = *y;
|
|
zt0 = _mm_mul_ps(vec4::load_xmm(x->row0), _mm_shuffle_ps(yt, yt, 0x00));
|
|
zt1 = _mm_mul_ps(vec4::load_xmm(x->row1), _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt2 = _mm_mul_ps(vec4::load_xmm(x->row2), _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt = _mm_add_ps(_mm_add_ps(zt0, zt1), zt2);
|
|
*z = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat4_mult_vec3_inv(const mat4* x, const vec3* y, vec3* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
yt = vec3::load_xmm(*y);
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row0));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->x = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row1));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->y = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row2));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->z = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
}
|
|
|
|
inline void mat4_mult_vec3_trans(const mat4* x, const vec3* y, vec3* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
__m128 zt3;
|
|
*(vec3*)&yt = *y;
|
|
zt0 = _mm_mul_ps(vec4::load_xmm(x->row0), _mm_shuffle_ps(yt, yt, 0x00));
|
|
zt1 = _mm_mul_ps(vec4::load_xmm(x->row1), _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt2 = _mm_mul_ps(vec4::load_xmm(x->row2), _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt3 = vec4::load_xmm(x->row3);
|
|
zt = _mm_add_ps(_mm_add_ps(zt0, zt1), _mm_add_ps(zt2, zt3));
|
|
*z = *(vec3*)&zt;
|
|
}
|
|
|
|
inline void mat4_mult_vec3_inv_trans(const mat4* x, const vec3* y, vec3* z) {
|
|
__m128 yt;
|
|
__m128 zt;
|
|
yt = vec3::load_xmm(*y);
|
|
yt = _mm_sub_ps(yt, vec4::load_xmm(x->row3));
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row0));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->x = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row1));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->y = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
zt = _mm_mul_ps(yt, vec4::load_xmm(x->row2));
|
|
zt = _mm_hadd_ps(zt, zt);
|
|
z->z = _mm_cvtss_f32(_mm_hadd_ps(zt, zt));
|
|
}
|
|
|
|
inline void mat4_mult_vec(const mat4* x, vec4* y, vec4* z) {
|
|
__m128 yt;
|
|
__m128 zt0;
|
|
__m128 zt1;
|
|
__m128 zt2;
|
|
__m128 zt3;
|
|
yt = vec4::load_xmm(*y);
|
|
zt0 = _mm_mul_ps(vec4::load_xmm(x->row0), _mm_shuffle_ps(yt, yt, 0x00));
|
|
zt1 = _mm_mul_ps(vec4::load_xmm(x->row1), _mm_shuffle_ps(yt, yt, 0x55));
|
|
zt2 = _mm_mul_ps(vec4::load_xmm(x->row2), _mm_shuffle_ps(yt, yt, 0xAA));
|
|
zt3 = _mm_mul_ps(vec4::load_xmm(x->row3), _mm_shuffle_ps(yt, yt, 0xFF));
|
|
*z = vec4::store_xmm(_mm_add_ps(_mm_add_ps(zt0, zt1), _mm_add_ps(zt2, zt3)));
|
|
}
|
|
|
|
inline void mat4_mult_scalar(const mat4* x, float_t y, mat4* z) {
|
|
__m128 yt;
|
|
yt = vec4::load_xmm(y);
|
|
z->row0 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row0), yt));
|
|
z->row1 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row1), yt));
|
|
z->row2 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row2), yt));
|
|
z->row3 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row3), yt));
|
|
}
|
|
|
|
inline void mat4_transpose(const mat4* x, mat4* z) {
|
|
__m128 xt0;
|
|
__m128 xt1;
|
|
__m128 xt2;
|
|
__m128 xt3;
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
__m128 yt2;
|
|
__m128 yt3;
|
|
xt0 = vec4::load_xmm(x->row0);
|
|
xt1 = vec4::load_xmm(x->row1);
|
|
xt2 = vec4::load_xmm(x->row2);
|
|
xt3 = vec4::load_xmm(x->row3);
|
|
yt0 = _mm_unpacklo_ps(xt0, xt1);
|
|
yt1 = _mm_unpackhi_ps(xt0, xt1);
|
|
yt2 = _mm_unpacklo_ps(xt2, xt3);
|
|
yt3 = _mm_unpackhi_ps(xt2, xt3);
|
|
z->row0 = vec4::store_xmm(_mm_movelh_ps(yt0, yt2));
|
|
z->row1 = vec4::store_xmm(_mm_movehl_ps(yt2, yt0));
|
|
z->row2 = vec4::store_xmm(_mm_movelh_ps(yt1, yt3));
|
|
z->row3 = vec4::store_xmm(_mm_movehl_ps(yt3, yt1));
|
|
}
|
|
|
|
void mat4_inverse(const mat4* x, mat4* z) {
|
|
static const __m128 xor0 = { -0.0f, 0.0f, -0.0f, 0.0f };
|
|
static const __m128 xor1 = { 0.0f, -0.0f, 0.0f, -0.0f };
|
|
|
|
__m128 xt0, xt1, xt2, xt3;
|
|
__m128 xt0x, xt1x, xt2x, xt3x;
|
|
__m128 xt0y, xt1y, xt2y, xt3y;
|
|
__m128 xt0z, xt1z, xt2z, xt3z;
|
|
__m128 xt0w, xt1w, xt2w, xt3w;
|
|
__m128 yt00, yt01, yt02, yt03, yt04, yt05, yt06, yt07, yt08, yt09, yt10, yt11;
|
|
__m128 zt0, zt1, zt2, zt3;
|
|
__m128 wt;
|
|
__m128 wt0, wt1, wt2;
|
|
__m128 t0, t1, t2, t3, t4, t5;
|
|
xt0 = vec4::load_xmm(x->row0);
|
|
xt1 = vec4::load_xmm(x->row1);
|
|
xt2 = vec4::load_xmm(x->row2);
|
|
xt3 = vec4::load_xmm(x->row3);
|
|
xt0x = _mm_shuffle_ps(xt0, xt0, 0x00);
|
|
xt0y = _mm_shuffle_ps(xt0, xt0, 0x55);
|
|
xt0z = _mm_shuffle_ps(xt0, xt0, 0xAA);
|
|
xt0w = _mm_shuffle_ps(xt0, xt0, 0xFF);
|
|
xt1x = _mm_shuffle_ps(xt1, xt1, 0x00);
|
|
xt1y = _mm_shuffle_ps(xt1, xt1, 0x55);
|
|
xt1z = _mm_shuffle_ps(xt1, xt1, 0xAA);
|
|
xt1w = _mm_shuffle_ps(xt1, xt1, 0xFF);
|
|
xt2x = _mm_shuffle_ps(xt2, xt2, 0x00);
|
|
xt2y = _mm_shuffle_ps(xt2, xt2, 0x55);
|
|
xt2z = _mm_shuffle_ps(xt2, xt2, 0xAA);
|
|
xt2w = _mm_shuffle_ps(xt2, xt2, 0xFF);
|
|
xt3x = _mm_shuffle_ps(xt3, xt3, 0x00);
|
|
xt3y = _mm_shuffle_ps(xt3, xt3, 0x55);
|
|
xt3z = _mm_shuffle_ps(xt3, xt3, 0xAA);
|
|
xt3w = _mm_shuffle_ps(xt3, xt3, 0xFF);
|
|
yt00 = _mm_movelh_ps(_mm_unpacklo_ps(xt1y, xt0y), xt0y);
|
|
yt01 = _mm_movelh_ps(xt2y, xt1y);
|
|
yt02 = _mm_movelh_ps(xt3y, _mm_unpacklo_ps(xt3y, xt2y));
|
|
yt03 = _mm_movelh_ps(xt2z, xt1z);
|
|
yt04 = _mm_movelh_ps(xt3w, _mm_unpacklo_ps(xt3w, xt2w));
|
|
yt05 = _mm_movelh_ps(xt2w, xt1w);
|
|
yt06 = _mm_movelh_ps(_mm_unpacklo_ps(xt3z, xt3z), _mm_unpacklo_ps(xt3z, xt2z));
|
|
yt07 = _mm_movelh_ps(_mm_unpacklo_ps(xt1z, xt0z), xt0z);
|
|
yt08 = _mm_movelh_ps(_mm_unpacklo_ps(xt1w, xt0w), xt0w);
|
|
yt09 = _mm_movelh_ps(_mm_unpacklo_ps(xt1x, xt0x), xt0x);
|
|
yt10 = _mm_movelh_ps(xt2x, xt1x);
|
|
yt11 = _mm_movelh_ps(xt3x, _mm_unpacklo_ps(xt3x, xt2x));
|
|
|
|
t0 = _mm_sub_ps(_mm_mul_ps(yt03, yt04), _mm_mul_ps(yt05, yt06));
|
|
t1 = _mm_sub_ps(_mm_mul_ps(yt07, yt04), _mm_mul_ps(yt08, yt06));
|
|
t2 = _mm_sub_ps(_mm_mul_ps(yt07, yt05), _mm_mul_ps(yt08, yt03));
|
|
|
|
t3 = _mm_xor_ps(yt09, xor0);
|
|
t4 = _mm_xor_ps(yt10, xor1);
|
|
t5 = _mm_xor_ps(yt11, xor0);
|
|
|
|
wt0 = _mm_mul_ps(_mm_xor_ps(yt00, xor1), t0);
|
|
wt1 = _mm_mul_ps(_mm_xor_ps(yt01, xor0), t1);
|
|
wt2 = _mm_mul_ps(_mm_xor_ps(yt02, xor1), t2);
|
|
zt0 = _mm_add_ps(_mm_add_ps(wt0, wt1), wt2);
|
|
|
|
wt0 = _mm_mul_ps(t3, t0);
|
|
wt1 = _mm_mul_ps(t4, t1);
|
|
wt2 = _mm_mul_ps(t5, t2);
|
|
zt1 = _mm_add_ps(_mm_add_ps(wt0, wt1), wt2);
|
|
|
|
wt0 = _mm_mul_ps(_mm_xor_ps(yt09, xor1), _mm_sub_ps(_mm_mul_ps(yt01, yt04), _mm_mul_ps(yt05, yt02)));
|
|
wt1 = _mm_mul_ps(_mm_xor_ps(yt10, xor0), _mm_sub_ps(_mm_mul_ps(yt00, yt04), _mm_mul_ps(yt08, yt02)));
|
|
wt2 = _mm_mul_ps(_mm_xor_ps(yt11, xor1), _mm_sub_ps(_mm_mul_ps(yt00, yt05), _mm_mul_ps(yt08, yt01)));
|
|
zt2 = _mm_add_ps(_mm_add_ps(wt0, wt1), wt2);
|
|
|
|
wt0 = _mm_mul_ps(t3, _mm_sub_ps(_mm_mul_ps(yt01, yt06), _mm_mul_ps(yt03, yt02)));
|
|
wt1 = _mm_mul_ps(t4, _mm_sub_ps(_mm_mul_ps(yt00, yt06), _mm_mul_ps(yt07, yt02)));
|
|
wt2 = _mm_mul_ps(t5, _mm_sub_ps(_mm_mul_ps(yt00, yt03), _mm_mul_ps(yt07, yt01)));
|
|
zt3 = _mm_add_ps(_mm_add_ps(wt0, wt1), wt2);
|
|
|
|
wt = _mm_movelh_ps(_mm_unpacklo_ps(zt0, zt1), _mm_unpacklo_ps(zt2, zt3));
|
|
wt = _mm_mul_ps(xt0, wt);
|
|
wt = _mm_hadd_ps(wt, wt);
|
|
wt = _mm_hadd_ps(wt, wt);
|
|
if (_mm_cvtss_f32(wt) != 0.0f)
|
|
wt = _mm_div_ss(_mm_set_ss(1.0f), wt);
|
|
wt = _mm_shuffle_ps(wt, wt, 0);
|
|
z->row0 = vec4::store_xmm(_mm_mul_ps(zt0, wt));
|
|
z->row1 = vec4::store_xmm(_mm_mul_ps(zt1, wt));
|
|
z->row2 = vec4::store_xmm(_mm_mul_ps(zt2, wt));
|
|
z->row3 = vec4::store_xmm(_mm_mul_ps(zt3, wt));
|
|
}
|
|
|
|
inline void mat4_invtrans(const mat4* x, mat4* z) {
|
|
mat4 t = *x;
|
|
mat4_inverse(&t, &t);
|
|
mat4_transpose(&t, &t);
|
|
*z = t;
|
|
}
|
|
|
|
inline void mat4_invrot(const mat4* x, mat4* z) {
|
|
mat3 yt;
|
|
mat3_from_mat4(x, &yt);
|
|
mat3_inverse(&yt, &yt);
|
|
mat4_from_mat3(&yt, z);
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_inverse_normalized(const mat4* x, mat4* z) {
|
|
mat3 yt;
|
|
mat3_from_mat4(x, &yt);
|
|
vec3 row3;
|
|
row3.x = vec3::dot(*(vec3*)&x->row0, *(vec3*)&x->row3);
|
|
row3.y = vec3::dot(*(vec3*)&x->row1, *(vec3*)&x->row3);
|
|
row3.z = vec3::dot(*(vec3*)&x->row2, *(vec3*)&x->row3);
|
|
mat3_transpose(&yt, &yt);
|
|
mat4_from_mat3(&yt, z);
|
|
*(vec3*)&z->row3 = -row3;
|
|
z->row0.w = 0.0f;
|
|
z->row1.w = 0.0f;
|
|
z->row2.w = 0.0f;
|
|
z->row3.w = 1.0f;
|
|
}
|
|
|
|
inline void mat4_invrot_normalized(const mat4* x, mat4* z) {
|
|
mat3 yt;
|
|
mat3_from_mat4(x, &yt);
|
|
mat3_transpose(&yt, &yt);
|
|
mat4_from_mat3(&yt, z);
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_normalize(const mat4* x, mat4* z) {
|
|
__m128 det;
|
|
det = _mm_set_ss(mat4_determinant(x));
|
|
if (_mm_cvtss_f32(det) != 0.0f)
|
|
det = _mm_div_ss(_mm_set_ss(1.0f), det);
|
|
det = _mm_shuffle_ps(det, det, 0);
|
|
z->row0 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row0), det));
|
|
z->row1 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row1), det));
|
|
z->row2 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row2), det));
|
|
z->row3 = vec4::store_xmm(_mm_mul_ps(vec4::load_xmm(x->row3), det));
|
|
}
|
|
|
|
inline void mat4_normalize_rotation(const mat4* x, mat4* z) {
|
|
*(vec3*)&z->row0 = vec3::normalize(*(vec3*)&x->row0);
|
|
*(vec3*)&z->row1 = vec3::normalize(*(vec3*)&x->row1);
|
|
*(vec3*)&z->row2 = vec3::normalize(*(vec3*)&x->row2);
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline float_t mat4_determinant(const mat4* x) {
|
|
vec4 xt0;
|
|
vec4 xt1;
|
|
vec4 xt2;
|
|
vec4 xt3;
|
|
xt0 = x->row0;
|
|
xt1 = x->row1;
|
|
xt2 = x->row2;
|
|
xt3 = x->row3;
|
|
float_t b00 = xt0.x * xt1.y - xt0.y * xt1.x;
|
|
float_t b01 = xt0.x * xt1.z - xt0.z * xt1.x;
|
|
float_t b02 = xt0.x * xt1.w - xt0.w * xt1.x;
|
|
float_t b03 = xt0.y * xt1.z - xt0.z * xt1.y;
|
|
float_t b04 = xt0.y * xt1.w - xt0.w * xt1.y;
|
|
float_t b05 = xt0.z * xt1.w - xt0.w * xt1.z;
|
|
float_t b06 = xt2.x * xt3.y - xt2.y * xt3.x;
|
|
float_t b07 = xt2.x * xt3.z - xt2.z * xt3.x;
|
|
float_t b08 = xt2.x * xt3.w - xt2.w * xt3.x;
|
|
float_t b09 = xt2.y * xt3.z - xt2.z * xt3.y;
|
|
float_t b10 = xt2.y * xt3.w - xt2.w * xt3.y;
|
|
float_t b11 = xt2.z * xt3.w - xt2.w * xt3.z;
|
|
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
}
|
|
|
|
inline void mat4_rotate_xyz(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (x != 0.0f)
|
|
mat4_rotate_x(x, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (x != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat4_rotate_y(y, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (y != 0.0f || x != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat4_rotate_z(z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_xzy(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (x != 0.0f)
|
|
mat4_rotate_x(x, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (x != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat4_rotate_z(z, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (z != 0.0f || x != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat4_rotate_y(y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_yxz(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (y != 0.0f)
|
|
mat4_rotate_y(y, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (y != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat4_rotate_x(x, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (x != 0.0f || y != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat4_rotate_z(z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_yzx(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (y != 0.0f)
|
|
mat4_rotate_y(y, &dt);
|
|
|
|
if (z != 0.0f)
|
|
if (y != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
else
|
|
mat4_rotate_z(z, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (z != 0.0f || y != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat4_rotate_x(x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_zxy(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (z != 0.0f)
|
|
mat4_rotate_z(z, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (z != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat4_rotate_x(x, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (x != 0.0f || z != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat4_rotate_y(y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_zyx(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (z != 0.0f)
|
|
mat4_rotate_z(z, &dt);
|
|
|
|
if (y != 0.0f)
|
|
if (z != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
else
|
|
mat4_rotate_y(y, &dt);
|
|
|
|
if (x != 0.0f)
|
|
if (y != 0.0f || z != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
else
|
|
mat4_rotate_x(x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_x(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat4_identity;
|
|
yt.row1.y = x_cos;
|
|
yt.row1.z = x_sin;
|
|
yt.row2.y = -x_sin;
|
|
yt.row2.z = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_y(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat4_identity;
|
|
yt.row0.x = x_cos;
|
|
yt.row0.z = -x_sin;
|
|
yt.row2.x = x_sin;
|
|
yt.row2.z = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_z(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
float_t x_sin = sinf(x);
|
|
float_t x_cos = cosf(x);
|
|
yt = mat4_identity;
|
|
yt.row0.x = x_cos;
|
|
yt.row0.y = x_sin;
|
|
yt.row1.x = -x_sin;
|
|
yt.row1.y = x_cos;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_xyz_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_xzy_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_yxz_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_yzx_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_zxy_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_zyx_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = *s;
|
|
if (z != 0.0f)
|
|
mat4_rotate_z_mult(&dt, z, &dt);
|
|
if (y != 0.0f)
|
|
mat4_rotate_y_mult(&dt, y, &dt);
|
|
if (x != 0.0f)
|
|
mat4_rotate_x_mult(&dt, x, &dt);
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_rotate_x_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
z->row0 = vec4::store_xmm(y0);
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_cos));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_sin));
|
|
z->row1 = vec4::store_xmm(_mm_add_ps(t1, t2));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(-y_sin));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_cos));
|
|
z->row2 = vec4::store_xmm(_mm_add_ps(t1, t2));
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_rotate_y_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 t0;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_cos));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(-y_sin));
|
|
z->row0 = vec4::store_xmm(_mm_add_ps(t0, t2));
|
|
z->row1 = vec4::store_xmm(y1);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_sin));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(y_cos));
|
|
z->row2 = vec4::store_xmm(_mm_add_ps(t0, t2));
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_rotate_z_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
float_t y_sin = sinf(y);
|
|
float_t y_cos = cosf(y);
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(y_cos));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_sin));
|
|
z->row0 = vec4::store_xmm(_mm_add_ps(t0, t1));
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(-y_sin));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(y_cos));
|
|
z->row1 = vec4::store_xmm(_mm_add_ps(t0, t1));
|
|
z->row2 = vec4::store_xmm(y2);
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_rotate_x_sin_cos(float_t sin_val, float_t cos_val, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row1.y = cos_val;
|
|
yt.row1.z = sin_val;
|
|
yt.row2.y = -sin_val;
|
|
yt.row2.z = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_y_sin_cos(float_t sin_val, float_t cos_val, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row0.x = cos_val;
|
|
yt.row0.z = -sin_val;
|
|
yt.row2.x = sin_val;
|
|
yt.row2.z = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_z_sin_cos(float_t sin_val, float_t cos_val, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row0.x = cos_val;
|
|
yt.row0.y = sin_val;
|
|
yt.row1.x = -sin_val;
|
|
yt.row1.y = cos_val;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_rotate_x_mult_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) {
|
|
__m128 t1;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
z->row0 = vec4::store_xmm(y0);
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(cos_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(sin_val));
|
|
z->row1 = vec4::store_xmm(_mm_add_ps(t1, t2));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(-sin_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(cos_val));
|
|
z->row2 = vec4::store_xmm(_mm_add_ps(t1, t2));
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_rotate_y_mult_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) {
|
|
__m128 t0;
|
|
__m128 t2;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(cos_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(-sin_val));
|
|
z->row0 = vec4::store_xmm(_mm_add_ps(t0, t2));
|
|
z->row1 = vec4::store_xmm(y1);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(sin_val));
|
|
t2 = _mm_mul_ps(y2, vec4::load_xmm(cos_val));
|
|
z->row2 = vec4::store_xmm(_mm_add_ps(t0, t2));
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_rotate_z_mult_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) {
|
|
__m128 t0;
|
|
__m128 t1;
|
|
__m128 y0;
|
|
__m128 y1;
|
|
__m128 y2;
|
|
__m128 y3;
|
|
y0 = vec4::load_xmm(x->row0);
|
|
y1 = vec4::load_xmm(x->row1);
|
|
y2 = vec4::load_xmm(x->row2);
|
|
y3 = vec4::load_xmm(x->row3);
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(cos_val));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(sin_val));
|
|
z->row0 = vec4::store_xmm(_mm_add_ps(t0, t1));
|
|
t0 = _mm_mul_ps(y0, vec4::load_xmm(-sin_val));
|
|
t1 = _mm_mul_ps(y1, vec4::load_xmm(cos_val));
|
|
z->row1 = vec4::store_xmm(_mm_add_ps(t0, t1));
|
|
z->row2 = vec4::store_xmm(y2);
|
|
z->row3 = vec4::store_xmm(y3);
|
|
}
|
|
|
|
inline void mat4_scale(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
if (x != 1.0f)
|
|
dt.row0.x = x;
|
|
if (y != 1.0f)
|
|
dt.row1.y = y;
|
|
if (z != 1.0f)
|
|
dt.row2.z = z;
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_scale_x(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row0.x = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_scale_y(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row1.y = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_scale_z(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row2.z = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_scale_mult(const mat4* s, float_t x, float_t y, float_t z, float_t w, mat4* d) {
|
|
mat4 dt;
|
|
if (x != 1.0f || y != 1.0f || z != 1.0f || w != 1.0f) {
|
|
dt = mat4_identity;
|
|
dt.row0.x = x;
|
|
dt.row1.y = y;
|
|
dt.row2.z = z;
|
|
dt.row3.w = w;
|
|
mat4_mult(s, &dt, d);
|
|
}
|
|
else if (s != d)
|
|
*d = *s;
|
|
}
|
|
|
|
inline void mat4_scale_x_mult(const mat4* x, float_t y, mat4* z) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row0.x = y;
|
|
mat4_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat4_scale_y_mult(const mat4* x, float_t y, mat4* z) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row1.y = y;
|
|
mat4_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat4_scale_z_mult(const mat4* x, float_t y, mat4* z) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row2.z = y;
|
|
mat4_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat4_scale_w_mult(const mat4* x, float_t y, mat4* z) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row3.w = y;
|
|
mat4_mult(x, &yt, z);
|
|
}
|
|
|
|
inline void mat4_scale_rot(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
mat3 st;
|
|
mat3 dt;
|
|
if (x != 1.0f || y != 1.0f || z != 1.0f) {
|
|
st.row0 = *(vec3*)&s->row0;
|
|
st.row1 = *(vec3*)&s->row1;
|
|
st.row2 = *(vec3*)&s->row2;
|
|
dt = mat3_identity;
|
|
dt.row0.x = x;
|
|
dt.row1.y = y;
|
|
dt.row2.z = z;
|
|
mat3_mult(&st, &dt, &dt);
|
|
*(vec3*)&d->row0 = dt.row0;
|
|
*(vec3*)&d->row1 = dt.row1;
|
|
*(vec3*)&d->row2 = dt.row2;
|
|
d->row0.w = s->row0.w;
|
|
d->row1.w = s->row1.w;
|
|
d->row2.w = s->row2.w;
|
|
d->row3 = s->row3;
|
|
}
|
|
else
|
|
*d = *s;
|
|
}
|
|
|
|
inline void mat4_scale_x_rot(const mat4* x, float_t y, mat4* z) {
|
|
mat3 xt;
|
|
mat3 yt;
|
|
mat3 zt;
|
|
xt.row0 = *(vec3*)&x->row0;
|
|
xt.row1 = *(vec3*)&x->row1;
|
|
xt.row2 = *(vec3*)&x->row2;
|
|
yt = mat3_identity;
|
|
yt.row0.x = y;
|
|
mat3_mult(&xt, &yt, &zt);
|
|
*(vec3*)&z->row0 = zt.row0;
|
|
*(vec3*)&z->row1 = zt.row1;
|
|
*(vec3*)&z->row2 = zt.row2;
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_scale_y_rot(const mat4* x, float_t y, mat4* z) {
|
|
mat3 xt;
|
|
mat3 yt;
|
|
mat3 zt;
|
|
xt.row0 = *(vec3*)&x->row0;
|
|
xt.row1 = *(vec3*)&x->row1;
|
|
xt.row2 = *(vec3*)&x->row2;
|
|
yt = mat3_identity;
|
|
yt.row1.y = y;
|
|
mat3_mult(&xt, &yt, &zt);
|
|
*(vec3*)&z->row0 = zt.row0;
|
|
*(vec3*)&z->row1 = zt.row1;
|
|
*(vec3*)&z->row2 = zt.row2;
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_scale_z_rot(const mat4* x, float_t y, mat4* z) {
|
|
mat3 xt;
|
|
mat3 yt;
|
|
mat3 zt;
|
|
xt.row0 = *(vec3*)&x->row0;
|
|
xt.row1 = *(vec3*)&x->row1;
|
|
xt.row2 = *(vec3*)&x->row2;
|
|
yt = mat3_identity;
|
|
yt.row2.z = y;
|
|
mat3_mult(&xt, &yt, &zt);
|
|
*(vec3*)&z->row0 = zt.row0;
|
|
*(vec3*)&z->row1 = zt.row1;
|
|
*(vec3*)&z->row2 = zt.row2;
|
|
z->row0.w = x->row0.w;
|
|
z->row1.w = x->row1.w;
|
|
z->row2.w = x->row2.w;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_translate(float_t x, float_t y, float_t z, mat4* d) {
|
|
mat4 dt;
|
|
dt = mat4_identity;
|
|
dt.row3.x = x;
|
|
dt.row3.y = y;
|
|
dt.row3.z = z;
|
|
*d = dt;
|
|
}
|
|
|
|
inline void mat4_translate_x(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row3.x = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_translate_y(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row3.y = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_translate_z(float_t x, mat4* y) {
|
|
mat4 yt;
|
|
yt = mat4_identity;
|
|
yt.row3.z = x;
|
|
*y = yt;
|
|
}
|
|
|
|
inline void mat4_translate_mult(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
__m128 yt;
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
__m128 yt2;
|
|
__m128 yt3;
|
|
if (s != d)
|
|
*d = *s;
|
|
if (x != 0.0f || y != 0.0f || z != 0.0f) {
|
|
yt0 = _mm_mul_ps(vec4::load_xmm(s->row0), vec4::load_xmm(x));
|
|
yt1 = _mm_mul_ps(vec4::load_xmm(s->row1), vec4::load_xmm(y));
|
|
yt2 = _mm_mul_ps(vec4::load_xmm(s->row2), vec4::load_xmm(z));
|
|
yt3 = vec4::load_xmm(s->row3);
|
|
yt = _mm_add_ps(_mm_add_ps(yt0, yt1), _mm_add_ps(yt2, yt3));
|
|
*(vec3*)&d->row3 = vec3::store_xmm(yt);
|
|
}
|
|
}
|
|
|
|
inline void mat4_translate_x_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f) {
|
|
yt0 = vec4::load_xmm(x->row0);
|
|
yt1 = vec4::load_xmm(x->row3);
|
|
yt0 = _mm_add_ps(_mm_mul_ps(yt0, vec4::load_xmm(y)), yt1);
|
|
*(vec3*)&z->row3 = vec3::store_xmm(yt0);
|
|
}
|
|
}
|
|
|
|
inline void mat4_translate_y_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f) {
|
|
yt0 = vec4::load_xmm(x->row1);
|
|
yt1 = vec4::load_xmm(x->row3);
|
|
yt0 = _mm_add_ps(_mm_mul_ps(yt0, vec4::load_xmm(y)), yt1);
|
|
*(vec3*)&z->row3 = vec3::store_xmm(yt0);
|
|
}
|
|
}
|
|
|
|
inline void mat4_translate_z_mult(const mat4* x, float_t y, mat4* z) {
|
|
__m128 yt0;
|
|
__m128 yt1;
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f) {
|
|
yt0 = vec4::load_xmm(x->row2);
|
|
yt1 = vec4::load_xmm(x->row3);
|
|
yt0 = _mm_add_ps(_mm_mul_ps(yt0, vec4::load_xmm(y)), yt1);
|
|
*(vec3*)&z->row3 = vec3::store_xmm(yt0);
|
|
}
|
|
}
|
|
|
|
inline void mat4_translate_add(const mat4* s, float_t x, float_t y, float_t z, mat4* d) {
|
|
if (s != d)
|
|
*d = *s;
|
|
if (x != 0.0f || y != 0.0f || z != 0.0f)
|
|
d->row3 = vec4::store_xmm(_mm_add_ps(vec4::load_xmm(s->row3), vec4::load_xmm(vec4(x, y, z, 0.0f))));
|
|
}
|
|
|
|
inline void mat4_translate_x_add(const mat4* x, float_t y, mat4* z) {
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f)
|
|
z->row3.x += y;
|
|
}
|
|
|
|
inline void mat4_translate_y_add(const mat4* x, float_t y, mat4* z) {
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f)
|
|
z->row3.y += y;
|
|
}
|
|
|
|
inline void mat4_translate_z_add(const mat4* x, float_t y, mat4* z) {
|
|
if (x != z)
|
|
*z = *x;
|
|
if (y != 0.0f)
|
|
z->row3.z += y;
|
|
}
|
|
|
|
inline void mat4_from_quat(const quat* quat, mat4* mat) {
|
|
float_t y;
|
|
float_t x;
|
|
float_t z;
|
|
float_t w;
|
|
float_t len;
|
|
float_t xy;
|
|
float_t yy;
|
|
float_t xx;
|
|
float_t wx;
|
|
float_t wy;
|
|
float_t zz;
|
|
float_t xz;
|
|
float_t wz;
|
|
float_t yz;
|
|
|
|
x = quat->x;
|
|
y = quat->y;
|
|
z = quat->z;
|
|
w = quat->w;
|
|
len = quat::length_squared(*quat);
|
|
len = len > 0.0f ? 2.0f / len : 0.0f;
|
|
xx = x * x * len;
|
|
xy = x * y * len;
|
|
xz = x * z * len;
|
|
yy = y * y * len;
|
|
zz = z * z * len;
|
|
yz = y * z * len;
|
|
wx = w * x * len;
|
|
wy = w * y * len;
|
|
wz = w * z * len;
|
|
mat->row0.x = 1.0f - zz - yy;
|
|
mat->row0.y = xy + wz;
|
|
mat->row0.z = xz - wy;
|
|
mat->row0.w = 0.0f;
|
|
mat->row1.x = xy - wz;
|
|
mat->row1.y = 1.0f - zz - xx;
|
|
mat->row1.z = yz + wx;
|
|
mat->row1.w = 0.0f;
|
|
mat->row2.x = xz + wy;
|
|
mat->row2.y = yz - wx;
|
|
mat->row2.z = 1.0f - yy - xx;
|
|
mat->row2.w = 0.0f;
|
|
mat->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
float_t vec3_angle_between_two_vectors(const vec3* x, const vec3* y) {
|
|
vec3 z_t = vec3::cross(*x, *y);
|
|
float_t v2 = vec3::length(z_t);
|
|
float_t v3 = vec3::dot(*x, *y);
|
|
return fabsf(atan2f(v2, v3));
|
|
}
|
|
|
|
void mat4_from_two_vectors(const vec3* x, const vec3* y, mat4* mat) {
|
|
*mat = mat4_identity;
|
|
if (x->x == y->x && y->y == x->y && y->z == x->z)
|
|
return;
|
|
|
|
if (fabsf(1.0f - vec3::dot(*x, *y)) <= 0.000001f)
|
|
return;
|
|
|
|
vec3 axis = vec3::cross(*x, *y);
|
|
float_t axis_length = vec3::length(axis);
|
|
if (axis_length > 0.000001f) {
|
|
float_t angle = vec3_angle_between_two_vectors(x, y);
|
|
if (axis_length != 0.0)
|
|
axis *= 1.0f / axis_length;
|
|
mat4_from_axis_angle(&axis, angle, mat);
|
|
}
|
|
}
|
|
|
|
inline void mat4_from_axis_angle(const vec3* axis, float_t angle, mat4* mat) {
|
|
float_t angle_sin;
|
|
float_t angle_cos;
|
|
float_t angle_cos_1;
|
|
vec3 _axis;
|
|
vec3 _axis_sin;
|
|
vec3 temp;
|
|
|
|
angle_sin = sinf(angle);
|
|
angle_cos = cosf(angle);
|
|
angle_cos_1 = 1.0f - angle_cos;
|
|
|
|
_axis = vec3::normalize(*axis);
|
|
|
|
_axis_sin = _axis * angle_sin;
|
|
temp = _axis * (_axis.x * angle_cos_1);
|
|
mat->row0.x = temp.x + angle_cos;
|
|
mat->row1.x = temp.y - _axis_sin.z;
|
|
mat->row2.x = temp.z + _axis_sin.y;
|
|
temp = _axis * (_axis.y * angle_cos_1);
|
|
mat->row0.y = temp.x + _axis_sin.z;
|
|
mat->row1.y = temp.y + angle_cos;
|
|
mat->row2.y = temp.z - _axis_sin.x;
|
|
temp = _axis * (_axis.z * angle_cos_1);
|
|
mat->row0.z = temp.x - _axis_sin.y;
|
|
mat->row1.z = temp.y + _axis_sin.x;
|
|
mat->row2.z = temp.z + angle_cos;
|
|
mat->row0.w = 0.0f;
|
|
mat->row1.w = 0.0f;
|
|
mat->row2.w = 0.0f;
|
|
mat->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
inline void mat4_from_axis_angle_sin_cos(const vec3* axis, float_t sin_val, float_t cos_val, mat4* mat) {
|
|
float_t cos_val_1;
|
|
vec3 _axis;
|
|
vec3 _axis_sin;
|
|
vec3 temp;
|
|
|
|
cos_val_1 = 1.0f - cos_val;
|
|
|
|
_axis = vec3::normalize(*axis);
|
|
|
|
_axis_sin = _axis * sin_val;
|
|
temp = _axis * (_axis.x * cos_val_1);
|
|
mat->row0.x = temp.x + cos_val;
|
|
mat->row1.x = temp.y - _axis_sin.z;
|
|
mat->row2.x = temp.z + _axis_sin.y;
|
|
temp = _axis * (_axis.y * cos_val_1);
|
|
mat->row0.y = temp.x + _axis_sin.z;
|
|
mat->row1.y = temp.y + cos_val;
|
|
mat->row2.y = temp.z - _axis_sin.x;
|
|
temp = _axis * (_axis.z * cos_val_1);
|
|
mat->row0.z = temp.x - _axis_sin.y;
|
|
mat->row1.z = temp.y + _axis_sin.x;
|
|
mat->row2.z = temp.z + cos_val;
|
|
mat->row0.w = 0.0f;
|
|
mat->row1.w = 0.0f;
|
|
mat->row2.w = 0.0f;
|
|
mat->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
inline void mat4_from_mat3(const mat3* x, mat4* z) {
|
|
*(vec3*)&z->row0 = x->row0;
|
|
z->row0.w = 0.0f;
|
|
*(vec3*)&z->row1 = x->row1;
|
|
z->row1.w = 0.0f;
|
|
*(vec3*)&z->row2 = x->row2;
|
|
z->row2.w = 0.0f;
|
|
z->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
inline void mat4_from_mat3_inverse(const mat3* x, mat4* z) {
|
|
mat3 yt;
|
|
|
|
mat3_inverse(x, &yt);
|
|
*(vec3*)&z->row0 = yt.row0;
|
|
z->row0.w = 0.0f;
|
|
*(vec3*)&z->row1 = yt.row1;
|
|
z->row1.w = 0.0f;
|
|
*(vec3*)&z->row2 = yt.row2;
|
|
z->row2.w = 0.0f;
|
|
z->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
inline void mat4_clear_rot(mat4* x, mat4* z) {
|
|
z->row0 = mat4_identity.row0;
|
|
z->row1 = mat4_identity.row1;
|
|
z->row2 = mat4_identity.row2;
|
|
z->row3 = x->row3;
|
|
}
|
|
|
|
inline void mat4_clear_trans(mat4* x, mat4* z) {
|
|
if (x != z) {
|
|
z->row0 = x->row0;
|
|
z->row1 = x->row1;
|
|
z->row2 = x->row2;
|
|
}
|
|
z->row3 = { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
}
|
|
|
|
inline void mat4_get_rotation(const mat4* x, vec3* z) {
|
|
if (-x->row0.z >= 1.0f)
|
|
z->y = (float_t)M_PI_2;
|
|
else if (-x->row0.z <= -1.0f)
|
|
z->y = (float_t)-M_PI_2;
|
|
else
|
|
z->y = asinf(-x->row0.z);
|
|
|
|
if (fabs(x->row0.z) < 0.99999899f) {
|
|
z->x = atan2f(x->row1.z, x->row2.z);
|
|
z->z = atan2f(x->row0.y, x->row0.x);
|
|
}
|
|
else {
|
|
z->x = 0.0f;
|
|
z->z = atan2f(x->row2.y, x->row1.y);
|
|
if (x->row0.z > 0.0f)
|
|
z->z = -z->z;
|
|
}
|
|
}
|
|
|
|
inline void mat4_get_scale(const mat4* x, vec3* z) {
|
|
z->x = vec4::length(x->row0);
|
|
z->y = vec4::length(x->row1);
|
|
z->z = vec4::length(x->row2);
|
|
}
|
|
|
|
inline void mat4_get_translation(const mat4* x, vec3* z) {
|
|
*z = *(vec3*)&x->row3;
|
|
}
|
|
|
|
inline void mat4_set_translation(mat4* x, vec3* z) {
|
|
*(vec3*)&x->row3 = *z;
|
|
}
|
|
|
|
inline void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend) {
|
|
quat q0;
|
|
quat q1;
|
|
quat q2;
|
|
|
|
quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y,
|
|
x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q0);
|
|
quat_from_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y,
|
|
y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1);
|
|
|
|
vec3 t1;
|
|
vec3 t2;
|
|
vec3 t3;
|
|
mat4_get_translation(x, &t1);
|
|
mat4_get_translation(y, &t2);
|
|
|
|
q2 = quat::slerp(q0, q1, blend);
|
|
t3 = vec3::lerp(t1, t2, blend);
|
|
|
|
mat4_from_quat(&q2, z);
|
|
mat4_set_translation(z, &t3);
|
|
}
|
|
|
|
inline void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend) {
|
|
quat q0;
|
|
quat q1;
|
|
quat q2;
|
|
|
|
quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y,
|
|
x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1);
|
|
quat_from_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y,
|
|
y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1);
|
|
q2 = quat::slerp(q0, q1, blend);
|
|
mat4_from_quat(&q2, z);
|
|
}
|
|
|
|
void mat4_lerp_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend) {
|
|
vec3 m0;
|
|
vec3 m1;
|
|
m0 = vec3::lerp(*(vec3*)&x->row0, *(vec3*)&y->row0, blend);
|
|
m1 = vec3::lerp(*(vec3*)&x->row1, *(vec3*)&y->row1, blend);
|
|
|
|
float_t m0_len_sq = vec3::length_squared(m0);
|
|
float_t m1_len_sq = vec3::length_squared(m1);
|
|
|
|
if (m0_len_sq <= 0.000001f || m1_len_sq <= 0.000001f) {
|
|
*z = *y;
|
|
return;
|
|
}
|
|
|
|
vec3 m2;
|
|
m2 = vec3::cross(m0, m1);
|
|
m1 = vec3::cross(m2, m0);
|
|
|
|
float_t m2_len_sq;
|
|
m1_len_sq = vec3::length_squared(m1);
|
|
m2_len_sq = vec3::length_squared(m2);
|
|
if (m2_len_sq <= 0.000001f || m1_len_sq <= 0.000001) {
|
|
*z = *y;
|
|
return;
|
|
}
|
|
|
|
float_t m0_len = sqrtf(m0_len_sq);
|
|
if (m0_len != 0.0f)
|
|
m0 *= 1.0f / m0_len;
|
|
|
|
float_t m1_len = sqrtf(m1_len_sq);
|
|
if (m1_len != 0.0f)
|
|
m1 *= 1.0f / m1_len;
|
|
|
|
float_t m2_len = sqrtf(m2_len_sq);
|
|
if (m2_len != 0.0f)
|
|
m2 *= 1.0f / m2_len;
|
|
|
|
*z = mat4_identity;
|
|
*(vec3*)&z->row0 = m0;
|
|
*(vec3*)&z->row1 = m1;
|
|
*(vec3*)&z->row2 = m2;
|
|
}
|
|
|
|
inline float_t mat4_get_max_scale(const mat4* x) {
|
|
mat4 mat;
|
|
mat4_transpose(x, &mat);
|
|
|
|
float_t length;
|
|
float_t max = 0.0f;
|
|
length = vec3::length(*(vec3*)&mat.row0);
|
|
if (max < length)
|
|
max = length;
|
|
length = vec3::length(*(vec3*)&mat.row1);
|
|
if (max < length)
|
|
max = length;
|
|
length = vec3::length(*(vec3*)&mat.row2);
|
|
if (max < length)
|
|
max = length;
|
|
return max;
|
|
}
|
|
|
|
inline void mat4_mult_axis_angle(const mat4* x, const vec3* axis, const float_t angle, mat4* z) {
|
|
quat q1;
|
|
quat q2;
|
|
quat q3;
|
|
float_t t0;
|
|
float_t t1;
|
|
float_t t2;
|
|
vec4 t3;
|
|
|
|
t0 = x->row0.w;
|
|
t1 = x->row1.w;
|
|
t2 = x->row2.w;
|
|
t3 = x->row3;
|
|
quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y,
|
|
x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1);
|
|
quat_from_axis_angle(axis, angle, &q2);
|
|
quat_mult(&q2, &q1, &q3);
|
|
mat4_from_quat(&q3, z);
|
|
z->row0.w = t0;
|
|
z->row1.w = t1;
|
|
z->row2.w = t2;
|
|
z->row3 = t3;
|
|
}
|
|
|
|
inline void mat4_frustrum(double_t left, double_t right,
|
|
double_t bottom, double_t top, double_t z_near, double_t z_far, mat4* mat) {
|
|
*mat = mat4_null;
|
|
mat->row0.x = (float_t)((2.0 * z_near) / (right - left));
|
|
mat->row1.y = (float_t)((2.0 * z_near) / (top - bottom));
|
|
mat->row2.x = (float_t)((right + left) / (right - left));
|
|
mat->row2.y = (float_t)((top + bottom) / (top - bottom));
|
|
mat->row2.z = -(float_t)((z_far + z_near) / (z_far - z_near));
|
|
mat->row2.w = -1.0f;
|
|
mat->row3.z = -(float_t)((2.0 * z_far * z_near) / (z_far - z_near));
|
|
}
|
|
|
|
inline void mat4_ortho(double_t left, double_t right,
|
|
double_t bottom, double_t top, double_t z_near, double_t z_far, mat4* mat) {
|
|
*mat = mat4_identity;
|
|
mat->row0.x = (float_t)(2.0 / (right - left));
|
|
mat->row1.y = (float_t)(2.0 / (top - bottom));
|
|
mat->row2.z = (float_t)(-2.0 / (z_far - z_near));
|
|
mat->row3.x = -(float_t)((right + left) / (right - left));
|
|
mat->row3.y = -(float_t)((top + bottom) / (top - bottom));
|
|
mat->row3.z = -(float_t)((z_far + z_near) / (z_far - z_near));
|
|
}
|
|
|
|
inline void mat4_persp(double_t fov_y, double_t aspect, double_t z_near, double_t z_far, mat4* mat) {
|
|
double_t tan_fov = tan(fov_y * 0.5);
|
|
|
|
*mat = mat4_null;
|
|
mat->row0.x = (float_t)(1.0 / (aspect * tan_fov));
|
|
mat->row1.y = (float_t)(1.0 / tan_fov);
|
|
mat->row2.z = -(float_t)((z_far + z_near) / (z_far - z_near));
|
|
mat->row2.w = -1.0f;
|
|
mat->row3.z = -(float_t)((2.0 * z_far * z_near) / (z_far - z_near));
|
|
}
|
|
|
|
inline void mat4_look_at(const vec3* eye, const vec3* target, const vec3* up, mat4* mat) {
|
|
vec3 x_axis, y_axis, z_axis;
|
|
vec3 xyz;
|
|
|
|
z_axis = vec3::normalize(*eye - *target);
|
|
|
|
x_axis = vec3::normalize(vec3::cross(*up, z_axis));
|
|
if (vec3::length(x_axis) == 0.0f)
|
|
x_axis = { 1.0f, 0.0f, 0.0f };
|
|
|
|
y_axis = vec3::normalize(vec3::cross(z_axis, x_axis));
|
|
|
|
xyz.x = vec3::dot(x_axis, *eye);
|
|
xyz.y = vec3::dot(y_axis, *eye);
|
|
xyz.z = vec3::dot(z_axis, *eye);
|
|
|
|
mat->row0 = { x_axis.x, y_axis.x, z_axis.x, 0.0f };
|
|
mat->row1 = { x_axis.y, y_axis.y, z_axis.y, 0.0f };
|
|
mat->row2 = { x_axis.z, y_axis.z, z_axis.z, 0.0f };
|
|
*(vec3*)&mat->row3 = -xyz;
|
|
mat->row3.w = 1.0f;
|
|
}
|
|
|
|
inline void mat4_look_at(const vec3* eye, const vec3* target, mat4* mat) {
|
|
vec3 up = { 0.0f, 1.0f, 0.0f };
|
|
vec3 dir;
|
|
dir = *target - *eye;
|
|
if (vec3::length_squared(dir) <= 0.000001f) {
|
|
up.x = 0.0f;
|
|
up.y = 0.0f;
|
|
if (dir.z < 0.0f)
|
|
up.z = 1.0f;
|
|
else
|
|
up.z = -1.0f;
|
|
}
|
|
|
|
mat4_look_at(eye, target, &up, mat);
|
|
}
|