f8f776b7d834e1554a0b1dd5562f9d1616bb4708
[dosdemo] / src / cgmath / cgmath.h
1 /* gph-cmath - C graphics math library
2  * Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
3  *
4  * This program is free software. Feel free to use, modify, and/or redistribute
5  * it under the terms of the MIT/X11 license. See LICENSE for details.
6  * If you intend to redistribute parts of the code without the LICENSE file
7  * replace this paragraph with the full contents of the LICENSE file.
8  *
9  * Function prefixes signify the data type of their operand(s):
10  * - cgm_v... functions are operations on cgm_vec3 vectors
11  * - cgm_w... functions are operations on cgm_vec4 vectors
12  * - cgm_q... functions are operations on cgm_quat quaternions (w + xi + yj + zk)
13  * - cgm_m... functions are operations on 4x4 matrices (stored as linear 16 float arrays)
14  * - cgm_r... functions are operations on cgm_ray rays
15  *
16  * NOTE: *ALL* matrix arguments are pointers to 16 floats. Even the functions
17  * which operate on 3x3 matrices, actually use the upper 3x3 of a 4x4 matrix,
18  * and still expect an array of 16 floats.
19  *
20  * NOTE: matrices are treated by all operations as column-major, to match OpenGL
21  * conventions, so everything is pretty much transposed.
22 */
23 #ifndef CGMATH_H_
24 #define CGMATH_H_
25
26 #include <math.h>
27 #include <string.h>
28
29 typedef struct {
30         float x, y, z;
31 } cgm_vec3;
32
33 typedef struct {
34         float x, y, z, w;
35 } cgm_vec4, cgm_quat;
36
37 typedef struct {
38         cgm_vec3 origin, dir;
39 } cgm_ray;
40
41 typedef enum cgm_euler_mode {
42         CGM_EULER_XYZ,
43         CGM_EULER_XZY,
44         CGM_EULER_YXZ,
45         CGM_EULER_YZX,
46         CGM_EULER_ZXY,
47         CGM_EULER_ZYX,
48         CGM_EULER_ZXZ,
49         CGM_EULER_ZYZ,
50         CGM_EULER_YXY,
51         CGM_EULER_YZY,
52         CGM_EULER_XYX,
53         CGM_EULER_XZX
54 } cgm_euler_mode;
55
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59
60 /* --- operations on cgm_vec3 --- */
61 static inline void cgm_vcons(cgm_vec3 *v, float x, float y, float z);
62
63 static inline void cgm_vadd(cgm_vec3 *a, const cgm_vec3 *b);
64 static inline void cgm_vsub(cgm_vec3 *a, const cgm_vec3 *b);
65 static inline void cgm_vmul(cgm_vec3 *a, const cgm_vec3 *b);
66 static inline void cgm_vscale(cgm_vec3 *v, float s);
67 static inline void cgm_vmul_m4v3(cgm_vec3 *v, const float *m);  /* m4x4 * v */
68 static inline void cgm_vmul_v3m4(cgm_vec3 *v, const float *m);  /* v * m4x4 */
69 static inline void cgm_vmul_m3v3(cgm_vec3 *v, const float *m);  /* m3x3 * v (m still 16 floats) */
70 static inline void cgm_vmul_v3m3(cgm_vec3 *v, const float *m);  /* v * m3x3 (m still 16 floats) */
71
72 static inline float cgm_vdot(const cgm_vec3 *a, const cgm_vec3 *b);
73 static inline void cgm_vcross(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b);
74 static inline float cgm_vlength(const cgm_vec3 *v);
75 static inline float cgm_vlength_sq(const cgm_vec3 *v);
76 static inline float cgm_vdist(const cgm_vec3 *a, const cgm_vec3 *b);
77 static inline float cgm_vdist_sq(const cgm_vec3 *a, const cgm_vec3 *b);
78 static inline void cgm_vnormalize(cgm_vec3 *v);
79
80 static inline void cgm_vreflect(cgm_vec3 *v, const cgm_vec3 *n);
81 static inline void cgm_vrefract(cgm_vec3 *v, const cgm_vec3 *n, float ior);
82
83 static inline void cgm_vrotate_quat(cgm_vec3 *v, const cgm_quat *q);
84 static inline void cgm_vrotate_axis(cgm_vec3 *v, int axis, float angle);
85 static inline void cgm_vrotate(cgm_vec3 *v, float angle, float x, float y, float z);
86 static inline void cgm_vrotate_euler(cgm_vec3 *v, float a, float b, float c, enum cgm_euler_mode mode);
87
88 static inline void cgm_vlerp(cgm_vec3 *res, const cgm_vec3 *a, const cgm_vec3 *b, float t);
89
90 /* --- operations on cgm_vec4 --- */
91 static inline void cgm_wcons(cgm_vec4 *v, float x, float y, float z, float w);
92
93 static inline void cgm_wadd(cgm_vec4 *a, const cgm_vec4 *b);
94 static inline void cgm_wsub(cgm_vec4 *a, const cgm_vec4 *b);
95 static inline void cgm_wmul(cgm_vec4 *a, const cgm_vec4 *b);
96 static inline void cgm_wscale(cgm_vec4 *v, float s);
97
98 static inline void cgm_wmul_m4v4(cgm_vec4 *v, const float *m);
99 static inline void cgm_wmul_v4m4(cgm_vec4 *v, const float *m);
100 static inline void cgm_wmul_m34v4(cgm_vec4 *v, const float *m); /* doesn't affect w */
101 static inline void cgm_wmul_v4m43(cgm_vec4 *v, const float *m); /* doesn't affect w */
102 static inline void cgm_wmul_m3v4(cgm_vec4 *v, const float *m); /* (m still 16 floats) */
103 static inline void cgm_wmul_v4m3(cgm_vec4 *v, const float *m); /* (m still 16 floats) */
104
105 static inline float cgm_wlength(const cgm_vec4 *v);
106 static inline float cgm_wlength_sq(const cgm_vec4 *v);
107 static inline float cgm_wdist(const cgm_vec4 *a, const cgm_vec4 *b);
108 static inline float cgm_wdist_sq(const cgm_vec4 *a, const cgm_vec4 *b);
109 static inline void cgm_wnormalize(cgm_vec4 *v);
110
111 static inline void cgm_wlerp(cgm_vec4 *res, const cgm_vec4 *a, const cgm_vec4 *b, float t);
112
113 /* --- operations on quaternions --- */
114 static inline void cgm_qcons(cgm_quat *q, float x, float y, float z, float w);
115
116 static inline void cgm_qneg(cgm_quat *q);
117 static inline void cgm_qadd(cgm_quat *a, const cgm_quat *b);
118 static inline void cgm_qsub(cgm_quat *a, const cgm_quat *b);
119 static inline void cgm_qmul(cgm_quat *a, const cgm_quat *b);
120
121 static inline float cgm_qlength(const cgm_quat *q);
122 static inline float cgm_qlength_sq(const cgm_quat *q);
123 static inline void cgm_qnormalize(cgm_quat *q);
124 static inline void cgm_qconjugate(cgm_quat *q);
125 static inline void cgm_qinvert(cgm_quat *q);
126
127 static inline void cgm_qrotation(cgm_quat *q, const cgm_vec3 *axis, float angle);
128 static inline void cgm_qrotate(cgm_quat *q, const cgm_vec3 *axis, float angle);
129
130 static inline void cgm_qslerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t);
131 static inline void cgm_qlerp(cgm_quat *res, const cgm_quat *a, const cgm_quat *b, float t);
132
133 /* --- operations on matrices --- */
134 static inline void cgm_mcopy(float *dest, const float *src);
135 static inline void cgm_mzero(float *m);
136 static inline void cgm_midentity(float *m);
137
138 static inline void cgm_mmul(float *a, const float *b);
139
140 static inline void cgm_msubmatrix(float *m, int row, int col);
141 static inline void cgm_mupper3(float *m);
142 static inline float cgm_msubdet(const float *m, int row, int col);
143 static inline float cgm_mcofactor(const float *m, int row, int col);
144 static inline float cgm_mdet(const float *m);
145 static inline void cgm_mtranspose(float *m);
146 static inline void cgm_mcofmatrix(float *m);
147 static inline int cgm_minverse(float *m);       /* returns 0 on success, -1 for singular */
148
149 static inline void cgm_mtranslation(float *m, float x, float y, float z);
150 static inline void cgm_mscaling(float *m, float sx, float sy, float sz);
151 static inline void cgm_mrotation_x(float *m, float angle);
152 static inline void cgm_mrotation_y(float *m, float angle);
153 static inline void cgm_mrotation_z(float *m, float angle);
154 static inline void cgm_mrotation_axis(float *m, int idx, float angle);
155 static inline void cgm_mrotation(float *m, float angle, float x, float y, float z);
156 static inline void cgm_mrotation_euler(float *m, float a, float b, float c, int mode);
157
158 static inline void cgm_mtranslate(float *m, float x, float y, float z);
159 static inline void cgm_mscale(float *m, float sx, float sy, float sz);
160 static inline void cgm_mrotate_x(float *m, float angle);
161 static inline void cgm_mrotate_y(float *m, float angle);
162 static inline void cgm_mrotate_z(float *m, float angle);
163 static inline void cgm_mrotate_axis(float *m, int idx, float angle);
164 static inline void cgm_mrotate(float *m, float angle, float x, float y, float z);
165 static inline void cgm_mrotate_euler(float *m, float a, float b, float c, int mode);
166
167 static inline void cgm_mpretranslate(float *m, float x, float y, float z);
168 static inline void cgm_mprescale(float *m, float sx, float sy, float sz);
169 static inline void cgm_mprerotate_x(float *m, float angle);
170 static inline void cgm_mprerotate_y(float *m, float angle);
171 static inline void cgm_mprerotate_z(float *m, float angle);
172 static inline void cgm_mprerotate_axis(float *m, int idx, float angle);
173 static inline void cgm_mprerotate(float *m, float angle, float x, float y, float z);
174 static inline void cgm_mprerotate_euler(float *m, float a, float b, float c, int mode);
175
176 static inline void cgm_mget_translation(const float *m, cgm_vec3 *res);
177 static inline void cgm_mget_rotation(const float *m, cgm_quat *res);
178 static inline void cgm_mget_scaling(const float *m, cgm_vec3 *res);
179 static inline void cgm_mget_frustum_plane(const float *m, int p, cgm_vec4 *res);
180
181 static inline void cgm_mlookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ,
182                 const cgm_vec3 *up);
183 static inline void cgm_minv_lookat(float *m, const cgm_vec3 *pos, const cgm_vec3 *targ,
184                 const cgm_vec3 *up);
185 static inline void cgm_mortho(float *m, float left, float right, float bot, float top,
186                 float znear, float zfar);
187 static inline void cgm_mfrustum(float *m, float left, float right, float bot, float top,
188                 float znear, float zfar);
189 static inline void cgm_mperspective(float *m, float vfov, float aspect, float znear, float zfar);
190
191 static inline void cgm_mmirror(float *m, float a, float b, float c, float d);
192
193 /* --- operations on rays --- */
194 static inline void cgm_rcons(cgm_ray *r, float x, float y, float z, float dx, float dy, float dz);
195
196 static inline void cgm_rmul_mr(cgm_ray *ray, const float *m);   /* m4x4 * ray */
197 static inline void cgm_rmul_rm(cgm_ray *ray, const float *m);   /* ray * m4x4 */
198
199 static inline void cgm_rreflect(cgm_ray *ray, const cgm_vec3 *n);
200 static inline void cgm_rrefract(cgm_ray *ray, const cgm_vec3 *n, float ior);
201
202 /* --- miscellaneous utility functions --- */
203 static inline float cgm_deg_to_rad(float deg);
204 static inline float cgm_rad_to_deg(float rad);
205
206 static inline float cgm_smoothstep(float a, float b, float x);
207 static inline float cgm_bezier(float a, float b, float c, float d, float t);
208
209 static inline void cgm_discrand(cgm_vec3 *v, float rad);
210 static inline void cgm_sphrand(cgm_vec3 *v, float rad);
211
212 static inline void cgm_unproject(cgm_vec3 *res, const cgm_vec3 *norm_scrpos,
213                 const float *inv_viewproj);
214 static inline void cgm_glu_unproject(float winx, float winy, float winz,
215                 const float *view, const float *proj, const int *vp,
216                 float *objx, float *objy, float *objz);
217
218 static inline void cgm_pick_ray(cgm_ray *ray, float nx, float ny,
219                 const float *viewmat, const float *projmat);
220
221 static inline void cgm_raypos(cgm_vec3 *p, const cgm_ray *ray, float t);
222
223 /* calculate barycentric coordinates of point pt in triangle (a, b, c) */
224 static inline void cgm_bary(cgm_vec3 *bary, const cgm_vec3 *a,
225                 const cgm_vec3 *b, const cgm_vec3 *c, const cgm_vec3 *pt);
226
227 #include "cgmvec3.inl"
228 #include "cgmvec4.inl"
229 #include "cgmquat.inl"
230 #include "cgmmat.inl"
231 #include "cgmray.inl"
232 #include "cgmmisc.inl"
233
234 #ifdef __cplusplus
235 }
236 #endif
237
238 #endif  /* CGMATH_H_ */