summaryrefslogtreecommitdiff
path: root/src/math/math.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/math.h')
-rw-r--r--src/math/math.h306
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