mirror of
https://github.com/recp/cglm.git
synced 2026-02-17 03:39:05 +00:00
re-organise files, remove cglm prefix from file to make them more clean
This commit is contained in:
100
include/cglm/affine-mat.h
Normal file
100
include/cglm/affine-mat.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_mul(mat4 m1, mat4 m2, mat4 dest);
|
||||
CGLM_INLINE void glm_inv_tr(mat4 mat);
|
||||
*/
|
||||
|
||||
#ifndef cglm_affine_mat_h
|
||||
#define cglm_affine_mat_h
|
||||
|
||||
#include "common.h"
|
||||
#include "mat4.h"
|
||||
|
||||
#ifdef CGLM_SSE_FP
|
||||
# include "simd/sse2/affine.h"
|
||||
#endif
|
||||
|
||||
#ifdef CGLM_AVX_FP
|
||||
# include "simd/avx/affine.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mul(mat4 m1, mat4 m2, mat4 dest) {
|
||||
#ifdef __AVX__
|
||||
glm_mul_avx(m1, m2, dest);
|
||||
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mul_sse2(m1, m2, dest);
|
||||
#else
|
||||
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
||||
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
||||
a20 = m1[2][0], a21 = m1[2][1], a22 = m1[2][2], a23 = m1[2][3],
|
||||
a30 = m1[3][0], a31 = m1[3][1], a32 = m1[3][2], a33 = m1[3][3],
|
||||
|
||||
b00 = m2[0][0], b01 = m2[0][1], b02 = m2[0][2],
|
||||
b10 = m2[1][0], b11 = m2[1][1], b12 = m2[1][2],
|
||||
b20 = m2[2][0], b21 = m2[2][1], b22 = m2[2][2],
|
||||
b30 = m2[3][0], b31 = m2[3][1], b32 = m2[3][2], b33 = m2[3][3];
|
||||
|
||||
dest[0][0] = a00 * b00 + a10 * b01 + a20 * b02;
|
||||
dest[0][1] = a01 * b00 + a11 * b01 + a21 * b02;
|
||||
dest[0][2] = a02 * b00 + a12 * b01 + a22 * b02;
|
||||
dest[0][3] = a03 * b00 + a13 * b01 + a23 * b02;
|
||||
|
||||
dest[1][0] = a00 * b10 + a10 * b11 + a20 * b12;
|
||||
dest[1][1] = a01 * b10 + a11 * b11 + a21 * b12;
|
||||
dest[1][2] = a02 * b10 + a12 * b11 + a22 * b12;
|
||||
dest[1][3] = a03 * b10 + a13 * b11 + a23 * b12;
|
||||
|
||||
dest[2][0] = a00 * b20 + a10 * b21 + a20 * b22;
|
||||
dest[2][1] = a01 * b20 + a11 * b21 + a21 * b22;
|
||||
dest[2][2] = a02 * b20 + a12 * b21 + a22 * b22;
|
||||
dest[2][3] = a03 * b20 + a13 * b21 + a23 * b22;
|
||||
|
||||
dest[3][0] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
|
||||
dest[3][1] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
|
||||
dest[3][2] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
|
||||
dest[3][3] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief inverse orthonormal rotation + translation matrix (ridig-body)
|
||||
*
|
||||
* @code
|
||||
* X = | R T | X' = | R' -R'T |
|
||||
* | 0 1 | | 0 1 |
|
||||
* @endcode
|
||||
*
|
||||
* @param[in,out] mat matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_inv_tr(mat4 mat) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_inv_tr_sse2(mat);
|
||||
#else
|
||||
CGLM_ALIGN(16) mat3 r;
|
||||
CGLM_ALIGN(16) vec3 t;
|
||||
|
||||
/* rotate */
|
||||
glm_mat4_pick3t(mat, r);
|
||||
glm_mat4_ins3(r, mat);
|
||||
|
||||
/* translate */
|
||||
glm_mat3_mulv(r, mat[3], t);
|
||||
glm_vec_flipsign(t);
|
||||
glm_vec_copy(t, mat[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* cglm_affine_mat_h */
|
||||
409
include/cglm/affine.h
Normal file
409
include/cglm/affine.h
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_translate_to(mat4 m, vec3 v, mat4 dest);
|
||||
CGLM_INLINE void glm_translate(mat4 m, vec3 v);
|
||||
CGLM_INLINE void glm_translate_x(mat4 m, float to);
|
||||
CGLM_INLINE void glm_translate_y(mat4 m, float to);
|
||||
CGLM_INLINE void glm_translate_z(mat4 m, float to);
|
||||
CGLM_INLINE void glm_translate_make(mat4 m, vec3 v);
|
||||
CGLM_INLINE void glm_scale_to(mat4 m, vec3 v, mat4 dest);
|
||||
CGLM_INLINE void glm_scale_make(mat4 m, vec3 v);
|
||||
CGLM_INLINE void glm_scale(mat4 m, vec3 v);
|
||||
CGLM_INLINE void glm_scale1(mat4 m, float s);
|
||||
CGLM_INLINE void glm_rotate_x(mat4 m, float rad, mat4 dest);
|
||||
CGLM_INLINE void glm_rotate_y(mat4 m, float rad, mat4 dest);
|
||||
CGLM_INLINE void glm_rotate_z(mat4 m, float rad, mat4 dest);
|
||||
CGLM_INLINE void glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc);
|
||||
CGLM_INLINE void glm_rotate_make(mat4 m, float angle, vec3 axis);
|
||||
CGLM_INLINE void glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc);
|
||||
CGLM_INLINE void glm_rotate(mat4 m, float angle, vec3 axis);
|
||||
CGLM_INLINE void glm_decompose_scalev(mat4 m, vec3 s);
|
||||
CGLM_INLINE bool glm_uniscaled(mat4 m);
|
||||
CGLM_INLINE void glm_decompose_rs(mat4 m, mat4 r, vec3 s);
|
||||
CGLM_INLINE void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s);
|
||||
*/
|
||||
|
||||
#ifndef cglm_affine_h
|
||||
#define cglm_affine_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec4.h"
|
||||
#include "affine-mat.h"
|
||||
#include "util.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate_to(mat4 m, vec3 v, mat4 dest) {
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest[3],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_load_ps(t[0]),
|
||||
_mm_set1_ps(v[0])),
|
||||
_mm_mul_ps(_mm_load_ps(t[1]),
|
||||
_mm_set1_ps(v[1]))),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_load_ps(t[2]),
|
||||
_mm_set1_ps(v[2])),
|
||||
_mm_load_ps(t[3]))))
|
||||
;
|
||||
|
||||
_mm_store_ps(dest[0], _mm_load_ps(m[0]));
|
||||
_mm_store_ps(dest[1], _mm_load_ps(m[1]));
|
||||
_mm_store_ps(dest[2], _mm_load_ps(m[2]));
|
||||
#else
|
||||
vec4 v1, v2, v3;
|
||||
|
||||
glm_vec4_scale(t[0], v[0], v1);
|
||||
glm_vec4_scale(t[1], v[1], v2);
|
||||
glm_vec4_scale(t[2], v[2], v3);
|
||||
|
||||
glm_vec4_add(v1, t[3], t[3]);
|
||||
glm_vec4_add(v2, t[3], t[3]);
|
||||
glm_vec4_add(v3, t[3], t[3]);
|
||||
|
||||
glm__memcpy(float, dest, t, sizeof(mat4));
|
||||
#endif
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate(mat4 m, vec3 v) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(m[3],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[0]),
|
||||
_mm_set1_ps(v[0])),
|
||||
_mm_mul_ps(_mm_load_ps(m[1]),
|
||||
_mm_set1_ps(v[1]))),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[2]),
|
||||
_mm_set1_ps(v[2])),
|
||||
_mm_load_ps(m[3]))))
|
||||
;
|
||||
#else
|
||||
vec4 v1, v2, v3;
|
||||
|
||||
glm_vec4_scale(m[0], v[0], v1);
|
||||
glm_vec4_scale(m[1], v[1], v2);
|
||||
glm_vec4_scale(m[2], v[2], v3);
|
||||
|
||||
glm_vec4_add(v1, m[3], m[3]);
|
||||
glm_vec4_add(v2, m[3], m[3]);
|
||||
glm_vec4_add(v3, m[3], m[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate_x(mat4 m, float to) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(m[3],
|
||||
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[0]),
|
||||
_mm_set1_ps(to)),
|
||||
_mm_load_ps(m[3])))
|
||||
;
|
||||
#else
|
||||
vec4 v1;
|
||||
glm_vec4_scale(m[0], to, v1);
|
||||
glm_vec4_add(v1, m[3], m[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate_y(mat4 m, float to) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(m[3],
|
||||
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[1]),
|
||||
_mm_set1_ps(to)),
|
||||
_mm_load_ps(m[3])))
|
||||
;
|
||||
#else
|
||||
vec4 v1;
|
||||
glm_vec4_scale(m[1], to, v1);
|
||||
glm_vec4_add(v1, m[3], m[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate_z(mat4 m, float to) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(m[3],
|
||||
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[2]),
|
||||
_mm_set1_ps(to)),
|
||||
_mm_load_ps(m[3])))
|
||||
;
|
||||
#else
|
||||
vec4 v1;
|
||||
glm_vec4_scale(m[2], to, v1);
|
||||
glm_vec4_add(v1, m[3], m[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_translate_make(mat4 m, vec3 v) {
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_translate_to(t, v, m);
|
||||
}
|
||||
|
||||
/* scale */
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_scale_to(mat4 m, vec3 v, mat4 dest) {
|
||||
glm_vec4_scale(m[0], v[0], dest[0]);
|
||||
glm_vec4_scale(m[1], v[1], dest[1]);
|
||||
glm_vec4_scale(m[2], v[2], dest[2]);
|
||||
|
||||
glm_vec4_copy(m[3], dest[3]);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_scale_make(mat4 m, vec3 v) {
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_scale_to(t, v, m);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_scale(mat4 m, vec3 v) {
|
||||
glm_scale_to(m, v, m);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_scale1(mat4 m, float s) {
|
||||
vec3 v = { s, s, s };
|
||||
glm_scale_to(m, v, m);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_x(mat4 m, float rad, mat4 dest) {
|
||||
float cosVal;
|
||||
float sinVal;
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
|
||||
cosVal = cosf(rad);
|
||||
sinVal = sinf(rad);
|
||||
|
||||
t[1][1] = cosVal;
|
||||
t[1][2] = sinVal;
|
||||
t[2][1] = -sinVal;
|
||||
t[2][2] = cosVal;
|
||||
|
||||
glm_mat4_mul(m, t, dest);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_y(mat4 m, float rad, mat4 dest) {
|
||||
float cosVal;
|
||||
float sinVal;
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
|
||||
cosVal = cosf(rad);
|
||||
sinVal = sinf(rad);
|
||||
|
||||
t[0][0] = cosVal;
|
||||
t[0][2] = -sinVal;
|
||||
t[2][0] = sinVal;
|
||||
t[2][2] = cosVal;
|
||||
|
||||
glm_mat4_mul(m, t, dest);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_z(mat4 m, float rad, mat4 dest) {
|
||||
float cosVal;
|
||||
float sinVal;
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
|
||||
cosVal = cosf(rad);
|
||||
sinVal = sinf(rad);
|
||||
|
||||
t[0][0] = cosVal;
|
||||
t[0][1] = sinVal;
|
||||
t[1][0] = -sinVal;
|
||||
t[1][1] = cosVal;
|
||||
|
||||
glm_mat4_mul(m, t, dest);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
|
||||
/* https://www.opengl.org/sdk/docs/man2/xhtml/glRotate.xml */
|
||||
|
||||
vec3 v, vs;
|
||||
float c;
|
||||
|
||||
c = cosf(angle);
|
||||
|
||||
glm_vec_scale(axis_ndc, 1.0f - c, v);
|
||||
glm_vec_scale(axis_ndc, sinf(angle), vs);
|
||||
|
||||
glm_vec_scale(axis_ndc, v[0], m[0]);
|
||||
glm_vec_scale(axis_ndc, v[1], m[1]);
|
||||
glm_vec_scale(axis_ndc, v[2], m[2]);
|
||||
|
||||
m[0][0] += c;
|
||||
m[0][1] += vs[2];
|
||||
m[0][2] -= vs[1];
|
||||
|
||||
m[1][0] -= vs[2];
|
||||
m[1][1] += c;
|
||||
m[1][2] += vs[0];
|
||||
|
||||
m[2][0] += vs[1];
|
||||
m[2][1] -= vs[0];
|
||||
m[2][2] += c;
|
||||
|
||||
m[0][3] = m[1][3] = m[2][3] = m[3][0] = m[3][1] = m[3][2] = 0.0f;
|
||||
m[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_make(mat4 m, float angle, vec3 axis) {
|
||||
vec3 axis_ndc;
|
||||
|
||||
glm_vec_normalize_to(axis, axis_ndc);
|
||||
glm_rotate_ndc_make(m, angle, axis_ndc);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
|
||||
mat4 rot, tmp;
|
||||
|
||||
glm_rotate_ndc_make(rot, angle, axis_ndc);
|
||||
|
||||
glm_vec4_scale(m[0], rot[0][0], tmp[1]);
|
||||
glm_vec4_scale(m[1], rot[0][1], tmp[0]);
|
||||
glm_vec4_add(tmp[1], tmp[0], tmp[1]);
|
||||
glm_vec4_scale(m[2], rot[0][2], tmp[0]);
|
||||
glm_vec4_add(tmp[1], tmp[0], tmp[1]);
|
||||
|
||||
glm_vec4_scale(m[0], rot[1][0], tmp[2]);
|
||||
glm_vec4_scale(m[1], rot[1][1], tmp[0]);
|
||||
glm_vec4_add(tmp[2], tmp[0], tmp[2]);
|
||||
glm_vec4_scale(m[2], rot[1][2], tmp[0]);
|
||||
glm_vec4_add(tmp[2], tmp[0], tmp[2]);
|
||||
|
||||
glm_vec4_scale(m[0], rot[2][0], tmp[3]);
|
||||
glm_vec4_scale(m[1], rot[2][1], tmp[0]);
|
||||
glm_vec4_add(tmp[3], tmp[0], tmp[3]);
|
||||
glm_vec4_scale(m[2], rot[2][2], tmp[0]);
|
||||
glm_vec4_add(tmp[3], tmp[0], tmp[3]);
|
||||
|
||||
glm_vec4_copy(tmp[1], m[0]);
|
||||
glm_vec4_copy(tmp[2], m[1]);
|
||||
glm_vec4_copy(tmp[3], m[2]);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_rotate(mat4 m, float angle, vec3 axis) {
|
||||
vec3 axis_ndc;
|
||||
|
||||
glm_vec_normalize_to(axis, axis_ndc);
|
||||
glm_rotate_ndc(m, angle, axis_ndc);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief decompose scale vector
|
||||
*
|
||||
* @param[in] m affine transform
|
||||
* @param[out] s scale vector (Sx, Sy, Sz)
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_decompose_scalev(mat4 m, vec3 s) {
|
||||
s[0] = glm_vec_norm(m[0]);
|
||||
s[1] = glm_vec_norm(m[1]);
|
||||
s[2] = glm_vec_norm(m[2]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief returns true if matrix is uniform scaled. This is helpful for
|
||||
* creating normal matrix.
|
||||
*
|
||||
* @param[in] m m
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_uniscaled(mat4 m) {
|
||||
vec3 s;
|
||||
glm_decompose_scalev(m, s);
|
||||
|
||||
return glm_vec_eq_all(s);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
|
||||
* DON'T pass projected matrix here
|
||||
*
|
||||
* @param[in] m affine transform
|
||||
* @param[out] r rotation matrix
|
||||
* @param[out] s scale matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_decompose_rs(mat4 m, mat4 r, vec3 s) {
|
||||
vec4 t = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vec3 v;
|
||||
|
||||
glm_vec4_copy(m[0], r[0]);
|
||||
glm_vec4_copy(m[1], r[1]);
|
||||
glm_vec4_copy(m[2], r[2]);
|
||||
glm_vec4_copy(t, r[3]);
|
||||
|
||||
s[0] = glm_vec_norm(m[0]);
|
||||
s[1] = glm_vec_norm(m[1]);
|
||||
s[2] = glm_vec_norm(m[2]);
|
||||
|
||||
glm_vec4_scale(r[0], 1.0f/s[0], r[0]);
|
||||
glm_vec4_scale(r[1], 1.0f/s[1], r[1]);
|
||||
glm_vec4_scale(r[2], 1.0f/s[2], r[2]);
|
||||
|
||||
/* Note from Apple Open Source (asume that the matrix is orthonormal):
|
||||
check for a coordinate system flip. If the determinant
|
||||
is -1, then negate the matrix and the scaling factors. */
|
||||
glm_vec_cross(m[0], m[1], v);
|
||||
if (glm_vec_dot(v, m[2]) < 0.0f) {
|
||||
glm_vec4_flipsign(r[0]);
|
||||
glm_vec4_flipsign(r[1]);
|
||||
glm_vec4_flipsign(r[2]);
|
||||
glm_vec_flipsign(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief decompose affine transform, TODO: extract shear factors.
|
||||
* DON'T pass projected matrix here
|
||||
*
|
||||
* @param[in] m affine transfrom
|
||||
* @param[out] t translation vector
|
||||
* @param[out] r rotation matrix (mat4)
|
||||
* @param[out] s scaling vector [X, Y, Z]
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s) {
|
||||
glm_vec4_copy(m[3], t);
|
||||
glm_decompose_rs(m, r, s);
|
||||
}
|
||||
|
||||
#endif /* cglm_affine_h */
|
||||
28
include/cglm/call.h
Normal file
28
include/cglm/call.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_call_h
|
||||
#define cglm_call_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cglm.h"
|
||||
#include "call/vec3.h"
|
||||
#include "call/vec4.h"
|
||||
#include "call/mat4.h"
|
||||
#include "call/mat3.h"
|
||||
#include "call/affine.h"
|
||||
#include "call/cam.h"
|
||||
#include "call/quat.h"
|
||||
#include "call/euler.h"
|
||||
#include "call/io.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglm_call_h */
|
||||
91
include/cglm/call/affine.h
Normal file
91
include/cglm/call/affine.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_affine_h
|
||||
#define cglmc_affine_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_translate_to(mat4 m, vec3 v, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_translate(mat4 m, vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_translate_x(mat4 m, float to);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_translate_y(mat4 m, float to);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_translate_z(mat4 m, float to);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_scale_to(mat4 m, vec3 v, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_scale(mat4 m, vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_scale1(mat4 m, float s);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_x(mat4 m, float rad, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_y(mat4 m, float rad, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_z(mat4 m, float rad, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_make(mat4 m, float angle, vec3 axis);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate_ndc(mat4 m, float angle, vec3 axis_ndc);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_rotate(mat4 m, float angle, vec3 axis);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_decompose_scalev(mat4 m, vec3 s);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_decompose_rs(mat4 m, mat4 r, vec3 s);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_decompose(mat4 m, vec4 t, mat4 r, vec3 s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_affine_h */
|
||||
54
include/cglm/call/cam.h
Normal file
54
include/cglm/call/cam.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_cam_h
|
||||
#define cglmc_cam_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_frustum(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_ortho(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_perspective(float fovy,
|
||||
float aspect,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_lookat(vec3 eye,
|
||||
vec3 center,
|
||||
vec3 up,
|
||||
mat4 dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_cam_h */
|
||||
51
include/cglm/call/euler.h
Normal file
51
include/cglm/call/euler.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_euler_h
|
||||
#define cglmc_euler_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_angles(mat4 m, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_zyx(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_zxy(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_xzy(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_yzx(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_yxz(vec3 angles, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_euler_by_order(vec3 angles, glm_euler_sq axis, mat4 dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_euler_h */
|
||||
44
include/cglm/call/io.h
Normal file
44
include/cglm/call/io.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_io_h
|
||||
#define cglmc_io_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_print(mat4 matrix,
|
||||
FILE * __restrict ostream);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_print(mat3 matrix,
|
||||
FILE * __restrict ostream);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_print(vec4 vec,
|
||||
FILE * __restrict ostream);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec3_print(vec3 vec,
|
||||
FILE * __restrict ostream);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_versor_print(versor vec,
|
||||
FILE * __restrict ostream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_io_h */
|
||||
66
include/cglm/call/mat3.h
Normal file
66
include/cglm/call/mat3.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_mat3_h
|
||||
#define cglmc_mat3_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glmc_mat3_dup(mat, dest) glmc_mat3_copy(mat, dest)
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_copy(mat3 mat, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_identity(mat3 mat);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_mul(mat3 m1, mat3 m2, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_transpose_to(mat3 m, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_transpose(mat3 m);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_mulv(mat3 m, vec3 v, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_scale(mat3 m, float s);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_mat3_det(mat3 mat);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_inv(mat3 mat, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_swap_col(mat3 mat, int col1, int col2);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat3_swap_row(mat3 mat, int row1, int row2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_mat3_h */
|
||||
95
include/cglm/call/mat4.h
Normal file
95
include/cglm/call/mat4.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_mat_h
|
||||
#define cglmc_mat_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glmc_mat4_udup(mat, dest) glmc_mat4_ucopy(mat, dest)
|
||||
#define glmc_mat4_dup(mat, dest) glmc_mat4_copy(mat, dest)
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_ucopy(mat4 mat, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_copy(mat4 mat, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_identity(mat4 mat);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_pick3(mat4 mat, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_pick3t(mat4 mat, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_ins3(mat3 mat, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_mul(mat4 m1, mat4 m2, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_mulN(mat4 * __restrict matrices[], int len, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_mulv(mat4 m, vec4 v, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_transpose_to(mat4 m, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_transpose(mat4 m);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_scale_p(mat4 m, float s);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_scale(mat4 m, float s);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_mat4_det(mat4 mat);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_inv(mat4 mat, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_inv_precise(mat4 mat, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_swap_col(mat4 mat, int col1, int col2);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_mat4_swap_row(mat4 mat, int row1, int row2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_mat_h */
|
||||
64
include/cglm/call/quat.h
Normal file
64
include/cglm/call/quat.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_quat_h
|
||||
#define cglmc_quat_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_identity(versor q);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat(versor q,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_quat_norm(versor q);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_normalize(versor q);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_quat_dot(versor q, versor r);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_mulv(versor q1, versor q2, versor dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_mat4(versor q, mat4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_slerp(versor q,
|
||||
versor r,
|
||||
float t,
|
||||
versor dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_quat_h */
|
||||
94
include/cglm/call/vec3.h
Normal file
94
include/cglm/call/vec3.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_vec3_h
|
||||
#define cglmc_vec3_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glmc_vec_dup(v, dest) glmc_vec_copy(v, dest)
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_copy(vec3 a, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec_dot(vec3 a, vec3 b);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_cross(vec3 a, vec3 b, vec3 d);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec_norm(vec3 vec);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec_norm2(vec3 vec);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_normalize_to(vec3 vec, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_normalize(vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_add(vec3 v1, vec3 v2, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_sub(vec3 v1, vec3 v2, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_scale(vec3 v, float s, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_scale_as(vec3 v, float s, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_flipsign(vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec_angle(vec3 v1, vec3 v2);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_rotate(vec3 v, float angle, vec3 axis);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_rotate_m4(mat4 m, vec3 v, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_proj(vec3 a, vec3 b, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec_center(vec3 v1, vec3 v2, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec_distance(vec3 v1, vec3 v2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_vec3_h */
|
||||
76
include/cglm/call/vec4.h
Normal file
76
include/cglm/call/vec4.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_vec4_h
|
||||
#define cglmc_vec4_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glmc_vec4_dup3(v, dest) glmc_vec4_copy3(v, dest)
|
||||
#define glmc_vec4_dup(v, dest) glmc_vec4_copy(v, dest)
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_copy3(vec4 a, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_copy(vec4 v, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec4_dot(vec4 a, vec4 b);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec4_norm(vec4 vec);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec4_norm2(vec4 vec);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_normalize_to(vec4 vec, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_normalize(vec4 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_add(vec4 v1, vec4 v2, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_sub(vec4 v1, vec4 v2, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_scale(vec4 v, float s, vec4 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_scale_as(vec3 v, float s, vec3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_vec4_flipsign(vec4 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
glmc_vec4_distance(vec4 v1, vec4 v2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_vec4_h */
|
||||
|
||||
284
include/cglm/cam.h
Normal file
284
include/cglm/cam.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_frustum(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float near,
|
||||
float far,
|
||||
mat4 dest);
|
||||
CGLM_INLINE void glm_ortho(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float near,
|
||||
float far,
|
||||
mat4 dest);
|
||||
CGLM_INLINE void glm_ortho_default(float aspect, mat4 dest);
|
||||
CGLM_INLINE void glm_ortho_default_s(float aspect, float size, mat4 dest);
|
||||
CGLM_INLINE void glm_perspective(float fovy,
|
||||
float aspect,
|
||||
float near,
|
||||
float far,
|
||||
mat4 dest);
|
||||
CGLM_INLINE void glm_perspective_default(float aspect, mat4 dest);
|
||||
CGLM_INLINE void glm_perspective_resize(float aspect, mat4 proj);
|
||||
CGLM_INLINE void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vcam_h
|
||||
#define cglm_vcam_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*!
|
||||
* @brief set up perspective peprojection matrix
|
||||
*
|
||||
* @param[in] left viewport.left
|
||||
* @param[in] right viewport.right
|
||||
* @param[in] bottom viewport.bottom
|
||||
* @param[in] top viewport.top
|
||||
* @param[in] nearVal near clipping plane
|
||||
* @param[in] farVal far clipping plane
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_frustum(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest) {
|
||||
float rl, tb, fn, nv;
|
||||
|
||||
glm__memzero(float, dest, sizeof(mat4));
|
||||
|
||||
rl = 1.0f / (right - left);
|
||||
tb = 1.0f / (top - bottom);
|
||||
fn =-1.0f / (farVal - nearVal);
|
||||
nv = 2.0f * nearVal;
|
||||
|
||||
dest[0][0] = nv * rl;
|
||||
dest[1][1] = nv * tb;
|
||||
dest[2][0] = (right + left) * rl;
|
||||
dest[2][1] = (top + bottom) * tb;
|
||||
dest[2][2] = (farVal + nearVal) * fn;
|
||||
dest[2][3] =-1.0f;
|
||||
dest[3][2] = farVal * nv * fn;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up orthographic projection matrix
|
||||
*
|
||||
* @param[in] left viewport.left
|
||||
* @param[in] right viewport.right
|
||||
* @param[in] bottom viewport.bottom
|
||||
* @param[in] top viewport.top
|
||||
* @param[in] nearVal near clipping plane
|
||||
* @param[in] farVal far clipping plane
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_ortho(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest) {
|
||||
float rl, tb, fn;
|
||||
|
||||
glm__memzero(float, dest, sizeof(mat4));
|
||||
|
||||
rl = 1.0f / (right - left);
|
||||
tb = 1.0f / (top - bottom);
|
||||
fn =-1.0f / (farVal - nearVal);
|
||||
|
||||
dest[0][0] = 2.0f * rl;
|
||||
dest[1][1] = 2.0f * tb;
|
||||
dest[2][2] = 2.0f * fn;
|
||||
dest[3][0] =-(right + left) * rl;
|
||||
dest[3][1] =-(top + bottom) * tb;
|
||||
dest[3][2] = (farVal + nearVal) * fn;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up unit orthographic projection matrix
|
||||
*
|
||||
* @param[in] aspect aspect ration ( width / height )
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_ortho_default(float aspect,
|
||||
mat4 dest) {
|
||||
if (aspect >= 1.0f) {
|
||||
glm_ortho(-1.0f * aspect,
|
||||
1.0f * aspect,
|
||||
-1.0f,
|
||||
1.0f,
|
||||
-100.0f,
|
||||
100.0f,
|
||||
dest);
|
||||
return;
|
||||
}
|
||||
|
||||
glm_ortho(-1.0f,
|
||||
1.0f,
|
||||
-1.0f / aspect,
|
||||
1.0f / aspect,
|
||||
-100.0f,
|
||||
100.0f,
|
||||
dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up orthographic projection matrix with given CUBE size
|
||||
*
|
||||
* @param[in] aspect aspect ratio ( width / height )
|
||||
* @param[in] size cube size
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_ortho_default_s(float aspect,
|
||||
float size,
|
||||
mat4 dest) {
|
||||
if (aspect >= 1.0f) {
|
||||
glm_ortho(-size * aspect,
|
||||
size * aspect,
|
||||
-size,
|
||||
size,
|
||||
-size - 100.0f,
|
||||
size + 100.0f,
|
||||
dest);
|
||||
return;
|
||||
}
|
||||
|
||||
glm_ortho(-size,
|
||||
size,
|
||||
-size / aspect,
|
||||
size / aspect,
|
||||
-size - 100.0f,
|
||||
size + 100.0f,
|
||||
dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up perspective projection matrix
|
||||
*
|
||||
* @param[in] fovy field of view angle
|
||||
* @param[in] aspect aspect ratio ( width / height )
|
||||
* @param[in] nearVal near clipping plane
|
||||
* @param[in] farVal far clipping planes
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_perspective(float fovy,
|
||||
float aspect,
|
||||
float nearVal,
|
||||
float farVal,
|
||||
mat4 dest) {
|
||||
float f, fn;
|
||||
|
||||
glm__memzero(float, dest, sizeof(mat4));
|
||||
|
||||
f = 1.0f / tanf(fovy * 0.5f);
|
||||
fn = 1.0f / (nearVal - farVal);
|
||||
|
||||
dest[0][0] = f / aspect;
|
||||
dest[1][1] = f;
|
||||
dest[2][2] = (nearVal + farVal) * fn;
|
||||
dest[2][3] =-1.0f;
|
||||
dest[3][2] = 2.0f * nearVal * farVal * fn;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up perspective projection matrix with default near/far
|
||||
* and angle values
|
||||
*
|
||||
* @param[in] aspect aspect ratio ( width / height )
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_perspective_default(float aspect,
|
||||
mat4 dest) {
|
||||
glm_perspective((float)CGLM_PI_4,
|
||||
aspect,
|
||||
0.01f,
|
||||
100.0f,
|
||||
dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief resize perspective matrix by aspect ratio ( width / height )
|
||||
* this very make easy to resize proj matrix when window, viewport
|
||||
* reized
|
||||
*
|
||||
* @param[in] aspect aspect ratio ( width / height )
|
||||
* @param[in, out] proj perspective projection matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_perspective_resize(float aspect,
|
||||
mat4 proj) {
|
||||
if (proj[0][0] == 0.0f)
|
||||
return;
|
||||
|
||||
proj[0][0] = proj[1][1] / aspect;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief set up view matrix
|
||||
*
|
||||
* @param[in] eye eye vector
|
||||
* @param[in] center center vector
|
||||
* @param[in] up up vector
|
||||
* @param[out] dest result matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_lookat(vec3 eye,
|
||||
vec3 center,
|
||||
vec3 up,
|
||||
mat4 dest) {
|
||||
vec3 f, u, s;
|
||||
|
||||
glm_vec_sub(center, eye, f);
|
||||
glm_vec_normalize(f);
|
||||
|
||||
glm_vec_cross(f, up, s);
|
||||
glm_vec_normalize(s);
|
||||
|
||||
glm_vec_cross(s, f, u);
|
||||
|
||||
dest[0][0] = s[0];
|
||||
dest[0][1] = u[0];
|
||||
dest[0][2] =-f[0];
|
||||
dest[1][0] = s[1];
|
||||
dest[1][1] = u[1];
|
||||
dest[1][2] =-f[1];
|
||||
dest[2][0] = s[2];
|
||||
dest[2][1] = u[2];
|
||||
dest[2][2] =-f[2];
|
||||
dest[3][0] =-glm_vec_dot(s, eye);
|
||||
dest[3][1] =-glm_vec_dot(u, eye);
|
||||
dest[3][2] = glm_vec_dot(f, eye);
|
||||
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
#endif /* cglm_vcam_h */
|
||||
23
include/cglm/cglm.h
Normal file
23
include/cglm/cglm.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_h
|
||||
#define cglm_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
||||
#include "mat3.h"
|
||||
#include "affine.h"
|
||||
#include "cam.h"
|
||||
#include "quat.h"
|
||||
#include "euler.h"
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
|
||||
#endif /* cglm_h */
|
||||
59
include/cglm/common.h
Normal file
59
include/cglm/common.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_common_h
|
||||
#define cglm_common_h
|
||||
|
||||
#define _USE_MATH_DEFINES /* for windows */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef CGLM_DLL
|
||||
# define CGLM_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define CGLM_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# define CGLM_INLINE __forceinline
|
||||
#else
|
||||
# define CGLM_EXPORT __attribute__((visibility("default")))
|
||||
# define CGLM_INLINE static inline __attribute((always_inline))
|
||||
#endif
|
||||
|
||||
#define glm__memcpy(type, dest, src, size) \
|
||||
do { \
|
||||
type *srci; \
|
||||
type *srci_end; \
|
||||
type *desti; \
|
||||
\
|
||||
srci = (type *)src; \
|
||||
srci_end = (type *)((char *)srci + size); \
|
||||
desti = (type *)dest; \
|
||||
\
|
||||
while (srci != srci_end) \
|
||||
*desti++ = *srci++; \
|
||||
} while (0)
|
||||
|
||||
#define glm__memset(type, dest, size, val) \
|
||||
do { \
|
||||
type *desti; \
|
||||
type *desti_end; \
|
||||
\
|
||||
desti = (type *)dest; \
|
||||
desti_end = (type *)((char *)desti + size); \
|
||||
\
|
||||
while (desti != desti_end) \
|
||||
*desti++ = val; \
|
||||
} while (0)
|
||||
|
||||
#define glm__memzero(type, dest, size) glm__memset(type, dest, size, 0)
|
||||
|
||||
#include "types.h"
|
||||
#include "simd/intrin.h"
|
||||
|
||||
#endif /* cglm_common_h */
|
||||
378
include/cglm/euler.h
Normal file
378
include/cglm/euler.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Types:
|
||||
enum glm_euler_sq
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE glm_euler_sq glm_euler_order(int newOrder[3]);
|
||||
CGLM_INLINE void glm_euler_angles(mat4 m, vec3 dest);
|
||||
CGLM_INLINE void glm_euler(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_zyx(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_zxy(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_xzy(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_yzx(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_yxz(vec3 angles, mat4 dest);
|
||||
CGLM_INLINE void glm_euler_by_order(vec3 angles,
|
||||
glm_euler_sq axis,
|
||||
mat4 dest);
|
||||
*/
|
||||
|
||||
#ifndef cglm_euler_h
|
||||
#define cglm_euler_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*!
|
||||
* if you have axis order like vec3 orderVec = [0, 1, 2] or [0, 2, 1]...
|
||||
* vector then you can convert it to this enum by doing this:
|
||||
* @code
|
||||
* glm_euler_sq order;
|
||||
* order = orderVec[0] | orderVec[1] << 2 | orderVec[2] << 4;
|
||||
* @endcode
|
||||
* you may need to explicit cast if required
|
||||
*/
|
||||
typedef enum glm_euler_sq {
|
||||
GLM_EULER_XYZ = 0 << 0 | 1 << 2 | 2 << 4,
|
||||
GLM_EULER_XZY = 0 << 0 | 2 << 2 | 1 << 4,
|
||||
GLM_EULER_YZX = 1 << 0 | 2 << 2 | 0 << 4,
|
||||
GLM_EULER_YXZ = 1 << 0 | 0 << 2 | 2 << 4,
|
||||
GLM_EULER_ZXY = 2 << 0 | 0 << 2 | 1 << 4,
|
||||
GLM_EULER_ZYX = 2 << 0 | 1 << 2 | 0 << 4
|
||||
} glm_euler_sq;
|
||||
|
||||
CGLM_INLINE
|
||||
glm_euler_sq
|
||||
glm_euler_order(int newOrder[3]) {
|
||||
return (glm_euler_sq)(newOrder[0] | newOrder[1] << 2 | newOrder[2] << 4);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief euler angles (in radian) using xyz sequence
|
||||
*
|
||||
* @param[in] m affine transform
|
||||
* @param[out] dest angles vector [x, y, z]
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_angles(mat4 m, vec3 dest) {
|
||||
if (m[0][2] < 1.0f) {
|
||||
if (m[0][2] > -1.0f) {
|
||||
vec3 a[2];
|
||||
float cy1, cy2;
|
||||
int path;
|
||||
|
||||
a[0][1] = asinf(-m[0][2]);
|
||||
a[1][1] = CGLM_PI - a[0][1];
|
||||
|
||||
cy1 = cosf(a[0][1]);
|
||||
cy2 = cosf(a[1][1]);
|
||||
|
||||
a[0][0] = atan2f(m[1][2] / cy1, m[2][2] / cy1);
|
||||
a[1][0] = atan2f(m[1][2] / cy2, m[2][2] / cy2);
|
||||
|
||||
a[0][2] = atan2f(m[0][1] / cy1, m[0][0] / cy1);
|
||||
a[1][2] = atan2f(m[0][1] / cy2, m[0][0] / cy2);
|
||||
|
||||
path = (fabsf(a[0][0]) + fabsf(a[0][1]) + fabsf(a[0][2])) >=
|
||||
(fabsf(a[1][0]) + fabsf(a[1][1]) + fabsf(a[1][2]));
|
||||
|
||||
glm_vec_copy(a[path], dest);
|
||||
} else {
|
||||
dest[0] = atan2f(m[1][0], m[2][0]);
|
||||
dest[1] = CGLM_PI_2;
|
||||
dest[2] = 0.0f;
|
||||
}
|
||||
} else {
|
||||
dest[0] = atan2f(-m[1][0], -m[2][0]);
|
||||
dest[1] =-CGLM_PI_2;
|
||||
dest[2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief build rotation matrix from euler angles(ExEyEz/RzRyRx)
|
||||
*
|
||||
* @param[in] angles angles as vector [Ex, Ey, Ez]
|
||||
* @param[out] dest rotation matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler(vec3 angles, mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz;
|
||||
dest[0][1] = cy * sz;
|
||||
dest[0][2] =-sy;
|
||||
dest[1][0] = cz * sx * sy - cx * sz;
|
||||
dest[1][1] = cx * cz + sx * sy * sz;
|
||||
dest[1][2] = cy * sx;
|
||||
dest[2][0] = cx * cz * sy + sx * sz;
|
||||
dest[2][1] =-cz * sx + cx * sy * sz;
|
||||
dest[2][2] = cx * cy;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief build rotation matrix from euler angles (EzEyEx/RxRyRz)
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_zyx(vec3 angles,
|
||||
mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz;
|
||||
dest[0][1] = cz * sx * sy + cx * sz;
|
||||
dest[0][2] =-cx * cz * sy + sx * sz;
|
||||
dest[1][0] =-cy * sz;
|
||||
dest[1][1] = cx * cz - sx * sy * sz;
|
||||
dest[1][2] = cz * sx + cx * sy * sz;
|
||||
dest[2][0] = sy;
|
||||
dest[2][1] =-cy * sx;
|
||||
dest[2][2] = cx * cy;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_zxy(vec3 angles,
|
||||
mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz + sx * sy * sz;
|
||||
dest[0][1] = cx * sz;
|
||||
dest[0][2] =-cz * sy + cy * sx * sz;
|
||||
dest[1][0] = cz * sx * sy - cy * sz;
|
||||
dest[1][1] = cx * cz;
|
||||
dest[1][2] = cy * cz * sx + sy * sz;
|
||||
dest[2][0] = cx * sy;
|
||||
dest[2][1] =-sx;
|
||||
dest[2][2] = cx * cy;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_xzy(vec3 angles,
|
||||
mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz;
|
||||
dest[0][1] = sz;
|
||||
dest[0][2] =-cz * sy;
|
||||
dest[1][0] = sx * sy - cx * cy * sz;
|
||||
dest[1][1] = cx * cz;
|
||||
dest[1][2] = cy * sx + cx * sy * sz;
|
||||
dest[2][0] = cx * sy + cy * sx * sz;
|
||||
dest[2][1] =-cz * sx;
|
||||
dest[2][2] = cx * cy - sx * sy * sz;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_yzx(vec3 angles,
|
||||
mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz;
|
||||
dest[0][1] = sx * sy + cx * cy * sz;
|
||||
dest[0][2] =-cx * sy + cy * sx * sz;
|
||||
dest[1][0] =-sz;
|
||||
dest[1][1] = cx * cz;
|
||||
dest[1][2] = cz * sx;
|
||||
dest[2][0] = cz * sy;
|
||||
dest[2][1] =-cy * sx + cx * sy * sz;
|
||||
dest[2][2] = cx * cy + sx * sy * sz;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_yxz(vec3 angles,
|
||||
mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
dest[0][0] = cy * cz - sx * sy * sz;
|
||||
dest[0][1] = cz * sx * sy + cy * sz;
|
||||
dest[0][2] =-cx * sy;
|
||||
dest[1][0] =-cx * sz;
|
||||
dest[1][1] = cx * cz;
|
||||
dest[1][2] = sx;
|
||||
dest[2][0] = cz * sy + cy * sx * sz;
|
||||
dest[2][1] =-cy * cz * sx + sy * sz;
|
||||
dest[2][2] = cx * cy;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_euler_by_order(vec3 angles, glm_euler_sq axis, mat4 dest) {
|
||||
float cx, cy, cz,
|
||||
sx, sy, sz;
|
||||
|
||||
float cycz, cysz, cysx, cxcy,
|
||||
czsy, cxcz, czsx, cxsz,
|
||||
sysz;
|
||||
|
||||
sx = sinf(angles[0]); cx = cosf(angles[0]);
|
||||
sy = sinf(angles[1]); cy = cosf(angles[1]);
|
||||
sz = sinf(angles[2]); cz = cosf(angles[2]);
|
||||
|
||||
cycz = cy * cz; cysz = cy * sz;
|
||||
cysx = cy * sx; cxcy = cx * cy;
|
||||
czsy = cz * sy; cxcz = cx * cz;
|
||||
czsx = cz * sx; cxsz = cx * sz;
|
||||
sysz = sy * sz;
|
||||
|
||||
switch (axis) {
|
||||
case GLM_EULER_XYZ:
|
||||
dest[0][0] = cycz;
|
||||
dest[0][1] = cysz;
|
||||
dest[0][2] =-sy;
|
||||
dest[1][0] = czsx * sy - cxsz;
|
||||
dest[1][1] = cxcz + sx * sysz;
|
||||
dest[1][2] = cysx;
|
||||
dest[2][0] = cx * czsy + sx * sz;
|
||||
dest[2][1] =-czsx + cx * sysz;
|
||||
dest[2][2] = cxcy;
|
||||
break;
|
||||
case GLM_EULER_XZY:
|
||||
dest[0][0] = cycz;
|
||||
dest[0][1] = sz;
|
||||
dest[0][2] =-czsy;
|
||||
dest[1][0] = sx * sy - cx * cysz;
|
||||
dest[1][1] = cxcz;
|
||||
dest[1][2] = cysx + cx * sysz;
|
||||
dest[2][0] = cx * sy + cysx * sz;
|
||||
dest[2][1] =-czsx;
|
||||
dest[2][2] = cxcy - sx * sysz;
|
||||
break;
|
||||
case GLM_EULER_ZXY:
|
||||
dest[0][0] = cycz + sx * sysz;
|
||||
dest[0][1] = cxsz;
|
||||
dest[0][2] =-czsy + cysx * sz;
|
||||
dest[1][0] = czsx * sy - cysz;
|
||||
dest[1][1] = cxcz;
|
||||
dest[1][2] = cycz * sx + sysz;
|
||||
dest[2][0] = cx * sy;
|
||||
dest[2][1] =-sx;
|
||||
dest[2][2] = cxcy;
|
||||
break;
|
||||
case GLM_EULER_ZYX:
|
||||
dest[0][0] = cycz;
|
||||
dest[0][1] = czsx * sy + cxsz;
|
||||
dest[0][2] =-cx * czsy + sx * sz;
|
||||
dest[1][0] =-cysz;
|
||||
dest[1][1] = cxcz - sx * sysz;
|
||||
dest[1][2] = czsx + cx * sysz;
|
||||
dest[2][0] = sy;
|
||||
dest[2][1] =-cysx;
|
||||
dest[2][2] = cxcy;
|
||||
break;
|
||||
case GLM_EULER_YXZ:
|
||||
dest[0][0] = cycz - sx * sysz;
|
||||
dest[0][1] = czsx * sy + cysz;
|
||||
dest[0][2] =-cx * sy;
|
||||
dest[1][0] =-cxsz;
|
||||
dest[1][1] = cxcz;
|
||||
dest[1][2] = sx;
|
||||
dest[2][0] = czsy + cysx * sz;
|
||||
dest[2][1] =-cycz * sx + sysz;
|
||||
dest[2][2] = cxcy;
|
||||
break;
|
||||
case GLM_EULER_YZX:
|
||||
dest[0][0] = cycz;
|
||||
dest[0][1] = sx * sy + cx * cysz;
|
||||
dest[0][2] =-cx * sy + cysx * sz;
|
||||
dest[1][0] =-sz;
|
||||
dest[1][1] = cxcz;
|
||||
dest[1][2] = czsx;
|
||||
dest[2][0] = czsy;
|
||||
dest[2][1] =-cysx + cx * sysz;
|
||||
dest[2][2] = cxcy + sx * sysz;
|
||||
break;
|
||||
}
|
||||
|
||||
dest[0][3] = 0.0f;
|
||||
dest[1][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
#endif /* cglm_euler_h */
|
||||
174
include/cglm/io.h
Normal file
174
include/cglm/io.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_mat4_print(mat4 matrix, FILE *ostream);
|
||||
CGLM_INLINE void glm_mat3_print(mat3 matrix, FILE *ostream);
|
||||
CGLM_INLINE void glm_vec4_print(vec4 vec, FILE *ostream);
|
||||
CGLM_INLINE void glm_vec3_print(vec3 vec, FILE *ostream);
|
||||
CGLM_INLINE void glm_ivec3_print(ivec3 vec, FILE *ostream);
|
||||
CGLM_INLINE void glm_versor_print(versor vec, FILE *ostream);
|
||||
*/
|
||||
|
||||
#ifndef cglm_io_h
|
||||
#define cglm_io_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_print(mat4 matrix,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
#define m 4
|
||||
#define n 4
|
||||
|
||||
fprintf(ostream, "Matrix (float%dx%d):\n", m, n);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "\t|");
|
||||
for (j = 0; j < n; j++) {
|
||||
fprintf(ostream, "%0.4f", matrix[j][i]);;
|
||||
|
||||
if (j != n - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n");
|
||||
}
|
||||
|
||||
fprintf(ostream, "\n");
|
||||
|
||||
#undef m
|
||||
#undef n
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_print(mat3 matrix,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
#define m 3
|
||||
#define n 3
|
||||
|
||||
fprintf(ostream, "Matrix (float%dx%d):\n", m, n);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "\t|");
|
||||
for (j = 0; j < n; j++) {
|
||||
fprintf(ostream, "%0.4f", matrix[j][i]);;
|
||||
|
||||
if (j != n - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n");
|
||||
}
|
||||
|
||||
fprintf(ostream, "\n");
|
||||
|
||||
#undef m
|
||||
#undef n
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_print(vec4 vec,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
|
||||
#define m 4
|
||||
|
||||
fprintf(ostream, "Vector (float%d):\n\t|", m);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "%0.4f", vec[i]);
|
||||
|
||||
if (i != m - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n\n");
|
||||
|
||||
#undef m
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec3_print(vec3 vec,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
|
||||
#define m 3
|
||||
|
||||
fprintf(ostream, "Vector (float%d):\n\t|", m);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "%0.4f", vec[i]);
|
||||
|
||||
if (i != m - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n\n");
|
||||
|
||||
#undef m
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_ivec3_print(ivec3 vec,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
|
||||
#define m 3
|
||||
|
||||
fprintf(ostream, "Vector (int%d):\n\t|", m);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "%d", vec[i]);
|
||||
|
||||
if (i != m - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n\n");
|
||||
|
||||
#undef m
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_versor_print(versor vec,
|
||||
FILE * __restrict ostream) {
|
||||
int i;
|
||||
|
||||
#define m 4
|
||||
|
||||
fprintf(ostream, "Versor (float%d):\n\t|", m);
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
fprintf(ostream, "%0.4f", vec[i]);
|
||||
|
||||
if (i != m - 1)
|
||||
fprintf(ostream, "\t");
|
||||
}
|
||||
|
||||
fprintf(ostream, "|\n\n");
|
||||
|
||||
#undef m
|
||||
}
|
||||
|
||||
#endif /* cglm_io_h */
|
||||
291
include/cglm/mat3.h
Normal file
291
include/cglm/mat3.h
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros:
|
||||
GLM_MAT3_IDENTITY_INIT
|
||||
GLM_MAT3_ZERO_INIT
|
||||
GLM_MAT3_IDENTITY
|
||||
GLM_MAT3_ZERO
|
||||
glm_mat3_dup(mat, dest)
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE void glm_mat3_copy(mat3 mat, mat3 dest);
|
||||
CGLM_INLINE void glm_mat3_identity(mat3 mat);
|
||||
CGLM_INLINE void glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest);
|
||||
CGLM_INLINE void glm_mat3_transpose_to(mat3 m, mat3 dest);
|
||||
CGLM_INLINE void glm_mat3_transpose(mat3 m);
|
||||
CGLM_INLINE void glm_mat3_mulv(mat3 m, vec3 v, vec3 dest);
|
||||
CGLM_INLINE void glm_mat3_scale(mat3 m, float s);
|
||||
CGLM_INLINE float glm_mat3_det(mat3 mat);
|
||||
CGLM_INLINE void glm_mat3_inv(mat3 mat, mat3 dest);
|
||||
CGLM_INLINE void glm_mat3_swap_col(mat3 mat, int col1, int col2);
|
||||
CGLM_INLINE void glm_mat3_swap_row(mat3 mat, int row1, int row2);
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat3_h
|
||||
#define cglm_mat3_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef CGLM_SSE_FP
|
||||
# include "simd/sse2/mat3.h"
|
||||
#endif
|
||||
|
||||
#define GLM_MAT3_IDENTITY_INIT {{1.0f, 0.0f, 0.0f}, \
|
||||
{0.0f, 1.0f, 0.0f}, \
|
||||
{0.0f, 0.0f, 1.0f}}
|
||||
#define GLM_MAT3_ZERO_INIT {{0.0f, 0.0f, 0.0f}, \
|
||||
{0.0f, 0.0f, 0.0f}, \
|
||||
{0.0f, 0.0f, 0.0f}}
|
||||
|
||||
|
||||
/* for C only */
|
||||
#define GLM_MAT3_IDENTITY (mat3)GLM_MAT3_IDENTITY_INIT
|
||||
#define GLM_MAT3_ZERO (mat3)GLM_MAT3_ZERO_INIT
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glm_mat3_dup(mat, dest) glm_mat3_copy(mat, dest)
|
||||
|
||||
/*!
|
||||
* @brief copy all members of [mat] to [dest]
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_copy(mat3 mat, mat3 dest) {
|
||||
glm__memcpy(float, dest, mat, sizeof(mat3));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief make given matrix identity. It is identical with below,
|
||||
* but it is more easy to do that with this func especially for members
|
||||
* e.g. glm_mat3_identity(aStruct->aMatrix);
|
||||
*
|
||||
* @code
|
||||
* glm_mat3_copy(GLM_MAT3_IDENTITY, mat); // C only
|
||||
*
|
||||
* // or
|
||||
* mat3 mat = GLM_MAT3_IDENTITY_INIT;
|
||||
* @endcode
|
||||
*
|
||||
* @param[in, out] mat destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_identity(mat3 mat) {
|
||||
mat3 t = GLM_MAT3_IDENTITY_INIT;
|
||||
glm_mat3_copy(t, mat);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply m1 and m2 to dest
|
||||
*
|
||||
* m1, m2 and dest matrices can be same matrix, it is possible to write this:
|
||||
*
|
||||
* @code
|
||||
* mat3 m = GLM_MAT3_IDENTITY_INIT;
|
||||
* glm_mat3_mul(m, m, m);
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] m1 left matrix
|
||||
* @param[in] m2 right matrix
|
||||
* @param[out] dest destination matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat3_mul_sse2(m1, m2, dest);
|
||||
#else
|
||||
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2],
|
||||
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2],
|
||||
a20 = m1[2][0], a21 = m1[2][1], a22 = m1[2][2],
|
||||
|
||||
b00 = m2[0][0], b01 = m2[0][1], b02 = m2[0][2],
|
||||
b10 = m2[1][0], b11 = m2[1][1], b12 = m2[1][2],
|
||||
b20 = m2[2][0], b21 = m2[2][1], b22 = m2[2][2];
|
||||
|
||||
dest[0][0] = a00 * b00 + a10 * b01 + a20 * b02;
|
||||
dest[0][1] = a01 * b00 + a11 * b01 + a21 * b02;
|
||||
dest[0][2] = a02 * b00 + a12 * b01 + a22 * b02;
|
||||
dest[1][0] = a00 * b10 + a10 * b11 + a20 * b12;
|
||||
dest[1][1] = a01 * b10 + a11 * b11 + a21 * b12;
|
||||
dest[1][2] = a02 * b10 + a12 * b11 + a22 * b12;
|
||||
dest[2][0] = a00 * b20 + a10 * b21 + a20 * b22;
|
||||
dest[2][1] = a01 * b20 + a11 * b21 + a21 * b22;
|
||||
dest[2][2] = a02 * b20 + a12 * b21 + a22 * b22;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief transpose mat3 and store in dest
|
||||
*
|
||||
* source matrix will not be transposed unless dest is m
|
||||
*
|
||||
* @param[in] m matrix
|
||||
* @param[out] dest result
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_transpose_to(mat3 m, mat3 dest) {
|
||||
dest[0][0] = m[0][0];
|
||||
dest[0][1] = m[1][0];
|
||||
dest[0][2] = m[2][0];
|
||||
dest[1][0] = m[0][1];
|
||||
dest[1][1] = m[1][1];
|
||||
dest[1][2] = m[2][1];
|
||||
dest[2][0] = m[0][2];
|
||||
dest[2][1] = m[1][2];
|
||||
dest[2][2] = m[2][2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief tranpose mat3 and store result in same matrix
|
||||
*
|
||||
* @param[in, out] m source and dest
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_transpose(mat3 m) {
|
||||
mat3 tmp;
|
||||
|
||||
tmp[0][1] = m[1][0];
|
||||
tmp[0][2] = m[2][0];
|
||||
tmp[1][0] = m[0][1];
|
||||
tmp[1][2] = m[2][1];
|
||||
tmp[2][0] = m[0][2];
|
||||
tmp[2][1] = m[1][2];
|
||||
|
||||
m[0][1] = tmp[0][1];
|
||||
m[0][2] = tmp[0][2];
|
||||
m[1][0] = tmp[1][0];
|
||||
m[1][2] = tmp[1][2];
|
||||
m[2][0] = tmp[2][0];
|
||||
m[2][1] = tmp[2][1];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply mat3 with vec3 (column vector) and store in dest vector
|
||||
*
|
||||
* @param[in] m mat3 (left)
|
||||
* @param[in] v vec3 (right, column vector)
|
||||
* @param[out] dest vec3 (result, column vector)
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_mulv(mat3 m, vec3 v, vec3 dest) {
|
||||
dest[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2];
|
||||
dest[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2];
|
||||
dest[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief scale (multiply with scalar) matrix
|
||||
*
|
||||
* multiply matrix with scalar
|
||||
*
|
||||
* @param[in, out] m matrix
|
||||
* @param[in] s scalar
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_scale(mat3 m, float s) {
|
||||
m[0][0] *= s; m[0][1] *= s; m[0][2] *= s;
|
||||
m[1][0] *= s; m[1][1] *= s; m[1][2] *= s;
|
||||
m[2][0] *= s; m[2][1] *= s; m[2][2] *= s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief mat3 determinant
|
||||
*
|
||||
* @param[in] mat matrix
|
||||
*
|
||||
* @return determinant
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_mat3_det(mat3 mat) {
|
||||
float a = mat[0][0], b = mat[0][1], c = mat[0][2],
|
||||
d = mat[1][0], e = mat[1][1], f = mat[1][2],
|
||||
g = mat[2][0], h = mat[2][1], i = mat[2][2];
|
||||
|
||||
return a * (e * i - h * f) - d * (b * i - c * h) + g * (b * f - c * e);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief inverse mat3 and store in dest
|
||||
*
|
||||
* @param[in] mat matrix
|
||||
* @param[out] dest inverse matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_inv(mat3 mat, mat3 dest) {
|
||||
float det;
|
||||
float a = mat[0][0], b = mat[0][1], c = mat[0][2],
|
||||
d = mat[1][0], e = mat[1][1], f = mat[1][2],
|
||||
g = mat[2][0], h = mat[2][1], i = mat[2][2];
|
||||
|
||||
dest[0][0] = e * i - f * h;
|
||||
dest[0][1] = -(b * i - h * c);
|
||||
dest[0][2] = b * f - e * c;
|
||||
dest[1][0] = -(d * i - g * f);
|
||||
dest[1][1] = a * i - c * g;
|
||||
dest[1][2] = -(a * f - d * c);
|
||||
dest[2][0] = d * h - g * e;
|
||||
dest[2][1] = -(a * h - g * b);
|
||||
dest[2][2] = a * e - b * d;
|
||||
|
||||
det = 1.0f / (a * dest[0][0] + b * dest[1][0] + c * dest[2][0]);
|
||||
|
||||
glm_mat3_scale(dest, det);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief swap two matrix columns
|
||||
*
|
||||
* @param[in,out] mat matrix
|
||||
* @param[in] col1 col1
|
||||
* @param[in] col2 col2
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_swap_col(mat3 mat, int col1, int col2) {
|
||||
vec3 tmp;
|
||||
glm_vec_copy(mat[col1], tmp);
|
||||
glm_vec_copy(mat[col2], mat[col1]);
|
||||
glm_vec_copy(tmp, mat[col2]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief swap two matrix rows
|
||||
*
|
||||
* @param[in,out] mat matrix
|
||||
* @param[in] row1 row1
|
||||
* @param[in] row2 row2
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_swap_row(mat3 mat, int row1, int row2) {
|
||||
vec3 tmp;
|
||||
tmp[0] = mat[0][row1];
|
||||
tmp[1] = mat[1][row1];
|
||||
tmp[2] = mat[2][row1];
|
||||
|
||||
mat[0][row1] = mat[0][row2];
|
||||
mat[1][row1] = mat[1][row2];
|
||||
mat[2][row1] = mat[2][row2];
|
||||
|
||||
mat[0][row2] = tmp[0];
|
||||
mat[1][row2] = tmp[1];
|
||||
mat[2][row2] = tmp[2];
|
||||
}
|
||||
|
||||
#endif /* cglm_mat3_h */
|
||||
572
include/cglm/mat4.h
Normal file
572
include/cglm/mat4.h
Normal file
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Most of functions in this header are optimized manually with SIMD
|
||||
* if available. You dont need to call/incude SIMD headers manually
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros:
|
||||
GLM_MAT4_IDENTITY_INIT
|
||||
GLM_MAT4_ZERO_INIT
|
||||
GLM_MAT4_IDENTITY
|
||||
GLM_MAT4_ZERO
|
||||
glm_mat4_udup(mat, dest)
|
||||
glm_mat4_dup(mat, dest)
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE void glm_mat4_ucopy(mat4 mat, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_copy(mat4 mat, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_identity(mat4 mat);
|
||||
CGLM_INLINE void glm_mat4_pick3(mat4 mat, mat3 dest);
|
||||
CGLM_INLINE void glm_mat4_pick3t(mat4 mat, mat3 dest);
|
||||
CGLM_INLINE void glm_mat4_ins3(mat3 mat, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_mulN(mat4 *matrices[], int len, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
|
||||
CGLM_INLINE void glm_mat4_mulv3(mat4 m, vec3 v, vec3 dest);
|
||||
CGLM_INLINE void glm_mat4_transpose_to(mat4 m, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_transpose(mat4 m);
|
||||
CGLM_INLINE void glm_mat4_scale_p(mat4 m, float s);
|
||||
CGLM_INLINE void glm_mat4_scale(mat4 m, float s);
|
||||
CGLM_INLINE float glm_mat4_det(mat4 mat);
|
||||
CGLM_INLINE void glm_mat4_inv(mat4 mat, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_inv_precise(mat4 mat, mat4 dest);
|
||||
CGLM_INLINE void glm_mat4_swap_col(mat4 mat, int col1, int col2);
|
||||
CGLM_INLINE void glm_mat4_swap_row(mat4 mat, int row1, int row2);
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat_h
|
||||
#define cglm_mat_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef CGLM_SSE_FP
|
||||
# include "simd/sse2/mat4.h"
|
||||
#endif
|
||||
|
||||
#ifdef CGLM_AVX_FP
|
||||
# include "simd/avx/mat4.h"
|
||||
#endif
|
||||
|
||||
#ifdef CGLM_NEON_FP
|
||||
# include "simd/neon/mat4.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define GLM_MAT4_IDENTITY_INIT {{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}}
|
||||
|
||||
#define GLM_MAT4_ZERO_INIT {{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}}
|
||||
|
||||
/* for C only */
|
||||
#define GLM_MAT4_IDENTITY (mat4)GLM_MAT4_IDENTITY_INIT
|
||||
#define GLM_MAT4_ZERO (mat4)GLM_MAT4_ZERO_INIT
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glm_mat4_udup(mat, dest) glm_mat4_ucopy(mat, dest)
|
||||
#define glm_mat4_dup(mat, dest) glm_mat4_copy(mat, dest)
|
||||
|
||||
/*!
|
||||
* @brief copy all members of [mat] to [dest]
|
||||
*
|
||||
* matrix may not be aligned, u stands for unaligned, this may be useful when
|
||||
* copying a matrix from external source e.g. asset importer...
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_ucopy(mat4 mat, mat4 dest) {
|
||||
glm__memcpy(float, dest, mat, sizeof(mat4));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief copy all members of [mat] to [dest]
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_copy(mat4 mat, mat4 dest) {
|
||||
#ifdef __AVX__
|
||||
_mm256_store_ps(dest[0], _mm256_load_ps(mat[0]));
|
||||
_mm256_store_ps(dest[2], _mm256_load_ps(mat[2]));
|
||||
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest[0], _mm_load_ps(mat[0]));
|
||||
_mm_store_ps(dest[1], _mm_load_ps(mat[1]));
|
||||
_mm_store_ps(dest[2], _mm_load_ps(mat[2]));
|
||||
_mm_store_ps(dest[3], _mm_load_ps(mat[3]));
|
||||
#else
|
||||
glm_mat4_ucopy(mat, dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief make given matrix identity. It is identical with below,
|
||||
* but it is more easy to do that with this func especially for members
|
||||
* e.g. glm_mat4_identity(aStruct->aMatrix);
|
||||
*
|
||||
* @code
|
||||
* glm_mat4_copy(GLM_MAT4_IDENTITY, mat); // C only
|
||||
*
|
||||
* // or
|
||||
* mat4 mat = GLM_MAT4_IDENTITY_INIT;
|
||||
* @endcode
|
||||
*
|
||||
* @param[in, out] mat destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_identity(mat4 mat) {
|
||||
mat4 t = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_mat4_copy(t, mat);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief copy upper-left of mat4 to mat3
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_pick3(mat4 mat, mat3 dest) {
|
||||
dest[0][0] = mat[0][0];
|
||||
dest[0][1] = mat[0][1];
|
||||
dest[0][2] = mat[0][2];
|
||||
|
||||
dest[1][0] = mat[1][0];
|
||||
dest[1][1] = mat[1][1];
|
||||
dest[1][2] = mat[1][2];
|
||||
|
||||
dest[2][0] = mat[2][0];
|
||||
dest[2][1] = mat[2][1];
|
||||
dest[2][2] = mat[2][2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief copy upper-left of mat4 to mat3 (transposed)
|
||||
*
|
||||
* the postfix t stands for transpose
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_pick3t(mat4 mat, mat3 dest) {
|
||||
dest[0][0] = mat[0][0];
|
||||
dest[0][1] = mat[1][0];
|
||||
dest[0][2] = mat[2][0];
|
||||
|
||||
dest[1][0] = mat[0][1];
|
||||
dest[1][1] = mat[1][1];
|
||||
dest[1][2] = mat[2][1];
|
||||
|
||||
dest[2][0] = mat[0][2];
|
||||
dest[2][1] = mat[1][2];
|
||||
dest[2][2] = mat[2][2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief copy mat3 to mat4's upper-left
|
||||
*
|
||||
* @param[in] mat source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_ins3(mat3 mat, mat4 dest) {
|
||||
dest[0][0] = mat[0][0];
|
||||
dest[0][1] = mat[0][1];
|
||||
dest[0][2] = mat[0][2];
|
||||
|
||||
dest[1][0] = mat[1][0];
|
||||
dest[1][1] = mat[1][1];
|
||||
dest[1][2] = mat[1][2];
|
||||
|
||||
dest[2][0] = mat[2][0];
|
||||
dest[2][1] = mat[2][1];
|
||||
dest[2][2] = mat[2][2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply m1 and m2 to dest
|
||||
*
|
||||
* m1, m2 and dest matrices can be same matrix, it is possible to write this:
|
||||
*
|
||||
* @code
|
||||
* mat4 m = GLM_MAT4_IDENTITY_INIT;
|
||||
* glm_mat4_mul(m, m, m);
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] m1 left matrix
|
||||
* @param[in] m2 right matrix
|
||||
* @param[out] dest destination matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) {
|
||||
#ifdef __AVX__
|
||||
glm_mat4_mul_avx(m1, m2, dest);
|
||||
#elif defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_mul_sse2(m1, m2, dest);
|
||||
#elif defined( __ARM_NEON_FP )
|
||||
glm_mat4_mul_neon(m1, m2, dest);
|
||||
#else
|
||||
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
|
||||
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
|
||||
a20 = m1[2][0], a21 = m1[2][1], a22 = m1[2][2], a23 = m1[2][3],
|
||||
a30 = m1[3][0], a31 = m1[3][1], a32 = m1[3][2], a33 = m1[3][3],
|
||||
|
||||
b00 = m2[0][0], b01 = m2[0][1], b02 = m2[0][2], b03 = m2[0][3],
|
||||
b10 = m2[1][0], b11 = m2[1][1], b12 = m2[1][2], b13 = m2[1][3],
|
||||
b20 = m2[2][0], b21 = m2[2][1], b22 = m2[2][2], b23 = m2[2][3],
|
||||
b30 = m2[3][0], b31 = m2[3][1], b32 = m2[3][2], b33 = m2[3][3];
|
||||
|
||||
dest[0][0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;
|
||||
dest[0][1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;
|
||||
dest[0][2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;
|
||||
dest[0][3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;
|
||||
dest[1][0] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;
|
||||
dest[1][1] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;
|
||||
dest[1][2] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;
|
||||
dest[1][3] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;
|
||||
dest[2][0] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;
|
||||
dest[2][1] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;
|
||||
dest[2][2] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;
|
||||
dest[2][3] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;
|
||||
dest[3][0] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;
|
||||
dest[3][1] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;
|
||||
dest[3][2] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;
|
||||
dest[3][3] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief mupliply N mat4 matrices and store result in dest
|
||||
*
|
||||
* this function lets you multiply multiple (more than two or more...) matrices
|
||||
* <br><br>multiplication will be done in loop, this may reduce instructions
|
||||
* size but if <b>len</b> is too small then compiler may unroll whole loop,
|
||||
* usage:
|
||||
* @code
|
||||
* mat m1, m2, m3, m4, res;
|
||||
*
|
||||
* glm_mat4_mulN((mat4 *[]){&m1, &m2, &m3, &m4}, 4, res);
|
||||
* @endcode
|
||||
*
|
||||
* @warning matrices parameter is pointer array not mat4 array!
|
||||
*
|
||||
* @param[in] matrices mat4 * array
|
||||
* @param[in] len matrices count
|
||||
* @param[out] dest result
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mulN(mat4 * __restrict matrices[], int len, mat4 dest) {
|
||||
int i;
|
||||
|
||||
assert(len > 1 && "there must be least 2 matrices to go!");
|
||||
|
||||
glm_mat4_mul(*matrices[0],
|
||||
*matrices[1],
|
||||
dest);
|
||||
|
||||
for (i = 2; i < len; i++)
|
||||
glm_mat4_mul(dest,
|
||||
*matrices[i],
|
||||
dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply mat4 with vec4 (column vector) and store in dest vector
|
||||
*
|
||||
* @param[in] m mat4 (left)
|
||||
* @param[in] v vec4 (right, column vector)
|
||||
* @param[out] dest vec4 (result, column vector)
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_mulv_sse2(m, v, dest);
|
||||
#else
|
||||
vec4 res;
|
||||
res[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3];
|
||||
res[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3];
|
||||
res[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3];
|
||||
res[3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3];
|
||||
glm_vec4_copy(res, dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply vector with mat4's mat3 part(rotation)
|
||||
*
|
||||
* @param[in] m mat4(affine transform)
|
||||
* @param[in] v vec3
|
||||
* @param[out] dest vec3
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mulv3(mat4 m, vec3 v, vec3 dest) {
|
||||
vec3 res;
|
||||
res[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2];
|
||||
res[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2];
|
||||
res[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2];
|
||||
glm_vec_copy(res, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief transpose mat4 and store in dest
|
||||
*
|
||||
* source matrix will not be transposed unless dest is m
|
||||
*
|
||||
* @param[in] m matrix
|
||||
* @param[out] dest result
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_transpose_to(mat4 m, mat4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_transp_sse2(m, dest);
|
||||
#else
|
||||
dest[0][0] = m[0][0]; dest[1][0] = m[0][1];
|
||||
dest[0][1] = m[1][0]; dest[1][1] = m[1][1];
|
||||
dest[0][2] = m[2][0]; dest[1][2] = m[2][1];
|
||||
dest[0][3] = m[3][0]; dest[1][3] = m[3][1];
|
||||
dest[2][0] = m[0][2]; dest[3][0] = m[0][3];
|
||||
dest[2][1] = m[1][2]; dest[3][1] = m[1][3];
|
||||
dest[2][2] = m[2][2]; dest[3][2] = m[2][3];
|
||||
dest[2][3] = m[3][2]; dest[3][3] = m[3][3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief tranpose mat4 and store result in same matrix
|
||||
*
|
||||
* @param[in, out] m source and dest
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_transpose(mat4 m) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_transp_sse2(m, m);
|
||||
#else
|
||||
mat4 d;
|
||||
|
||||
glm_mat4_transpose_to(m, d);
|
||||
|
||||
glm__memcpy(float, m, d, sizeof(mat4));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief scale (multiply with scalar) matrix without simd optimization
|
||||
*
|
||||
* multiply matrix with scalar
|
||||
*
|
||||
* @param[in, out] m matrix
|
||||
* @param[in] s scalar
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_scale_p(mat4 m, float s) {
|
||||
m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; m[0][3] *= s;
|
||||
m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; m[1][3] *= s;
|
||||
m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; m[2][3] *= s;
|
||||
m[3][0] *= s; m[3][1] *= s; m[3][2] *= s; m[3][3] *= s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief scale (multiply with scalar) matrix
|
||||
*
|
||||
* multiply matrix with scalar
|
||||
*
|
||||
* @param[in, out] m matrix
|
||||
* @param[in] s scalar
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_scale(mat4 m, float s) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_scale_sse2(m, s);
|
||||
#else
|
||||
glm_mat4_scale_p(m, s);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief mat4 determinant
|
||||
*
|
||||
* @param[in] mat matrix
|
||||
*
|
||||
* @return determinant
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_mat4_det(mat4 mat) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
return glm_mat4_det_sse2(mat);
|
||||
#else
|
||||
/* [square] det(A) = det(At) */
|
||||
float t[6];
|
||||
float a = mat[0][0], b = mat[0][1], c = mat[0][2], d = mat[0][3],
|
||||
e = mat[1][0], f = mat[1][1], g = mat[1][2], h = mat[1][3],
|
||||
i = mat[2][0], j = mat[2][1], k = mat[2][2], l = mat[2][3],
|
||||
m = mat[3][0], n = mat[3][1], o = mat[3][2], p = mat[3][3];
|
||||
|
||||
t[0] = k * p - o * l;
|
||||
t[1] = j * p - n * l;
|
||||
t[2] = j * o - n * k;
|
||||
t[3] = i * p - m * l;
|
||||
t[4] = i * o - m * k;
|
||||
t[5] = i * n - m * j;
|
||||
|
||||
return a * (f * t[0] - g * t[1] + h * t[2])
|
||||
- b * (e * t[0] - g * t[3] + h * t[4])
|
||||
+ c * (e * t[1] - f * t[3] + h * t[5])
|
||||
- d * (e * t[2] - f * t[4] + g * t[5]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief inverse mat4 and store in dest
|
||||
*
|
||||
* this func uses reciprocal approximation without extra corrections
|
||||
* e.g Newton-Raphson. this should work faster than _precise,
|
||||
* to get precise value use _precise version
|
||||
*
|
||||
* @param[in] mat matrix
|
||||
* @param[out] dest inverse matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_inv(mat4 mat, mat4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_inv_sse2(mat, dest);
|
||||
#else
|
||||
float t[6];
|
||||
float det;
|
||||
float a = mat[0][0], b = mat[0][1], c = mat[0][2], d = mat[0][3],
|
||||
e = mat[1][0], f = mat[1][1], g = mat[1][2], h = mat[1][3],
|
||||
i = mat[2][0], j = mat[2][1], k = mat[2][2], l = mat[2][3],
|
||||
m = mat[3][0], n = mat[3][1], o = mat[3][2], p = mat[3][3];
|
||||
|
||||
t[0] = k * p - o * l; t[1] = j * p - n * l; t[2] = j * o - n * k;
|
||||
t[3] = i * p - m * l; t[4] = i * o - m * k; t[5] = i * n - m * j;
|
||||
|
||||
dest[0][0] = f * t[0] - g * t[1] + h * t[2];
|
||||
dest[1][0] =-(e * t[0] - g * t[3] + h * t[4]);
|
||||
dest[2][0] = e * t[1] - f * t[3] + h * t[5];
|
||||
dest[3][0] =-(e * t[2] - f * t[4] + g * t[5]);
|
||||
|
||||
dest[0][1] =-(b * t[0] - c * t[1] + d * t[2]);
|
||||
dest[1][1] = a * t[0] - c * t[3] + d * t[4];
|
||||
dest[2][1] =-(a * t[1] - b * t[3] + d * t[5]);
|
||||
dest[3][1] = a * t[2] - b * t[4] + c * t[5];
|
||||
|
||||
t[0] = g * p - o * h; t[1] = f * p - n * h; t[2] = f * o - n * g;
|
||||
t[3] = e * p - m * h; t[4] = e * o - m * g; t[5] = e * n - m * f;
|
||||
|
||||
dest[0][2] = b * t[0] - c * t[1] + d * t[2];
|
||||
dest[1][2] =-(a * t[0] - c * t[3] + d * t[4]);
|
||||
dest[2][2] = a * t[1] - b * t[3] + d * t[5];
|
||||
dest[3][2] =-(a * t[2] - b * t[4] + c * t[5]);
|
||||
|
||||
t[0] = g * l - k * h; t[1] = f * l - j * h; t[2] = f * k - j * g;
|
||||
t[3] = e * l - i * h; t[4] = e * k - i * g; t[5] = e * j - i * f;
|
||||
|
||||
dest[0][3] =-(b * t[0] - c * t[1] + d * t[2]);
|
||||
dest[1][3] = a * t[0] - c * t[3] + d * t[4];
|
||||
dest[2][3] =-(a * t[1] - b * t[3] + d * t[5]);
|
||||
dest[3][3] = a * t[2] - b * t[4] + c * t[5];
|
||||
|
||||
det = 1.0f / (a * dest[0][0] + b * dest[1][0]
|
||||
+ c * dest[2][0] + d * dest[3][0]);
|
||||
|
||||
glm_mat4_scale_p(dest, det);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief inverse mat4 precisely and store in dest
|
||||
*
|
||||
* this do same thing as glm_mat4_inv did. the only diff is this func uses
|
||||
* division instead of reciprocal approximation. Due to division this might
|
||||
* work slower than glm_mat4_inv
|
||||
*
|
||||
* @param[in] mat matrix
|
||||
* @param[out] dest inverse matrix
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_inv_precise(mat4 mat, mat4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_mat4_inv_precise_sse2(mat, dest);
|
||||
#else
|
||||
glm_mat4_inv(mat, dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief swap two matrix columns
|
||||
*
|
||||
* @param[in,out] mat matrix
|
||||
* @param[in] col1 col1
|
||||
* @param[in] col2 col2
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_swap_col(mat4 mat, int col1, int col2) {
|
||||
vec4 tmp;
|
||||
glm_vec4_copy(mat[col1], tmp);
|
||||
glm_vec4_copy(mat[col2], mat[col1]);
|
||||
glm_vec4_copy(tmp, mat[col2]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief swap two matrix rows
|
||||
*
|
||||
* @param[in,out] mat matrix
|
||||
* @param[in] row1 row1
|
||||
* @param[in] row2 row2
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_swap_row(mat4 mat, int row1, int row2) {
|
||||
vec4 tmp;
|
||||
tmp[0] = mat[0][row1];
|
||||
tmp[1] = mat[1][row1];
|
||||
tmp[2] = mat[2][row1];
|
||||
tmp[3] = mat[3][row1];
|
||||
|
||||
mat[0][row1] = mat[0][row2];
|
||||
mat[1][row1] = mat[1][row2];
|
||||
mat[2][row1] = mat[2][row2];
|
||||
mat[3][row1] = mat[3][row2];
|
||||
|
||||
mat[0][row2] = tmp[0];
|
||||
mat[1][row2] = tmp[1];
|
||||
mat[2][row2] = tmp[2];
|
||||
mat[3][row2] = tmp[3];
|
||||
}
|
||||
|
||||
#else
|
||||
#endif /* cglm_mat_h */
|
||||
212
include/cglm/quat.h
Normal file
212
include/cglm/quat.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros:
|
||||
GLM_QUAT_IDENTITY_INIT
|
||||
GLM_QUAT_IDENTITY
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE void glm_quat_identity(versor q);
|
||||
CGLM_INLINE void glm_quat(versor q, float angle, float x, float y, float z);
|
||||
CGLM_INLINE void glm_quatv(versor q, float angle, vec3 v);
|
||||
CGLM_INLINE float glm_quat_norm(versor q);
|
||||
CGLM_INLINE void glm_quat_normalize(versor q);
|
||||
CGLM_INLINE float glm_quat_dot(versor q, versor r);
|
||||
CGLM_INLINE void glm_quat_mulv(versor q1, versor q2, versor dest);
|
||||
CGLM_INLINE void glm_quat_mat4(versor q, mat4 dest);
|
||||
CGLM_INLINE void glm_quat_slerp(versor q, versor r, float t, versor dest);
|
||||
*/
|
||||
|
||||
#ifndef cglm_quat_h
|
||||
#define cglm_quat_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec4.h"
|
||||
|
||||
#ifdef CGLM_SSE_FP
|
||||
# include "simd/sse2/quat.h"
|
||||
#endif
|
||||
|
||||
#define GLM_QUAT_IDENTITY_INIT {0.0f, 0.0f, 0.0f, 1.0f}
|
||||
#define GLM_QUAT_IDENTITY (versor){0.0f, 0.0f, 0.0f, 1.0f}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_identity(versor q) {
|
||||
versor v = GLM_QUAT_IDENTITY_INIT;
|
||||
glm_vec4_copy(v, q);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat(versor q,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z) {
|
||||
float a, c, s;
|
||||
|
||||
a = angle * 0.5f;
|
||||
c = cosf(a);
|
||||
s = sinf(a);
|
||||
|
||||
q[0] = c;
|
||||
q[1] = s * x;
|
||||
q[2] = s * y;
|
||||
q[3] = s * z;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v) {
|
||||
float a, c, s;
|
||||
|
||||
a = angle * 0.5f;
|
||||
c = cosf(a);
|
||||
s = sinf(a);
|
||||
|
||||
q[0] = c;
|
||||
q[1] = s * v[0];
|
||||
q[2] = s * v[1];
|
||||
q[3] = s * v[2];
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_quat_norm(versor q) {
|
||||
return glm_vec4_norm(q);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_normalize(versor q) {
|
||||
float sum;
|
||||
|
||||
sum = q[0] * q[0] + q[1] * q[1]
|
||||
+ q[2] * q[2] + q[3] * q[3];
|
||||
|
||||
if (fabs(1.0f - sum) < 0.0001f)
|
||||
return;
|
||||
|
||||
glm_vec4_scale(q, 1.0f / sqrtf(sum), q);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_quat_dot(versor q, versor r) {
|
||||
return glm_vec4_dot(q, r);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_mulv(versor q1, versor q2, versor dest) {
|
||||
dest[0] = q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2] - q2[3] * q1[3];
|
||||
dest[1] = q2[0] * q1[1] + q2[1] * q1[0] - q2[2] * q1[3] + q2[3] * q1[2];
|
||||
dest[2] = q2[0] * q1[2] + q2[1] * q1[3] + q2[2] * q1[0] - q2[3] * q1[1];
|
||||
dest[3] = q2[0] * q1[3] - q2[1] * q1[2] + q2[2] * q1[1] + q2[3] * q1[0];
|
||||
|
||||
glm_quat_normalize(dest);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_mat4(versor q, mat4 dest) {
|
||||
float w, x, y, z;
|
||||
float xx, yy, zz;
|
||||
float xy, yz, xz;
|
||||
float wx, wy, wz;
|
||||
|
||||
w = q[0];
|
||||
x = q[1];
|
||||
y = q[2];
|
||||
z = q[3];
|
||||
|
||||
xx = 2.0f * x * x; xy = 2.0f * x * y; wx = 2.0f * w * x;
|
||||
yy = 2.0f * y * y; yz = 2.0f * y * z; wy = 2.0f * w * y;
|
||||
zz = 2.0f * z * z; xz = 2.0f * x * z; wz = 2.0f * w * z;
|
||||
|
||||
dest[0][0] = 1.0f - yy - zz;
|
||||
dest[1][1] = 1.0f - xx - zz;
|
||||
dest[2][2] = 1.0f - xx - yy;
|
||||
|
||||
dest[0][1] = xy + wz;
|
||||
dest[1][2] = yz + wx;
|
||||
dest[2][0] = xz + wy;
|
||||
|
||||
dest[1][0] = xy - wz;
|
||||
dest[2][1] = yz - wx;
|
||||
dest[0][2] = xz - wy;
|
||||
|
||||
dest[1][3] = 0.0f;
|
||||
dest[0][3] = 0.0f;
|
||||
dest[2][3] = 0.0f;
|
||||
dest[3][0] = 0.0f;
|
||||
dest[3][1] = 0.0f;
|
||||
dest[3][2] = 0.0f;
|
||||
dest[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_slerp(versor q,
|
||||
versor r,
|
||||
float t,
|
||||
versor dest) {
|
||||
/* https://en.wikipedia.org/wiki/Slerp */
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_quat_slerp_sse2(q, r, t, dest);
|
||||
#else
|
||||
float cosTheta, sinTheta, angle, a, b, c;
|
||||
|
||||
cosTheta = glm_quat_dot(q, r);
|
||||
if (cosTheta < 0.0f) {
|
||||
q[0] *= -1.0f;
|
||||
q[1] *= -1.0f;
|
||||
q[2] *= -1.0f;
|
||||
q[3] *= -1.0f;
|
||||
|
||||
cosTheta = -cosTheta;
|
||||
}
|
||||
|
||||
if (fabs(cosTheta) >= 1.0f) {
|
||||
dest[0] = q[0];
|
||||
dest[1] = q[1];
|
||||
dest[2] = q[2];
|
||||
dest[3] = q[3];
|
||||
return;
|
||||
}
|
||||
|
||||
sinTheta = sqrt(1.0f - cosTheta * cosTheta);
|
||||
|
||||
c = 1.0f - t;
|
||||
|
||||
/* LERP */
|
||||
/* TODO: FLT_EPSILON vs 0.001? */
|
||||
if (sinTheta < 0.001f) {
|
||||
dest[0] = c * q[0] + t * r[0];
|
||||
dest[1] = c * q[1] + t * r[1];
|
||||
dest[2] = c * q[2] + t * r[2];
|
||||
dest[3] = c * q[3] + t * r[3];
|
||||
return;
|
||||
}
|
||||
|
||||
/* SLERP */
|
||||
angle = acosf(cosTheta);
|
||||
a = sinf(c * angle);
|
||||
b = sinf(t * angle);
|
||||
|
||||
dest[0] = (q[0] * a + r[0] * b) / sinTheta;
|
||||
dest[1] = (q[1] * a + r[1] * b) / sinTheta;
|
||||
dest[2] = (q[2] * a + r[2] * b) / sinTheta;
|
||||
dest[3] = (q[3] * a + r[3] * b) / sinTheta;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* cglm_quat_h */
|
||||
63
include/cglm/simd/avx/affine.h
Normal file
63
include/cglm/simd/avx/affine.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_affine_mat_avx_h
|
||||
#define cglm_affine_mat_avx_h
|
||||
#ifdef __AVX__
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
|
||||
/* D = R * L (Column-Major) */
|
||||
|
||||
__m256 y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
|
||||
|
||||
y0 = _mm256_load_ps(m2[0]); /* h g f e d c b a */
|
||||
y1 = _mm256_load_ps(m2[2]); /* p o n m l k j i */
|
||||
|
||||
y2 = _mm256_load_ps(m1[0]); /* h g f e d c b a */
|
||||
y3 = _mm256_load_ps(m1[2]); /* p o n m l k j i */
|
||||
|
||||
y4 = _mm256_permute2f128_ps(y2, y2, 0b00000011); /* d c b a h g f e */
|
||||
y5 = _mm256_permute2f128_ps(y3, y3, 0b00000000); /* l k j i l k j i */
|
||||
|
||||
/* f f f f a a a a */
|
||||
/* g g g g c c c c */
|
||||
/* e e e e b b b b */
|
||||
y7 = _mm256_permute_ps(y0, 0b10101010);
|
||||
y6 = _mm256_permutevar_ps(y0, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
|
||||
y8 = _mm256_permutevar_ps(y0, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
|
||||
|
||||
_mm256_store_ps(dest[0],
|
||||
_mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
|
||||
_mm256_mul_ps(y4, y8)),
|
||||
_mm256_mul_ps(y5, y7)));
|
||||
|
||||
|
||||
/* n n n n i i i i */
|
||||
/* p p p p k k k k */
|
||||
/* m m m m j j j j */
|
||||
/* o o o o l l l l */
|
||||
y6 = _mm256_permutevar_ps(y1, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
|
||||
y7 = _mm256_permutevar_ps(y1, _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2));
|
||||
y8 = _mm256_permutevar_ps(y1, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
|
||||
y9 = _mm256_permutevar_ps(y1, _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3));
|
||||
|
||||
_mm256_store_ps(dest[2],
|
||||
_mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
|
||||
_mm256_mul_ps(y3, y7)),
|
||||
_mm256_add_ps(_mm256_mul_ps(y4, y8),
|
||||
_mm256_mul_ps(y5, y9))));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_affine_mat_avx_h */
|
||||
65
include/cglm/simd/avx/mat4.h
Normal file
65
include/cglm/simd/avx/mat4.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat_simd_avx_h
|
||||
#define cglm_mat_simd_avx_h
|
||||
#ifdef __AVX__
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mul_avx(mat4 m1, mat4 m2, mat4 dest) {
|
||||
/* D = R * L (Column-Major) */
|
||||
|
||||
__m256 y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
|
||||
|
||||
y0 = _mm256_load_ps(m2[0]); /* h g f e d c b a */
|
||||
y1 = _mm256_load_ps(m2[2]); /* p o n m l k j i */
|
||||
|
||||
y2 = _mm256_load_ps(m1[0]); /* h g f e d c b a */
|
||||
y3 = _mm256_load_ps(m1[2]); /* p o n m l k j i */
|
||||
|
||||
y4 = _mm256_permute2f128_ps(y2, y2, 0b00000011); /* d c b a h g f e */
|
||||
y5 = _mm256_permute2f128_ps(y3, y3, 0b00000011); /* l k j i p o n m */
|
||||
|
||||
/* f f f f a a a a */
|
||||
/* h h h h c c c c */
|
||||
/* e e e e b b b b */
|
||||
/* g g g g d d d d */
|
||||
y6 = _mm256_permutevar_ps(y0, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
|
||||
y7 = _mm256_permutevar_ps(y0, _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2));
|
||||
y8 = _mm256_permutevar_ps(y0, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
|
||||
y9 = _mm256_permutevar_ps(y0, _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3));
|
||||
|
||||
_mm256_store_ps(dest[0],
|
||||
_mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
|
||||
_mm256_mul_ps(y3, y7)),
|
||||
_mm256_add_ps(_mm256_mul_ps(y4, y8),
|
||||
_mm256_mul_ps(y5, y9))));
|
||||
|
||||
/* n n n n i i i i */
|
||||
/* p p p p k k k k */
|
||||
/* m m m m j j j j */
|
||||
/* o o o o l l l l */
|
||||
y6 = _mm256_permutevar_ps(y1, _mm256_set_epi32(1, 1, 1, 1, 0, 0, 0, 0));
|
||||
y7 = _mm256_permutevar_ps(y1, _mm256_set_epi32(3, 3, 3, 3, 2, 2, 2, 2));
|
||||
y8 = _mm256_permutevar_ps(y1, _mm256_set_epi32(0, 0, 0, 0, 1, 1, 1, 1));
|
||||
y9 = _mm256_permutevar_ps(y1, _mm256_set_epi32(2, 2, 2, 2, 3, 3, 3, 3));
|
||||
|
||||
_mm256_store_ps(dest[2],
|
||||
_mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(y2, y6),
|
||||
_mm256_mul_ps(y3, y7)),
|
||||
_mm256_add_ps(_mm256_mul_ps(y4, y8),
|
||||
_mm256_mul_ps(y5, y9))));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_mat_simd_avx_h */
|
||||
52
include/cglm/simd/intrin.h
Normal file
52
include/cglm/simd/intrin.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_intrin_h
|
||||
#define cglm_intrin_h
|
||||
|
||||
#if defined( _WIN32 )
|
||||
# if (defined(_M_AMD64) || defined(_M_X64)) || _M_IX86_FP == 2
|
||||
# define __SSE2__
|
||||
# elif _M_IX86_FP == 1
|
||||
# define __SSE__
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
# include <xmmintrin.h>
|
||||
# include <emmintrin.h>
|
||||
|
||||
/* float */
|
||||
# define _mm_shuffle1_ps(a, z, y, x, w) \
|
||||
_mm_shuffle_ps(a, a, _MM_SHUFFLE(z, y, x, w))
|
||||
|
||||
# define _mm_shuffle1_ps1(a, x) \
|
||||
_mm_shuffle_ps(a, a, _MM_SHUFFLE(x, x, x, x))
|
||||
|
||||
# define _mm_shuffle2_ps(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \
|
||||
_mm_shuffle1_ps(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \
|
||||
z1, y1, x1, w1)
|
||||
#endif
|
||||
|
||||
/* x86, x64 */
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
# define CGLM_SSE_FP 1
|
||||
#endif
|
||||
|
||||
#ifdef __AVX__
|
||||
# define CGLM_AVX_FP 1
|
||||
#endif
|
||||
|
||||
/* ARM Neon */
|
||||
#if defined(__ARM_NEON) && defined(__ARM_NEON_FP)
|
||||
# include <arm_neon.h>
|
||||
# define CGLM_NEON_FP 1
|
||||
#else
|
||||
# undef CGLM_NEON_FP
|
||||
#endif
|
||||
|
||||
#endif /* cglm_intrin_h */
|
||||
57
include/cglm/simd/neon/mat4.h
Normal file
57
include/cglm/simd/neon/mat4.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat4_neon_h
|
||||
#define cglm_mat4_neon_h
|
||||
#if defined(__ARM_NEON_FP)
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
|
||||
/* D = R * L (Column-Major) */
|
||||
float32x4_t l0, l1, l2, l3, r, d0, d1, d2, d3;
|
||||
|
||||
l0 = vld1q_f32(m2[0]);
|
||||
l1 = vld1q_f32(m2[1]);
|
||||
l2 = vld1q_f32(m2[2]);
|
||||
l3 = vld1q_f32(m2[3]);
|
||||
|
||||
r = vld1q_f32(m1[0]);
|
||||
d0 = vmulq_lane_f32(r, vget_low_f32(l0), 0);
|
||||
d1 = vmulq_lane_f32(r, vget_low_f32(l1), 0);
|
||||
d2 = vmulq_lane_f32(r, vget_low_f32(l2), 0);
|
||||
d3 = vmulq_lane_f32(r, vget_low_f32(l3), 0);
|
||||
|
||||
r = vld1q_f32(m1[1]);
|
||||
d0 = vmlaq_lane_f32(d0, r, vget_low_f32(l0), 1);
|
||||
d1 = vmlaq_lane_f32(d1, r, vget_low_f32(l1), 1);
|
||||
d2 = vmlaq_lane_f32(d2, r, vget_low_f32(l2), 1);
|
||||
d3 = vmlaq_lane_f32(d3, r, vget_low_f32(l3), 1);
|
||||
|
||||
r = vld1q_f32(m1[2]);
|
||||
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 0);
|
||||
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 0);
|
||||
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 0);
|
||||
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 0);
|
||||
|
||||
r = vld1q_f32(m1[3]);
|
||||
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 1);
|
||||
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 1);
|
||||
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 1);
|
||||
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 1);
|
||||
|
||||
vst1q_f32(dest[0], d0);
|
||||
vst1q_f32(dest[1], d1);
|
||||
vst1q_f32(dest[2], d2);
|
||||
vst1q_f32(dest[3], d3);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_mat4_neon_h */
|
||||
79
include/cglm/simd/sse2/affine.h
Normal file
79
include/cglm/simd/sse2/affine.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_affine_mat_sse2_h
|
||||
#define cglm_affine_mat_sse2_h
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
||||
/* D = R * L (Column-Major) */
|
||||
__m128 l0, l1, l2, l3, r;
|
||||
|
||||
l0 = _mm_load_ps(m1[0]);
|
||||
l1 = _mm_load_ps(m1[1]);
|
||||
l2 = _mm_load_ps(m1[2]);
|
||||
l3 = _mm_load_ps(m1[3]);
|
||||
|
||||
r = _mm_load_ps(m2[0]);
|
||||
_mm_store_ps(dest[0],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
|
||||
|
||||
r = _mm_load_ps(m2[1]);
|
||||
_mm_store_ps(dest[1],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
|
||||
|
||||
r = _mm_load_ps(m2[2]);
|
||||
_mm_store_ps(dest[2],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
|
||||
|
||||
r = _mm_load_ps(m2[3]);
|
||||
_mm_store_ps(dest[3],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_inv_tr_sse2(mat4 mat) {
|
||||
__m128 r0, r1, r2, r3, x0, x1;
|
||||
|
||||
r0 = _mm_load_ps(mat[0]);
|
||||
r1 = _mm_load_ps(mat[1]);
|
||||
r2 = _mm_load_ps(mat[2]);
|
||||
r3 = _mm_load_ps(mat[3]);
|
||||
x1 = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
_MM_TRANSPOSE4_PS(r0, r1, r2, x1);
|
||||
|
||||
x0 = _mm_add_ps(_mm_mul_ps(r0, _mm_shuffle1_ps(r3, 0, 0, 0, 0)),
|
||||
_mm_mul_ps(r1, _mm_shuffle1_ps(r3, 1, 1, 1, 1)));
|
||||
x0 = _mm_add_ps(x0, _mm_mul_ps(r2, _mm_shuffle1_ps(r3, 2, 2, 2, 2)));
|
||||
x0 = _mm_xor_ps(x0, _mm_set1_ps(-0.f));
|
||||
|
||||
x0 = _mm_add_ps(x0, x1);
|
||||
|
||||
_mm_store_ps(mat[0], r0);
|
||||
_mm_store_ps(mat[1], r1);
|
||||
_mm_store_ps(mat[2], r2);
|
||||
_mm_store_ps(mat[3], x0);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_affine_mat_sse2_h */
|
||||
61
include/cglm/simd/sse2/mat3.h
Normal file
61
include/cglm/simd/sse2/mat3.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat3_sse_h
|
||||
#define cglm_mat3_sse_h
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat3_mul_sse2(mat3 m1, mat3 m2, mat3 dest) {
|
||||
__m128 l0, l1, l2;
|
||||
__m128 r0, r1, r2;
|
||||
__m128 x0, x1, x2;
|
||||
|
||||
l0 = _mm_loadu_ps(m1[0]);
|
||||
l1 = _mm_loadu_ps(&m1[1][1]);
|
||||
l2 = _mm_set1_ps(m1[2][2]);
|
||||
|
||||
r0 = _mm_loadu_ps(m2[0]);
|
||||
r1 = _mm_loadu_ps(&m2[1][1]);
|
||||
r2 = _mm_set1_ps(m2[2][2]);
|
||||
|
||||
x1 = _mm_shuffle2_ps(l0, l1, 1, 0, 3, 3, 0, 3, 2, 0);
|
||||
x2 = _mm_shuffle2_ps(l1, l2, 0, 0, 3, 2, 0, 2, 1, 0);
|
||||
|
||||
x0 = _mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps(l0, 0, 2, 1, 0),
|
||||
_mm_shuffle1_ps(r0, 3, 0, 0, 0)),
|
||||
_mm_mul_ps(x1,
|
||||
_mm_shuffle2_ps(r0, r1, 0, 0, 1, 1, 2, 0, 0, 0)));
|
||||
|
||||
x0 = _mm_add_ps(x0,
|
||||
_mm_mul_ps(x2,
|
||||
_mm_shuffle2_ps(r0, r1, 1, 1, 2, 2, 2, 0, 0, 0)));
|
||||
|
||||
_mm_storeu_ps(dest[0], x0);
|
||||
|
||||
x0 = _mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps(l0, 1, 0, 2, 1),
|
||||
_mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 2, 3, 3))),
|
||||
_mm_mul_ps(_mm_shuffle1_ps(x1, 1, 0, 2, 1),
|
||||
_mm_shuffle1_ps(r1, 3, 3, 0, 0)));
|
||||
|
||||
x0 = _mm_add_ps(x0,
|
||||
_mm_mul_ps(_mm_shuffle1_ps(x2, 1, 0, 2, 1),
|
||||
_mm_shuffle_ps(r1, r2, _MM_SHUFFLE(0, 0, 1, 1))));
|
||||
|
||||
_mm_storeu_ps(&dest[1][1], x0);
|
||||
|
||||
dest[2][2] = m1[0][2] * m2[2][0]
|
||||
+ m1[1][2] * m2[2][1]
|
||||
+ m1[2][2] * m2[2][2];
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_mat3_sse_h */
|
||||
407
include/cglm/simd/sse2/mat4.h
Normal file
407
include/cglm/simd/sse2/mat4.h
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_mat_sse_h
|
||||
#define cglm_mat_sse_h
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_scale_sse2(mat4 m, float s){
|
||||
__m128 x0;
|
||||
x0 = _mm_set1_ps(s);
|
||||
|
||||
_mm_store_ps(m[0], _mm_mul_ps(_mm_load_ps(m[0]), x0));
|
||||
_mm_store_ps(m[1], _mm_mul_ps(_mm_load_ps(m[1]), x0));
|
||||
_mm_store_ps(m[2], _mm_mul_ps(_mm_load_ps(m[2]), x0));
|
||||
_mm_store_ps(m[3], _mm_mul_ps(_mm_load_ps(m[3]), x0));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_transp_sse2(mat4 m, mat4 dest){
|
||||
__m128 r0, r1, r2, r3;
|
||||
|
||||
r0 = _mm_load_ps(m[0]);
|
||||
r1 = _mm_load_ps(m[1]);
|
||||
r2 = _mm_load_ps(m[2]);
|
||||
r3 = _mm_load_ps(m[3]);
|
||||
|
||||
_MM_TRANSPOSE4_PS(r0, r1, r2, r3);
|
||||
|
||||
_mm_store_ps(dest[0], r0);
|
||||
_mm_store_ps(dest[1], r1);
|
||||
_mm_store_ps(dest[2], r2);
|
||||
_mm_store_ps(dest[3], r3);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
|
||||
/* D = R * L (Column-Major) */
|
||||
|
||||
__m128 l0, l1, l2, l3, r;
|
||||
|
||||
l0 = _mm_load_ps(m1[0]);
|
||||
l1 = _mm_load_ps(m1[1]);
|
||||
l2 = _mm_load_ps(m1[2]);
|
||||
l3 = _mm_load_ps(m1[3]);
|
||||
|
||||
r = _mm_load_ps(m2[0]);
|
||||
_mm_store_ps(dest[0],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
|
||||
r = _mm_load_ps(m2[1]);
|
||||
_mm_store_ps(dest[1],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
|
||||
r = _mm_load_ps(m2[2]);
|
||||
_mm_store_ps(dest[2],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
|
||||
|
||||
r = _mm_load_ps(m2[3]);
|
||||
_mm_store_ps(dest[3],
|
||||
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
|
||||
_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2),
|
||||
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) {
|
||||
__m128 x0, x1, x2;
|
||||
|
||||
x0 = _mm_load_ps(v);
|
||||
x1 = _mm_add_ps(_mm_mul_ps(_mm_load_ps(m[0]),
|
||||
_mm_shuffle1_ps1(x0, 0)),
|
||||
_mm_mul_ps(_mm_load_ps(m[1]),
|
||||
_mm_shuffle1_ps1(x0, 1)));
|
||||
|
||||
x2 = _mm_add_ps(_mm_mul_ps(_mm_load_ps(m[2]),
|
||||
_mm_shuffle1_ps1(x0, 2)),
|
||||
_mm_mul_ps(_mm_load_ps(m[3]),
|
||||
_mm_shuffle1_ps1(x0, 3)));
|
||||
|
||||
_mm_store_ps(dest, _mm_add_ps(x1, x2));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_mat4_det_sse2(mat4 mat) {
|
||||
__m128 r0, r1, r2, r3, x0, x1, x2;
|
||||
|
||||
/* 127 <- 0, [square] det(A) = det(At) */
|
||||
r0 = _mm_load_ps(mat[0]); /* d c b a */
|
||||
r1 = _mm_load_ps(mat[1]); /* h g f e */
|
||||
r2 = _mm_load_ps(mat[2]); /* l k j i */
|
||||
r3 = _mm_load_ps(mat[3]); /* p o n m */
|
||||
|
||||
/*
|
||||
t[1] = j * p - n * l;
|
||||
t[2] = j * o - n * k;
|
||||
t[3] = i * p - m * l;
|
||||
t[4] = i * o - m * k;
|
||||
*/
|
||||
x0 = _mm_sub_ps(_mm_mul_ps(_mm_shuffle1_ps(r2, 0, 0, 1, 1),
|
||||
_mm_shuffle1_ps(r3, 2, 3, 2, 3)),
|
||||
_mm_mul_ps(_mm_shuffle1_ps(r3, 0, 0, 1, 1),
|
||||
_mm_shuffle1_ps(r2, 2, 3, 2, 3)));
|
||||
/*
|
||||
t[0] = k * p - o * l;
|
||||
t[0] = k * p - o * l;
|
||||
t[5] = i * n - m * j;
|
||||
t[5] = i * n - m * j;
|
||||
*/
|
||||
x1 = _mm_sub_ps(_mm_mul_ps(_mm_shuffle1_ps(r2, 0, 0, 2, 2),
|
||||
_mm_shuffle1_ps(r3, 1, 1, 3, 3)),
|
||||
_mm_mul_ps(_mm_shuffle1_ps(r3, 0, 0, 2, 2),
|
||||
_mm_shuffle1_ps(r2, 1, 1, 3, 3)));
|
||||
|
||||
/*
|
||||
a * (f * t[0] - g * t[1] + h * t[2])
|
||||
- b * (e * t[0] - g * t[3] + h * t[4])
|
||||
+ c * (e * t[1] - f * t[3] + h * t[5])
|
||||
- d * (e * t[2] - f * t[4] + g * t[5])
|
||||
*/
|
||||
x2 = _mm_sub_ps(_mm_mul_ps(_mm_shuffle1_ps(r1, 0, 0, 0, 1),
|
||||
_mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0))),
|
||||
_mm_mul_ps(_mm_shuffle1_ps(r1, 1, 1, 2, 2),
|
||||
_mm_shuffle1_ps(x0, 3, 2, 2, 0)));
|
||||
|
||||
x2 = _mm_add_ps(x2,
|
||||
_mm_mul_ps(_mm_shuffle1_ps(r1, 2, 3, 3, 3),
|
||||
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1))));
|
||||
x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||
|
||||
x0 = _mm_mul_ps(r0, x2);
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 0, 1, 2, 3));
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 1, 3, 3, 1));
|
||||
|
||||
return _mm_cvtss_f32(x0);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_inv_sse2(mat4 mat, mat4 dest) {
|
||||
__m128 r0, r1, r2, r3,
|
||||
v0, v1, v2, v3,
|
||||
t0, t1, t2, t3, t4, t5,
|
||||
x0, x1, x2, x3, x4, x5, x6, x7;
|
||||
|
||||
/* 127 <- 0 */
|
||||
r0 = _mm_load_ps(mat[0]); /* d c b a */
|
||||
r1 = _mm_load_ps(mat[1]); /* h g f e */
|
||||
r2 = _mm_load_ps(mat[2]); /* l k j i */
|
||||
r3 = _mm_load_ps(mat[3]); /* p o n m */
|
||||
|
||||
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
|
||||
x1 = _mm_shuffle1_ps(x0, 1, 3, 3, 3); /* l p p p */
|
||||
x2 = _mm_shuffle1_ps(x0, 0, 2, 2, 2); /* k o o o */
|
||||
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
||||
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
||||
|
||||
/* t1[0] = k * p - o * l;
|
||||
t1[0] = k * p - o * l;
|
||||
t2[0] = g * p - o * h;
|
||||
t3[0] = g * l - k * h; */
|
||||
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
|
||||
|
||||
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
|
||||
x4 = _mm_shuffle1_ps(x4, 0, 2, 2, 2); /* j n n n */
|
||||
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
||||
|
||||
/* t1[1] = j * p - n * l;
|
||||
t1[1] = j * p - n * l;
|
||||
t2[1] = f * p - n * h;
|
||||
t3[1] = f * l - j * h; */
|
||||
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
|
||||
|
||||
/* t1[2] = j * o - n * k
|
||||
t1[2] = j * o - n * k;
|
||||
t2[2] = f * o - n * g;
|
||||
t3[2] = f * k - j * g; */
|
||||
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
|
||||
|
||||
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
||||
x7 = _mm_shuffle2_ps(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
|
||||
|
||||
/* t1[3] = i * p - m * l;
|
||||
t1[3] = i * p - m * l;
|
||||
t2[3] = e * p - m * h;
|
||||
t3[3] = e * l - i * h; */
|
||||
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
|
||||
|
||||
/* t1[4] = i * o - m * k;
|
||||
t1[4] = i * o - m * k;
|
||||
t2[4] = e * o - m * g;
|
||||
t3[4] = e * k - i * g; */
|
||||
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
|
||||
|
||||
/* t1[5] = i * n - m * j;
|
||||
t1[5] = i * n - m * j;
|
||||
t2[5] = e * n - m * f;
|
||||
t3[5] = e * j - i * f; */
|
||||
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
|
||||
|
||||
x0 = _mm_shuffle2_ps(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
|
||||
x1 = _mm_shuffle2_ps(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
|
||||
x2 = _mm_shuffle2_ps(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
|
||||
x3 = _mm_shuffle2_ps(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
|
||||
|
||||
/*
|
||||
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
||||
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
||||
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
||||
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
||||
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
|
||||
_mm_sub_ps(_mm_mul_ps(x1, t0),
|
||||
_mm_mul_ps(x2, t1)));
|
||||
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||
|
||||
/*
|
||||
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
||||
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
||||
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
||||
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
||||
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t0),
|
||||
_mm_mul_ps(x2, t3)));
|
||||
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
||||
|
||||
/*
|
||||
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
||||
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
||||
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
||||
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
||||
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t1),
|
||||
_mm_mul_ps(x1, t3)));
|
||||
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||
|
||||
/*
|
||||
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
||||
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
||||
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
||||
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
||||
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t2),
|
||||
_mm_mul_ps(x1, t4)));
|
||||
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
||||
|
||||
/* determinant */
|
||||
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
||||
|
||||
x0 = _mm_mul_ps(x0, r0);
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 0, 1, 2, 3));
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 1, 0, 0, 1));
|
||||
x0 = _mm_rcp_ps(x0);
|
||||
|
||||
_mm_store_ps(dest[0], _mm_mul_ps(v0, x0));
|
||||
_mm_store_ps(dest[1], _mm_mul_ps(v1, x0));
|
||||
_mm_store_ps(dest[2], _mm_mul_ps(v2, x0));
|
||||
_mm_store_ps(dest[3], _mm_mul_ps(v3, x0));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_mat4_inv_precise_sse2(mat4 mat, mat4 dest) {
|
||||
__m128 r0, r1, r2, r3,
|
||||
v0, v1, v2, v3,
|
||||
t0, t1, t2, t3, t4, t5,
|
||||
x0, x1, x2, x3, x4, x5, x6, x7;
|
||||
|
||||
/* 127 <- 0 */
|
||||
r0 = _mm_load_ps(mat[0]); /* d c b a */
|
||||
r1 = _mm_load_ps(mat[1]); /* h g f e */
|
||||
r2 = _mm_load_ps(mat[2]); /* l k j i */
|
||||
r3 = _mm_load_ps(mat[3]); /* p o n m */
|
||||
|
||||
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
|
||||
x1 = _mm_shuffle1_ps(x0, 1, 3, 3, 3); /* l p p p */
|
||||
x2 = _mm_shuffle1_ps(x0, 0, 2, 2, 2); /* k o o o */
|
||||
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
|
||||
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
|
||||
|
||||
/* t1[0] = k * p - o * l;
|
||||
t1[0] = k * p - o * l;
|
||||
t2[0] = g * p - o * h;
|
||||
t3[0] = g * l - k * h; */
|
||||
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
|
||||
|
||||
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
|
||||
x4 = _mm_shuffle1_ps(x4, 0, 2, 2, 2); /* j n n n */
|
||||
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
|
||||
|
||||
/* t1[1] = j * p - n * l;
|
||||
t1[1] = j * p - n * l;
|
||||
t2[1] = f * p - n * h;
|
||||
t3[1] = f * l - j * h; */
|
||||
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
|
||||
|
||||
/* t1[2] = j * o - n * k
|
||||
t1[2] = j * o - n * k;
|
||||
t2[2] = f * o - n * g;
|
||||
t3[2] = f * k - j * g; */
|
||||
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
|
||||
|
||||
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
|
||||
x7 = _mm_shuffle2_ps(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
|
||||
|
||||
/* t1[3] = i * p - m * l;
|
||||
t1[3] = i * p - m * l;
|
||||
t2[3] = e * p - m * h;
|
||||
t3[3] = e * l - i * h; */
|
||||
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
|
||||
|
||||
/* t1[4] = i * o - m * k;
|
||||
t1[4] = i * o - m * k;
|
||||
t2[4] = e * o - m * g;
|
||||
t3[4] = e * k - i * g; */
|
||||
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
|
||||
|
||||
/* t1[5] = i * n - m * j;
|
||||
t1[5] = i * n - m * j;
|
||||
t2[5] = e * n - m * f;
|
||||
t3[5] = e * j - i * f; */
|
||||
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
|
||||
|
||||
x0 = _mm_shuffle2_ps(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
|
||||
x1 = _mm_shuffle2_ps(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
|
||||
x2 = _mm_shuffle2_ps(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
|
||||
x3 = _mm_shuffle2_ps(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
|
||||
|
||||
/*
|
||||
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
|
||||
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
|
||||
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
|
||||
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
|
||||
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
|
||||
_mm_sub_ps(_mm_mul_ps(x1, t0),
|
||||
_mm_mul_ps(x2, t1)));
|
||||
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||
|
||||
/*
|
||||
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
|
||||
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
|
||||
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
|
||||
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
|
||||
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t0),
|
||||
_mm_mul_ps(x2, t3)));
|
||||
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
||||
|
||||
/*
|
||||
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
|
||||
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
|
||||
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
|
||||
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
|
||||
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t1),
|
||||
_mm_mul_ps(x1, t3)));
|
||||
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
|
||||
|
||||
/*
|
||||
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
|
||||
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
|
||||
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
|
||||
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
|
||||
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
|
||||
_mm_sub_ps(_mm_mul_ps(x0, t2),
|
||||
_mm_mul_ps(x1, t4)));
|
||||
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
|
||||
|
||||
/* determinant */
|
||||
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
|
||||
|
||||
x0 = _mm_mul_ps(x0, r0);
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 0, 1, 2, 3));
|
||||
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 1, 0, 0, 1));
|
||||
x0 = _mm_div_ps(_mm_set1_ps(1.0f), x0);
|
||||
|
||||
_mm_store_ps(dest[0], _mm_mul_ps(v0, x0));
|
||||
_mm_store_ps(dest[1], _mm_mul_ps(v1, x0));
|
||||
_mm_store_ps(dest[2], _mm_mul_ps(v2, x0));
|
||||
_mm_store_ps(dest[3], _mm_mul_ps(v3, x0));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_mat_sse_h */
|
||||
69
include/cglm/simd/sse2/quat.h
Normal file
69
include/cglm/simd/sse2/quat.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_quat_simd_h
|
||||
#define cglm_quat_simd_h
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
|
||||
#include "../../common.h"
|
||||
#include "../intrin.h"
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat_slerp_sse2(versor q,
|
||||
versor r,
|
||||
float t,
|
||||
versor dest) {
|
||||
/* https://en.wikipedia.org/wiki/Slerp */
|
||||
float cosTheta, sinTheta, angle, a, b, c;
|
||||
|
||||
__m128 xmm_q;
|
||||
|
||||
xmm_q = _mm_load_ps(q);
|
||||
|
||||
cosTheta = glm_vec4_dot(q, r);
|
||||
if (cosTheta < 0.0f) {
|
||||
_mm_store_ps(q,
|
||||
_mm_xor_ps(xmm_q,
|
||||
_mm_set1_ps(-0.f))) ;
|
||||
|
||||
cosTheta = -cosTheta;
|
||||
}
|
||||
|
||||
if (cosTheta >= 1.0f) {
|
||||
_mm_store_ps(dest, xmm_q);
|
||||
return;
|
||||
}
|
||||
|
||||
sinTheta = sqrtf(1.0f - cosTheta * cosTheta);
|
||||
|
||||
c = 1.0f - t;
|
||||
|
||||
/* LERP */
|
||||
if (sinTheta < 0.001f) {
|
||||
_mm_store_ps(dest, _mm_add_ps(_mm_mul_ps(_mm_set1_ps(c),
|
||||
xmm_q),
|
||||
_mm_mul_ps(_mm_set1_ps(t),
|
||||
_mm_load_ps(r))));
|
||||
return;
|
||||
}
|
||||
|
||||
/* SLERP */
|
||||
angle = acosf(cosTheta);
|
||||
a = sinf(c * angle);
|
||||
b = sinf(t * angle);
|
||||
|
||||
_mm_store_ps(dest,
|
||||
_mm_div_ps(_mm_add_ps(_mm_mul_ps(_mm_set1_ps(a),
|
||||
xmm_q),
|
||||
_mm_mul_ps(_mm_set1_ps(b),
|
||||
_mm_load_ps(r))),
|
||||
_mm_set1_ps(sinTheta)));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* cglm_quat_simd_h */
|
||||
30
include/cglm/types.h
Normal file
30
include/cglm/types.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_types_h
|
||||
#define cglm_types_h
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define CGLM_ALIGN(X) /* __declspec(align(X)) */
|
||||
#else
|
||||
# define CGLM_ALIGN(X) __attribute((aligned(X)))
|
||||
#endif
|
||||
|
||||
typedef float vec3[3];
|
||||
typedef int ivec3[3];
|
||||
typedef CGLM_ALIGN(16) float vec4[4];
|
||||
|
||||
typedef vec3 mat3[3];
|
||||
typedef vec4 mat4[4];
|
||||
|
||||
typedef vec4 versor;
|
||||
|
||||
#define CGLM_PI (float)M_PI
|
||||
#define CGLM_PI_2 (float)M_PI_2
|
||||
#define CGLM_PI_4 (float)M_PI_4
|
||||
|
||||
#endif /* cglm_types_h */
|
||||
64
include/cglm/util.h
Normal file
64
include/cglm/util.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE int glm_sign(int val);
|
||||
CGLM_INLINE float glm_rad(float deg);
|
||||
CGLM_INLINE float glm_deg(float rad);
|
||||
CGLM_INLINE void glm_make_rad(float *deg);
|
||||
CGLM_INLINE void glm_make_deg(float *rad);
|
||||
CGLM_INLINE float glm_pow2(float x);
|
||||
*/
|
||||
|
||||
#ifndef cglm_util_h
|
||||
#define cglm_util_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*!
|
||||
* @brief get sign of 32 bit integer as +1 or -1
|
||||
*
|
||||
* @param val integer value
|
||||
*/
|
||||
CGLM_INLINE
|
||||
int
|
||||
glm_sign(int val) {
|
||||
return ((val >> 31) - (-val >> 31));
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_rad(float deg) {
|
||||
return deg * CGLM_PI / 180.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_deg(float rad) {
|
||||
return rad * 180.0f / CGLM_PI;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_make_rad(float *deg) {
|
||||
*deg = *deg * CGLM_PI / 180.0f;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_make_deg(float *rad) {
|
||||
*rad = *rad * 180.0f / CGLM_PI;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_pow2(float x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
#endif /* cglm_util_h */
|
||||
163
include/cglm/vec3-ext.h
Normal file
163
include/cglm/vec3-ext.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief SIMD like functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_vec_mulv(vec3 a, vec3 b, vec3 d);
|
||||
CGLM_INLINE void glm_vec_broadcast(float val, vec3 d);
|
||||
CGLM_INLINE bool glm_vec_eq(vec3 v, float val);
|
||||
CGLM_INLINE bool glm_vec_eq_eps(vec4 v, float val);
|
||||
CGLM_INLINE bool glm_vec_eq_all(vec3 v);
|
||||
CGLM_INLINE bool glm_vec_eqv(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE bool glm_vec_eqv_eps(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE float glm_vec_max(vec3 v);
|
||||
CGLM_INLINE float glm_vec_min(vec3 v);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vec3_ext_h
|
||||
#define cglm_vec3_ext_h
|
||||
|
||||
#include "common.h"
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
/*!
|
||||
* @brief multiplies individual items, just for convenient like SIMD
|
||||
*
|
||||
* @param a vec1
|
||||
* @param b vec2
|
||||
* @param d vec3 = (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2])
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_mulv(vec3 a, vec3 b, vec3 d) {
|
||||
d[0] = a[0] * b[0];
|
||||
d[1] = a[1] * b[1];
|
||||
d[2] = a[2] * b[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief fill a vector with specified value
|
||||
*
|
||||
* @param val value
|
||||
* @param d dest
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_broadcast(float val, vec3 d) {
|
||||
d[0] = d[1] = d[2] = val;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to value (without epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
* @param val value
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec_eq(vec3 v, float val) {
|
||||
return v[0] == val && v[0] == v[1] && v[0] == v[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to value (with epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
* @param val value
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec_eq_eps(vec4 v, float val) {
|
||||
return fabsf(v[0] - val) <= FLT_EPSILON
|
||||
&& fabsf(v[1] - val) <= FLT_EPSILON
|
||||
&& fabsf(v[2] - val) <= FLT_EPSILON;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vectors members are equal (without epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec_eq_all(vec3 v) {
|
||||
return v[0] == v[1] && v[0] == v[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to another (without epsilon)
|
||||
*
|
||||
* @param v1 vector
|
||||
* @param v2 vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec_eqv(vec3 v1, vec3 v2) {
|
||||
return v1[0] == v2[0]
|
||||
&& v1[1] == v2[1]
|
||||
&& v1[2] == v2[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to another (with epsilon)
|
||||
*
|
||||
* @param v1 vector
|
||||
* @param v2 vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec_eqv_eps(vec3 v1, vec3 v2) {
|
||||
return fabsf(v1[0] - v2[0]) <= FLT_EPSILON
|
||||
&& fabsf(v1[1] - v2[1]) <= FLT_EPSILON
|
||||
&& fabsf(v1[2] - v2[2]) <= FLT_EPSILON;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief max value of vector
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_max(vec3 v) {
|
||||
float max;
|
||||
|
||||
max = v[0];
|
||||
if (v[1] > max)
|
||||
max = v[1];
|
||||
if (v[2] > max)
|
||||
max = v[2];
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief min value of vector
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_min(vec3 v) {
|
||||
float min;
|
||||
|
||||
min = v[0];
|
||||
if (v[1] < min)
|
||||
min = v[1];
|
||||
if (v[2] < min)
|
||||
min = v[2];
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
#endif /* cglm_vec3_ext_h */
|
||||
367
include/cglm/vec3.h
Normal file
367
include/cglm/vec3.h
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*!
|
||||
* vec3 functions dont have suffix e.g glm_vec_dot (not glm_vec3_dot)
|
||||
* all functions without suffix are vec3 functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros:
|
||||
glm_vec_dup(v, dest)
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE void glm_vec_copy(vec3 a, vec3 dest);
|
||||
CGLM_INLINE float glm_vec_dot(vec3 a, vec3 b);
|
||||
CGLM_INLINE void glm_vec_cross(vec3 a, vec3 b, vec3 d);
|
||||
CGLM_INLINE float glm_vec_norm2(vec3 v);
|
||||
CGLM_INLINE float glm_vec_norm(vec3 vec);
|
||||
CGLM_INLINE void glm_vec_add(vec3 v1, vec3 v2, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_sub(vec3 v1, vec3 v2, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_scale(vec3 v, float s, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_scale_as(vec3 v, float s, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_flipsign(vec3 v);
|
||||
CGLM_INLINE void glm_vec_normalize(vec3 v);
|
||||
CGLM_INLINE void glm_vec_normalize_to(vec3 vec, vec3 dest);
|
||||
CGLM_INLINE float glm_vec_distance(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE float glm_vec_angle(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE void glm_vec_rotate(vec3 v, float angle, vec3 axis);
|
||||
CGLM_INLINE void glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_proj(vec3 a, vec3 b, vec3 dest);
|
||||
CGLM_INLINE void glm_vec_center(vec3 v1, vec3 v2, vec3 dest);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vec3_h
|
||||
#define cglm_vec3_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec3-ext.h"
|
||||
#include "util.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glm_vec_dup(v, dest) glm_vec_copy(v, dest)
|
||||
|
||||
/*!
|
||||
* @brief copy all members of [a] to [dest]
|
||||
*
|
||||
* @param[in] a source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_copy(vec3 a, vec3 dest) {
|
||||
dest[0] = a[0];
|
||||
dest[1] = a[1];
|
||||
dest[2] = a[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief vec3 dot product
|
||||
*
|
||||
* @param[in] a vector1
|
||||
* @param[in] b vector2
|
||||
*
|
||||
* @return dot product
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_dot(vec3 a, vec3 b) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief vec3 cross product
|
||||
*
|
||||
* @param[in] a source 1
|
||||
* @param[in] b source 2
|
||||
* @param[out] d destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_cross(vec3 a, vec3 b, vec3 d) {
|
||||
/* (u2.v3 - u3.v2, u3.v1 - u1.v3, u1.v2 - u2.v1) */
|
||||
d[0] = a[1] * b[2] - a[2] * b[1];
|
||||
d[1] = a[2] * b[0] - a[0] * b[2];
|
||||
d[2] = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief norm * norm (magnitude) of vec
|
||||
*
|
||||
* we can use this func instead of calling norm * norm, because it would call
|
||||
* sqrtf fuction twice but with this func we can avoid func call, maybe this is
|
||||
* not good name for this func
|
||||
*
|
||||
* @param[in] v vector
|
||||
*
|
||||
* @return norm * norm
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_norm2(vec3 v) {
|
||||
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief norm (magnitude) of vec3
|
||||
*
|
||||
* @param[in] vec vector
|
||||
*
|
||||
* @return norm
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_norm(vec3 vec) {
|
||||
return sqrtf(glm_vec_norm2(vec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief add v2 vector to v1 vector store result in dest
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_add(vec3 v1, vec3 v2, vec3 dest) {
|
||||
dest[0] = v1[0] + v2[0];
|
||||
dest[1] = v1[1] + v2[1];
|
||||
dest[2] = v1[2] + v2[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief subtract v2 vector from v1 vector store result in dest
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_sub(vec3 v1, vec3 v2, vec3 dest) {
|
||||
dest[0] = v1[0] - v2[0];
|
||||
dest[1] = v1[1] - v2[1];
|
||||
dest[2] = v1[2] - v2[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply/scale vec3 vector with scalar: result = v * s
|
||||
*
|
||||
* @param[in] v vector
|
||||
* @param[in] s scalar
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_scale(vec3 v, float s, vec3 dest) {
|
||||
dest[0] = v[0] * s;
|
||||
dest[1] = v[1] * s;
|
||||
dest[2] = v[2] * s;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief make vec3 vector scale as specified: result = unit(v) * s
|
||||
*
|
||||
* @param[in] v vector
|
||||
* @param[in] s scalar
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_scale_as(vec3 v, float s, vec3 dest) {
|
||||
float norm;
|
||||
norm = glm_vec_norm(v);
|
||||
|
||||
if (norm == 0) {
|
||||
glm_vec_copy(v, dest);
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec_scale(v, s / norm, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief flip sign of all vec3 members
|
||||
*
|
||||
* @param[in, out] v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_flipsign(vec3 v) {
|
||||
v[0] = -v[0];
|
||||
v[1] = -v[1];
|
||||
v[2] = -v[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief normalize vec3 and store result in same vec
|
||||
*
|
||||
* @param[in, out] v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_normalize(vec3 v) {
|
||||
float norm;
|
||||
|
||||
norm = glm_vec_norm(v);
|
||||
|
||||
if (norm == 0.0f) {
|
||||
v[0] = v[1] = v[2] = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec_scale(v, 1.0f / norm, v);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief normalize vec3 to dest
|
||||
*
|
||||
* @param[in] vec source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_normalize_to(vec3 vec, vec3 dest) {
|
||||
float norm;
|
||||
|
||||
norm = glm_vec_norm(vec);
|
||||
|
||||
if (norm == 0.0f) {
|
||||
dest[0] = dest[1] = dest[2] = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec_scale(vec, 1.0f / norm, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief angle betwen two vector
|
||||
*
|
||||
* @return angle as radians
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_angle(vec3 v1, vec3 v2) {
|
||||
float norm;
|
||||
|
||||
/* maybe compiler generate approximation instruction (rcp) */
|
||||
norm = 1.0f / (glm_vec_norm(v1) * glm_vec_norm(v2));
|
||||
return acosf(glm_vec_dot(v1, v2) * norm);
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v);
|
||||
|
||||
/*!
|
||||
* @brief rotate vec3 around axis by angle using Rodrigues' rotation formula
|
||||
*
|
||||
* @param[in, out] v vector
|
||||
* @param[in] axis axis vector (must be unit vector)
|
||||
* @param[in] angle angle by radians
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_rotate(vec3 v, float angle, vec3 axis) {
|
||||
versor q;
|
||||
vec3 v1, v2, v3;
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
/* Right Hand, Rodrigues' rotation formula:
|
||||
v = v*cos(t) + (kxv)sin(t) + k*(k.v)(1 - cos(t))
|
||||
*/
|
||||
|
||||
/* quaternion */
|
||||
glm_quatv(q, angle, v);
|
||||
|
||||
glm_vec_scale(v, c, v1);
|
||||
|
||||
glm_vec_cross(axis, v, v2);
|
||||
glm_vec_scale(v2, s, v2);
|
||||
|
||||
glm_vec_scale(axis,
|
||||
glm_vec_dot(axis, v) * (1.0f - c),
|
||||
v3);
|
||||
|
||||
glm_vec_add(v1, v2, v1);
|
||||
glm_vec_add(v1, v3, v);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief apply rotation matrix to vector
|
||||
*
|
||||
* @param[in] m affine matrix or rot matrix
|
||||
* @param[in] v vector
|
||||
* @param[out] dest rotated vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest) {
|
||||
vec3 res, x, y, z;
|
||||
|
||||
glm_vec_normalize_to(m[0], x);
|
||||
glm_vec_normalize_to(m[1], y);
|
||||
glm_vec_normalize_to(m[2], z);
|
||||
|
||||
res[0] = x[0] * v[0] + y[0] * v[1] + z[0] * v[2];
|
||||
res[1] = x[1] * v[0] + y[1] * v[1] + z[1] * v[2];
|
||||
res[2] = x[2] * v[0] + y[2] * v[1] + z[2] * v[2];
|
||||
|
||||
glm_vec_copy(res, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief project a vector onto b vector
|
||||
*
|
||||
* @param[in] a vector1
|
||||
* @param[in] b vector2
|
||||
* @param[out] dest projected vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_proj(vec3 a, vec3 b, vec3 dest) {
|
||||
glm_vec_scale(b,
|
||||
glm_vec_dot(a, b) / glm_vec_norm2(b),
|
||||
dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief find center point of two vector
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @param[out] dest center point
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_center(vec3 v1, vec3 v2, vec3 dest) {
|
||||
glm_vec_add(v1, v2, dest);
|
||||
glm_vec_scale(dest, 0.5f, dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief distance between two vectors
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @return returns distance
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec_distance(vec3 v1, vec3 v2) {
|
||||
return sqrtf(glm_pow2(v2[0] - v1[0])
|
||||
+ glm_pow2(v2[1] - v1[1])
|
||||
+ glm_pow2(v2[2] - v1[2]));
|
||||
}
|
||||
|
||||
#endif /* cglm_vec3_h */
|
||||
177
include/cglm/vec4-ext.h
Normal file
177
include/cglm/vec4-ext.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief SIMD like functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_vec4_mulv(vec4 a, vec4 b, vec4 d);
|
||||
CGLM_INLINE void glm_vec4_broadcast(float val, vec4 d);
|
||||
CGLM_INLINE bool glm_vec4_eq(vec4 v, float val);
|
||||
CGLM_INLINE bool glm_vec4_eq_eps(vec4 v, float val);
|
||||
CGLM_INLINE bool glm_vec4_eq_all(vec4 v);
|
||||
CGLM_INLINE bool glm_vec4_eqv(vec4 v1, vec4 v2);
|
||||
CGLM_INLINE bool glm_vec4_eqv_eps(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE float glm_vec4_max(vec4 v);
|
||||
CGLM_INLINE float glm_vec4_min(vec4 v);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vec4_ext_h
|
||||
#define cglm_vec4_ext_h
|
||||
|
||||
#include "common.h"
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
/*!
|
||||
* @brief multiplies individual items, just for convenient like SIMD
|
||||
*
|
||||
* @param a v1
|
||||
* @param b v2
|
||||
* @param d v3 = (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3])
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_mulv(vec4 a, vec4 b, vec4 d) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(d, _mm_mul_ps(_mm_load_ps(a), _mm_load_ps(b)));
|
||||
#else
|
||||
d[0] = a[0] * b[0];
|
||||
d[1] = a[1] * b[1];
|
||||
d[2] = a[2] * b[2];
|
||||
d[3] = a[3] * b[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief fill a vector with specified value
|
||||
*
|
||||
* @param val value
|
||||
* @param d dest
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_broadcast(float val, vec4 d) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(d, _mm_set1_ps(val));
|
||||
#else
|
||||
d[0] = d[1] = d[2] = d[3] = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to value (without epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
* @param val value
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eq(vec4 v, float val) {
|
||||
return v[0] == val
|
||||
&& v[0] == v[1]
|
||||
&& v[0] == v[2]
|
||||
&& v[0] == v[3];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to value (with epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
* @param val value
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eq_eps(vec4 v, float val) {
|
||||
return fabsf(v[0] - val) <= FLT_EPSILON
|
||||
&& fabsf(v[1] - val) <= FLT_EPSILON
|
||||
&& fabsf(v[2] - val) <= FLT_EPSILON
|
||||
&& fabsf(v[3] - val) <= FLT_EPSILON;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vectors members are equal (without epsilon)
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eq_all(vec4 v) {
|
||||
return v[0] == v[1]
|
||||
&& v[0] == v[2]
|
||||
&& v[0] == v[3];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to another (without epsilon)
|
||||
*
|
||||
* @param v1 vector
|
||||
* @param v2 vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eqv(vec4 v1, vec4 v2) {
|
||||
return v1[0] == v2[0]
|
||||
&& v1[1] == v2[1]
|
||||
&& v1[2] == v2[2]
|
||||
&& v1[3] == v2[3];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief check if vector is equal to another (with epsilon)
|
||||
*
|
||||
* @param v1 vector
|
||||
* @param v2 vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eqv_eps(vec3 v1, vec3 v2) {
|
||||
return fabsf(v1[0] - v2[0]) <= FLT_EPSILON
|
||||
&& fabsf(v1[1] - v2[1]) <= FLT_EPSILON
|
||||
&& fabsf(v1[2] - v2[2]) <= FLT_EPSILON
|
||||
&& fabsf(v1[3] - v2[3]) <= FLT_EPSILON;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief max value of vector
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_max(vec4 v) {
|
||||
float max;
|
||||
|
||||
max = glm_vec_max(v);
|
||||
if (v[3] > max)
|
||||
max = v[3];
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief min value of vector
|
||||
*
|
||||
* @param v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_min(vec4 v) {
|
||||
float min;
|
||||
|
||||
min = glm_vec_min(v);
|
||||
if (v[3] < min)
|
||||
min = v[3];
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
#endif /* cglm_vec4_ext_h */
|
||||
|
||||
285
include/cglm/vec4.h
Normal file
285
include/cglm/vec4.h
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*!
|
||||
* vec3 functions dont have suffix e.g glm_vec_dot (not glm_vec3_dot)
|
||||
* all functions without suffix are vec3 functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Macros:
|
||||
glm_vec4_dup3(v, dest)
|
||||
glm_vec4_dup(v, dest)
|
||||
|
||||
Functions:
|
||||
CGLM_INLINE void glm_vec4_copy3(vec4 a, vec3 dest);
|
||||
CGLM_INLINE void glm_vec4_copy(vec4 v, vec4 dest);
|
||||
CGLM_INLINE float glm_vec4_dot(vec4 a, vec4 b);
|
||||
CGLM_INLINE float glm_vec4_norm2(vec4 v);
|
||||
CGLM_INLINE float glm_vec4_norm(vec4 vec);
|
||||
CGLM_INLINE void glm_vec4_add(vec4 v1, vec4 v2, vec4 dest);
|
||||
CGLM_INLINE void glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest);
|
||||
CGLM_INLINE void glm_vec4_scale(vec4 v, float s, vec4 dest);
|
||||
CGLM_INLINE void glm_vec4_scale_as(vec4 v, float s, vec4 dest);
|
||||
CGLM_INLINE void glm_vec4_flipsign(vec4 v);
|
||||
CGLM_INLINE void glm_vec4_normalize(vec4 v);
|
||||
CGLM_INLINE void glm_vec4_normalize_to(vec4 vec, vec4 dest);
|
||||
CGLM_INLINE float glm_vec4_distance(vec4 v1, vec4 v2);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vec4_h
|
||||
#define cglm_vec4_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec4-ext.h"
|
||||
#include "util.h"
|
||||
|
||||
/* DEPRECATED! use _copy, _ucopy versions */
|
||||
#define glm_vec4_dup3(v, dest) glm_vec4_copy3(v, dest)
|
||||
#define glm_vec4_dup(v, dest) glm_vec4_copy(v, dest)
|
||||
|
||||
/*!
|
||||
* @brief copy first 3 members of [a] to [dest]
|
||||
*
|
||||
* @param[in] a source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_copy3(vec4 a, vec3 dest) {
|
||||
dest[0] = a[0];
|
||||
dest[1] = a[1];
|
||||
dest[2] = a[2];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief copy all members of [a] to [dest]
|
||||
*
|
||||
* @param[in] v source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_copy(vec4 v, vec4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest, _mm_load_ps(v));
|
||||
#else
|
||||
dest[0] = v[0];
|
||||
dest[1] = v[1];
|
||||
dest[2] = v[2];
|
||||
dest[3] = v[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief vec4 dot product
|
||||
*
|
||||
* @param[in] a vector1
|
||||
* @param[in] b vector2
|
||||
*
|
||||
* @return dot product
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_dot(vec4 a, vec4 b) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief norm * norm (magnitude) of vec
|
||||
*
|
||||
* we can use this func instead of calling norm * norm, because it would call
|
||||
* sqrtf fuction twice but with this func we can avoid func call, maybe this is
|
||||
* not good name for this func
|
||||
*
|
||||
* @param[in] v vec4
|
||||
*
|
||||
* @return norm * norm
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_norm2(vec4 v) {
|
||||
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief norm (magnitude) of vec4
|
||||
*
|
||||
* @param[in] vec vector
|
||||
*
|
||||
* @return norm
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_norm(vec4 vec) {
|
||||
return sqrtf(glm_vec4_norm2(vec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief add v2 vector to v1 vector store result in dest
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_add(vec4 v1, vec4 v2, vec4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest,
|
||||
_mm_add_ps(_mm_load_ps(v1),
|
||||
_mm_load_ps(v2)));
|
||||
#else
|
||||
dest[0] = v1[0] + v2[0];
|
||||
dest[1] = v1[1] + v2[1];
|
||||
dest[2] = v1[2] + v2[2];
|
||||
dest[3] = v1[3] + v2[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief subtract v2 vector from v1 vector store result in dest
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest,
|
||||
_mm_sub_ps(_mm_load_ps(v1),
|
||||
_mm_load_ps(v2)));
|
||||
#else
|
||||
dest[0] = v1[0] - v2[0];
|
||||
dest[1] = v1[1] - v2[1];
|
||||
dest[2] = v1[2] - v2[2];
|
||||
dest[3] = v1[3] - v2[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief multiply/scale vec4 vector with scalar: result = v * s
|
||||
*
|
||||
* @param[in] v vector
|
||||
* @param[in] s scalar
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_scale(vec4 v, float s, vec4 dest) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(dest,
|
||||
_mm_mul_ps(_mm_load_ps(v),
|
||||
_mm_set1_ps(s)));
|
||||
#else
|
||||
dest[0] = v[0] * s;
|
||||
dest[1] = v[1] * s;
|
||||
dest[2] = v[2] * s;
|
||||
dest[3] = v[3] * s;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief make vec4 vector scale as specified: result = unit(v) * s
|
||||
*
|
||||
* @param[in] v vector
|
||||
* @param[in] s scalar
|
||||
* @param[out] dest destination vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_scale_as(vec4 v, float s, vec4 dest) {
|
||||
float norm;
|
||||
norm = glm_vec4_norm(v);
|
||||
|
||||
if (norm == 0) {
|
||||
glm_vec4_copy(v, dest);
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec4_scale(v, s / norm, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief flip sign of all vec4 members
|
||||
*
|
||||
* @param[in, out] v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_flipsign(vec4 v) {
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
_mm_store_ps(v, _mm_xor_ps(_mm_load_ps(v),
|
||||
_mm_set1_ps(-0.0f)));
|
||||
#else
|
||||
v[0] = -v[0];
|
||||
v[1] = -v[1];
|
||||
v[2] = -v[2];
|
||||
v[3] = -v[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief normalize vec4 and store result in same vec
|
||||
*
|
||||
* @param[in, out] v vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_normalize(vec4 v) {
|
||||
float norm;
|
||||
|
||||
norm = glm_vec4_norm(v);
|
||||
|
||||
if (norm == 0.0f) {
|
||||
v[0] = v[1] = v[2] = v[3] = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec4_scale(v, 1.0f / norm, v);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief normalize vec4 to dest
|
||||
*
|
||||
* @param[in] vec source
|
||||
* @param[out] dest destination
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec4_normalize_to(vec4 vec, vec4 dest) {
|
||||
float norm;
|
||||
|
||||
norm = glm_vec4_norm(vec);
|
||||
|
||||
if (norm == 0.0f) {
|
||||
dest[0] = dest[1] = dest[2] = dest[3] = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
glm_vec4_scale(vec, 1.0f / norm, dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief distance between two vectors
|
||||
*
|
||||
* @param[in] v1 vector1
|
||||
* @param[in] v2 vector2
|
||||
* @return returns distance
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_vec4_distance(vec4 v1, vec4 v2) {
|
||||
return sqrtf(glm_pow2(v2[0] - v1[0])
|
||||
+ glm_pow2(v2[1] - v1[1])
|
||||
+ glm_pow2(v2[2] - v1[2])
|
||||
+ glm_pow2(v2[3] - v1[3]));
|
||||
}
|
||||
|
||||
#endif /* cglm_vec4_h */
|
||||
15
include/cglm/version.h
Normal file
15
include/cglm/version.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_version_h
|
||||
#define cglm_version_h
|
||||
|
||||
#define CGLM_VERSION_MAJOR 0
|
||||
#define CGLM_VERSION_MINOR 2
|
||||
#define CGLM_VERSION_PATCH 1
|
||||
|
||||
#endif /* cglm_version_h */
|
||||
Reference in New Issue
Block a user