summaryrefslogtreecommitdiff
path: root/src/math/math.h
blob: 8793336c4c954083dad45df831431ab9bc4e6778 (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
294
295
296
#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 {
	float x, y;
} Vec2;

typedef union {
	struct {
		float x, y, z;
	};
	struct {
		float A, B, C; /*��������*/
	};
	Vec2 xy;
} Vec3;

typedef union {
	struct {
		float x, y, z, w;
	};
	struct {
		float r, g, b, a;
	};
	Vec3 xyz;
} Vec4;

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

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

typedef union {
	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 {
	struct {
		float
			e00, e10, e20, /*colum 0*/
			e01, e11, e21,
			e02, e12, e22;
	};
} Mat3;

typedef union {
	struct {
		float
			e00, e10, /*colum 0*/
			e01, e11, 
			e02, e12;
	};
} Mat23;

typedef union {
	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);// �����ij˷���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);

void vec4_scale(Vec4* v, 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); /*��Dz�����������*/
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_mulvec4(Mat4* m, Vec4* v, Vec4* out);
void mat4_mulvec3(Mat4* m, Vec3* v, Vec3* 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