├── README.md
├── LICENSE
└── dvector.h
/README.md:
--------------------------------------------------------------------------------
1 | ## Documentation
2 |
3 | This is a header-only library, as such most of its functional documentation is contained within the "header section" of the
4 | source code in the form of comments. It is highly recommended that you read said documentation before using this library.
5 |
6 | ## Features
7 |
8 | The dvector library provides both common and more specialized 2D/3D vector math operations, its features include:
9 |
10 | - No hard dependencies besides the standard library, making it fully portable for most purposes
11 | - Provides vec2, vec3, vec4, quat, mat2, mat3, and mat4 types with various important operations
12 | - Supports an additional frst type along with frustum culling functions for spheres and AABBs
13 | - All dvector types are pass-by-value, allowing for easy use as arguments or return values
14 |
15 | ## Attribution
16 |
17 | You are not required to give attribution when using this library. If you want to give attribution anyway, either link to
18 | this repository, [my website](https://www.slopegames.com/), or credit me as [BareRose](https://github.com/BareRose).
19 | If you want to support me financially, consider giving to my [Patreon](https://www.patreon.com/slopegames).
20 |
21 | ## License
22 |
23 | Licensed under CC0 aka the most lawyer-friendly way of spelling "public domain".
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
117 |
--------------------------------------------------------------------------------
/dvector.h:
--------------------------------------------------------------------------------
1 | /*
2 | dvector.h - Portable, single-file, 2D/3D vector/quaternion/matrix math library, originally based on ccVector
3 |
4 | To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring
5 | rights to this software to the public domain worldwide. This software is distributed without any warranty.
6 | You should have received a copy of the CC0 Public Domain Dedication along with this software.
7 | If not, see .
8 | */
9 |
10 | /*
11 | dvector supports the following three configurations:
12 | #define DVECTOR_EXTERN
13 | Default, should be used when using dvector in multiple compilation units within the same project.
14 | #define DVECTOR_IMPLEMENTATION
15 | Must be defined in exactly one source file within a project for dvector to be found by the linker.
16 | #define DVECTOR_STATIC
17 | Defines all dvector functions as static, useful if dvector is only used in a single compilation unit.
18 |
19 | dvector supports the following additional options:
20 | #define DVECTOR_DOUBLE
21 | Configures dvector to use double instead of the default float. Cannot use both float and double versions in the same compilation unit.
22 | #define DVECTOR_ISOC
23 | Changes the way dvector types are defined for compatibility with ISO C99. Only affects convenience without limiting functionality.
24 |
25 | dvector types:
26 | Supports vec2, vec3, vec4, quat, mat2, mat3, and mat4 types with various property aliases for flexible use and concise code.
27 | Each of the above types comes with a TYPE_ZERO and TYPE_IDEN (for quat and matrix types) constant which translates to a literal.
28 | Function-like macros of the form TYPE(...) also exist and are meant to provide a concise alternative to typing out literals.
29 | The auxiliary frst type supports frustum generation from a projview matrix and simple frustum culling of bounding volumes.
30 |
31 | dvector functions:
32 | Provided functions should be reasonably self-explanatory, and use of macros was deliberately kept low for better readability.
33 | All equality functions use direct comparison (no epsilon), therefore floating point errors may break equality for some values.
34 | All quat functions should return normalized quats, occasional normalization is recommended due to float error accumulation.
35 | All angles are in radians. Frustum culling of volumes returns 1 for volumes inside the frustum, 0 for volumes outside it.
36 | All coordinate systems are right-handed unless otherwise noted. Projection functions assume OpenGL-style screen space.
37 | */
38 |
39 | //header section
40 | #ifndef DVECTOR_H
41 | #define DVECTOR_H
42 |
43 | //process configuration
44 | #ifdef DVECTOR_STATIC
45 | #define DVECTOR_IMPLEMENTATION
46 | #define DVDEF static
47 | #else //DVECTOR_EXTERN
48 | #define DVDEF extern
49 | #endif
50 |
51 | /*
52 | Use the below macros and constants for function parameters and variable
53 | definitions in local scope. To initialize globals, use naked literals.
54 | Example:
55 | vec3 default_position = {0, 0, 0};
56 | void foo(){
57 | bar(VEC3_ZERO);
58 | }
59 | */
60 |
61 | //macros
62 | #ifdef DVECTOR_ISOC
63 | #define VEC2(X, Y) (vec2){X, Y}
64 | #define VEC3(X, Y, Z) (vec3){X, Y, Z}
65 | #define VEC4(X, Y, Z, W) (vec4){X, Y, Z, W}
66 | #define QUAT(X, Y, Z, W) (quat){X, Y, Z, W}
67 | #else
68 | #define VEC2(X, Y) (vec2){{X, Y}}
69 | #define VEC3(X, Y, Z) (vec3){{X, Y, Z}}
70 | #define VEC4(X, Y, Z, W) (vec4){{X, Y, Z, W}}
71 | #define QUAT(X, Y, Z, W) (quat){{X, Y, Z, W}}
72 | #endif
73 | #define MAT2(M00, M01, M10, M11) (mat2){{{M00, M01}, {M10, M11}}}
74 | #define MAT3(M00, M01, M02, M10, M11, M12, M20, M21, M22) (mat3){{{M00, M01, M02}, {M10, M11, M12}, {M20, M21, M22}}}
75 | #define MAT4(M00, M01, M02, M03, M10, M11, M12, M13, M20, M21, M22, M23, M30, M31, M32, M33) \
76 | (mat4){{{M00, M01, M02, M03}, {M10, M11, M12, M13}, {M20, M21, M22, M23}, {M30, M31, M32, M33}}}
77 |
78 | //constants
79 | #define VEC2_ZERO VEC2(0, 0)
80 | #define VEC3_ZERO VEC3(0, 0, 0)
81 | #define VEC4_ZERO VEC4(0, 0, 0, 0)
82 | #define QUAT_IDEN QUAT(0, 0, 0, 1)
83 | #define MAT2_ZERO MAT2(0, 0, 0, 0)
84 | #define MAT2_IDEN MAT2(1, 0, 0, 1)
85 | #define MAT3_ZERO MAT3(0, 0, 0, 0, 0, 0, 0, 0, 0)
86 | #define MAT3_IDEN MAT3(1, 0, 0, 0, 1, 0, 0, 0, 1)
87 | #define MAT4_ZERO MAT4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
88 | #define MAT4_IDEN MAT4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
89 |
90 | //math configuration
91 | #include
92 | #ifdef DVECTOR_DOUBLE
93 | #define DVTYPE double
94 | #define DVCOS cos
95 | #define DVSIN sin
96 | #define DVTAN tan
97 | #define DVACOS acos
98 | #define DVHYPOT hypot
99 | #else
100 | #define DVTYPE float
101 | #define DVCOS cosf
102 | #define DVSIN sinf
103 | #define DVTAN tanf
104 | #define DVACOS acosf
105 | #define DVHYPOT hypotf
106 | #endif
107 |
108 | //types
109 | #ifdef DVECTOR_ISOC
110 | typedef struct vec2 {
111 | DVTYPE x, y;
112 | } vec2;
113 | typedef struct vec3 {
114 | DVTYPE x, y, z;
115 | } vec3;
116 | typedef struct vec4 {
117 | DVTYPE x, y, z, w;
118 | } vec4, quat;
119 | typedef union mat2 {
120 | DVTYPE m[2][2];
121 | vec2 col[2];
122 | } mat2;
123 | typedef union mat3 {
124 | DVTYPE m[3][3];
125 | vec3 col[3];
126 | } mat3;
127 | typedef union mat4 {
128 | DVTYPE m[4][4];
129 | vec4 col[4];
130 | } mat4;
131 | typedef union frst {
132 | DVTYPE f[24];
133 | vec4 pln[6];
134 | } frst;
135 | #else
136 | typedef union vec2 {
137 | DVTYPE v[2];
138 | struct {DVTYPE x, y;};
139 | } vec2;
140 | typedef union vec3 {
141 | DVTYPE v[3];
142 | struct {DVTYPE x, y, z;};
143 | struct {vec2 xy; DVTYPE _z;};
144 | struct {DVTYPE _x; vec2 yz;};
145 | } vec3;
146 | typedef union vec4 {
147 | DVTYPE v[4];
148 | struct {DVTYPE x, y, z, w;};
149 | struct {vec3 xyz; DVTYPE _w;};
150 | struct {DVTYPE _x; vec3 yzw;};
151 | struct {vec2 xy; vec2 zw;};
152 | struct {DVTYPE __x; vec2 yz; DVTYPE __w;};
153 | } vec4, quat;
154 | typedef union mat2 {
155 | DVTYPE m[2][2];
156 | struct {DVTYPE m00, m01, m10, m11;};
157 | vec2 col[2];
158 | struct {vec2 col0, col1;};
159 | } mat2;
160 | typedef union mat3 {
161 | DVTYPE m[3][3];
162 | struct {DVTYPE m00, m01, m02, m10, m11, m12, m20, m21, m22;};
163 | vec3 col[3];
164 | struct {vec3 col0, col1, col2;};
165 | } mat3;
166 | typedef union mat4 {
167 | DVTYPE m[4][4];
168 | struct {DVTYPE m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33;};
169 | vec4 col[4];
170 | struct {vec4 col0, col1, col2, col3;};
171 | } mat4;
172 | typedef union frst {
173 | DVTYPE f[24];
174 | vec4 pln[6];
175 | struct {vec4 left, right, top, bottom, near, far;};
176 | } frst;
177 | #endif
178 |
179 | //vec2 function declarations
180 | DVDEF DVTYPE vec2Length(vec2);
181 | DVDEF DVTYPE vec2DotProduct(vec2, vec2);
182 | DVDEF vec2 vec2Negate(vec2);
183 | DVDEF vec2 vec2Normalize(vec2);
184 | DVDEF vec2 vec2Multiply(vec2, DVTYPE);
185 | DVDEF vec2 vec2Divide(vec2, DVTYPE);
186 | DVDEF vec2 vec2Rotate(vec2, DVTYPE);
187 | DVDEF vec2 vec2RotateXZ(vec2, DVTYPE);
188 | DVDEF vec2 vec2Add(vec2, vec2);
189 | DVDEF vec2 vec2Subtract(vec2, vec2);
190 | DVDEF vec2 vec2Reflect(vec2, vec2);
191 | DVDEF vec2 vec2Mix(vec2, vec2, DVTYPE);
192 | DVDEF int vec2Equal(vec2, vec2);
193 |
194 | //vec3 function declarations
195 | DVDEF DVTYPE vec3Length(vec3);
196 | DVDEF DVTYPE vec3DotProduct(vec3, vec3);
197 | DVDEF vec2 vec3GetXZ(vec3);
198 | DVDEF vec3 vec3Negate(vec3);
199 | DVDEF vec3 vec3Normalize(vec3);
200 | DVDEF vec3 vec3Multiply(vec3, DVTYPE);
201 | DVDEF vec3 vec3Divide(vec3, DVTYPE);
202 | DVDEF vec3 vec3Add(vec3, vec3);
203 | DVDEF vec3 vec3Subtract(vec3, vec3);
204 | DVDEF vec3 vec3Reflect(vec3, vec3);
205 | DVDEF vec3 vec3CrossProduct(vec3, vec3);
206 | DVDEF vec3 vec3Mix(vec3, vec3, DVTYPE);
207 | DVDEF int vec3Equal(vec3, vec3);
208 |
209 | //vec4 function declarations
210 | DVDEF vec3 vec4GetXYZ(vec4);
211 | DVDEF DVTYPE vec4Length(vec4);
212 | DVDEF DVTYPE vec4DotProduct(vec4, vec4);
213 | DVDEF vec4 vec4Negate(vec4);
214 | DVDEF vec4 vec4Normalize(vec4);
215 | DVDEF vec4 vec4Multiply(vec4, DVTYPE);
216 | DVDEF vec4 vec4Divide(vec4, DVTYPE);
217 | DVDEF vec4 vec4Add(vec4, vec4);
218 | DVDEF vec4 vec4Subtract(vec4, vec4);
219 | DVDEF vec4 vec4Reflect(vec4, vec4);
220 | DVDEF vec4 vec4Mix(vec4, vec4, DVTYPE);
221 | DVDEF int vec4Equal(vec4, vec4);
222 |
223 | //quat function declarations
224 | DVDEF vec3 quatGetXYZ(quat);
225 | DVDEF vec3 quatMultiplyVector(quat, vec3);
226 | DVDEF quat quatAxisAngle(vec3, DVTYPE);
227 | DVDEF quat quatEulerXYZ(DVTYPE, DVTYPE, DVTYPE);
228 | DVDEF quat quatEulerXZY(DVTYPE, DVTYPE, DVTYPE);
229 | DVDEF quat quatEulerYXZ(DVTYPE, DVTYPE, DVTYPE);
230 | DVDEF quat quatEulerYZX(DVTYPE, DVTYPE, DVTYPE);
231 | DVDEF quat quatEulerZXY(DVTYPE, DVTYPE, DVTYPE);
232 | DVDEF quat quatEulerZYX(DVTYPE, DVTYPE, DVTYPE);
233 | DVDEF quat quatNormalize(quat);
234 | DVDEF quat quatConjugate(quat);
235 | DVDEF quat quatLerp(quat, quat, DVTYPE);
236 | DVDEF quat quatSlerp(quat, quat, DVTYPE);
237 | DVDEF quat quatMultiply(quat, quat);
238 | DVDEF int quatEqual(quat, quat);
239 |
240 | //mat2 function declarations
241 | DVDEF vec2 mat2MultiplyVector(mat2, vec2);
242 | DVDEF mat2 mat2Transpose(mat2);
243 | DVDEF mat2 mat2Inverse(mat2);
244 | DVDEF mat2 mat2MultiplyScalar(mat2, DVTYPE);
245 | DVDEF mat2 mat2MultiplyMatrix(mat2, mat2);
246 | DVDEF mat2 mat2Add(mat2, mat2);
247 | DVDEF mat2 mat2Subtract(mat2, mat2);
248 | DVDEF int mat2Equal(mat2, mat2);
249 |
250 | //mat3 function declarations
251 | DVDEF vec3 mat3MultiplyVector(mat3, vec3);
252 | DVDEF mat3 mat3SetRotation(DVTYPE);
253 | DVDEF mat3 mat3SetScale(DVTYPE);
254 | DVDEF mat3 mat3SetScaleXY(vec2);
255 | DVDEF mat3 mat3SetTranslation(vec2);
256 | DVDEF mat3 mat3Transpose(mat3);
257 | DVDEF mat3 mat3Inverse(mat3);
258 | DVDEF mat3 mat3MultiplyScalar(mat3, DVTYPE);
259 | DVDEF mat3 mat3Rotate(mat3, DVTYPE);
260 | DVDEF mat3 mat3Scale(mat3, DVTYPE);
261 | DVDEF mat3 mat3ScaleXY(mat3, vec2);
262 | DVDEF mat3 mat3Translate(mat3, vec2);
263 | DVDEF mat3 mat3MultiplyMatrix(mat3, mat3);
264 | DVDEF mat3 mat3Add(mat3, mat3);
265 | DVDEF mat3 mat3Subtract(mat3, mat3);
266 | DVDEF int mat3Equal(mat3, mat3);
267 |
268 | //mat4 function declarations
269 | DVDEF vec4 mat4MultiplyVector(mat4, vec4);
270 | DVDEF mat4 mat4SetRotationX(DVTYPE);
271 | DVDEF mat4 mat4SetRotationY(DVTYPE);
272 | DVDEF mat4 mat4SetRotationZ(DVTYPE);
273 | DVDEF mat4 mat4SetRotationQuaternion(quat);
274 | DVDEF mat4 mat4SetScale(DVTYPE);
275 | DVDEF mat4 mat4SetScaleXYZ(vec3);
276 | DVDEF mat4 mat4SetTranslation(vec3);
277 | DVDEF mat4 mat4LookAt(vec3, vec3, vec3);
278 | DVDEF mat4 mat4Perspective(DVTYPE, DVTYPE, DVTYPE, DVTYPE);
279 | DVDEF mat4 mat4Ortho(DVTYPE, DVTYPE, DVTYPE, DVTYPE, DVTYPE, DVTYPE);
280 | DVDEF mat4 mat4Transpose(mat4);
281 | DVDEF mat4 mat4Inverse(mat4);
282 | DVDEF mat4 mat4MultiplyScalar(mat4, DVTYPE);
283 | DVDEF mat4 mat4RotateX(mat4, DVTYPE);
284 | DVDEF mat4 mat4RotateY(mat4, DVTYPE);
285 | DVDEF mat4 mat4RotateZ(mat4, DVTYPE);
286 | DVDEF mat4 mat4RotateQuaternion(mat4, quat);
287 | DVDEF mat4 mat4Scale(mat4, DVTYPE);
288 | DVDEF mat4 mat4ScaleXYZ(mat4, vec3);
289 | DVDEF mat4 mat4Translate(mat4, vec3);
290 | DVDEF mat4 mat4MultiplyMatrix(mat4, mat4);
291 | DVDEF mat4 mat4Add(mat4, mat4);
292 | DVDEF mat4 mat4Subtract(mat4, mat4);
293 | DVDEF int mat4Equal(mat4, mat4);
294 |
295 | //frst function declarations
296 | DVDEF frst frstFromMatrix(mat4);
297 | DVDEF int frstCullSphere(frst, vec3, DVTYPE);
298 | DVDEF int frstCullAABB(frst, vec3, vec3);
299 |
300 | #endif //DVECTOR_H
301 |
302 | //implementation section
303 | #ifdef DVECTOR_IMPLEMENTATION
304 | #undef DVECTOR_IMPLEMENTATION
305 |
306 | //vec2 functions
307 | DVDEF DVTYPE vec2Length (vec2 v) {
308 | return DVHYPOT(v.x, v.y);
309 | }
310 | DVDEF DVTYPE vec2DotProduct (vec2 v1, vec2 v2) {
311 | return v1.x*v2.x + v1.y*v2.y;
312 | }
313 | DVDEF vec2 vec2Negate (vec2 v) {
314 | return VEC2(-v.x, -v.y);
315 | }
316 | DVDEF vec2 vec2Normalize (vec2 v) {
317 | return vec2Divide(v, vec2Length(v));
318 | }
319 | DVDEF vec2 vec2Multiply (vec2 v, DVTYPE s) {
320 | return VEC2(v.x*s, v.y*s);
321 | }
322 | DVDEF vec2 vec2Divide (vec2 v, DVTYPE s) {
323 | return VEC2(v.x/s, v.y/s);
324 | }
325 | DVDEF vec2 vec2Rotate (vec2 v, DVTYPE r) {
326 | DVTYPE c = DVCOS(r), s = DVSIN(r);
327 | return VEC2(v.x*c-v.y*s, v.y*c+v.x*s);
328 | }
329 | DVDEF vec2 vec2RotateXZ (vec2 v, DVTYPE r) {
330 | DVTYPE c = DVCOS(r), s = DVSIN(r);
331 | return VEC2(v.x*c+v.y*s, v.y*c-v.x*s);
332 | }
333 | DVDEF vec2 vec2Add (vec2 v1, vec2 v2) {
334 | return VEC2(v1.x+v2.x, v1.y+v2.y);
335 | }
336 | DVDEF vec2 vec2Subtract (vec2 v1, vec2 v2) {
337 | return VEC2(v1.x-v2.x, v1.y-v2.y);
338 | }
339 | DVDEF vec2 vec2Reflect (vec2 v1, vec2 v2) {
340 | return vec2Subtract(v1, vec2Multiply(v2, 2*vec2DotProduct(v1, v2)));
341 | }
342 | DVDEF vec2 vec2Mix (vec2 v1, vec2 v2, DVTYPE s) {
343 | return VEC2(v1.x+(v2.x-v1.x)*s, v1.y+(v2.y-v1.y)*s);
344 | }
345 | DVDEF int vec2Equal (vec2 v1, vec2 v2) {
346 | return (v1.x == v2.x)&&(v1.y == v2.y);
347 | }
348 |
349 | //vec3 functions
350 | DVDEF DVTYPE vec3Length (vec3 v) {
351 | return DVHYPOT(DVHYPOT(v.x, v.y), v.z);
352 | }
353 | DVDEF DVTYPE vec3DotProduct (vec3 v1, vec3 v2) {
354 | return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
355 | }
356 | DVDEF vec2 vec3GetXZ (vec3 v) {
357 | return VEC2(v.x, v.z);
358 | }
359 | DVDEF vec3 vec3Negate (vec3 v) {
360 | return VEC3(-v.x, -v.y, -v.z);
361 | }
362 | DVDEF vec3 vec3Normalize (vec3 v) {
363 | return vec3Divide(v, vec3Length(v));
364 | }
365 | DVDEF vec3 vec3Multiply (vec3 v, DVTYPE s) {
366 | return VEC3(v.x*s, v.y*s, v.z*s);
367 | }
368 | DVDEF vec3 vec3Divide (vec3 v, DVTYPE s) {
369 | return VEC3(v.x/s, v.y/s, v.z/s);
370 | }
371 | DVDEF vec3 vec3Add (vec3 v1, vec3 v2) {
372 | return VEC3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z);
373 | }
374 | DVDEF vec3 vec3Subtract (vec3 v1, vec3 v2) {
375 | return VEC3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z);
376 | }
377 | DVDEF vec3 vec3Reflect (vec3 v1, vec3 v2) {
378 | return vec3Subtract(v1, vec3Multiply(v2, 2*vec3DotProduct(v1, v2)));
379 | }
380 | DVDEF vec3 vec3CrossProduct (vec3 v1, vec3 v2) {
381 | return VEC3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
382 | }
383 | DVDEF vec3 vec3Mix (vec3 v1, vec3 v2, DVTYPE s) {
384 | return VEC3(v1.x+(v2.x-v1.x)*s, v1.y+(v2.y-v1.y)*s, v1.z+(v2.z-v1.z)*s);
385 | }
386 | DVDEF int vec3Equal (vec3 v1, vec3 v2) {
387 | return (v1.x == v2.x)&&(v1.y == v2.y)&&(v1.z == v2.z);
388 | }
389 |
390 |
391 | //vec4 functions
392 | DVDEF vec3 vec4GetXYZ (vec4 v) {
393 | return VEC3(v.x, v.y, v.z);
394 | }
395 | DVDEF DVTYPE vec4Length (vec4 v) {
396 | return DVHYPOT(DVHYPOT(v.x, v.y), DVHYPOT(v.z, v.w));
397 | }
398 | DVDEF DVTYPE vec4DotProduct (vec4 v1, vec4 v2) {
399 | return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w;
400 | }
401 | DVDEF vec4 vec4Negate (vec4 v) {
402 | return VEC4(-v.x, -v.y, -v.z, -v.w);
403 | }
404 | DVDEF vec4 vec4Normalize (vec4 v) {
405 | return vec4Divide(v, vec4Length(v));
406 | }
407 | DVDEF vec4 vec4Multiply (vec4 v, DVTYPE s) {
408 | return VEC4(v.x*s, v.y*s, v.z*s, v.w*s);
409 | }
410 | DVDEF vec4 vec4Divide (vec4 v, DVTYPE s) {
411 | return VEC4(v.x/s, v.y/s, v.z/s, v.w/s);
412 | }
413 | DVDEF vec4 vec4Add (vec4 v1, vec4 v2) {
414 | return VEC4(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z, v1.w+v2.w);
415 | }
416 | DVDEF vec4 vec4Subtract (vec4 v1, vec4 v2) {
417 | return VEC4(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z, v1.w-v2.w);
418 | }
419 | DVDEF vec4 vec4Reflect (vec4 v1, vec4 v2) {
420 | return vec4Subtract(v1, vec4Multiply(v2, 2*vec4DotProduct(v1, v2)));
421 | }
422 | DVDEF vec4 vec4Mix (vec4 v1, vec4 v2, DVTYPE s) {
423 | return VEC4(v1.x+(v2.x-v1.x)*s, v1.y+(v2.y-v1.y)*s, v1.z+(v2.z-v1.z)*s, v1.w+(v2.w-v1.w)*s);
424 | }
425 | DVDEF int vec4Equal (vec4 v1, vec4 v2) {
426 | return (v1.x == v2.x)&&(v1.y == v2.y)&&(v1.z == v2.z)&&(v1.w == v2.w);
427 | }
428 |
429 | //quat functions
430 | DVDEF vec3 quatGetXYZ (quat q) {
431 | return VEC3(q.x, q.y, q.z);
432 | }
433 | DVDEF vec3 quatMultiplyVector (quat q, vec3 v) {
434 | vec3 q_xyz = VEC3(q.x, q.y, q.z);
435 | vec3 t = vec3Multiply(vec3CrossProduct(q_xyz, v), 2);
436 | return vec3Add(vec3Add(v, vec3Multiply(t, q.w)), vec3CrossProduct(q_xyz, t));
437 | }
438 | DVDEF quat quatAxisAngle (vec3 a, DVTYPE r) {
439 | DVTYPE s = DVSIN(r/2);
440 | return QUAT(a.x*s, a.y*s, a.z*s, DVCOS(r/2));
441 | }
442 | DVDEF quat quatEulerXYZ (DVTYPE a, DVTYPE b, DVTYPE c) {
443 | return quatMultiply(quatAxisAngle(VEC3(0, 0, 1), c), quatMultiply(quatAxisAngle(VEC3(0, 1, 0), b), quatAxisAngle(VEC3(1, 0, 0), a)));
444 | }
445 | DVDEF quat quatEulerXZY (DVTYPE a, DVTYPE b, DVTYPE c) {
446 | return quatMultiply(quatAxisAngle(VEC3(0, 1, 0), c), quatMultiply(quatAxisAngle(VEC3(0, 0, 1), b), quatAxisAngle(VEC3(1, 0, 0), a)));
447 | }
448 | DVDEF quat quatEulerYXZ (DVTYPE a, DVTYPE b, DVTYPE c) {
449 | return quatMultiply(quatAxisAngle(VEC3(0, 0, 1), c), quatMultiply(quatAxisAngle(VEC3(1, 0, 0), b), quatAxisAngle(VEC3(0, 1, 0), a)));
450 | }
451 | DVDEF quat quatEulerYZX (DVTYPE a, DVTYPE b, DVTYPE c) {
452 | return quatMultiply(quatAxisAngle(VEC3(1, 0, 0), c), quatMultiply(quatAxisAngle(VEC3(0, 0, 1), b), quatAxisAngle(VEC3(0, 1, 0), a)));
453 | }
454 | DVDEF quat quatEulerZXY (DVTYPE a, DVTYPE b, DVTYPE c) {
455 | return quatMultiply(quatAxisAngle(VEC3(0, 1, 0), c), quatMultiply(quatAxisAngle(VEC3(1, 0, 0), b), quatAxisAngle(VEC3(0, 0, 1), a)));
456 | }
457 | DVDEF quat quatEulerZYX (DVTYPE a, DVTYPE b, DVTYPE c) {
458 | return quatMultiply(quatAxisAngle(VEC3(1, 0, 0), c), quatMultiply(quatAxisAngle(VEC3(0, 1, 0), b), quatAxisAngle(VEC3(0, 0, 1), a)));
459 | }
460 | DVDEF quat quatNormalize (quat q) {
461 | return vec4Normalize(q);
462 | }
463 | DVDEF quat quatConjugate (quat q) {
464 | return QUAT(-q.x, -q.y, -q.z, q.w);
465 | }
466 | DVDEF quat quatLerp (quat q1, quat q2, DVTYPE s) {
467 | return quatNormalize(QUAT((1-s)*q1.x + s*q2.x, (1-s)*q1.y + s*q2.y, (1-s)*q1.z + s*q2.z, (1-s)*q1.w + s*q2.w));
468 | }
469 | DVDEF quat quatSlerp (quat q1, quat q2, DVTYPE s) {
470 | DVTYPE th = DVACOS(q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w), sn = DVSIN(th), wa = DVSIN((1-s)*th)/sn, wb = DVSIN(s*th)/sn;
471 | return quatNormalize(QUAT(wa*q1.x + wb*q2.x, wa*q1.y + wb*q2.y, wa*q1.z + wb*q2.z, wa*q1.w + wb*q2.w));
472 | }
473 | DVDEF quat quatMultiply (quat q1, quat q2) {
474 | return QUAT(q1.x*q2.w + q1.y*q2.z - q1.z*q2.y + q1.w*q2.x, -q1.x*q2.z + q1.y*q2.w + q1.z*q2.x + q1.w*q2.y,
475 | q1.x*q2.y - q1.y*q2.x + q1.z*q2.w + q1.w*q2.z, -q1.x*q2.x - q1.y*q2.y - q1.z*q2.z + q1.w*q2.w);
476 | }
477 | DVDEF int quatEqual (quat q1, quat q2) {
478 | return (q1.x == q2.x)&&(q1.y == q2.y)&&(q1.z == q2.z)&&(q1.w == q2.w);
479 | }
480 |
481 | //mat2 functions
482 | DVDEF vec2 mat2MultiplyVector (mat2 m, vec2 v) {
483 | return VEC2(m.m[0][0]*v.x + m.m[1][0]*v.y, m.m[0][1]*v.x + m.m[1][1]*v.y);
484 | }
485 | DVDEF mat2 mat2Transpose (mat2 m) {
486 | return MAT2(m.m[0][0], m.m[1][0], m.m[0][1], m.m[1][1]);
487 | }
488 | DVDEF mat2 mat2Inverse (mat2 m) {
489 | return mat2MultiplyScalar(MAT2(m.m[1][1], -m.m[0][1], -m.m[1][0], m.m[0][0]), 1/(m.m[0][0]*m.m[1][1]-m.m[1][0]*m.m[0][1]));
490 | }
491 | DVDEF mat2 mat2MultiplyScalar (mat2 m, DVTYPE s) {
492 | return MAT2(m.m[0][0]*s, m.m[0][1]*s, m.m[1][0]*s, m.m[1][1]*s);
493 | }
494 | DVDEF mat2 mat2MultiplyMatrix (mat2 m1, mat2 m2) {
495 | mat2 m;
496 | for (int i = 0; i < 2; i++)
497 | for (int j = 0; j < 2; j++)
498 | m.m[i][j] = m1.m[i][0]*m2.m[0][j] + m1.m[i][1]*m2.m[1][j];
499 | return m;
500 | }
501 | DVDEF mat2 mat2Add (mat2 m1, mat2 m2) {
502 | return MAT2(m1.m[0][0]+m2.m[0][0], m1.m[0][1]+m2.m[0][1], m1.m[1][0]+m2.m[1][0], m1.m[1][1]+m2.m[1][1]);
503 | }
504 | DVDEF mat2 mat2Subtract (mat2 m1, mat2 m2) {
505 | return MAT2(m1.m[0][0]-m2.m[0][0], m1.m[0][1]-m2.m[0][1], m1.m[1][0]-m2.m[1][0], m1.m[1][1]-m2.m[1][1]);
506 | }
507 | DVDEF int mat2Equal (mat2 m1, mat2 m2) {
508 | return (m1.m[0][0] == m2.m[0][0])&&(m1.m[0][1] == m2.m[0][1])&&(m1.m[1][0] == m2.m[1][0])&&(m1.m[1][1] == m2.m[1][1]);
509 | }
510 |
511 | //mat3 function declarations
512 | DVDEF vec3 mat3MultiplyVector (mat3 m, vec3 v) {
513 | DVTYPE r[3];
514 | for (int i = 0; i < 3; i++)
515 | r[i] = m.m[0][i]*v.x + m.m[1][i]*v.y + m.m[2][i]*v.z;
516 | return VEC3(r[0], r[1], r[2]);
517 | }
518 | DVDEF mat3 mat3SetRotation (DVTYPE r) {
519 | DVTYPE c = DVCOS(r), s = DVSIN(r);
520 | return MAT3(c, s, 0, -s, c, 0, 0, 0, 1);
521 | }
522 | DVDEF mat3 mat3SetScale (DVTYPE s) {
523 | return MAT3(s, 0, 0, 0, s, 0, 0, 0, 1);
524 | }
525 | DVDEF mat3 mat3SetScaleXY (vec2 s) {
526 | return MAT3(s.x, 0, 0, 0, s.y, 0, 0, 0, 1);
527 | }
528 | DVDEF mat3 mat3SetTranslation (vec2 v) {
529 | return MAT3(1, 0, 0, 0, 1, 0, v.x, v.y, 1);
530 | }
531 | DVDEF mat3 mat3Transpose (mat3 m) {
532 | return MAT3(m.m[0][0], m.m[1][0], m.m[2][0], m.m[0][1], m.m[1][1], m.m[2][1], m.m[0][2], m.m[1][2], m.m[2][2]);
533 | }
534 | DVDEF mat3 mat3Inverse (mat3 m) {
535 | mat3 t = MAT3(m.m[1][1]*m.m[2][2] - m.m[2][1]*m.m[1][2], m.m[1][2]*m.m[2][0] - m.m[1][0]*m.m[2][2], m.m[1][0]*m.m[2][1] - m.m[1][1]*m.m[2][0],
536 | m.m[2][1]*m.m[0][2] - m.m[0][1]*m.m[2][2], m.m[0][0]*m.m[2][2] - m.m[0][2]*m.m[2][0], m.m[0][1]*m.m[2][0] - m.m[0][0]*m.m[2][1],
537 | m.m[0][1]*m.m[1][2] - m.m[1][1]*m.m[0][2], m.m[0][2]*m.m[1][0] - m.m[0][0]*m.m[1][2], m.m[0][0]*m.m[1][1] - m.m[0][1]*m.m[1][0]);
538 | return mat3MultiplyScalar(t, 1/(m.m[0][0]*t.m[0][0] + m.m[1][0]*t.m[1][0] + m.m[2][0]*t.m[2][0]));
539 | }
540 | DVDEF mat3 mat3MultiplyScalar (mat3 m, DVTYPE s) {
541 | for (int i = 0; i < 3; i++)
542 | for (int j = 0; j < 3; j++)
543 | m.m[i][j] *= s;
544 | return m;
545 | }
546 | DVDEF mat3 mat3Rotate (mat3 m, DVTYPE r) {
547 | return mat3MultiplyMatrix(m, mat3SetRotation(r));
548 | }
549 | DVDEF mat3 mat3Scale (mat3 m, DVTYPE s) {
550 | return mat3MultiplyMatrix(m, mat3SetScale(s));
551 | }
552 | DVDEF mat3 mat3ScaleXY (mat3 m, vec2 v) {
553 | return mat3MultiplyMatrix(m, mat3SetScaleXY(v));
554 | }
555 | DVDEF mat3 mat3Translate (mat3 m, vec2 v) {
556 | return mat3MultiplyMatrix(m, mat3SetTranslation(v));
557 | }
558 | DVDEF mat3 mat3MultiplyMatrix (mat3 m1, mat3 m2) {
559 | mat3 m;
560 | for (int i = 0; i < 3; i++)
561 | for (int j = 0; j < 3; j++)
562 | m.m[i][j] = m1.m[i][0]*m2.m[0][j] + m1.m[i][1]*m2.m[1][j] + m1.m[i][2]*m2.m[2][j];
563 | return m;
564 | }
565 | DVDEF mat3 mat3Add (mat3 m1, mat3 m2) {
566 | mat3 m;
567 | for (int i = 0; i < 3; i++)
568 | for (int j = 0; j < 3; j++)
569 | m.m[i][j] = m1.m[i][j] + m2.m[i][j];
570 | return m;
571 | }
572 | DVDEF mat3 mat3Subtract (mat3 m1, mat3 m2) {
573 | mat3 m;
574 | for (int i = 0; i < 3; i++)
575 | for (int j = 0; j < 3; j++)
576 | m.m[i][j] = m1.m[i][j] - m2.m[i][j];
577 | return m;
578 | }
579 | DVDEF int mat3Equal (mat3 m1, mat3 m2) {
580 | for (int i = 0; i < 3; i++)
581 | for (int j = 0; j < 3; j++)
582 | if (m1.m[i][j] != m2.m[i][j])
583 | return 0;
584 | return 1;
585 | }
586 |
587 | //mat4 function declarations
588 | DVDEF vec4 mat4MultiplyVector (mat4 m, vec4 v) {
589 | DVTYPE r[4];
590 | for (int i = 0; i < 4; i++)
591 | r[i] = m.m[0][i]*v.x + m.m[1][i]*v.y + m.m[2][i]*v.z + m.m[3][i]*v.w;
592 | return VEC4(r[0], r[1], r[2], r[3]);
593 | }
594 | DVDEF mat4 mat4SetRotationX (DVTYPE r) {
595 | DVTYPE c = DVCOS(r), s = DVSIN(r);
596 | return MAT4(1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1);
597 | }
598 | DVDEF mat4 mat4SetRotationY (DVTYPE r) {
599 | DVTYPE c = DVCOS(r), s = DVSIN(r);
600 | return MAT4(c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1);
601 | }
602 | DVDEF mat4 mat4SetRotationZ (DVTYPE r) {
603 | DVTYPE c = DVCOS(r), s = DVSIN(r);
604 | return MAT4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
605 | }
606 | DVDEF mat4 mat4SetRotationQuaternion (quat q) {
607 | DVTYPE xx = q.x*q.x, xy = q.x*q.y, xz = q.x*q.z, xw = q.x*q.w, yy = q.y*q.y, yz = q.y*q.z, yw = q.y*q.w, zz = q.z*q.z, zw = q.z*q.w;
608 | return MAT4(1-2*yy-2*zz, 2*xy+2*zw, 2*xz-2*yw, 0, 2*xy-2*zw, 1-2*xx-2*zz, 2*yz+2*xw, 0, 2*xz+2*yw, 2*yz-2*xw, 1-2*xx-2*yy, 0, 0, 0, 0, 1);
609 | }
610 | DVDEF mat4 mat4SetScale (DVTYPE s) {
611 | return MAT4(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
612 | }
613 | DVDEF mat4 mat4SetScaleXYZ (vec3 v) {
614 | return MAT4(v.x, 0, 0, 0, 0, v.y, 0, 0, 0, 0, v.z, 0, 0, 0, 0, 1);
615 | }
616 | DVDEF mat4 mat4SetTranslation (vec3 v) {
617 | return MAT4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v.x, v.y, v.z, 1);
618 | }
619 | DVDEF mat4 mat4LookAt (vec3 from, vec3 to, vec3 up) {
620 | vec3 f = vec3Normalize(vec3Subtract(to, from)), s = vec3Normalize(vec3CrossProduct(f, up)), t = vec3CrossProduct(s, f);
621 | mat4 m = MAT4(s.x, t.x, -f.x, 0, s.y, t.y, -f.y, 0, s.z, t.z, -f.z, 0, 0, 0, 0, 1);
622 | for (int i = 0; i < 3; i++)
623 | m.m[3][i] = -vec3DotProduct(VEC3(m.m[0][i], m.m[1][i], m.m[2][i]), from);
624 | return m;
625 | }
626 | DVDEF mat4 mat4Perspective (DVTYPE vfov, DVTYPE aspect, DVTYPE ndist, DVTYPE fdist) {
627 | DVTYPE a = 1/DVTAN(vfov/2);
628 | return MAT4(a/aspect, 0, 0, 0, 0, a, 0, 0, 0, 0, -((fdist+ndist)/(fdist-ndist)), -1, 0, 0, -((2*fdist*ndist)/(fdist-ndist)), 0);
629 | }
630 | DVDEF mat4 mat4Ortho (DVTYPE left, DVTYPE right, DVTYPE bottom, DVTYPE top, DVTYPE ndist, DVTYPE fdist) {
631 | return MAT4(2/(right-left), 0, 0, 0, 0, 2/(top-bottom), 0, 0, 0, 0, -2/(fdist-ndist), 0,
632 | -(right+left)/(right-left), -(top+bottom)/(top-bottom), -(fdist+ndist)/(fdist-ndist), 1);
633 | }
634 | DVDEF mat4 mat4Transpose (mat4 m) {
635 | return MAT4(m.m[0][0], m.m[1][0], m.m[2][0], m.m[3][0], m.m[0][1], m.m[1][1], m.m[2][1], m.m[3][1],
636 | m.m[0][2], m.m[1][2], m.m[2][2], m.m[3][2], m.m[0][3], m.m[1][3], m.m[2][3], m.m[3][3]);
637 | }
638 | DVDEF mat4 mat4Inverse (mat4 m) {
639 | DVTYPE s[6] = {m.m[0][0]*m.m[1][1] - m.m[1][0]*m.m[0][1], m.m[0][0]*m.m[1][2] - m.m[1][0]*m.m[0][2], m.m[0][0]*m.m[1][3] - m.m[1][0]*m.m[0][3],
640 | m.m[0][1]*m.m[1][2] - m.m[1][1]*m.m[0][2], m.m[0][1]*m.m[1][3] - m.m[1][1]*m.m[0][3], m.m[0][2]*m.m[1][3] - m.m[1][2]*m.m[0][3]};
641 | DVTYPE c[6] = {m.m[2][0]*m.m[3][1] - m.m[3][0]*m.m[2][1], m.m[2][0]*m.m[3][2] - m.m[3][0]*m.m[2][2], m.m[2][0]*m.m[3][3] - m.m[3][0]*m.m[2][3],
642 | m.m[2][1]*m.m[3][2] - m.m[3][1]*m.m[2][2], m.m[2][1]*m.m[3][3] - m.m[3][1]*m.m[2][3], m.m[2][2]*m.m[3][3] - m.m[3][2]*m.m[2][3]};
643 | return mat4MultiplyScalar(MAT4(m.m[1][1]*c[5] - m.m[1][2]*c[4] + m.m[1][3]*c[3], m.m[0][2]*c[4] - m.m[0][1]*c[5] - m.m[0][3]*c[3],
644 | m.m[3][1]*s[5] - m.m[3][2]*s[4] + m.m[3][3]*s[3], m.m[2][2]*s[4] - m.m[2][1]*s[5] - m.m[2][3]*s[3], m.m[1][2]*c[2] - m.m[1][0]*c[5] - m.m[1][3]*c[1],
645 | m.m[0][0]*c[5] - m.m[0][2]*c[2] + m.m[0][3]*c[1], m.m[3][2]*s[2] - m.m[3][0]*s[5] - m.m[3][3]*s[1], m.m[2][0]*s[5] - m.m[2][2]*s[2] + m.m[2][3]*s[1],
646 | m.m[1][0]*c[4] - m.m[1][1]*c[2] + m.m[1][3]*c[0], m.m[0][1]*c[2] - m.m[0][0]*c[4] - m.m[0][3]*c[0], m.m[3][0]*s[4] - m.m[3][1]*s[2] + m.m[3][3]*s[0],
647 | m.m[2][1]*s[2] - m.m[2][0]*s[4] - m.m[2][3]*s[0], m.m[1][1]*c[1] - m.m[1][0]*c[3] - m.m[1][2]*c[0], m.m[0][0]*c[3] - m.m[0][1]*c[1] + m.m[0][2]*c[0],
648 | m.m[3][1]*s[1] - m.m[3][0]*s[3] - m.m[3][2]*s[0], m.m[2][0]*s[3] - m.m[2][1]*s[1] + m.m[2][2]*s[0]),
649 | 1/(s[0]*c[5] - s[1]*c[4] + s[2]*c[3] + s[3]*c[2] - s[4]*c[1] + s[5]*c[0]));
650 | }
651 | DVDEF mat4 mat4MultiplyScalar (mat4 m, DVTYPE s) {
652 | for (int i = 0; i < 4; i++)
653 | for (int j = 0; j < 4; j++)
654 | m.m[i][j] *= s;
655 | return m;
656 | }
657 | DVDEF mat4 mat4RotateX (mat4 m, DVTYPE r) {
658 | return mat4MultiplyMatrix(mat4SetRotationX(r), m);
659 | }
660 | DVDEF mat4 mat4RotateY (mat4 m, DVTYPE r) {
661 | return mat4MultiplyMatrix(mat4SetRotationY(r), m);
662 | }
663 | DVDEF mat4 mat4RotateZ (mat4 m, DVTYPE r) {
664 | return mat4MultiplyMatrix(mat4SetRotationZ(r), m);
665 | }
666 | DVDEF mat4 mat4RotateQuaternion (mat4 m, quat q) {
667 | return mat4MultiplyMatrix(mat4SetRotationQuaternion(q), m);
668 | }
669 | DVDEF mat4 mat4Scale (mat4 m, DVTYPE s) {
670 | return mat4MultiplyMatrix(mat4SetScale(s), m);
671 | }
672 | DVDEF mat4 mat4ScaleXYZ (mat4 m, vec3 v) {
673 | return mat4MultiplyMatrix(mat4SetScaleXYZ(v), m);
674 | }
675 | DVDEF mat4 mat4Translate (mat4 m, vec3 v) {
676 | return mat4MultiplyMatrix(mat4SetTranslation(v), m);
677 | }
678 | DVDEF mat4 mat4MultiplyMatrix (mat4 m1, mat4 m2) {
679 | mat4 m;
680 | for (int i = 0; i < 4; i++)
681 | for (int j = 0; j < 4; j++)
682 | m.m[i][j] = m1.m[0][j]*m2.m[i][0] + m1.m[1][j]*m2.m[i][1] + m1.m[2][j]*m2.m[i][2] + m1.m[3][j]*m2.m[i][3];
683 | return m;
684 | }
685 | DVDEF mat4 mat4Add (mat4 m1, mat4 m2) {
686 | mat4 m;
687 | for (int i = 0; i < 4; i++)
688 | for (int j = 0; j < 4; j++)
689 | m.m[i][j] = m1.m[i][j] + m2.m[i][j];
690 | return m;
691 | }
692 | DVDEF mat4 mat4Subtract (mat4 m1, mat4 m2) {
693 | mat4 m;
694 | for (int i = 0; i < 4; i++)
695 | for (int j = 0; j < 4; j++)
696 | m.m[i][j] = m1.m[i][j] - m2.m[i][j];
697 | return m;
698 | }
699 | DVDEF int mat4Equal (mat4 m1, mat4 m2) {
700 | for (int i = 0; i < 4; i++)
701 | for (int j = 0; j < 4; j++)
702 | if (m1.m[i][j] != m2.m[i][j])
703 | return 0;
704 | return 1;
705 | }
706 |
707 | //frst functions
708 | DVDEF frst frstFromMatrix (mat4 m) {
709 | frst f;
710 | f.pln[0] = VEC4(m.m[0][3]+m.m[0][0], m.m[1][3]+m.m[1][0], m.m[2][3]+m.m[2][0], m.m[3][3]+m.m[3][0]); //left
711 | f.pln[1] = VEC4(m.m[0][3]-m.m[0][0], m.m[1][3]-m.m[1][0], m.m[2][3]-m.m[2][0], m.m[3][3]-m.m[3][0]); //right
712 | f.pln[2] = VEC4(m.m[0][3]-m.m[0][1], m.m[1][3]-m.m[1][1], m.m[2][3]-m.m[2][1], m.m[3][3]-m.m[3][1]); //top
713 | f.pln[3] = VEC4(m.m[0][3]+m.m[0][1], m.m[1][3]+m.m[1][1], m.m[2][3]+m.m[2][1], m.m[3][3]+m.m[3][1]); //bottom
714 | f.pln[4] = VEC4(m.m[0][3]+m.m[0][2], m.m[1][3]+m.m[1][2], m.m[2][3]+m.m[2][2], m.m[3][3]+m.m[3][2]); //near
715 | f.pln[5] = VEC4(m.m[0][3]-m.m[0][2], m.m[1][3]-m.m[1][2], m.m[2][3]-m.m[2][2], m.m[3][3]-m.m[3][2]); //far
716 | for (int i = 0; i < 6; i++)
717 | f.pln[i] = vec4Divide(f.pln[i], vec3Length(vec4GetXYZ(f.pln[i])));
718 | return f;
719 | }
720 | DVDEF int frstCullSphere (frst f, vec3 v, DVTYPE s) {
721 | for (int i = 0; i < 6; i++)
722 | if (vec3DotProduct(vec4GetXYZ(f.pln[i]), v) + f.pln[i].w + s < 0)
723 | return 0;
724 | return 1;
725 | }
726 | DVDEF int frstCullAABB (frst f, vec3 min, vec3 max) {
727 | for (int i = 0; i < 6; i++) {
728 | const vec3 v = VEC3(f.pln[i].x > 0 ? max.x : min.x, f.pln[i].y > 0 ? max.y : min.y, f.pln[i].z > 0 ? max.z : min.z);
729 | if (vec3DotProduct(vec4GetXYZ(f.pln[i]), v) + f.pln[i].w < 0)
730 | return 0;
731 | }
732 | return 1;
733 | }
734 |
735 | #endif //DVECTOR_IMPLEMENTATION
736 |
--------------------------------------------------------------------------------