summaryrefslogtreecommitdiff
path: root/src/math/math.h
blob: 1db7df77c5f685f1e83233d536ed1b35947241a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#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 1e-6f

/* 用来打印的公共buffer */
extern char printbuffer[1024];

#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;

typedef union Euler { /*in degree, for visualize quaternion*/
	struct {
		float x, y, z;
	};
	struct {
		float pitch, yaw, roll;
	};
} Euler;

typedef struct Quat {
	float x, y, z, w;
} Quat;

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->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)*/
extern Vec3 vec3zero; /*(0,0,0)*/
extern Vec2 vec2zero; /*(0,0,0)*/
extern Vec4 vec4zero; /*(0,0,0)*/

#define zerovec3 {0, 0, 0}
#define zerovec2 {0, 0}
#define zerovec4 {0, 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);

void vec4_lerp(Vec4* a, Vec4* b, float t, Vec4* out);

/************************************************************************/
/* 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_setortho(float l, float r, float b, float t, float n, float f, 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