Merge branch 'master' into vec2_mat2

This commit is contained in:
Recep Aslantas
2019-08-22 15:16:35 +03:00
committed by GitHub
57 changed files with 5333 additions and 153 deletions

View File

@@ -8,6 +8,8 @@
#ifndef cglm_bezier_h
#define cglm_bezier_h
#include "common.h"
#define GLM_BEZIER_MAT_INIT {{-1.0f, 3.0f, -3.0f, 1.0f}, \
{ 3.0f, -6.0f, 3.0f, 0.0f}, \
{-3.0f, 3.0f, 0.0f, 0.0f}, \

View File

@@ -47,7 +47,7 @@ glmc_euler_yxz(vec3 angles, mat4 dest);
CGLM_EXPORT
void
glmc_euler_by_order(vec3 angles, glm_euler_sq axis, mat4 dest);
glmc_euler_by_order(vec3 angles, glm_euler_seq axis, mat4 dest);
#ifdef __cplusplus
}

View File

@@ -91,7 +91,7 @@ glmc_quat_angle(versor q);
CGLM_EXPORT
void
glmc_quat_axis(versor q, versor dest);
glmc_quat_axis(versor q, vec3 dest);
CGLM_EXPORT
void

View File

@@ -7,48 +7,37 @@
/*
Functions:
CGLM_INLINE void glm_frustum(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
CGLM_INLINE void glm_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal,
mat4 dest)
CGLM_INLINE void glm_ortho(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
CGLM_INLINE void glm_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
CGLM_INLINE void glm_ortho_aabb_pz(vec3 box[2], float padding, 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_ortho_default_s(float aspect, float size, mat4 dest)
CGLM_INLINE void glm_perspective(float fovy,
float aspect,
float nearVal,
float farVal,
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_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)
CGLM_INLINE void glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup(vec3 eye, vec3 dir, mat4 dest)
CGLM_INLINE void glm_persp_decomp(mat4 proj,
float *nearVal,
float *farVal,
float *top,
float *bottom,
float *left,
float *right)
float *nearVal, float *farVal,
float *top, float *bottom,
float *left, float *right)
CGLM_INLINE void glm_persp_decompv(mat4 proj, float dest[6])
CGLM_INLINE void glm_persp_decomp_x(mat4 proj, float *left, float *right)
CGLM_INLINE void glm_persp_decomp_y(mat4 proj, float *top, float *bottom)
CGLM_INLINE void glm_persp_decomp_z(mat4 proj,
float *nearVal,
float *farVal)
CGLM_INLINE void glm_persp_decomp_z(mat4 proj, float *nearv, float *farv)
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float *farVal)
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float *nearVal)
CGLM_INLINE float glm_persp_fovy(mat4 proj)
@@ -75,12 +64,9 @@
*/
CGLM_INLINE
void
glm_frustum(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
glm_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal,
mat4 dest) {
float rl, tb, fn, nv;
@@ -113,12 +99,9 @@ glm_frustum(float left,
*/
CGLM_INLINE
void
glm_ortho(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
glm_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal,
mat4 dest) {
float rl, tb, fn;
@@ -218,9 +201,7 @@ glm_ortho_default(float aspect, mat4 dest) {
*/
CGLM_INLINE
void
glm_ortho_default_s(float aspect,
float size,
mat4 dest) {
glm_ortho_default_s(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho(-size * aspect,
size * aspect,
@@ -420,12 +401,9 @@ glm_look_anyup(vec3 eye, vec3 dir, mat4 dest) {
CGLM_INLINE
void
glm_persp_decomp(mat4 proj,
float * __restrict nearVal,
float * __restrict farVal,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
float * __restrict right) {
float * __restrict nearVal, float * __restrict farVal,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;

View File

@@ -28,6 +28,9 @@
# define CGLM_INLINE static inline __attribute((always_inline))
#endif
#define GLM_SHUFFLE4(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
#define GLM_SHUFFLE3(z, y, x) (((z) << 4) | ((y) << 2) | (x))
#include "types.h"
#include "simd/intrin.h"

View File

@@ -15,10 +15,10 @@
/*
Types:
enum glm_euler_sq
enum glm_euler_seq
Functions:
CGLM_INLINE glm_euler_sq glm_euler_order(int newOrder[3]);
CGLM_INLINE glm_euler_seq 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_xyz(vec3 angles, mat4 dest);
@@ -28,7 +28,7 @@
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 ord,
glm_euler_seq ord,
mat4 dest);
*/
@@ -41,24 +41,26 @@
* 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;
* glm_euler_seq order;
* order = orderVec[0] | orderVec[1] << 2 | orderVec[2] << 4;
* @endcode
* you may need to explicit cast if required
*/
typedef enum glm_euler_sq {
typedef enum glm_euler_seq {
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;
} glm_euler_seq;
typedef glm_euler_seq glm_euler_sq;
CGLM_INLINE
glm_euler_sq
glm_euler_seq
glm_euler_order(int ord[3]) {
return (glm_euler_sq)(ord[0] << 0 | ord[1] << 2 | ord[2] << 4);
return (glm_euler_seq)(ord[0] << 0 | ord[1] << 2 | ord[2] << 4);
}
/*!
@@ -352,7 +354,7 @@ glm_euler_zyx(vec3 angles, mat4 dest) {
*/
CGLM_INLINE
void
glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest) {
glm_euler_by_order(vec3 angles, glm_euler_seq ord, mat4 dest) {
float cx, cy, cz,
sx, sy, sz;

View File

@@ -65,7 +65,7 @@
* Exracted planes order: [left, right, bottom, top, near, far]
*
* @param[in] m matrix (see brief)
* @param[out] dest exracted view frustum planes (see brief)
* @param[out] dest extracted view frustum planes (see brief)
*/
CGLM_INLINE
void

View File

@@ -25,7 +25,7 @@
/*!
* @brief normalizes a plane
*
* @param[in, out] plane pnale to normalize
* @param[in, out] plane plane to normalize
*/
CGLM_INLINE
void

View File

@@ -8,6 +8,7 @@
#ifndef cglm_project_h
#define cglm_project_h
#include "common.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"

View File

@@ -29,7 +29,7 @@
CGLM_INLINE void glm_quat_imagn(versor q, vec3 dest);
CGLM_INLINE float glm_quat_imaglen(versor q);
CGLM_INLINE float glm_quat_angle(versor q);
CGLM_INLINE void glm_quat_axis(versor q, versor dest);
CGLM_INLINE void glm_quat_axis(versor q, vec3 dest);
CGLM_INLINE void glm_quat_mul(versor p, versor q, versor dest);
CGLM_INLINE void glm_quat_mat4(versor q, mat4 dest);
CGLM_INLINE void glm_quat_mat4t(versor q, mat4 dest);
@@ -233,7 +233,7 @@ glm_quat_normalize_to(versor q, versor dest) {
dot = glm_vec4_norm2(q);
if (dot <= 0.0f) {
glm_quat_identity(q);
glm_quat_identity(dest);
return;
}
@@ -388,7 +388,7 @@ glm_quat_angle(versor q) {
*/
CGLM_INLINE
void
glm_quat_axis(versor q, versor dest) {
glm_quat_axis(versor q, vec3 dest) {
glm_quat_imagn(q, dest);
}

36
include/cglm/struct.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_structs_h
#define cglm_structs_h
#ifdef __cplusplus
extern "C" {
#endif
#include "cglm.h"
#include "types-struct.h"
#include "struct/vec3.h"
#include "struct/vec4.h"
#include "struct/mat3.h"
#include "struct/mat4.h"
#include "struct/affine.h"
#include "struct/frustum.h"
#include "struct/plane.h"
#include "struct/box.h"
#include "struct/color.h"
#include "struct/io.h"
#include "struct/cam.h"
#include "struct/quat.h"
#include "struct/euler.h"
#include "struct/project.h"
#include "struct/sphere.h"
#include "struct/curve.h"
#ifdef __cplusplus
}
#endif
#endif /* cglm_structs_h */

View File

@@ -0,0 +1,337 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE mat4s glms_translate(mat4s m, vec3s v);
CGLM_INLINE mat4s glms_translate_x(mat4s m, float x);
CGLM_INLINE mat4s glms_translate_y(mat4s m, float y);
CGLM_INLINE mat4s glms_translate_z(mat4s m, float z);
CGLM_INLINE mat4s glms_translate_make(vec3s v);
CGLM_INLINE mat4s glms_scale_to(mat4s m, vec3s v);
CGLM_INLINE mat4s glms_scale_make(vec3s v);
CGLM_INLINE mat4s glms_scale(mat4s m, vec3s v);
CGLM_INLINE mat4s glms_scale_uni(mat4s m, float s);
CGLM_INLINE mat4s glmx_rotate_x(mat4s m, float angle);
CGLM_INLINE mat4s glms_rotate_y(mat4s m, float angle);
CGLM_INLINE mat4s glms_rotate_z(mat4s m, float angle);
CGLM_INLINE mat4s glms_rotate_make(float angle, vec3s axis);
CGLM_INLINE mat4s glms_rotate(mat4s m, float angle, vec3s axis);
CGLM_INLINE mat4s glms_rotate_at(mat4s m, vec3s pivot, float angle, vec3s axis);
CGLM_INLINE mat4s glms_rotate_atm(mat4s m, vec3s pivot, float angle, vec3s axis);
CGLM_INLINE vec3s glms_decompose_scalev(mat4s m);
CGLM_INLINE bool glms_uniscaled(mat4s m);
CGLM_INLINE void glms_decompose_rs(mat4s m, mat4s * r, vec3s * s);
CGLM_INLINE void glms_decompose(mat4s m, vec4s t, mat4s * r, vec3s * s);
*/
#ifndef cglms_affines_h
#define cglms_affines_h
#include "../common.h"
#include "../types-struct.h"
#include "../affine.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
CGLM_INLINE
mat4s
glms_mat4_mul(mat4s m1, mat4s m2);
/*!
* @brief translate existing transform matrix by v vector
* and stores result in same matrix
*
* @param[in] m affine transfrom
* @param[in] v translate vector [x, y, z]
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_translate(mat4s m, vec3s v) {
glm_translate(m.raw, v.raw);
return m;
}
/*!
* @brief translate existing transform matrix by x factor
*
* @param[in] m affine transfrom
* @param[in] x x factor
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_translate_x(mat4s m, float x) {
glm_translate_x(m.raw, x);
return m;
}
/*!
* @brief translate existing transform matrix by y factor
*
* @param[in] m affine transfrom
* @param[in] y y factor
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_translate_y(mat4s m, float y) {
glm_translate_y(m.raw, y);
return m;
}
/*!
* @brief translate existing transform matrix by z factor
*
* @param[in] m affine transfrom
* @param[in] z z factor
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_translate_z(mat4s m, float z) {
glm_translate_z(m.raw, z);
return m;
}
/*!
* @brief creates NEW translate transform matrix by v vector
*
* @param[in] v translate vector [x, y, z]
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_translate_make(vec3s v) {
mat4s m;
glm_translate_make(m.raw, v.raw);
return m;
}
/*!
* @brief creates NEW scale matrix by v vector
*
* @param[in] v scale vector [x, y, z]
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_scale_make(vec3s v) {
mat4s m;
glm_scale_make(m.raw, v.raw);
return m;
}
/*!
* @brief scales existing transform matrix by v vector
* and stores result in same matrix
*
* @param[in] m affine transfrom
* @param[in] v scale vector [x, y, z]
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_scale(mat4s m, vec3s v) {
mat4s r;
glm_scale_to(m.raw, v.raw, r.raw);
return r;
}
/*!
* @brief applies uniform scale to existing transform matrix v = [s, s, s]
* and stores result in same matrix
*
* @param[in] m affine transfrom
* @param[in] s scale factor
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_scale_uni(mat4s m, float s) {
glm_scale_uni(m.raw, s);
return m;
}
/*!
* @brief rotate existing transform matrix around X axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @returns rotated matrix
*/
CGLM_INLINE
mat4s
glmx_rotate_x(mat4s m, float angle) {
mat4s r;
glm_rotate_x(m.raw, angle, r.raw);
return r;
}
/*!
* @brief rotate existing transform matrix around Y axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @returns rotated matrix
*/
CGLM_INLINE
mat4s
glms_rotate_y(mat4s m, float angle) {
mat4s r;
glm_rotate_y(m.raw, angle, r.raw);
return r;
}
/*!
* @brief rotate existing transform matrix around Z axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @returns rotated matrix
*/
CGLM_INLINE
mat4s
glms_rotate_z(mat4s m, float angle) {
mat4s r;
glm_rotate_z(m.raw, angle, r.raw);
return r;
}
/*!
* @brief creates NEW rotation matrix by angle and axis
*
* axis will be normalized so you don't need to normalize it
*
* @param[in] angle angle (radians)
* @param[in] axis axis
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_rotate_make(float angle, vec3s axis) {
mat4s m;
glm_rotate_make(m.raw, angle, axis.raw);
return m;
}
/*!
* @brief rotate existing transform matrix around given axis by angle
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_rotate(mat4s m, float angle, vec3s axis) {
glm_rotate(m.raw, angle, axis.raw);
return m;
}
/*!
* @brief rotate existing transform
* around given axis by angle at given pivot point (rotation center)
*
* @param[in] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_rotate_at(mat4s m, vec3s pivot, float angle, vec3s axis) {
glm_rotate_at(m.raw, pivot.raw, angle, axis.raw);
return m;
}
/*!
* @brief creates NEW rotation matrix by angle and axis at given point
*
* this creates rotation matrix, it assumes you don't have a matrix
*
* this should work faster than glm_rotate_at because it reduces
* one glm_translate.
*
* @param[in] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
* @returns affine transfrom
*/
CGLM_INLINE
mat4s
glms_rotate_atm(mat4s m, vec3s pivot, float angle, vec3s axis) {
glm_rotate_atm(m.raw, pivot.raw, angle, axis.raw);
return m;
}
/*!
* @brief decompose scale vector
*
* @param[in] m affine transform
* @returns scale vector (Sx, Sy, Sz)
*/
CGLM_INLINE
vec3s
glms_decompose_scalev(mat4s m) {
vec3s r;
glm_decompose_scalev(m.raw, r.raw);
return r;
}
/*!
* @brief returns true if matrix is uniform scaled. This is helpful for
* creating normal matrix.
*
* @param[in] m m
*
* @return boolean
*/
CGLM_INLINE
bool
glms_uniscaled(mat4s m) {
return glm_uniscaled(m.raw);
}
/*!
* @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
glms_decompose_rs(mat4s m, mat4s * __restrict r, vec3s * __restrict s) {
glm_decompose_rs(m.raw, r->raw, s->raw);
}
/*!
* @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
glms_decompose(mat4s m, vec4s * __restrict t, mat4s * __restrict r, vec3s * __restrict s) {
glm_decompose(m.raw, t->raw, r->raw, s->raw);
}
#endif /* cglms_affines_h */

256
include/cglm/struct/box.h Normal file
View File

@@ -0,0 +1,256 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_boxs_h
#define cglms_boxs_h
#include "../common.h"
#include "../types-struct.h"
#include "../box.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
/*!
* @brief apply transform to Axis-Aligned Bounding Box
*
* @param[in] box bounding box
* @param[in] m transform matrix
* @param[out] dest transformed bounding box
*/
CGLM_INLINE
void
glms_aabb_transform(vec3s box[2], mat4s m, vec3s dest[2]) {
vec3 rawBox[2];
vec3 rawDest[2];
glms_vec3_unpack(rawBox, box, 2);
glm_aabb_transform(rawBox, m.raw, rawDest);
glms_vec3_pack(dest, rawDest, 2);
}
/*!
* @brief merges two AABB bounding box and creates new one
*
* two box must be in same space, if one of box is in different space then
* you should consider to convert it's space by glm_box_space
*
* @param[in] box1 bounding box 1
* @param[in] box2 bounding box 2
* @param[out] dest merged bounding box
*/
CGLM_INLINE
void
glms_aabb_merge(vec3s box1[2], vec3s box2[2], vec3s dest[2]) {
vec3 rawBox1[2];
vec3 rawBox2[2];
vec3 rawDest[2];
glms_vec3_unpack(rawBox1, box1, 2);
glms_vec3_unpack(rawBox2, box2, 2);
glm_aabb_merge(rawBox1, rawBox2, rawDest);
glms_vec3_pack(dest, rawDest, 2);
}
/*!
* @brief crops a bounding box with another one.
*
* this could be useful for gettng a bbox which fits with view frustum and
* object bounding boxes. In this case you crop view frustum box with objects
* box
*
* @param[in] box bounding box 1
* @param[in] cropBox crop box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glms_aabb_crop(vec3s box[2], vec3s cropBox[2], vec3s dest[2]) {
vec3 rawBox[2];
vec3 rawCropBox[2];
vec3 rawDest[2];
glms_vec3_unpack(rawBox, box, 2);
glms_vec3_unpack(rawCropBox, cropBox, 2);
glm_aabb_crop(rawBox, rawCropBox, rawDest);
glms_vec3_pack(dest, rawDest, 2);
}
/*!
* @brief crops a bounding box with another one.
*
* this could be useful for gettng a bbox which fits with view frustum and
* object bounding boxes. In this case you crop view frustum box with objects
* box
*
* @param[in] box bounding box
* @param[in] cropBox crop box
* @param[in] clampBox miniumum box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glms_aabb_crop_until(vec3s box[2],
vec3s cropBox[2],
vec3s clampBox[2],
vec3s dest[2]) {
glms_aabb_crop(box, cropBox, dest);
glms_aabb_merge(clampBox, dest, dest);
}
/*!
* @brief check if AABB intersects with frustum planes
*
* this could be useful for frustum culling using AABB.
*
* OPTIMIZATION HINT:
* if planes order is similar to LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
* then this method should run even faster because it would only use two
* planes if object is not inside the two planes
* fortunately cglm extracts planes as this order! just pass what you got!
*
* @param[in] box bounding box
* @param[in] planes frustum planes
*/
CGLM_INLINE
bool
glms_aabb_frustum(vec3s box[2], vec4s planes[6]) {
vec3 rawBox[2];
vec4 rawPlanes[6];
glms_vec3_unpack(rawBox, box, 2);
glms_vec4_unpack(rawPlanes, planes, 6);
return glm_aabb_frustum(rawBox, rawPlanes);
}
/*!
* @brief invalidate AABB min and max values
*
* @param[in, out] box bounding box
*/
CGLM_INLINE
void
glms_aabb_invalidate(vec3s box[2]) {
box[0] = glms_vec3_broadcast(FLT_MAX);
box[1] = glms_vec3_broadcast(-FLT_MAX);
}
/*!
* @brief check if AABB is valid or not
*
* @param[in] box bounding box
*/
CGLM_INLINE
bool
glms_aabb_isvalid(vec3s box[2]) {
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
return glm_aabb_isvalid(rawBox);
}
/*!
* @brief distance between of min and max
*
* @param[in] box bounding box
*/
CGLM_INLINE
float
glms_aabb_size(vec3s box[2]) {
return glm_vec3_distance(box[0].raw, box[1].raw);
}
/*!
* @brief radius of sphere which surrounds AABB
*
* @param[in] box bounding box
*/
CGLM_INLINE
float
glms_aabb_radius(vec3s box[2]) {
return glms_aabb_size(box) * 0.5f;
}
/*!
* @brief computes center point of AABB
*
* @param[in] box bounding box
* @returns center of bounding box
*/
CGLM_INLINE
vec3s
glms_aabb_center(vec3s box[2]) {
return glms_vec3_center(box[0], box[1]);
}
/*!
* @brief check if two AABB intersects
*
* @param[in] box bounding box
* @param[in] other other bounding box
*/
CGLM_INLINE
bool
glms_aabb_aabb(vec3s box[2], vec3s other[2]) {
vec3 rawBox[2];
vec3 rawOther[2];
glms_vec3_unpack(rawBox, box, 2);
glms_vec3_unpack(rawOther, other, 2);
return glm_aabb_aabb(rawBox, rawOther);
}
/*!
* @brief check if AABB intersects with sphere
*
* https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
* Solid Box - Solid Sphere test.
*
* @param[in] box solid bounding box
* @param[in] s solid sphere
*/
CGLM_INLINE
bool
glms_aabb_sphere(vec3s box[2], vec4s s) {
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
return glm_aabb_sphere(rawBox, s.raw);
}
/*!
* @brief check if point is inside of AABB
*
* @param[in] box bounding box
* @param[in] point point
*/
CGLM_INLINE
bool
glms_aabb_point(vec3s box[2], vec3s point) {
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
return glm_aabb_point(rawBox, point.raw);
}
/*!
* @brief check if AABB contains other AABB
*
* @param[in] box bounding box
* @param[in] other other bounding box
*/
CGLM_INLINE
bool
glms_aabb_contains(vec3s box[2], vec3s other[2]) {
vec3 rawBox[2];
vec3 rawOther[2];
glms_vec3_unpack(rawBox, box, 2);
glms_vec3_unpack(rawOther, other, 2);
return glm_aabb_contains(rawBox, rawOther);
}
#endif /* cglms_boxs_h */

451
include/cglm/struct/cam.h Normal file
View File

@@ -0,0 +1,451 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE mat4s glms_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal)
CGLM_INLINE mat4s glms_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal)
CGLM_INLINE mat4s glms_ortho_aabb(vec3s box[2]);
CGLM_INLINE mat4s glms_ortho_aabb_p(vec3s box[2], float padding);
CGLM_INLINE mat4s glms_ortho_aabb_pz(vec3s box[2], float padding);
CGLM_INLINE mat4s glms_ortho_default(float aspect)
CGLM_INLINE mat4s glms_ortho_default_s(float aspect, float size)
CGLM_INLINE mat4s glms_perspective(float fovy,
float aspect,
float nearVal,
float farVal)
CGLM_INLINE void glms_persp_move_far(mat4s proj, float deltaFar)
CGLM_INLINE mat4s glms_perspective_default(float aspect)
CGLM_INLINE void glms_perspective_resize(mat4s proj, float aspect)
CGLM_INLINE mat4s glms_lookat(vec3s eye, vec3s center, vec3s up)
CGLM_INLINE mat4s glms_look(vec3s eye, vec3s dir, vec3s up)
CGLM_INLINE mat4s glms_look_anyup(vec3s eye, vec3s dir)
CGLM_INLINE void glms_persp_decomp(mat4s proj,
float *nearv, float *farv,
float *top, float *bottom,
float *left, float *right)
CGLM_INLINE void glms_persp_decompv(mat4s proj, float dest[6])
CGLM_INLINE void glms_persp_decomp_x(mat4s proj, float *left, float *right)
CGLM_INLINE void glms_persp_decomp_y(mat4s proj, float *top, float *bottom)
CGLM_INLINE void glms_persp_decomp_z(mat4s proj, float *nearv, float *farv)
CGLM_INLINE void glms_persp_decomp_far(mat4s proj, float *farVal)
CGLM_INLINE void glms_persp_decomp_near(mat4s proj, float *nearVal)
CGLM_INLINE float glms_persp_fovy(mat4s proj)
CGLM_INLINE float glms_persp_aspect(mat4s proj)
CGLM_INLINE vec4s glms_persp_sizes(mat4s proj, float fovy)
*/
#ifndef cglms_cam_h
#define cglms_cam_h
#include "../common.h"
#include "../types-struct.h"
#include "../plane.h"
#include "../cam.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
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal) {
mat4s dest;
glm_frustum(left, right, bottom, top, nearVal, farVal, dest.raw);
return dest;
}
/*!
* @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
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal) {
mat4s dest;
glm_ortho(left, right, bottom, top, nearVal, farVal, dest.raw);
return dest;
}
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho_aabb(vec3s box[2]) {
mat4s dest;
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
glm_ortho_aabb(rawBox, dest.raw);
return dest;
}
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[in] padding padding
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho_aabb_p(vec3s box[2], float padding) {
mat4s dest;
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
glm_ortho_aabb_p(rawBox, padding, dest.raw);
return dest;
}
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[in] padding padding for near and far
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho_aabb_pz(vec3s box[2], float padding) {
mat4s dest;
vec3 rawBox[2];
glms_vec3_unpack(rawBox, box, 2);
glm_ortho_aabb_pz(rawBox, padding, dest.raw);
return dest;
}
/*!
* @brief set up unit orthographic projection matrix
*
* @param[in] aspect aspect ration ( width / height )
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho_default(float aspect) {
mat4s dest;
glm_ortho_default(aspect, dest.raw);
return dest;
}
/*!
* @brief set up orthographic projection matrix with given CUBE size
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in] size cube size
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_ortho_default_s(float aspect, float size) {
mat4s dest;
glm_ortho_default_s(aspect, size, dest.raw);
return 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
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_perspective(float fovy, float aspect, float nearVal, float farVal) {
mat4s dest;
glm_perspective(fovy, aspect, nearVal, farVal, dest.raw);
return dest;
}
/*!
* @brief extend perspective projection matrix's far distance
*
* this function does not guarantee far >= near, be aware of that!
*
* @param[in, out] proj projection matrix to extend
* @param[in] deltaFar distance from existing far (negative to shink)
*/
CGLM_INLINE
void
glms_persp_move_far(mat4s proj, float deltaFar) {
glm_persp_move_far(proj.raw, deltaFar);
}
/*!
* @brief set up perspective projection matrix with default near/far
* and angle values
*
* @param[in] aspect aspect ratio ( width / height )
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_perspective_default(float aspect) {
mat4s dest;
glm_perspective_default(aspect, dest.raw);
return dest;
}
/*!
* @brief resize perspective matrix by aspect ratio ( width / height )
* this makes very easy to resize proj matrix when window /viewport
* reized
*
* @param[in, out] proj perspective projection matrix
* @param[in] aspect aspect ratio ( width / height )
*/
CGLM_INLINE
void
glms_perspective_resize(mat4s proj, float aspect) {
glm_perspective_resize(aspect, proj.raw);
}
/*!
* @brief set up view matrix
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_lookat(vec3s eye, vec3s center, vec3s up) {
mat4s dest;
glm_lookat(eye.raw, center.raw, up.raw, dest.raw);
return dest;
}
/*!
* @brief set up view matrix
*
* convenient wrapper for lookat: if you only have direction not target self
* then this might be useful. Because you need to get target from direction.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] dir direction vector
* @param[in] up up vector
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_look(vec3s eye, vec3s dir, vec3s up) {
mat4s dest;
glm_look(eye.raw, dir.raw, up.raw, dest.raw);
return dest;
}
/*!
* @brief set up view matrix
*
* convenient wrapper for look: if you only have direction and if you don't
* care what UP vector is then this might be useful to create view matrix
*
* @param[in] eye eye vector
* @param[in] dir direction vector
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_look_anyup(vec3s eye, vec3s dir) {
mat4s dest;
glm_look_anyup(eye.raw, dir.raw, dest.raw);
return dest;
}
/*!
* @brief decomposes frustum values of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
* @param[out] farVal far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glms_persp_decomp(mat4s proj,
float * __restrict nearVal, float * __restrict farVal,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
glm_persp_decomp(proj.raw, nearVal, farVal, top, bottom, left, right);
}
/*!
* @brief decomposes frustum values of perspective projection.
* this makes easy to get all values at once
*
* @param[in] proj perspective projection matrix
* @param[out] dest array
*/
CGLM_INLINE
void
glms_persp_decompv(mat4s proj, float dest[6]) {
glm_persp_decompv(proj.raw, dest);
}
/*!
* @brief decomposes left and right values of perspective projection.
* x stands for x axis (left / right axis)
*
* @param[in] proj perspective projection matrix
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glms_persp_decomp_x(mat4s proj,
float * __restrict left,
float * __restrict right) {
glm_persp_decomp_x(proj.raw, left, right);
}
/*!
* @brief decomposes top and bottom values of perspective projection.
* y stands for y axis (top / botom axis)
*
* @param[in] proj perspective projection matrix
* @param[out] top top
* @param[out] bottom bottom
*/
CGLM_INLINE
void
glms_persp_decomp_y(mat4s proj,
float * __restrict top,
float * __restrict bottom) {
glm_persp_decomp_y(proj.raw, top, bottom);
}
/*!
* @brief decomposes near and far values of perspective projection.
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
* @param[out] farVal far
*/
CGLM_INLINE
void
glms_persp_decomp_z(mat4s proj,
float * __restrict nearVal,
float * __restrict farVal) {
glm_persp_decomp_z(proj.raw, nearVal, farVal);
}
/*!
* @brief decomposes far value of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] farVal far
*/
CGLM_INLINE
void
glms_persp_decomp_far(mat4s proj, float * __restrict farVal) {
glm_persp_decomp_far(proj.raw, farVal);
}
/*!
* @brief decomposes near value of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
*/
CGLM_INLINE
void
glms_persp_decomp_near(mat4s proj, float * __restrict nearVal) {
glm_persp_decomp_near(proj.raw, nearVal);
}
/*!
* @brief returns field of view angle along the Y-axis (in radians)
*
* if you need to degrees, use glm_deg to convert it or use this:
* fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glms_persp_fovy(mat4s proj) {
return glm_persp_fovy(proj.raw);
}
/*!
* @brief returns aspect ratio of perspective projection
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glms_persp_aspect(mat4s proj) {
return glm_persp_aspect(proj.raw);
}
/*!
* @brief returns sizes of near and far planes of perspective projection
*
* @param[in] proj perspective projection matrix
* @param[in] fovy fovy (see brief)
* @returns sizes as vector, sizes order: [Wnear, Hnear, Wfar, Hfar]
*/
CGLM_INLINE
vec4s
glms_persp_sizes(mat4s proj, float fovy) {
vec4s dest;
glm_persp_sizes(proj.raw, fovy, dest.raw);
return dest;
}
#endif /* cglms_cam_h */

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_colors_h
#define cglms_colors_h
#include "../common.h"
#include "../types-struct.h"
#include "../color.h"
#include "vec3.h"
/*!
* @brief averages the color channels into one value
*
* @param[in] rgb RGB color
*/
CGLM_INLINE
float
glms_luminance(vec3s rgb) {
return glm_luminance(rgb.raw);
}
#endif /* cglms_colors_h */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_curves_h
#define cglms_curves_h
#include "../common.h"
#include "../types-struct.h"
#include "../curve.h"
#include "vec4.h"
#include "mat4.h"
/*!
* @brief helper function to calculate S*M*C multiplication for curves
*
* This function does not encourage you to use SMC,
* instead it is a helper if you use SMC.
*
* if you want to specify S as vector then use more generic glm_mat4_rmc() func.
*
* Example usage:
* B(s) = glm_smc(s, GLM_BEZIER_MAT, (vec4){p0, c0, c1, p1})
*
* @param[in] s parameter between 0 and 1 (this will be [s3, s2, s, 1])
* @param[in] m basis matrix
* @param[in] c position/control vector
*
* @return B(s)
*/
CGLM_INLINE
float
glms_smc(float s, mat4s m, vec4s c) {
return glm_smc(s, m.raw, c.raw);
}
#endif /* cglms_curves_h */

152
include/cglm/struct/euler.h Normal file
View File

@@ -0,0 +1,152 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
NOTE:
angles must be passed as [X-Angle, Y-Angle, Z-angle] order
For instance you don't pass angles as [Z-Angle, X-Angle, Y-angle] to
glm_euler_zxy funciton, All RELATED functions accept angles same order
which is [X, Y, Z].
*/
/*
Types:
enum glm_euler_seq
Functions:
CGLM_INLINE vec3s glms_euler_angles(mat4s m)
CGLM_INLINE mat4s glms_euler_xyz(vec3s angles)
CGLM_INLINE mat4s glms_euler_xzy(vec3s angles)
CGLM_INLINE mat4s glms_euler_yxz(vec3s angles)
CGLM_INLINE mat4s glms_euler_yzx(vec3s angles)
CGLM_INLINE mat4s glms_euler_zxy(vec3s angles)
CGLM_INLINE mat4s glms_euler_zyx(vec3s angles)
CGLM_INLINE mat4s glms_euler_by_order(vec3s angles, glm_euler_seq ord)
*/
#ifndef cglms_euler_h
#define cglms_euler_h
#include "../common.h"
#include "../types-struct.h"
#include "../euler.h"
/*!
* @brief extract euler angles (in radians) using xyz order
*
* @param[in] m affine transform
* @returns angles vector [x, y, z]
*/
CGLM_INLINE
vec3s
glms_euler_angles(mat4s m) {
vec3s dest;
glm_euler_angles(m.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_xyz(vec3s angles) {
mat4s dest;
glm_euler_xyz(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_xzy(vec3s angles) {
mat4s dest;
glm_euler_xzy(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_yxz(vec3s angles) {
mat4s dest;
glm_euler_yxz(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_yzx(vec3s angles) {
mat4s dest;
glm_euler_yzx(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_zxy(vec3s angles) {
mat4s dest;
glm_euler_zxy(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_zyx(vec3s angles) {
mat4s dest;
glm_euler_zyx(angles.raw, dest.raw);
return dest;
}
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Xangle, Yangle, Zangle]
* @param[in] ord euler order
* @returns rotation matrix
*/
CGLM_INLINE
mat4s
glms_euler_by_order(vec3s angles, glm_euler_seq ord) {
mat4s dest;
glm_euler_by_order(angles.raw, ord, dest.raw);
return dest;
}
#endif /* cglms_euler_h */

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_frustums_h
#define cglms_frustums_h
#include "../common.h"
#include "../types-struct.h"
#include "../frustum.h"
#include "plane.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
/* you can override clip space coords
but you have to provide all with same name
e.g.: define GLM_CSCOORD_LBN {0.0f, 0.0f, 1.0f, 1.0f} */
#ifndef GLM_CUSTOM_CLIPSPACE
/* near */
#define GLMS_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
#define GLMS_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
#define GLMS_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
#define GLMS_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
/* far */
#define GLMS_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
#define GLMS_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
#define GLMS_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
#define GLMS_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
#endif
/*!
* @brief extracts view frustum planes
*
* planes' space:
* 1- if m = proj: View Space
* 2- if m = viewProj: World Space
* 3- if m = MVP: Object Space
*
* You probably want to extract planes in world space so use viewProj as m
* Computing viewProj:
* glm_mat4_mul(proj, view, viewProj);
*
* Exracted planes order: [left, right, bottom, top, near, far]
*
* @param[in] m matrix (see brief)
* @param[out] dest extracted view frustum planes (see brief)
*/
CGLM_INLINE
void
glms_frustum_planes(mat4s m, vec4s dest[6]) {
vec4 rawDest[6];
glm_frustum_planes(m.raw, rawDest);
glms_vec4_pack(dest, rawDest, 6);
}
/*!
* @brief extracts view frustum corners using clip-space coordinates
*
* corners' space:
* 1- if m = invViewProj: World Space
* 2- if m = invMVP: Object Space
*
* You probably want to extract corners in world space so use invViewProj
* Computing invViewProj:
* glm_mat4_mul(proj, view, viewProj);
* ...
* glm_mat4_inv(viewProj, invViewProj);
*
* if you have a near coord at i index, you can get it's far coord by i + 4
*
* Find center coordinates:
* for (j = 0; j < 4; j++) {
* glm_vec3_center(corners[i], corners[i + 4], centerCorners[i]);
* }
*
* @param[in] invMat matrix (see brief)
* @param[out] dest exracted view frustum corners (see brief)
*/
CGLM_INLINE
void
glms_frustum_corners(mat4s invMat, vec4s dest[8]) {
vec4 rawDest[8];
glm_frustum_corners(invMat.raw, rawDest);
glms_vec4_pack(dest, rawDest, 8);
}
/*!
* @brief finds center of view frustum
*
* @param[in] corners view frustum corners
* @returns view frustum center
*/
CGLM_INLINE
vec4s
glms_frustum_center(vec4s corners[8]) {
vec4 rawCorners[8];
vec4s r;
glms_vec4_unpack(rawCorners, corners, 8);
glm_frustum_center(rawCorners, r.raw);
return r;
}
/*!
* @brief finds bounding box of frustum relative to given matrix e.g. view mat
*
* @param[in] corners view frustum corners
* @param[in] m matrix to convert existing conners
* @param[out] box bounding box as array [min, max]
*/
CGLM_INLINE
void
glms_frustum_box(vec4s corners[8], mat4s m, vec3s box[2]) {
vec4 rawCorners[8];
vec3 rawBox[2];
glms_vec4_unpack(rawCorners, corners, 8);
glm_frustum_box(rawCorners, m.raw, rawBox);
glms_vec3_pack(box, rawBox, 2);
}
/*!
* @brief finds planes corners which is between near and far planes (parallel)
*
* this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
* find planes' corners but you will need to one more plane.
* Actually you have it, it is near, far or created previously with this func ;)
*
* @param[in] corners view frustum corners
* @param[in] splitDist split distance
* @param[in] farDist far distance (zFar)
* @param[out] planeCorners plane corners [LB, LT, RT, RB]
*/
CGLM_INLINE
void
glms_frustum_corners_at(vec4s corners[8],
float splitDist,
float farDist,
vec4s planeCorners[4]) {
vec4 rawCorners[8];
vec4 rawPlaneCorners[4];
glms_vec4_unpack(rawCorners, corners, 8);
glm_frustum_corners_at(rawCorners, splitDist, farDist, rawPlaneCorners);
glms_vec4_pack(planeCorners, rawPlaneCorners, 8);
}
#endif /* cglms_frustums_h */

82
include/cglm/struct/io.h Normal file
View File

@@ -0,0 +1,82 @@
/*
* 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 cglms_ios_h
#define cglms_ios_h
#include "../common.h"
#include "../io.h"
#include "mat4.h"
#include <stdio.h>
#include <stdlib.h>
CGLM_INLINE
void
glms_mat4_print(mat4s matrix,
FILE * __restrict ostream) {
glm_mat4_print(matrix.raw, ostream);
}
CGLM_INLINE
void
glms_mat3_print(mat3s matrix,
FILE * __restrict ostream) {
glm_mat3_print(matrix.raw, ostream);
}
CGLM_INLINE
void
glms_vec4_print(vec4s vec,
FILE * __restrict ostream) {
glm_vec4_print(vec.raw, ostream);
}
CGLM_INLINE
void
glms_vec3_print(vec3s vec,
FILE * __restrict ostream) {
glm_vec3_print(vec.raw, ostream);
}
CGLM_INLINE
void
glms_ivec3_print(ivec3s vec,
FILE * __restrict ostream) {
glm_ivec3_print(vec.raw, ostream);
}
CGLM_INLINE
void
glms_versor_print(versors vec,
FILE * __restrict ostream) {
glm_versor_print(vec.raw, ostream);
}
CGLM_INLINE
void
glms_aabb_print(vec3s bbox[2],
const char * __restrict tag,
FILE * __restrict ostream) {
vec3 rawBbox[2];
glms_vec3_unpack(rawBbox, bbox, 2);
glm_aabb_print(rawBbox, tag, ostream);
}
#endif /* cglms_ios_h */

289
include/cglm/struct/mat3.h Normal file
View File

@@ -0,0 +1,289 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Macros:
GLMS_MAT3_IDENTITY_INIT
GLMS_MAT3_ZERO_INIT
GLMS_MAT3_IDENTITY
GLMS_MAT3_ZERO
Functions:
CGLM_INLINE mat3s glms_mat3_copy(mat3s mat);
CGLM_INLINE mat3s glms_mat3_identity();
CGLM_INLINE void glms_mat3_identity_array(mat3s * __restrict mat, size_t count);
CGLM_INLINE mat3s glms_mat3_zero();
CGLM_INLINE mat3s glms_mat3_mul(mat3s m1, mat3s m2);
CGLM_INLINE ma3s glms_mat3_transpose(mat3s m);
CGLM_INLINE vec3s glms_mat3_mulv(mat3s m, vec3s v);
CGLM_INLINE float glms_mat3_trace(mat3s m);
CGLM_INLINE versor glms_mat3_quat(mat3s m);
CGLM_INLINE mat3s glms_mat3_scale(mat3s m, float s);
CGLM_INLINE float glms_mat3_det(mat3s mat);
CGLM_INLINE mat3s glms_mat3_inv(mat3s mat);
CGLM_INLINE mat3s glms_mat3_swap_col(mat3s mat, int col1, int col2);
CGLM_INLINE mat3s glms_mat3_swap_row(mat3s mat, int row1, int row2);
CGLM_INLINE float glms_mat3_rmc(vec3s r, mat3s m, vec3s c);
*/
#ifndef cglms_mat3s_h
#define cglms_mat3s_h
#include "../common.h"
#include "../types-struct.h"
#include "../mat3.h"
#include "vec3.h"
#define GLMS_MAT3_IDENTITY_INIT {1.0f, 0.0f, 0.0f, \
0.0f, 1.0f, 0.0f, \
0.0f, 0.0f, 1.0f}
#define GLMS_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 GLMS_MAT3_IDENTITY ((mat3s)GLMS_MAT3_IDENTITY_INIT)
#define GLMS_MAT3_ZERO ((mat3s)GLMS_MAT3_ZERO_INIT)
/*!
* @brief copy all members of [mat] to [dest]
*
* @param[in] mat source
* @returns destination
*/
CGLM_INLINE
mat3s
glms_mat3_copy(mat3s mat) {
mat3s r;
glm_mat3_copy(mat.raw, r.raw);
return r;
}
/*!
* @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
*
* @returns destination
*/
CGLM_INLINE
mat3s
glms_mat3_identity() {
mat3s r;
glm_mat3_identity(r.raw);
return r;
}
/*!
* @brief make given matrix array's each element identity matrix
*
* @param[in, out] mat matrix array (must be aligned (16/32)
* if alignment is not disabled)
*
* @param[in] count count of matrices
*/
CGLM_INLINE
void
glms_mat3_identity_array(mat3s * __restrict mat, size_t count) {
CGLM_ALIGN_MAT mat3s t = GLMS_MAT3_IDENTITY_INIT;
size_t i;
for (i = 0; i < count; i++) {
glm_mat3_copy(t.raw, mat[i].raw);
}
}
/*!
* @brief make given matrix zero.
*
* @returns matrix
*/
CGLM_INLINE
mat3s
glms_mat3_zero() {
mat3s r;
glm_mat3_zero(r.raw);
return r;
}
/*!
* @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
* @returns destination matrix
*/
CGLM_INLINE
mat3s
glms_mat3_mul(mat3s m1, mat3s m2) {
mat3s r;
glm_mat3_mul(m1.raw, m2.raw, r.raw);
return r;
}
/*!
* @brief tranpose mat3 and store result in same matrix
*
* @param[in, out] m source and dest
*/
CGLM_INLINE
mat3s
glms_mat3_transpose(mat3s m) {
glm_mat3_transpose(m.raw);
return m;
}
/*!
* @brief multiply mat3 with vec3 (column vector) and store in dest vector
*
* @param[in] m mat3 (left)
* @param[in] v vec3 (right, column vector)
* @returns vec3 (result, column vector)
*/
CGLM_INLINE
vec3s
glms_mat3_mulv(mat3s m, vec3s v) {
vec3s r;
glm_mat3_mulv(m.raw, v.raw, r.raw);
return r;
}
/*!
* @brief trace of matrix
*
* sum of the elements on the main diagonal from upper left to the lower right
*
* @param[in] m matrix
*/
CGLM_INLINE
float
glms_mat3_trace(mat3s m) {
return glm_mat3_trace(m.raw);
}
/*!
* @brief convert mat3 to quaternion
*
* @param[in] m rotation matrix
* @returns destination quaternion
*/
CGLM_INLINE
versors
glms_mat3_quat(mat3s m) {
versors r;
glm_mat3_quat(m.raw, r.raw);
return r;
}
/*!
* @brief scale (multiply with scalar) matrix
*
* multiply matrix with scalar
*
* @param[in] m matrix
* @param[in] s scalar
* @returns scaled matrix
*/
CGLM_INLINE
mat3s
glms_mat3_scale(mat3s m, float s) {
glm_mat3_scale(m.raw, s);
return m;
}
/*!
* @brief mat3 determinant
*
* @param[in] mat matrix
*
* @return determinant
*/
CGLM_INLINE
float
glms_mat3_det(mat3s mat) {
return glm_mat3_det(mat.raw);
}
/*!
* @brief inverse mat3 and store in dest
*
* @param[in] mat matrix
* @returns inverse matrix
*/
CGLM_INLINE
mat3s
glms_mat3_inv(mat3s mat) {
mat3s r;
glm_mat3_inv(mat.raw, r.raw);
return r;
}
/*!
* @brief swap two matrix columns
*
* @param[in] mat matrix
* @param[in] col1 col1
* @param[in] col2 col2
* @returns matrix
*/
CGLM_INLINE
mat3s
glms_mat3_swap_col(mat3s mat, int col1, int col2) {
glm_mat3_swap_col(mat.raw, col1, col2);
return mat;
}
/*!
* @brief swap two matrix rows
*
* @param[in] mat matrix
* @param[in] row1 row1
* @param[in] row2 row2
* @returns matrix
*/
CGLM_INLINE
mat3s
glms_mat3_swap_row(mat3s mat, int row1, int row2) {
glm_mat3_swap_row(mat.raw, row1, row2);
return mat;
}
/*!
* @brief helper for R (row vector) * M (matrix) * C (column vector)
*
* rmc stands for Row * Matrix * Column
*
* the result is scalar because R * M = Matrix1x3 (row vector),
* then Matrix1x3 * Vec3 (column vector) = Matrix1x1 (Scalar)
*
* @param[in] r row vector or matrix1x3
* @param[in] m matrix3x3
* @param[in] c column vector or matrix3x1
*
* @return scalar value e.g. Matrix1x1
*/
CGLM_INLINE
float
glms_mat3_rmc(vec3s r, mat3s m, vec3s c) {
return glm_mat3_rmc(r.raw, m.raw, c.raw);
}
#endif /* cglms_mat3s_h */

466
include/cglm/struct/mat4.h Normal file
View File

@@ -0,0 +1,466 @@
/*
* 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:
GLMS_MAT4_IDENTITY_INIT
GLMS_MAT4_ZERO_INIT
GLMS_MAT4_IDENTITY
GLMS_MAT4_ZERO
Functions:
CGLM_INLINE mat4s glms_mat4_ucopy(mat4s mat);
CGLM_INLINE mat4s glms_mat4_copy(mat4s mat);
CGLM_INLINE mat4s glms_mat4_identity();
CGLM_INLINE void glms_mat4_identity_array(mat4s * __restrict mat, size_t count);
CGLM_INLINE mat4s glms_mat4_zero();
CGLM_INLINE mat3s glms_mat4_pick3(mat4s mat);
CGLM_INLINE mat3s glms_mat4_pick3t(mat4s mat);
CGLM_INLINE mat4s glms_mat4_ins3(mat3s mat);
CGLM_INLINE mat4s glms_mat4_mul(mat4s m1, mat4s m2);
CGLM_INLINE mat4s glms_mat4_mulN(mat4s * __restrict matrices[], uint32_t len);
CGLM_INLINE vec4s glms_mat4_mulv(mat4s m, vec4s v);
CGLM_INLINE float glms_mat4_trace(mat4s m);
CGLM_INLINE float glms_mat4_trace3(mat4s m);
CGLM_INLINE versors glms_mat4_quat(mat4s m);
CGLM_INLINE vec3s glms_mat4_mulv3(mat4s m, vec3s v, float last);
CGLM_INLINE mat4s glms_mat4_transpose(mat4s m);
CGLM_INLINE mat4s glms_mat4_scale_p(mat4s m, float s);
CGLM_INLINE mat4s glms_mat4_scale(mat4s m, float s);
CGLM_INLINE float glms_mat4_det(mat4s mat);
CGLM_INLINE mat4s glms_mat4_inv(mat4s mat);
CGLM_INLINE mat4s glms_mat4_inv_fast(mat4s mat);
CGLM_INLINE mat4s glms_mat4_swap_col(mat4s mat, int col1, int col2);
CGLM_INLINE mat4s glms_mat4_swap_row(mat4s mat, int row1, int row2);
CGLM_INLINE float glms_mat4_rmc(vec4s r, mat4s m, vec4s c);
*/
#ifndef cglms_mat4s_h
#define cglms_mat4s_h
#include "../common.h"
#include "../types-struct.h"
#include "../mat4.h"
#include "vec4.h"
#include "vec3.h"
#define GLMS_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 GLMS_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 GLMS_MAT4_IDENTITY ((mat4s)GLMS_MAT4_IDENTITY_INIT)
#define GLMS_MAT4_ZERO ((mat4s)GLMS_MAT4_ZERO_INIT)
/*!
* @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
* @returns destination
*/
CGLM_INLINE
mat4s
glms_mat4_ucopy(mat4s mat) {
mat4s r;
glm_mat4_ucopy(mat.raw, r.raw);
return r;
}
/*!
* @brief copy all members of [mat] to [dest]
*
* @param[in] mat source
* @returns destination
*/
CGLM_INLINE
mat4s
glms_mat4_copy(mat4s mat) {
mat4s r;
glm_mat4_copy(mat.raw, r.raw);
return r;
}
/*!
* @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
*
* @retuns destination
*/
CGLM_INLINE
mat4s
glms_mat4_identity() {
mat4s r;
glm_mat4_identity(r.raw);
return r;
}
/*!
* @brief make given matrix array's each element identity matrix
*
* @param[in, out] mat matrix array (must be aligned (16/32)
* if alignment is not disabled)
*
* @param[in] count count of matrices
*/
CGLM_INLINE
void
glms_mat4_identity_array(mat4s * __restrict mat, size_t count) {
CGLM_ALIGN_MAT mat4s t = GLMS_MAT4_IDENTITY_INIT;
size_t i;
for (i = 0; i < count; i++) {
glm_mat4_copy(t.raw, mat[i].raw);
}
}
/*!
* @brief make given matrix zero.
*
* @returns matrix
*/
CGLM_INLINE
mat4s
glms_mat4_zero() {
mat4s r;
glm_mat4_zero(r.raw);
return r;
}
/*!
* @brief copy upper-left of mat4 to mat3
*
* @param[in] mat source
* @returns destination
*/
CGLM_INLINE
mat3s
glms_mat4_pick3(mat4s mat) {
mat3s r;
glm_mat4_pick3(mat.raw, r.raw);
return r;
}
/*!
* @brief copy upper-left of mat4 to mat3 (transposed)
*
* the postfix t stands for transpose
*
* @param[in] mat source
* @returns destination
*/
CGLM_INLINE
mat3s
glms_mat4_pick3t(mat4s mat) {
mat3s r;
glm_mat4_pick3t(mat.raw, r.raw);
return r;
}
/*!
* @brief copy mat3 to mat4's upper-left
*
* @param[in] mat source
* @returns destination
*/
CGLM_INLINE
mat4s
glms_mat4_ins3(mat3s mat) {
mat4s r;
glm_mat4_ins3(mat.raw, r.raw);
return r;
}
/*!
* @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
* @returns destination matrix
*/
CGLM_INLINE
mat4s
glms_mat4_mul(mat4s m1, mat4s m2) {
mat4s r;
glm_mat4_mul(m1.raw, m2.raw, r.raw);
return r;
}
/*!
* @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;
*
* res = glm_mat4_mulN((mat4 *[]){&m1, &m2, &m3, &m4}, 4);
* @endcode
*
* @warning matrices parameter is pointer array not mat4 array!
*
* @param[in] matrices mat4 * array
* @param[in] len matrices count
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_mat4_mulN(mat4s * __restrict matrices[], uint32_t len) {
CGLM_ALIGN_MAT mat4s r = GLMS_MAT4_IDENTITY_INIT;
size_t i;
for (i = 0; i < len; i++) {
r = glms_mat4_mul(r, *matrices[i]);
}
return r;
}
/*!
* @brief multiply mat4 with vec4 (column vector) and store in dest vector
*
* @param[in] m mat4 (left)
* @param[in] v vec4 (right, column vector)
* @returns vec4 (result, column vector)
*/
CGLM_INLINE
vec4s
glms_mat4_mulv(mat4s m, vec4s v) {
vec4s r;
glm_mat4_mulv(m.raw, v.raw, r.raw);
return r;
}
/*!
* @brief trace of matrix
*
* sum of the elements on the main diagonal from upper left to the lower right
*
* @param[in] m matrix
*/
CGLM_INLINE
float
glms_mat4_trace(mat4s m) {
return glm_mat4_trace(m.raw);
}
/*!
* @brief trace of matrix (rotation part)
*
* sum of the elements on the main diagonal from upper left to the lower right
*
* @param[in] m matrix
*/
CGLM_INLINE
float
glms_mat4_trace3(mat4s m) {
return glm_mat4_trace3(m.raw);
}
/*!
* @brief convert mat4's rotation part to quaternion
*
* @param[in] m affine matrix
* @returns destination quaternion
*/
CGLM_INLINE
versors
glms_mat4_quat(mat4s m) {
versors r;
glm_mat4_quat(m.raw, r.raw);
return r;
}
/*!
* @brief multiply vector with mat4
*
* @param[in] m mat4(affine transform)
* @param[in] v vec3
* @param[in] last 4th item to make it vec4
* @returns result vector (vec3)
*/
CGLM_INLINE
vec3s
glms_mat4_mulv3(mat4s m, vec3s v, float last) {
vec3s r;
glm_mat4_mulv3(m.raw, v.raw, last, r.raw);
return r;
}
/*!
* @brief tranpose mat4 and store result in same matrix
*
* @param[in] m source
* @returns result
*/
CGLM_INLINE
mat4s
glms_mat4_transpose(mat4s m) {
glm_mat4_transpose(m.raw);
return m;
}
/*!
* @brief scale (multiply with scalar) matrix without simd optimization
*
* multiply matrix with scalar
*
* @param[in] m matrix
* @param[in] s scalar
* @returns matrix
*/
CGLM_INLINE
mat4s
glms_mat4_scale_p(mat4s m, float s) {
glm_mat4_scale_p(m.raw, s);
return m;
}
/*!
* @brief scale (multiply with scalar) matrix
*
* multiply matrix with scalar
*
* @param[in] m matrix
* @param[in] s scalar
* @returns matrix
*/
CGLM_INLINE
mat4s
glms_mat4_scale(mat4s m, float s) {
glm_mat4_scale(m.raw, s);
return m;
}
/*!
* @brief mat4 determinant
*
* @param[in] mat matrix
*
* @return determinant
*/
CGLM_INLINE
float
glms_mat4_det(mat4s mat) {
return glm_mat4_det(mat.raw);
}
/*!
* @brief inverse mat4 and store in dest
*
* @param[in] mat matrix
* @returns inverse matrix
*/
CGLM_INLINE
mat4s
glms_mat4_inv(mat4s mat) {
mat4s r;
glm_mat4_inv(mat.raw, r.raw);
return r;
}
/*!
* @brief inverse mat4 and store in dest
*
* this func uses reciprocal approximation without extra corrections
* e.g Newton-Raphson. this should work faster than normal,
* to get more precise use glm_mat4_inv version.
*
* NOTE: You will lose precision, glm_mat4_inv is more accurate
*
* @param[in] mat matrix
* @returns inverse matrix
*/
CGLM_INLINE
mat4s
glms_mat4_inv_fast(mat4s mat) {
mat4s r;
glm_mat4_inv_fast(mat.raw, r.raw);
return r;
}
/*!
* @brief swap two matrix columns
*
* @param[in] mat matrix
* @param[in] col1 col1
* @param[in] col2 col2
* @returns matrix
*/
CGLM_INLINE
mat4s
glms_mat4_swap_col(mat4s mat, int col1, int col2) {
glm_mat4_swap_col(mat.raw, col1, col2);
return mat;
}
/*!
* @brief swap two matrix rows
*
* @param[in] mat matrix
* @param[in] row1 row1
* @param[in] row2 row2
* @returns matrix
*/
CGLM_INLINE
mat4s
glms_mat4_swap_row(mat4s mat, int row1, int row2) {
glm_mat4_swap_row(mat.raw, row1, row2);
return mat;
}
/*!
* @brief helper for R (row vector) * M (matrix) * C (column vector)
*
* rmc stands for Row * Matrix * Column
*
* the result is scalar because R * M = Matrix1x4 (row vector),
* then Matrix1x4 * Vec4 (column vector) = Matrix1x1 (Scalar)
*
* @param[in] r row vector or matrix1x4
* @param[in] m matrix4x4
* @param[in] c column vector or matrix4x1
*
* @return scalar value e.g. B(s)
*/
CGLM_INLINE
float
glms_mat4_rmc(vec4s r, mat4s m, vec4s c) {
return glm_mat4_rmc(r.raw, m.raw, c.raw);
}
#endif /* cglms_mat4s_h */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_planes_h
#define cglms_planes_h
#include "../common.h"
#include "../types-struct.h"
#include "../plane.h"
#include "vec4.h"
/*
Plane equation: Ax + By + Cz + D = 0;
It stored in vec4 as [A, B, C, D]. (A, B, C) is normal and D is distance
*/
/*
Functions:
CGLM_INLINE vec4s glms_plane_normalize(vec4s plane);
*/
/*!
* @brief normalizes a plane
*
* @param[in] plane plane to normalize
* @returns normalized plane
*/
CGLM_INLINE
vec4s
glms_plane_normalize(vec4s plane) {
glm_plane_normalize(plane.raw);
return plane;
}
#endif /* cglms_planes_h */

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_projects_h
#define cglms_projects_h
#include "../common.h"
#include "../types-struct.h"
#include "../project.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
/*!
* @brief maps the specified viewport coordinates into specified space [1]
* the matrix should contain projection matrix.
*
* if you don't have ( and don't want to have ) an inverse matrix then use
* glm_unproject version. You may use existing inverse of matrix in somewhere
* else, this is why glm_unprojecti exists to save save inversion cost
*
* [1] space:
* 1- if m = invProj: View Space
* 2- if m = invViewProj: World Space
* 3- if m = invMVP: Object Space
*
* You probably want to map the coordinates into object space
* so use invMVP as m
*
* Computing viewProj:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
* glm_mat4_inv(viewProj, invMVP);
*
* @param[in] pos point/position in viewport coordinates
* @param[in] invMat matrix (see brief)
* @param[in] vp viewport as [x, y, width, height]
* @returns unprojected coordinates
*/
CGLM_INLINE
vec3s
glms_unprojecti(vec3s pos, mat4s invMat, vec4s vp) {
vec3s r;
glm_unprojecti(pos.raw, invMat.raw, vp.raw, r.raw);
return r;
}
/*!
* @brief maps the specified viewport coordinates into specified space [1]
* the matrix should contain projection matrix.
*
* this is same as glm_unprojecti except this function get inverse matrix for
* you.
*
* [1] space:
* 1- if m = proj: View Space
* 2- if m = viewProj: World Space
* 3- if m = MVP: Object Space
*
* You probably want to map the coordinates into object space
* so use MVP as m
*
* Computing viewProj and MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] pos point/position in viewport coordinates
* @param[in] m matrix (see brief)
* @param[in] vp viewport as [x, y, width, height]
* @returns unprojected coordinates
*/
CGLM_INLINE
vec3s
glms_unproject(vec3s pos, mat4s m, vec4s vp) {
vec3s r;
glm_unproject(pos.raw, m.raw, vp.raw, r.raw);
return r;
}
/*!
* @brief map object coordinates to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] pos object coordinates
* @param[in] m MVP matrix
* @param[in] vp viewport as [x, y, width, height]
* @returns projected coordinates
*/
CGLM_INLINE
vec3s
glms_project(vec3s pos, mat4s m, vec4s vp) {
vec3s r;
glm_project(pos.raw, m.raw, vp.raw, r.raw);
return r;
}
#endif /* cglms_projects_h */

514
include/cglm/struct/quat.h Normal file
View File

@@ -0,0 +1,514 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Macros:
GLMS_QUAT_IDENTITY_INIT
GLMS_QUAT_IDENTITY
Functions:
CGLM_INLINE versors glms_quat_identity()
CGLM_INLINE void glms_quat_identity_array(versor *q, size_t count)
CGLM_INLINE versors glms_quat_init(float x, float y, float z, float w)
CGLM_INLINE versors glms_quatv(float angle, vec3s axis)
CGLM_INLINE versors glms_quat(float angle, float x, float y, float z)
CGLM_INLINE float glms_quat_norm(versors q)
CGLM_INLINE versors glms_quat_normalize(versors q)
CGLM_INLINE float glms_quat_dot(versors p, versors q)
CGLM_INLINE versors glms_quat_conjugate(versors q)
CGLM_INLINE versors glms_quat_inv(versors q)
CGLM_INLINE versors glms_quat_add(versors p, versors q)
CGLM_INLINE versors glms_quat_sub(versors p, versors q)
CGLM_INLINE vec3s glms_quat_imagn(versors q)
CGLM_INLINE float glms_quat_imaglen(versors q)
CGLM_INLINE float glms_quat_angle(versors q)
CGLM_INLINE vec3s glms_quat_axis(versors q)
CGLM_INLINE versors glms_quat_mul(versors p, versors q)
CGLM_INLINE mat4s glms_quat_mat4(versors q)
CGLM_INLINE mat4s glms_quat_mat4t(versors q)
CGLM_INLINE mat3s glms_quat_mat3(versors q)
CGLM_INLINE mat3s glms_quat_mat3t(versors q)
CGLM_INLINE versors glms_quat_lerp(versors from, versors to, float t)
CGLM_INLINE versors glms_quat_slerp(versors from, versors to, float t)
CGLM_INLINE mat4s. glms_quat_look(vec3s eye, versors ori)
CGLM_INLINE versors glms_quat_for(vec3s dir, vec3s fwd, vec3s up)
CGLM_INLINE versors glms_quat_forp(vec3s from, vec3s to, vec3s fwd, vec3s up)
CGLM_INLINE vec3s glms_quat_rotatev(versors q, vec3s v)
CGLM_INLINE mat4s glms_quat_rotate(mat4s m, versors q)
CGLM_INLINE mat4s glms_quat_rotate_at(mat4s m, versors q, vec3s pivot)
CGLM_INLINE mat4s glms_quat_rotate_atm(versors q, vec3s pivot)
*/
#ifndef cglms_quat_h
#define cglms_quat_h
#include "../common.h"
#include "../types-struct.h"
#include "../plane.h"
#include "../quat.h"
/*
* IMPORTANT:
* ----------------------------------------------------------------------------
* cglm stores quat as [x, y, z, w] since v0.3.6
*
* it was [w, x, y, z] before v0.3.6 it has been changed to [x, y, z, w]
* with v0.3.6 version.
* ----------------------------------------------------------------------------
*/
#define GLMS_QUAT_IDENTITY_INIT GLM_QUAT_IDENTITY_INIT
#define GLMS_QUAT_IDENTITY ((versors)GLMS_QUAT_IDENTITY_INIT)
/*!
* @brief makes given quat to identity
*
* @returns identity quaternion
*/
CGLM_INLINE
versors
glms_quat_identity() {
versors dest;
glm_quat_identity(dest.raw);
return dest;
}
/*!
* @brief make given quaternion array's each element identity quaternion
*
* @param[in, out] q quat array (must be aligned (16)
* if alignment is not disabled)
*
* @param[in] count count of quaternions
*/
CGLM_INLINE
void
glms_quat_identity_array(versors * __restrict q, size_t count) {
CGLM_ALIGN(16) versor v = GLM_QUAT_IDENTITY_INIT;
size_t i;
for (i = 0; i < count; i++) {
glm_vec4_copy(v, q[i].raw);
}
}
/*!
* @brief inits quaterion with raw values
*
* @param[in] x x
* @param[in] y y
* @param[in] z z
* @param[in] w w (real part)
* @returns quaternion
*/
CGLM_INLINE
versors
glms_quat_init(float x, float y, float z, float w) {
versors dest;
glm_quat_init(dest.raw, x, y, z, w);
return dest;
}
/*!
* @brief creates NEW quaternion with axis vector
*
* @param[in] angle angle (radians)
* @param[in] axis axis
* @returns quaternion
*/
CGLM_INLINE
versors
glms_quatv(float angle, vec3s axis) {
versors dest;
glm_quatv(dest.raw, angle, axis.raw);
return dest;
}
/*!
* @brief creates NEW quaternion with individual axis components
*
* @param[in] angle angle (radians)
* @param[in] x axis.x
* @param[in] y axis.y
* @param[in] z axis.z
* @returns quaternion
*/
CGLM_INLINE
versors
glms_quat(float angle, float x, float y, float z) {
versors dest;
glm_quat(dest.raw, angle, x, y, z);
return dest;
}
/*!
* @brief returns norm (magnitude) of quaternion
*
* @param[out] q quaternion
*/
CGLM_INLINE
float
glms_quat_norm(versors q) {
return glm_quat_norm(q.raw);
}
/*!
* @brief normalize quaternion
*
* @param[in] q quaternion
* @returns quaternion
*/
CGLM_INLINE
versors
glms_quat_normalize(versors q) {
versors dest;
glm_quat_normalize_to(q.raw, dest.raw);
return dest;
}
/*!
* @brief dot product of two quaternion
*
* @param[in] p quaternion 1
* @param[in] q quaternion 2
* @returns dot product
*/
CGLM_INLINE
float
glms_quat_dot(versors p, versors q) {
return glm_quat_dot(p.raw, q.raw);
}
/*!
* @brief conjugate of quaternion
*
* @param[in] q quaternion
* @returns conjugate
*/
CGLM_INLINE
versors
glms_quat_conjugate(versors q) {
versors dest;
glm_quat_conjugate(q.raw, dest.raw);
return dest;
}
/*!
* @brief inverse of non-zero quaternion
*
* @param[in] q quaternion
* @returns inverse quaternion
*/
CGLM_INLINE
versors
glms_quat_inv(versors q) {
versors dest;
glm_quat_inv(q.raw, dest.raw);
return dest;
}
/*!
* @brief add (componentwise) two quaternions and store result in dest
*
* @param[in] p quaternion 1
* @param[in] q quaternion 2
* @returns result quaternion
*/
CGLM_INLINE
versors
glms_quat_add(versors p, versors q) {
versors dest;
glm_quat_add(p.raw, q.raw, dest.raw);
return dest;
}
/*!
* @brief subtract (componentwise) two quaternions and store result in dest
*
* @param[in] p quaternion 1
* @param[in] q quaternion 2
* @returns result quaternion
*/
CGLM_INLINE
versors
glms_quat_sub(versors p, versors q) {
versors dest;
glm_quat_sub(p.raw, q.raw, dest.raw);
return dest;
}
/*!
* @brief returns normalized imaginary part of quaternion
*
* @param[in] q quaternion
*/
CGLM_INLINE
vec3s
glms_quat_imagn(versors q) {
vec3s dest;
glm_normalize_to(q.imag.raw, dest.raw);
return dest;
}
/*!
* @brief returns length of imaginary part of quaternion
*
* @param[in] q quaternion
*/
CGLM_INLINE
float
glms_quat_imaglen(versors q) {
return glm_quat_imaglen(q.raw);
}
/*!
* @brief returns angle of quaternion
*
* @param[in] q quaternion
*/
CGLM_INLINE
float
glms_quat_angle(versors q) {
return glm_quat_angle(q.raw);
}
/*!
* @brief axis of quaternion
*
* @param[in] q quaternion
* @returns axis of quaternion
*/
CGLM_INLINE
vec3s
glms_quat_axis(versors q) {
vec3s dest;
glm_quat_axis(q.raw, dest.raw);
return dest;
}
/*!
* @brief multiplies two quaternion and stores result in dest
* this is also called Hamilton Product
*
* According to WikiPedia:
* The product of two rotation quaternions [clarification needed] will be
* equivalent to the rotation q followed by the rotation p
*
* @param[in] p quaternion 1
* @param[in] q quaternion 2
* @returns result quaternion
*/
CGLM_INLINE
versors
glms_quat_mul(versors p, versors q) {
versors dest;
glm_quat_mul(p.raw, q.raw, dest.raw);
return dest;
}
/*!
* @brief convert quaternion to mat4
*
* @param[in] q quaternion
* @returns result matrix
*/
CGLM_INLINE
mat4s
glms_quat_mat4(versors q) {
mat4s dest;
glm_quat_mat4(q.raw, dest.raw);
return dest;
}
/*!
* @brief convert quaternion to mat4 (transposed)
*
* @param[in] q quaternion
* @returns result matrix as transposed
*/
CGLM_INLINE
mat4s
glms_quat_mat4t(versors q) {
mat4s dest;
glm_quat_mat4t(q.raw, dest.raw);
return dest;
}
/*!
* @brief convert quaternion to mat3
*
* @param[in] q quaternion
* @returns result matrix
*/
CGLM_INLINE
mat3s
glms_quat_mat3(versors q) {
mat3s dest;
glm_quat_mat3(q.raw, dest.raw);
return dest;
}
/*!
* @brief convert quaternion to mat3 (transposed)
*
* @param[in] q quaternion
* @returns result matrix
*/
CGLM_INLINE
mat3s
glms_quat_mat3t(versors q) {
mat3s dest;
glm_quat_mat3t(q.raw, dest.raw);
return dest;
}
/*!
* @brief interpolates between two quaternions
* using linear interpolation (LERP)
*
* @param[in] from from
* @param[in] to to
* @param[in] t interpolant (amount) clamped between 0 and 1
* @returns result quaternion
*/
CGLM_INLINE
versors
glms_quat_lerp(versors from, versors to, float t) {
versors dest;
glm_quat_lerp(from.raw, to.raw, t, dest.raw);
return dest;
}
/*!
* @brief interpolates between two quaternions
* using spherical linear interpolation (SLERP)
*
* @param[in] from from
* @param[in] to to
* @param[in] t amout
* @returns result quaternion
*/
CGLM_INLINE
versors
glms_quat_slerp(versors from, versors to, float t) {
versors dest;
glm_quat_slerp(from.raw, to.raw, t, dest.raw);
return dest;
}
/*!
* @brief creates view matrix using quaternion as camera orientation
*
* @param[in] eye eye
* @param[in] ori orientation in world space as quaternion
* @returns view matrix
*/
CGLM_INLINE
mat4s
glms_quat_look(vec3s eye, versors ori) {
mat4s dest;
glm_quat_look(eye.raw, ori.raw, dest.raw);
return dest;
}
/*!
* @brief creates look rotation quaternion
*
* @param[in] dir direction to look
* @param[in] fwd forward vector
* @param[in] up up vector
* @returns destination quaternion
*/
CGLM_INLINE
versors
glms_quat_for(vec3s dir, vec3s fwd, vec3s up) {
versors dest;
glm_quat_for(dir.raw, fwd.raw, up.raw, dest.raw);
return dest;
}
/*!
* @brief creates look rotation quaternion using source and
* destination positions p suffix stands for position
*
* @param[in] from source point
* @param[in] to destination point
* @param[in] fwd forward vector
* @param[in] up up vector
* @returns destination quaternion
*/
CGLM_INLINE
versors
glms_quat_forp(vec3s from, vec3s to, vec3s fwd, vec3s up) {
versors dest;
glm_quat_forp(from.raw, to.raw, fwd.raw, up.raw, dest.raw);
return dest;
}
/*!
* @brief rotate vector using using quaternion
*
* @param[in] q quaternion
* @param[in] v vector to rotate
* @returns rotated vector
*/
CGLM_INLINE
vec3s
glms_quat_rotatev(versors q, vec3s v) {
vec3s dest;
glm_quat_rotatev(q.raw, v.raw, dest.raw);
return dest;
}
/*!
* @brief rotate existing transform matrix using quaternion
*
* @param[in] m existing transform matrix
* @param[in] q quaternion
* @returns rotated matrix/transform
*/
CGLM_INLINE
mat4s
glms_quat_rotate(mat4s m, versors q) {
glm_quat_rotate(m.raw, q.raw, m.raw);
return m;
}
/*!
* @brief rotate existing transform matrix using quaternion at pivot point
*
* @param[in, out] m existing transform matrix
* @param[in] q quaternion
* @returns pivot
*/
CGLM_INLINE
mat4s
glms_quat_rotate_at(mat4s m, versors q, vec3s pivot) {
glm_quat_rotate_at(m.raw, q.raw, pivot.raw);
return m;
}
/*!
* @brief rotate NEW transform matrix using quaternion at pivot point
*
* this creates rotation matrix, it assumes you don't have a matrix
*
* this should work faster than glm_quat_rotate_at because it reduces
* one glm_translate.
*
* @param[in] q quaternion
* @returns pivot
*/
CGLM_INLINE
mat4s
glms_quat_rotate_atm(versors q, vec3s pivot) {
mat4s dest;
glm_quat_rotate_atm(dest.raw, q.raw, pivot.raw);
return dest;
}
#endif /* cglms_quat_h */

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_spheres_h
#define cglms_spheres_h
#include "../common.h"
#include "../types-struct.h"
#include "../sphere.h"
#include "mat4.h"
/*
Sphere Representation in cglm: [center.x, center.y, center.z, radii]
You could use this representation or you can convert it to vec4 before call
any function
*/
/*!
* @brief helper for getting sphere radius
*
* @param[in] s sphere
*
* @return returns radii
*/
CGLM_INLINE
float
glms_sphere_radii(vec4s s) {
return glm_sphere_radii(s.raw);
}
/*!
* @brief apply transform to sphere, it is just wrapper for glm_mat4_mulv3
*
* @param[in] s sphere
* @param[in] m transform matrix
* @returns transformed sphere
*/
CGLM_INLINE
vec4s
glms_sphere_transform(vec4s s, mat4 m) {
vec4s r;
glm_sphere_transform(s.raw, m, r.raw);
return r;
}
/*!
* @brief merges two spheres and creates a new one
*
* two sphere must be in same space, for instance if one in world space then
* the other must be in world space too, not in local space.
*
* @param[in] s1 sphere 1
* @param[in] s2 sphere 2
* returns merged/extended sphere
*/
CGLM_INLINE
vec4s
glms_sphere_merge(vec4s s1, vec4s s2) {
vec4s r;
glm_sphere_merge(s1.raw, s2.raw, r.raw);
return r;
}
/*!
* @brief check if two sphere intersects
*
* @param[in] s1 sphere
* @param[in] s2 other sphere
*/
CGLM_INLINE
bool
glms_sphere_sphere(vec4s s1, vec4s s2) {
return glm_sphere_sphere(s1.raw, s2.raw);
}
/*!
* @brief check if sphere intersects with point
*
* @param[in] s sphere
* @param[in] point point
*/
CGLM_INLINE
bool
glms_sphere_point(vec4s s, vec3s point) {
return glm_sphere_point(s.raw, point.raw);
}
#endif /* cglms_spheres_h */

View File

@@ -0,0 +1,198 @@
/*
* 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 vec3s glms_vec3_broadcast(float val);
CGLM_INLINE bool glms_vec3_eq(vec3s v, float val);
CGLM_INLINE bool glms_vec3_eq_eps(vec3s v, float val);
CGLM_INLINE bool glms_vec3_eq_all(vec3s v);
CGLM_INLINE bool glms_vec3_eqv(vec3s a, vec3s b);
CGLM_INLINE bool glms_vec3_eqv_eps(vec3s a, vec3s b);
CGLM_INLINE float glms_vec3_max(vec3s v);
CGLM_INLINE float glms_vec3_min(vec3s v);
CGLM_INLINE bool glms_vec3_isnan(vec3s v);
CGLM_INLINE bool glms_vec3_isinf(vec3s v);
CGLM_INLINE bool glms_vec3_isvalid(vec3s v);
CGLM_INLINE vec3s glms_vec3_sign(vec3s v);
CGLM_INLINE vec3s glms_vec3_sqrt(vec3s v);
*/
#ifndef cglms_vec3s_ext_h
#define cglms_vec3s_ext_h
#include "../common.h"
#include "../types-struct.h"
#include "../util.h"
#include "../vec3-ext.h"
/*!
* @brief fill a vector with specified value
*
* @param[in] val value
* @returns dest
*/
CGLM_INLINE
vec3s
glms_vec3_broadcast(float val) {
vec3s r;
glm_vec3_broadcast(val, r.raw);
return r;
}
/*!
* @brief check if vector is equal to value (without epsilon)
*
* @param[in] v vector
* @param[in] val value
*/
CGLM_INLINE
bool
glms_vec3_eq(vec3s v, float val) {
return glm_vec3_eq(v.raw, val);
}
/*!
* @brief check if vector is equal to value (with epsilon)
*
* @param[in] v vector
* @param[in] val value
*/
CGLM_INLINE
bool
glms_vec3_eq_eps(vec3s v, float val) {
return glm_vec3_eq_eps(v.raw, val);
}
/*!
* @brief check if vectors members are equal (without epsilon)
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec3_eq_all(vec3s v) {
return glm_vec3_eq_all(v.raw);
}
/*!
* @brief check if vector is equal to another (without epsilon)
*
* @param[in] a vector
* @param[in] b vector
*/
CGLM_INLINE
bool
glms_vec3_eqv(vec3s a, vec3s b) {
return glm_vec3_eqv(a.raw, b.raw);
}
/*!
* @brief check if vector is equal to another (with epsilon)
*
* @param[in] a vector
* @param[in] b vector
*/
CGLM_INLINE
bool
glms_vec3_eqv_eps(vec3s a, vec3s b) {
return glm_vec3_eqv_eps(a.raw, b.raw);
}
/*!
* @brief max value of vector
*
* @param[in] v vector
*/
CGLM_INLINE
float
glms_vec3_max(vec3s v) {
return glm_vec3_max(v.raw);
}
/*!
* @brief min value of vector
*
* @param[in] v vector
*/
CGLM_INLINE
float
glms_vec3_min(vec3s v) {
return glm_vec3_min(v.raw);
}
/*!
* @brief check if all items are NaN (not a number)
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec3_isnan(vec3s v) {
return glm_vec3_isnan(v.raw);
}
/*!
* @brief check if all items are INFINITY
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec3_isinf(vec3s v) {
return glm_vec3_isinf(v.raw);
}
/*!
* @brief check if all items are valid number
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec3_isvalid(vec3s v) {
return glm_vec3_isvalid(v.raw);
}
/*!
* @brief get sign of 32 bit float as +1, -1, 0
*
* Important: It returns 0 for zero/NaN input
*
* @param v vector
* @returns sign vector
*/
CGLM_INLINE
vec3s
glms_vec3_sign(vec3s v) {
vec3s r;
glm_vec3_sign(v.raw, r.raw);
return r;
}
/*!
* @brief square root of each vector item
*
* @param[in] v vector
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_sqrt(vec3s v) {
vec3s r;
glm_vec3_sqrt(v.raw, r.raw);
return r;
}
#endif /* cglms_vec3s_ext_h */

768
include/cglm/struct/vec3.h Normal file
View File

@@ -0,0 +1,768 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Macros:
GLMS_VEC3_ONE_INIT
GLMS_VEC3_ZERO_INIT
GLMS_VEC3_ONE
GLMS_VEC3_ZERO
GLMS_YUP
GLMS_ZUP
GLMS_XUP
Functions:
CGLM_INLINE vec3s glms_vec3(vec4s v4);
CGLM_INLINE void glms_vec3_pack(vec3s dst[], vec3 src[], size_t len);
CGLM_INLINE void glms_vec3_unpack(vec3 dst[], vec3s src[], size_t len);
CGLM_INLINE vec3s glms_vec3_zero();
CGLM_INLINE vec3s glms_vec3_one();
CGLM_INLINE float glms_vec3_dot(vec3s a, vec3s b);
CGLM_INLINE float glms_vec3_norm2(vec3s v);
CGLM_INLINE float glms_vec3_norm(vec3s v);
CGLM_INLINE vec3s glms_vec3_add(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_adds(vec3s a, float s);
CGLM_INLINE vec3s glms_vec3_sub(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_subs(vec3s a, float s);
CGLM_INLINE vec3s glms_vec3_mul(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_scale(vec3s v, float s);
CGLM_INLINE vec3s glms_vec3_scale_as(vec3s v, float s);
CGLM_INLINE vec3s glms_vec3_div(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_divs(vec3s a, float s);
CGLM_INLINE vec3s glms_vec3_addadd(vec3s a, vec3s b, vec3s dest);
CGLM_INLINE vec3s glms_vec3_subadd(vec3s a, vec3s b, vec3s dest);
CGLM_INLINE vec3s glms_vec3_muladd(vec3s a, vec3s b, vec3s dest);
CGLM_INLINE vec3s glms_vec3_muladds(vec3s a, float s, vec3s dest);
CGLM_INLINE vec3s glms_vec3_maxadd(vec3s a, vec3s b, vec3s dest);
CGLM_INLINE vec3s glms_vec3_minadd(vec3s a, vec3s b, vec3s dest);
CGLM_INLINE vec3s glms_vec3_flipsign(vec3s v);
CGLM_INLINE vec3s glms_vec3_negate(vec3s v);
CGLM_INLINE vec3s glms_vec3_inv(vec3s v);
CGLM_INLINE vec3s glms_vec3_normalize(vec3s v);
CGLM_INLINE vec3s glms_vec3_cross(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_crossn(vec3s a, vec3s b);
CGLM_INLINE float glms_vec3_distance(vec3s a, vec3s b);
CGLM_INLINE float glms_vec3_angle(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_rotate(vec3s v, float angle, vec3s axis);
CGLM_INLINE vec3s glms_vec3_rotate_m4(mat4s m, vec3s v);
CGLM_INLINE vec3s glms_vec3_rotate_m3(mat3s m, vec3s v);
CGLM_INLINE vec3s glms_vec3_proj(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_center(vec3s a, vec3s b);
CGLM_INLINE float glms_vec3_distance2(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_maxv(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_minv(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_vec3_ortho(vec3s v);
CGLM_INLINE vec3s glms_vec3_clamp(vec3s v, float minVal, float maxVal);
CGLM_INLINE vec3s glms_vec3_lerp(vec3s from, vec3s to, float t);
CGLM_INLINE vec3s glms_vec3_swizzle(vec3s v, int mask);
Convenient:
CGLM_INLINE vec3s glms_cross(vec3s a, vec3s b);
CGLM_INLINE float glms_dot(vec3s a, vec3s b);
CGLM_INLINE vec3s glms_normalize(vec3s v);
*/
#ifndef cglms_vec3s_h
#define cglms_vec3s_h
#include "../common.h"
#include "../types-struct.h"
#include "../util.h"
#include "../vec3.h"
#include "vec3-ext.h"
#define GLMS_VEC3_ONE_INIT {1.0f, 1.0f, 1.0f}
#define GLMS_VEC3_ZERO_INIT {0.0f, 0.0f, 0.0f}
#define GLMS_VEC3_ONE ((vec3s)GLMS_VEC3_ONE_INIT)
#define GLMS_VEC3_ZERO ((vec3s)GLMS_VEC3_ZERO_INIT)
#define GLMS_YUP ((vec3s){0.0f, 1.0f, 0.0f})
#define GLMS_ZUP ((vec3s){0.0f, 0.0f, 1.0f})
#define GLMS_XUP ((vec3s){1.0f, 0.0f, 0.0f})
/*!
* @brief init vec3 using vec4
*
* @param[in] v4 vector4
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3(vec4s v4) {
vec3s r;
glm_vec3(v4.raw, r.raw);
return r;
}
/*!
* @brief pack an array of vec3 into an array of vec3s
*
* @param[out] dst array of vec3
* @param[in] src array of vec3s
* @param[in] len number of elements
*/
CGLM_INLINE
void
glms_vec3_pack(vec3s dst[], vec3 src[], size_t len) {
size_t i;
for (i = 0; i < len; i++) {
glm_vec3_copy(src[i], dst[i].raw);
}
}
/*!
* @brief unpack an array of vec3s into an array of vec3
*
* @param[out] dst array of vec3s
* @param[in] src array of vec3
* @param[in] len number of elements
*/
CGLM_INLINE
void
glms_vec3_unpack(vec3 dst[], vec3s src[], size_t len) {
size_t i;
for (i = 0; i < len; i++) {
glm_vec3_copy(src[i].raw, dst[i]);
}
}
/*!
* @brief make vector zero
*
* @returns zero vector
*/
CGLM_INLINE
vec3s
glms_vec3_zero() {
vec3s r;
glm_vec3_zero(r.raw);
return r;
}
/*!
* @brief make vector one
*
* @returns one vector
*/
CGLM_INLINE
vec3s
glms_vec3_one() {
vec3s r;
glm_vec3_one(r.raw);
return r;
}
/*!
* @brief vec3 dot product
*
* @param[in] a vector1
* @param[in] b vector2
*
* @return dot product
*/
CGLM_INLINE
float
glms_vec3_dot(vec3s a, vec3s b) {
return glm_vec3_dot(a.raw, b.raw);
}
/*!
* @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
glms_vec3_norm2(vec3s v) {
return glm_vec3_norm2(v.raw);
}
/*!
* @brief norm (magnitude) of vec3
*
* @param[in] v vector
*
* @return norm
*/
CGLM_INLINE
float
glms_vec3_norm(vec3s v) {
return glm_vec3_norm(v.raw);
}
/*!
* @brief add a vector to b vector store result in dest
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_add(vec3s a, vec3s b) {
vec3s r;
glm_vec3_add(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief add scalar to v vector store result in dest (d = v + s)
*
* @param[in] a vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_adds(vec3s a, float s) {
vec3s r;
glm_vec3_adds(a.raw, s, r.raw);
return r;
}
/*!
* @brief subtract b vector from a vector store result in dest
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_sub(vec3s a, vec3s b) {
vec3s r;
glm_vec3_sub(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief subtract scalar from v vector store result in dest (d = v - s)
*
* @param[in] a vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_subs(vec3s a, float s) {
vec3s r;
glm_vec3_subs(a.raw, s, r.raw);
return r;
}
/*!
* @brief multiply two vector (component-wise multiplication)
*
* @param a vector1
* @param b vector2
* @returns v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
*/
CGLM_INLINE
vec3s
glms_vec3_mul(vec3s a, vec3s b) {
vec3s r;
glm_vec3_mul(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief multiply/scale vec3 vector with scalar: result = v * s
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_scale(vec3s v, float s) {
vec3s r;
glm_vec3_scale(v.raw, s, r.raw);
return r;
}
/*!
* @brief make vec3 vector scale as specified: result = unit(v) * s
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec3s
glms_vec3_scale_as(vec3s v, float s) {
vec3s r;
glm_vec3_scale_as(v.raw, s, r.raw);
return r;
}
/*!
* @brief div vector with another component-wise division: d = a / b
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns result = (a[0]/b[0], a[1]/b[1], a[2]/b[2])
*/
CGLM_INLINE
vec3s
glms_vec3_div(vec3s a, vec3s b) {
vec3s r;
glm_vec3_div(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief div vector with scalar: d = v / s
*
* @param[in] a vector
* @param[in] s scalar
* @returns result = (a[0]/s, a[1]/s, a[2]/s)
*/
CGLM_INLINE
vec3s
glms_vec3_divs(vec3s a, float s) {
vec3s r;
glm_vec3_divs(a.raw, s, r.raw);
return r;
}
/*!
* @brief add two vectors and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a + b)
*/
CGLM_INLINE
vec3s
glms_vec3_addadd(vec3s a, vec3s b, vec3s dest) {
glm_vec3_addadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief sub two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a + b)
*/
CGLM_INLINE
vec3s
glms_vec3_subadd(vec3s a, vec3s b, vec3s dest) {
glm_vec3_subadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief mul two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a * b)
*/
CGLM_INLINE
vec3s
glms_vec3_muladd(vec3s a, vec3s b, vec3s dest) {
glm_vec3_muladd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief mul vector with scalar and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] s scalar
* @returns dest += (a * b)
*/
CGLM_INLINE
vec3s
glms_vec3_muladds(vec3s a, float s, vec3s dest) {
glm_vec3_muladds(a.raw, s, dest.raw);
return dest;
}
/*!
* @brief add max of two vector to result/dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += max(a, b)
*/
CGLM_INLINE
vec3s
glms_vec3_maxadd(vec3s a, vec3s b, vec3s dest) {
glm_vec3_maxadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief add min of two vector to result/dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += min(a, b)
*/
CGLM_INLINE
vec3s
glms_vec3_minadd(vec3s a, vec3s b, vec3s dest) {
glm_vec3_minadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief negate vector components and store result in dest
*
* @param[in] v vector
* @returns result vector
*/
CGLM_INLINE
vec3s
glms_vec3_flipsign(vec3s v) {
glm_vec3_flipsign(v.raw);
return v;
}
/*!
* @brief negate vector components
*
* @param[in] v vector
* @returns negated vector
*/
CGLM_INLINE
vec3s
glms_vec3_negate(vec3s v) {
glm_vec3_negate(v.raw);
return v;
}
/*!
* @brief normalize vec3 and store result in same vec
*
* @param[in] v vector
* @returns normalized vector
*/
CGLM_INLINE
vec3s
glms_vec3_normalize(vec3s v) {
glm_vec3_normalize(v.raw);
return v;
}
/*!
* @brief cross product of two vector (RH)
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3_cross(vec3s a, vec3s b) {
vec3s r;
glm_vec3_cross(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief cross product of two vector (RH) and normalize the result
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3_crossn(vec3s a, vec3s b) {
vec3s r;
glm_vec3_crossn(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief angle betwen two vector
*
* @param[in] a vector1
* @param[in] b vector2
*
* @return angle as radians
*/
CGLM_INLINE
float
glms_vec3_angle(vec3s a, vec3s b) {
return glm_vec3_angle(a.raw, b.raw);
}
/*!
* @brief rotate vec3 around axis by angle using Rodrigues' rotation formula
*
* @param[in] v vector
* @param[in] axis axis vector (must be unit vector)
* @param[in] angle angle by radians
* @returns rotated vector
*/
CGLM_INLINE
vec3s
glms_vec3_rotate(vec3s v, float angle, vec3s axis) {
glm_vec3_rotate(v.raw, angle, axis.raw);
return v;
}
/*!
* @brief apply rotation matrix to vector
*
* matrix format should be (no perspective):
* a b c x
* e f g y
* i j k z
* 0 0 0 w
*
* @param[in] m affine matrix or rot matrix
* @param[in] v vector
* @returns rotated vector
*/
CGLM_INLINE
vec3s
glms_vec3_rotate_m4(mat4s m, vec3s v) {
vec3s r;
glm_vec3_rotate_m4(m.raw, v.raw, r.raw);
return r;
}
/*!
* @brief apply rotation matrix to vector
*
* @param[in] m affine matrix or rot matrix
* @param[in] v vector
* @returns rotated vector
*/
CGLM_INLINE
vec3s
glms_vec3_rotate_m3(mat3s m, vec3s v) {
vec3s r;
glm_vec3_rotate_m3(m.raw, v.raw, r.raw);
return r;
}
/*!
* @brief project a vector onto b vector
*
* @param[in] a vector1
* @param[in] b vector2
* @returns projected vector
*/
CGLM_INLINE
vec3s
glms_vec3_proj(vec3s a, vec3s b) {
vec3s r;
glm_vec3_proj(a.raw, b.raw, r.raw);
return r;
}
/**
* @brief find center point of two vector
*
* @param[in] a vector1
* @param[in] b vector2
* @returns center point
*/
CGLM_INLINE
vec3s
glms_vec3_center(vec3s a, vec3s b) {
vec3s r;
glm_vec3_center(a.raw, b.raw, r.raw);
return r;
}
/**
* @brief squared distance between two vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @return squared distance (distance * distance)
*/
CGLM_INLINE
float
glms_vec3_distance2(vec3s a, vec3s b) {
return glm_vec3_distance2(a.raw, b.raw);
}
/**
* @brief distance between two vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @return distance
*/
CGLM_INLINE
float
glms_vec3_distance(vec3s a, vec3s b) {
return glm_vec3_distance(a.raw, b.raw);
}
/*!
* @brief max values of vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3_maxv(vec3s a, vec3s b) {
vec3s r;
glm_vec3_maxv(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief min values of vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3_minv(vec3s a, vec3s b) {
vec3s r;
glm_vec3_minv(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief possible orthogonal/perpendicular vector
*
* @param[in] v vector
* @returns orthogonal/perpendicular vector
*/
CGLM_INLINE
vec3s
glms_vec3_ortho(vec3s v) {
vec3s r;
glm_vec3_ortho(v.raw, r.raw);
return r;
}
/*!
* @brief clamp vector's individual members between min and max values
*
* @param[in] v vector
* @param[in] minVal minimum value
* @param[in] maxVal maximum value
* @returns clamped vector
*/
CGLM_INLINE
vec3s
glms_vec3_clamp(vec3s v, float minVal, float maxVal) {
glm_vec3_clamp(v.raw, minVal, maxVal);
return v;
}
/*!
* @brief linear interpolation between two vector
*
* formula: from + s * (to - from)
*
* @param[in] from from value
* @param[in] to to value
* @param[in] t interpolant (amount) clamped between 0 and 1
* @returns destination
*/
CGLM_INLINE
vec3s
glms_vec3_lerp(vec3s from, vec3s to, float t) {
vec3s r;
glm_vec3_lerp(from.raw, to.raw, t, r.raw);
return r;
}
/*!
* @brief vec3 cross product
*
* this is just convenient wrapper
*
* @param[in] a source 1
* @param[in] b source 2
* @returns destination
*/
CGLM_INLINE
vec3s
glms_cross(vec3s a, vec3s b) {
vec3s r;
glm_cross(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief vec3 dot product
*
* this is just convenient wrapper
*
* @param[in] a vector1
* @param[in] b vector2
* @return dot product
*/
CGLM_INLINE
float
glms_dot(vec3s a, vec3s b) {
return glm_dot(a.raw, b.raw);
}
/*!
* @brief normalize vec3 and store result in same vec
*
* this is just convenient wrapper
*
* @param[in] v vector
* @returns normalized vector
*/
CGLM_INLINE
vec3s
glms_normalize(vec3s v) {
glm_normalize(v.raw);
return v;
}
/*!
* @brief swizzle vector components
*
* you can use existin masks e.g. GLM_XXX, GLM_ZYX
*
* @param[in] v source
* @param[in] mask mask
* @returns swizzled vector
*/
CGLM_INLINE
vec3s
glms_vec3_swizzle(vec3s v, int mask) {
vec3s dest;
glm_vec3_swizzle(v.raw, mask, dest.raw);
return dest;
}
#endif /* cglms_vec3s_h */

View File

@@ -0,0 +1,198 @@
/*
* 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 vec4s glms_vec4_broadcast(float val);
CGLM_INLINE bool glms_vec4_eq(vec4s v, float val);
CGLM_INLINE bool glms_vec4_eq_eps(vec4s v, float val);
CGLM_INLINE bool glms_vec4_eq_all(vec4s v);
CGLM_INLINE bool glms_vec4_eqv(vec4s a, vec4s b);
CGLM_INLINE bool glms_vec4_eqv_eps(vec4s a, vec4s b);
CGLM_INLINE float glms_vec4_max(vec4s v);
CGLM_INLINE float glms_vec4_min(vec4s v);
CGLM_INLINE bool glms_vec4_isnan(vec4s v);
CGLM_INLINE bool glms_vec4_isinf(vec4s v);
CGLM_INLINE bool glms_vec4_isvalid(vec4s v);
CGLM_INLINE vec4s glms_vec4_sign(vec4s v);
CGLM_INLINE vec4s glms_vec4_sqrt(vec4s v);
*/
#ifndef cglms_vec4s_ext_h
#define cglms_vec4s_ext_h
#include "../common.h"
#include "../types-struct.h"
#include "../util.h"
#include "../vec4-ext.h"
/*!
* @brief fill a vector with specified value
*
* @param val value
* @returns dest
*/
CGLM_INLINE
vec4s
glms_vec4_broadcast(float val) {
vec4s r;
glm_vec4_broadcast(val, r.raw);
return r;
}
/*!
* @brief check if vector is equal to value (without epsilon)
*
* @param v vector
* @param val value
*/
CGLM_INLINE
bool
glms_vec4_eq(vec4s v, float val) {
return glm_vec4_eq(v.raw, val);
}
/*!
* @brief check if vector is equal to value (with epsilon)
*
* @param v vector
* @param val value
*/
CGLM_INLINE
bool
glms_vec4_eq_eps(vec4s v, float val) {
return glm_vec4_eq_eps(v.raw, val);
}
/*!
* @brief check if vectors members are equal (without epsilon)
*
* @param v vector
*/
CGLM_INLINE
bool
glms_vec4_eq_all(vec4s v) {
return glm_vec4_eq_all(v.raw);
}
/*!
* @brief check if vector is equal to another (without epsilon)
*
* @param a vector
* @param b vector
*/
CGLM_INLINE
bool
glms_vec4_eqv(vec4s a, vec4s b) {
return glm_vec4_eqv(a.raw, b.raw);
}
/*!
* @brief check if vector is equal to another (with epsilon)
*
* @param a vector
* @param b vector
*/
CGLM_INLINE
bool
glms_vec4_eqv_eps(vec4s a, vec4s b) {
return glm_vec4_eqv_eps(a.raw, b.raw);
}
/*!
* @brief max value of vector
*
* @param v vector
*/
CGLM_INLINE
float
glms_vec4_max(vec4s v) {
return glm_vec4_max(v.raw);
}
/*!
* @brief min value of vector
*
* @param v vector
*/
CGLM_INLINE
float
glms_vec4_min(vec4s v) {
return glm_vec4_min(v.raw);
}
/*!
* @brief check if one of items is NaN (not a number)
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec4_isnan(vec4s v) {
return glm_vec4_isnan(v.raw);
}
/*!
* @brief check if one of items is INFINITY
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec4_isinf(vec4s v) {
return glm_vec4_isinf(v.raw);
}
/*!
* @brief check if all items are valid number
* you should only use this in DEBUG mode or very critical asserts
*
* @param[in] v vector
*/
CGLM_INLINE
bool
glms_vec4_isvalid(vec4s v) {
return glm_vec4_isvalid(v.raw);
}
/*!
* @brief get sign of 32 bit float as +1, -1, 0
*
* Important: It returns 0 for zero/NaN input
*
* @param v vector
* @returns sign vector
*/
CGLM_INLINE
vec4s
glms_vec4_sign(vec4s v) {
vec4s r;
glm_vec4_sign(v.raw, r.raw);
return r;
}
/*!
* @brief square root of each vector item
*
* @param[in] v vector
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_sqrt(vec4s v) {
vec4s r;
glm_vec4_sqrt(v.raw, r.raw);
return r;
}
#endif /* cglms_vec4s_ext_h */

598
include/cglm/struct/vec4.h Normal file
View File

@@ -0,0 +1,598 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Macros:
GLM_VEC4_ONE_INIT
GLM_VEC4_BLACK_INIT
GLM_VEC4_ZERO_INIT
GLM_VEC4_ONE
GLM_VEC4_BLACK
GLM_VEC4_ZERO
Functions:
CGLM_INLINE vec4s glms_vec4(vec3s v3, float last);
CGLM_INLINE vec3s glms_vec4_copy3(vec4s v);
CGLM_INLINE vec4s glms_vec4_copy(vec4s v);
CGLM_INLINE vec4s glms_vec4_ucopy(vec4s v);
CGLM_INLINE void glms_vec4_pack(vec4s dst[], vec4 src[], size_t len);
CGLM_INLINE void glms_vec4_unpack(vec4 dst[], vec4s src[], size_t len);
CGLM_INLINE float glms_vec4_dot(vec4s a, vec4s b);
CGLM_INLINE float glms_vec4_norm2(vec4s v);
CGLM_INLINE float glms_vec4_norm(vec4s v);
CGLM_INLINE vec4s glms_vec4_add(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_adds(vec4s v, float s);
CGLM_INLINE vec4s glms_vec4_sub(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_subs(vec4s v, float s);
CGLM_INLINE vec4s glms_vec4_mul(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_scale(vec4s v, float s);
CGLM_INLINE vec4s glms_vec4_scale_as(vec4s v, float s);
CGLM_INLINE vec4s glms_vec4_div(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_divs(vec4s v, float s);
CGLM_INLINE vec4s glms_vec4_addadd(vec4s a, vec4s b, vec4s dest);
CGLM_INLINE vec4s glms_vec4_subadd(vec4s a, vec4s b, vec4s dest);
CGLM_INLINE vec4s glms_vec4_muladd(vec4s a, vec4s b, vec4s dest);
CGLM_INLINE vec4s glms_vec4_muladds(vec4s a, float s, vec4s dest);
CGLM_INLINE vec4s glms_vec4_maxadd(vec4s a, vec4s b, vec4s dest);
CGLM_INLINE vec4s glms_vec4_minadd(vec4s a, vec4s b, vec4s dest);
CGLM_INLINE vec4s glms_vec4_negate(vec4s v);
CGLM_INLINE vec4s glms_vec4_inv(vec4s v);
CGLM_INLINE vec4s glms_vec4_normalize(vec4s v);
CGLM_INLINE float glms_vec4_distance(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_maxv(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_minv(vec4s a, vec4s b);
CGLM_INLINE vec4s glms_vec4_clamp(vec4s v, float minVal, float maxVal);
CGLM_INLINE vec4s glms_vec4_lerp(vec4s from, vec4s to, float t);
CGLM_INLINE vec4s glms_vec4_cubic(float s);
CGLM_INLINE vec4s glms_vec4_swizzle(vec4s v, int mask);
*/
#ifndef cglms_vec4s_h
#define cglms_vec4s_h
#include "../common.h"
#include "../types-struct.h"
#include "../util.h"
#include "../vec4.h"
#include "vec4-ext.h"
#define GLMS_VEC4_ONE_INIT {1.0f, 1.0f, 1.0f, 1.0f}
#define GLMS_VEC4_BLACK_INIT {0.0f, 0.0f, 0.0f, 1.0f}
#define GLMS_VEC4_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f}
#define GLMS_VEC4_ONE ((vec4s)GLM_VEC4_ONE_INIT)
#define GLMS_VEC4_BLACK ((vec4s)GLM_VEC4_BLACK_INIT)
#define GLMS_VEC4_ZERO ((vec4s)GLM_VEC4_ZERO_INIT)
/*!
* @brief init vec4 using vec3
*
* @param[in] v3 vector3
* @param[in] last last item
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4(vec3s v3, float last) {
vec4s r;
glm_vec4(v3.raw, last, r.raw);
return r;
}
/*!
* @brief copy first 3 members of [a] to [dest]
*
* @param[in] v source
* @returns vec3
*/
CGLM_INLINE
vec3s
glms_vec4_copy3(vec4s v) {
vec3s r;
glm_vec4_copy3(v.raw, r.raw);
return r;
}
/*!
* @brief copy all members of [a] to [dest]
*
* @param[in] v source
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_copy(vec4s v) {
vec4s r;
glm_vec4_copy(v.raw, r.raw);
return r;
}
/*!
* @brief copy all members of [a] to [dest]
*
* alignment is not required
*
* @param[in] v source
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_ucopy(vec4s v) {
vec4s r;
glm_vec4_ucopy(v.raw, r.raw);
return r;
}
/*!
* @brief pack an array of vec4 into an array of vec4s
*
* @param[out] dst array of vec4
* @param[in] src array of vec4s
* @param[in] len number of elements
*/
CGLM_INLINE
void
glms_vec4_pack(vec4s dst[], vec4 src[], size_t len) {
size_t i;
for (i = 0; i < len; i++) {
glm_vec4_copy(src[i], dst[i].raw);
}
}
/*!
* @brief unpack an array of vec4s into an array of vec4
*
* @param[out] dst array of vec4s
* @param[in] src array of vec4
* @param[in] len number of elements
*/
CGLM_INLINE
void
glms_vec4_unpack(vec4 dst[], vec4s src[], size_t len) {
size_t i;
for (i = 0; i < len; i++) {
glm_vec4_copy(src[i].raw, dst[i]);
}
}
/*!
* @brief make vector zero
*
* @returns zero vector
*/
CGLM_INLINE
vec4s
glms_vec4_zero() {
vec4s r;
glm_vec4_zero(r.raw);
return r;
}
/*!
* @brief make vector one
*
* @returns one vector
*/
CGLM_INLINE
vec4s
glms_vec4_one() {
vec4s r;
glm_vec4_one(r.raw);
return r;
}
/*!
* @brief vec4 dot product
*
* @param[in] a vector1
* @param[in] b vector2
*
* @return dot product
*/
CGLM_INLINE
float
glms_vec4_dot(vec4s a, vec4s b) {
return glm_vec4_dot(a.raw, b.raw);
}
/*!
* @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
glms_vec4_norm2(vec4s v) {
return glm_vec4_norm2(v.raw);
}
/*!
* @brief norm (magnitude) of vec4
*
* @param[in] v vector
*
* @return norm
*/
CGLM_INLINE
float
glms_vec4_norm(vec4s v) {
return glm_vec4_norm(v.raw);
}
/*!
* @brief add b vector to a vector store result in dest
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_add(vec4s a, vec4s b) {
vec4s r;
glm_vec4_add(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief add scalar to v vector store result in dest (d = v + vec(s))
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_adds(vec4s v, float s) {
vec4s r;
glm_vec4_adds(v.raw, s, r.raw);
return r;
}
/*!
* @brief subtract b vector from a vector store result in dest (d = a - b)
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_sub(vec4s a, vec4s b) {
vec4s r;
glm_vec4_sub(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief subtract scalar from v vector store result in dest (d = v - vec(s))
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_subs(vec4s v, float s) {
vec4s r;
glm_vec4_subs(v.raw, s, r.raw);
return r;
}
/*!
* @brief multiply two vector (component-wise multiplication)
*
* @param a vector1
* @param b vector2
* @returns dest = (a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3])
*/
CGLM_INLINE
vec4s
glms_vec4_mul(vec4s a, vec4s b) {
vec4s r;
glm_vec4_mul(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief multiply/scale vec4 vector with scalar: result = v * s
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_scale(vec4s v, float s) {
vec4s r;
glm_vec4_scale(v.raw, s, r.raw);
return r;
}
/*!
* @brief make vec4 vector scale as specified: result = unit(v) * s
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_scale_as(vec4s v, float s) {
vec4s r;
glm_vec4_scale_as(v.raw, s, r.raw);
return r;
}
/*!
* @brief div vector with another component-wise division: d = a / b
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns result = (a[0]/b[0], a[1]/b[1], a[2]/b[2], a[3]/b[3])
*/
CGLM_INLINE
vec4s
glms_vec4_div(vec4s a, vec4s b) {
vec4s r;
glm_vec4_div(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief div vec4 vector with scalar: d = v / s
*
* @param[in] v vector
* @param[in] s scalar
* @returns destination vector
*/
CGLM_INLINE
vec4s
glms_vec4_divs(vec4s v, float s) {
vec4s r;
glm_vec4_divs(v.raw, s, r.raw);
return r;
}
/*!
* @brief add two vectors and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a + b)
*/
CGLM_INLINE
vec4s
glms_vec4_addadd(vec4s a, vec4s b, vec4s dest) {
glm_vec4_addadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief sub two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a - b)
*/
CGLM_INLINE
vec4s
glms_vec4_subadd(vec4s a, vec4s b, vec4s dest) {
glm_vec4_subadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief mul two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += (a * b)
*/
CGLM_INLINE
vec4s
glms_vec4_muladd(vec4s a, vec4s b, vec4s dest) {
glm_vec4_muladd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief mul vector with scalar and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] s scalar
* @returns dest += (a * b)
*/
CGLM_INLINE
vec4s
glms_vec4_muladds(vec4s a, float s, vec4s dest) {
glm_vec4_muladds(a.raw, s, dest.raw);
return dest;
}
/*!
* @brief add max of two vector to result/dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += max(a, b)
*/
CGLM_INLINE
vec4s
glms_vec4_maxadd(vec4s a, vec4s b, vec4s dest) {
glm_vec4_maxadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief add min of two vector to result/dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @returns dest += min(a, b)
*/
CGLM_INLINE
vec4s
glms_vec4_minadd(vec4s a, vec4s b, vec4s dest) {
glm_vec4_minadd(a.raw, b.raw, dest.raw);
return dest;
}
/*!
* @brief negate vector components and store result in dest
*
* @param[in] v vector
* @returns result vector
*/
CGLM_INLINE
vec4s
glms_vec4_negate(vec4s v) {
glm_vec4_negate(v.raw);
return v;
}
/*!
* @brief normalize vec4 and store result in same vec
*
* @param[in] v vector
* @returns normalized vector
*/
CGLM_INLINE
vec4s
glms_vec4_normalize(vec4s v) {
glm_vec4_normalize(v.raw);
return v;
}
/**
* @brief distance between two vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @return returns distance
*/
CGLM_INLINE
float
glms_vec4_distance(vec4s a, vec4s b) {
return glm_vec4_distance(a.raw, b.raw);
}
/*!
* @brief max values of vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_maxv(vec4s a, vec4s b) {
vec4s r;
glm_vec4_maxv(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief min values of vectors
*
* @param[in] a vector1
* @param[in] b vector2
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_minv(vec4s a, vec4s b) {
vec4s r;
glm_vec4_minv(a.raw, b.raw, r.raw);
return r;
}
/*!
* @brief clamp vector's individual members between min and max values
*
* @param[in] v vector
* @param[in] minVal minimum value
* @param[in] maxVal maximum value
* @returns clamped vector
*/
CGLM_INLINE
vec4s
glms_vec4_clamp(vec4s v, float minVal, float maxVal) {
glm_vec4_clamp(v.raw, minVal, maxVal);
return v;
}
/*!
* @brief linear interpolation between two vector
*
* formula: from + s * (to - from)
*
* @param[in] from from value
* @param[in] to to value
* @param[in] t interpolant (amount) clamped between 0 and 1
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_lerp(vec4s from, vec4s to, float t) {
vec4s r;
glm_vec4_lerp(from.raw, to.raw, t, r.raw);
return r;
}
/*!
* @brief helper to fill vec4 as [S^3, S^2, S, 1]
*
* @param[in] s parameter
* @returns destination
*/
CGLM_INLINE
vec4s
glms_vec4_cubic(float s) {
vec4s r;
glm_vec4_cubic(s, r.raw);
return r;
}
/*!
* @brief swizzle vector components
*
* you can use existin masks e.g. GLM_XXXX, GLM_WZYX
*
* @param[in] v source
* @param[in] mask mask
* @returns swizzled vector
*/
CGLM_INLINE
vec4s
glms_vec4_swizzle(vec4s v, int mask) {
vec4s dest;
glm_vec4_swizzle(v.raw, mask, dest.raw);
return dest;
}
#endif /* cglms_vec4s_h */

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_types_struct_h
#define cglm_types_struct_h
#include "types.h"
typedef union vec3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
float x;
float y;
float z;
};
#endif
vec3 raw;
} vec3s;
typedef union ivec3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
int x;
int y;
int z;
};
#endif
ivec3 raw;
} ivec3s;
typedef union CGLM_ALIGN_IF(16) vec4s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
float x;
float y;
float z;
float w;
};
#endif
vec4 raw;
} vec4s;
typedef union CGLM_ALIGN_IF(16) versors {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
float x;
float y;
float z;
float w;
};
struct {
vec3s imag;
float real;
};
#endif
vec4 raw;
} versors;
typedef union mat3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
float m00, m01, m02;
float m10, m11, m12;
float m20, m21, m22;
};
#endif
vec3s col[3];
mat3 raw;
} mat3s;
typedef union CGLM_ALIGN_MAT mat4s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
struct {
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
};
#endif
vec4s col[4];
mat4 raw;
} mat4s;
#endif /* cglm_types_struct_h */

View File

@@ -38,14 +38,8 @@ typedef int ivec3[3];
typedef CGLM_ALIGN_IF(16) float vec4[4];
typedef vec4 versor;
typedef vec3 mat3[3];
// typedef vec4 mat2;
typedef CGLM_ALIGN_IF(16) vec2 mat2[2];
#ifdef __AVX__
typedef CGLM_ALIGN_IF(32) vec4 mat4[4];
#else
typedef CGLM_ALIGN_IF(16) vec4 mat4[4];
#endif
typedef CGLM_ALIGN_MAT vec4 mat4[4];
#define GLM_E 2.71828182845904523536028747135266250 /* e */
#define GLM_LOG2E 1.44269504088896340735992468100189214 /* log2(e) */

View File

@@ -19,7 +19,6 @@
#define cglm_util_h
#include "common.h"
#include <stdbool.h>
#define GLM_MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define GLM_MAX(X, Y) (((X) > (Y)) ? (X) : (Y))

View File

@@ -31,9 +31,6 @@
#include "common.h"
#include "util.h"
#include <stdbool.h>
#include <math.h>
#include <float.h>
/*!
* @brief fill a vector with specified value

View File

@@ -61,6 +61,7 @@
CGLM_INLINE void glm_vec3_ortho(vec3 v, vec3 dest);
CGLM_INLINE void glm_vec3_clamp(vec3 v, float minVal, float maxVal);
CGLM_INLINE void glm_vec3_lerp(vec3 from, vec3 to, float t, vec3 dest);
CGLM_INLINE void glm_vec3_swizzle(vec3 v, int mask, vec3 dest);
Convenient:
CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d);
@@ -103,6 +104,11 @@
#define GLM_ZUP ((vec3){0.0f, 0.0f, 1.0f})
#define GLM_XUP ((vec3){1.0f, 0.0f, 0.0f})
#define GLM_XXX GLM_SHUFFLE3(0, 0, 0)
#define GLM_YYY GLM_SHUFFLE3(1, 1, 1)
#define GLM_ZZZ GLM_SHUFFLE3(2, 2, 2)
#define GLM_ZYX GLM_SHUFFLE3(0, 1, 2)
/*!
* @brief init vec3 using vec4
*
@@ -428,8 +434,8 @@ glm_vec3_maxadd(vec3 a, vec3 b, vec3 dest) {
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] b scalar
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += min(a, b)
*/
CGLM_INLINE
@@ -845,4 +851,25 @@ glm_normalize_to(vec3 v, vec3 dest) {
glm_vec3_normalize_to(v, dest);
}
/*!
* @brief swizzle vector components
*
* you can use existin masks e.g. GLM_XXX, GLM_ZYX
*
* @param[in] v source
* @param[in] mask mask
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec3_swizzle(vec3 v, int mask, vec3 dest) {
vec3 t;
t[0] = v[(mask & (3 << 0))];
t[1] = v[(mask & (3 << 2)) >> 2];
t[2] = v[(mask & (3 << 4)) >> 4];
glm_vec3_copy(t, dest);
}
#endif /* cglm_vec3_h */

View File

@@ -31,9 +31,6 @@
#include "common.h"
#include "vec3-ext.h"
#include <stdbool.h>
#include <math.h>
#include <float.h>
/*!
* @brief fill a vector with specified value

View File

@@ -47,6 +47,7 @@
CGLM_INLINE void glm_vec4_minv(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal);
CGLM_INLINE void glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest)
CGLM_INLINE void glm_vec4_swizzle(vec4 v, int mask, vec4 dest);
DEPRECATED:
glm_vec4_dup
@@ -81,6 +82,12 @@
#define GLM_VEC4_BLACK ((vec4)GLM_VEC4_BLACK_INIT)
#define GLM_VEC4_ZERO ((vec4)GLM_VEC4_ZERO_INIT)
#define GLM_XXXX GLM_SHUFFLE4(0, 0, 0, 0)
#define GLM_YYYY GLM_SHUFFLE4(1, 1, 1, 1)
#define GLM_ZZZZ GLM_SHUFFLE4(2, 2, 2, 2)
#define GLM_WWWW GLM_SHUFFLE4(3, 3, 3, 3)
#define GLM_WZYX GLM_SHUFFLE4(0, 1, 2, 3)
/*!
* @brief init vec4 using vec3
*
@@ -576,8 +583,8 @@ glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) {
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] b scalar
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += min(a, b)
*/
CGLM_INLINE
@@ -690,18 +697,9 @@ CGLM_INLINE
float
glm_vec4_distance(vec4 a, vec4 b) {
#if defined( __SSE__ ) || defined( __SSE2__ )
__m128 x0;
x0 = _mm_sub_ps(glmm_load(b), glmm_load(a));
x0 = _mm_mul_ps(x0, x0);
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 3, 2));
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_add_ss(x0,
glmm_shuff1(x0, 0, 1, 0, 1))));
return glmm_norm(_mm_sub_ps(glmm_load(b), glmm_load(a)));
#elif defined(CGLM_NEON_FP)
float32x4_t v0;
float32_t r;
v0 = vsubq_f32(vld1q_f32(a), vld1q_f32(b));
r = vaddvq_f32(vmulq_f32(v0, v0));
return sqrtf(r);
return glmm_norm(vsubq_f32(glmm_load(a), glmm_load(b)));
#else
return sqrtf(glm_pow2(b[0] - a[0])
+ glm_pow2(b[1] - a[1])
@@ -819,4 +817,26 @@ glm_vec4_cubic(float s, vec4 dest) {
dest[3] = 1.0f;
}
/*!
* @brief swizzle vector components
*
* you can use existin masks e.g. GLM_XXXX, GLM_WZYX
*
* @param[in] v source
* @param[in] mask mask
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec4_swizzle(vec4 v, int mask, vec4 dest) {
vec4 t;
t[0] = v[(mask & (3 << 0))];
t[1] = v[(mask & (3 << 2)) >> 2];
t[2] = v[(mask & (3 << 4)) >> 4];
t[3] = v[(mask & (3 << 6)) >> 6];
glm_vec4_copy(t, dest);
}
#endif /* cglm_vec4_h */

View File

@@ -9,7 +9,7 @@
#define cglm_version_h
#define CGLM_VERSION_MAJOR 0
#define CGLM_VERSION_MINOR 5
#define CGLM_VERSION_PATCH 4
#define CGLM_VERSION_MINOR 6
#define CGLM_VERSION_PATCH 0
#endif /* cglm_version_h */