diff options
Diffstat (limited to 'src/math/math.h')
-rw-r--r-- | src/math/math.h | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/src/math/math.h b/src/math/math.h new file mode 100644 index 0000000..4498920 --- /dev/null +++ b/src/math/math.h @@ -0,0 +1,306 @@ +#ifndef _SOFTSHADEROOM_MATH_H_ +#define _SOFTSHADEROOM_MATH_H_ + +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <limits.h> + +#include "../util/type.h" + +#define PI 3.141592653f +#define RAD2DEG 57.295779523f /*180.f/PI*/ +#define DEG2RAG 0.0174532925f /*PI/180.f*/ +#define EPSILON 0.000001f + +/* 用来打印的公共buffer */ +extern char printbuffer[2048]; + +/* +** 数学函数 +*/ +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define clamp(v, l, h) ((v) > (l) ? ((v) < (h) ? (v) : (h)) : (l)) +#define absf(v) ((v )> 0 ? (v ): -(v)) +#define radians(angle) (angle * DEG2RAG) +#define degree(rad) (rad * RAD2DEG) +#define compare(v1, v2) (absf((v1) - (v2)) < EPSILON) +#define swapi(a, b) {int temp = a; a = b; b = temp;} +float rsqrt(float n); +float lerp(float from, float to, float t); + +/* +** 二维向量,用来做屏幕上的一些计算 +*/ +typedef struct Vec2 { + float x, y; +} Vec2; + +/* +** 三维向量,用来做三维空间的计算 +*/ +typedef union Vec3 { + struct { + float x, y, z; + }; + struct { + float A, B, C; /*重心坐标*/ + }; + Vec2 xy; +} Vec3; + +/* +** 齐次坐标,列主项,平移变换和透视投影需要 +*/ +typedef union Vec4 { + struct { + float x, y, z, w; + }; + struct { + float r, g, b, a; + }; + Vec3 xyz; +} Vec4; + +/* +** 用来可视化四元数,欧拉角默认使用角度存储,用euler_deg2rad()转弧度 +*/ +typedef union Euler { + struct { + float x, y, z; + }; + struct { + float pitch, yaw, roll; + }; +} Euler; + +/* +** 四元数,用来做旋转变换。在进行变换复合以及插值的时候用,但最终还是需要通过quat_mat4转换成矩阵和其他变换矩阵 +** 一起对向量进行变换 +*/ +typedef struct Quat { + float x, y, z, w; +} Quat; + +/* +** 4x4矩阵,列主项,用来做平移和缩放变换。之所以用列主序存储,是为了快速读取矩阵的基向量 +*/ +typedef union Mat4 { + float l[16]; + float m[4][4]; + struct { + float + e00, e10, e20, e30, /*colum 0*/ + e01, e11, e21, e31, + e02, e12, e22, e32, + e03, e13, e23, e33; + }; + struct { + Vec4 x;/*colum 0*/ + Vec4 y; + Vec4 z; + Vec4 w; + } axis; /*轴*/ + struct { + Vec4 x;/*colum 0*/ + Vec4 y; + Vec4 z; + Vec4 w; + } basis; /*基向量*/ + struct { + Vec4 axisx; + Vec4 axisy; + Vec4 axisz; + Vec4 pos; + }; + Vec4 colums[4]; +} Mat4; + +typedef union Mat3 { + struct { + float + e00, e10, e20, /*colum 0*/ + e01, e11, e21, + e02, e12, e22; + }; +} Mat3; + +typedef union Mat23 { + struct { + float + e00, e10, /*colum 0*/ + e01, e11, + e02, e12; + }; +} Mat23; + +typedef union Mat43 { + struct { + float + e00, e10, e20, e30, /*colum 0*/ + e01, e11, e21, e31, + e02, e12, e22, e32; + }; + struct { /*三个齐次裁剪坐标*/ + Vec4 p1; + Vec4 p2; + Vec4 p3; + }; +} Mat43; + +//#define MAT(m, r, c) (m->l[r + (c<<2)]) +#define MAT(M, r, c) (M->m[c][r]) +/************************************************************************/ +/* Vec */ +/************************************************************************/ + +void vec2_scale(Vec2* v, float k, Vec2* out); +void vec2_plus(Vec2* v1, Vec2* v2, Vec2* out); +void vec2_offset(Vec2* v, float offset, Vec2* out); +void vec2_rotate(Vec2* v, float angle, Vec2* out); + +float vec2_dot(Vec2* v1, Vec2* v2); + +void vec2_tostring(Vec2* v, char buf[]); +void vec2_print(Vec2* v); + +#define vec3_xy(v) (v->xy) + +extern Vec3 vec3forward; /*(0,0,1)*/ +extern Vec3 vec3up; /*(0,1,0)*/ +extern Vec3 vec3left;/*(1,0,0)*/ + +void vec3_tostring(Vec3* v, char buf[]); +void vec3_print(Vec3* v); + +float vec3_intersection(Vec3* v1, Vec3* v2); /*夹角*/ +void vec3_projection(Vec3* v1, Vec3* v2, Vec3* out);/*v1在v2上的投影*/ +void vec3_scale(Vec3* v, float k, Vec3* out); +void vec3_plus(Vec3* v1, Vec3* v2, Vec3* out); +void vec3_offset(Vec3* v, float offset, Vec3* out); +void vec3_normalize(Vec3* v, Vec3* out); +void vec3_vec4(float w, Vec4* out); + +void vec3_minus(Vec3* v1, Vec3* v2, Vec3* out); +float vec3_dot(Vec3* v1, Vec3* v2); +void vec3_cross(Vec3* v1, Vec3* v2, Vec3* out); +void vec3_multiply(Vec3* v1, Vec3* v2, Quat* out);// 向量的乘法,st=sxt-s*t,结果是一个四元数 + +float vec3_magnitude(Vec3* v1); +float vec3_magnitude2(Vec3* v1); + +void vec3_lerp(Vec3* v1, Vec3* v2, float t, Vec3* out); +void vec3_slerp(Vec3* v1, Vec3* v2, float t, Vec3* out); + +void vec4_dividew(Vec4* v, Vec3* out); + +void vec4_tostring(Vec4* v, char buf[]); +void vec4_print(Vec4* v); + +/************************************************************************/ +/* Matrix */ +/************************************************************************/ + +extern Mat4 mat4identity; + +void mat4_tostring(Mat4* m, char str[]); +void mat4_print(Mat4* m); + +void mat4_zero(Mat4* out); +void mat4_setidentity(Mat4* out); +void mat4_setfrustum(float l, float r, float b, float t, float n, float f, Mat4* out); +void mat4_setperspective(float fov, float aspect, float near, float far, Mat4* out); +void mat4_setscale(float kx, float ky, float kz, Mat4* out); +void mat4_setposition(float x, float y, float z, Mat4* out); +void mat4_setrotatez(float angle, Mat4* out); +void mat4_setrotatex(float angle, Mat4* out); +void mat4_setrotatey(float angle, Mat4* out); +void mat4_setrotate(float angleX, float angleY, float angleZ, Mat4* out);/*RyRxRz*/ +void mat4_setaxisangle(Vec3* axis, float angle, Mat4* out); + +bool mat4_setlookrotation(Vec3* view, Vec3* up, Mat4* out); +void mat4_setorthonormalbias(Vec3* x, Vec3* y, Vec3* z, Mat4* out); /*正交的三个轴*/ + +void mat4_orthogonalize(Mat4* in, Mat4* out); /*解决矩阵蠕变,对左上角3x3矩阵进行正交化,结果是右手系的正交矩阵*/ +bool mat4_isorthogonal(Mat4* m); /*判断是不是正交矩阵*/ +bool mat4_isidentity(Mat4* m); + +void mat4_settr(Vec3* pos, Quat* rot, Mat4* out); /*用旋转和平移初始化mat4*/ +void mat4_settrs(Vec3* pos, Quat* rot, Vec3* scale, Mat4* out); +void mat4_settrinverse(Vec3* pos, Quat* rot, Mat4* out); + +void mat4_multiply(Mat4* m1, Mat4* m2, Mat4* out); /* m1的行乘m2的列,意义是用m1变换m2 */ + +void mat4_transpose(Mat4* m, Mat4* out); + +void mat4_scale(Mat4* m, Vec3* scale, Mat4* out);/* 后乘post-multiply scale */ +void mat4_translate(Mat4* m, Vec3* pos, Mat4* out); /* 后乘post-multiply translate */ +void mat4_rotate(Mat4*m, float angle, Vec3* rot, Mat4* out);/*后乘绕任意轴向量旋转矩阵*/ + +bool mat4_invertfull(Mat4* in, Mat4* out); /* 并不是所有矩阵都能求逆 */ +bool mat4_invertgeneral3d(Mat4* in, Mat4* out); /* 对scale rotate translate求逆 */ +void mat4_invertscale(Mat4* scale, Mat4* out); /* 对缩放矩阵求逆 */ +void mat4_invertrot(Mat4* rot, Mat4* out); /* 对旋转矩阵求逆 */ +void mat4_invertpos(Mat4* pos, Mat4* out); /* 对平移矩阵求逆 */ + +void mat4_decomposetrs(Mat4* src, Vec3* pos, Quat* quat, Vec3* scale); /*分解trs矩阵*/ + +void mat4_applytovec4(Mat4* m, Vec4* v, Vec4* out); + +bool mat4_toeuler(Mat4* in, Euler* out); /* 计算YXZ旋转矩阵的欧拉角 */ +void mat4_toquat(Mat4* in, Quat* out); /*in是正交矩阵*/ + +#define ROWMAT(A, ...)\ +Mat4 A={__VA_ARGS__};mat4_transpose(&A, &A); + +void mat3_applytovec3(Mat3* m, Vec3* v, Vec3* out); +void mat23_applytovec3(Mat23* m, Vec3* v, Vec2* out); +void mat43_applytovec3(Mat43* m, Vec3* v, Vec4* out); + +/************************************************************************/ +/* Quat */ +/************************************************************************/ + +void quat_tostring(Quat* q, char str[]); +void quat_print(Quat* q); + +void euler_toquat(Euler* e, Quat* out); +void euler_deg2rad(Euler* in, Euler* out); +void euler_rad2deg(Euler* in, Euler* out); + +void euler_tostring(Euler* v, char buf[]); +void euler_print(Euler* v); + +void quat_fromaxisangle(Vec3* axis, float angle, Quat* out); /*轴角转四元数*/ +void quat_fromeuler(Euler* euler, Quat* out); /*按照zxy顺序*/ + +void quat_tomat4(Quat* q, Mat4* out); +void quat_toeuler(Quat*q, Euler* out); + +void quat_normalize(Quat* q, Quat* out); /*解决蠕变,保持四元数合法*/ + +void quat_scale(Quat* q, float scale, Quat* out); +void quat_rotate(); + +void quat_minus(Quat* q1, Quat* q2, Quat* out); +void quat_slerp(Quat* start, Quat* end, float t, Quat* out); +void quat_lerp(Quat* start, Quat* end, float t, Quat* out); +void quat_translate(Quat* q, Vec4* v, Vec4* out); +void quat_invert(Quat* q, Quat* out); +float quat_dot(Quat* q1, Quat* q2); +void quat_multiply(Quat* q1, Quat* q2, Quat* out); +void quat_devide(Quat* q, float k, Quat* out); +void quat_negtive(Quat* in, Quat* out); +bool quat_isidentity(Quat* q); + +void quat_applytovec3(Quat* q, Vec3* v, Vec3* out); /*用四元数直接旋转向量*/ + +void quat_conjugate(Quat* in, Quat* out); + +bool quat_setlookrotation(Vec3* view, Vec3* up, Quat* out); + +float quat_magnitude(Quat* q); +float quat_magnitude2(Quat* q); + +#endif
\ No newline at end of file |