vrshoot

view libs/vmath/vector.inl @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 libvmath - a vector math library
3 Copyright (C) 2004-2013 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
19 #include <math.h>
21 #ifdef __cplusplus
22 extern "C" {
23 #endif /* __cplusplus */
25 scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
26 scalar_t bspline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
28 /* C 2D vector functions */
29 static inline vec2_t v2_cons(scalar_t x, scalar_t y)
30 {
31 vec2_t v;
32 v.x = x;
33 v.y = y;
34 return v;
35 }
37 static inline void v2_print(FILE *fp, vec2_t v)
38 {
39 fprintf(fp, "[ %.4f %.4f ]", v.x, v.y);
40 }
42 static inline vec2_t v2_add(vec2_t v1, vec2_t v2)
43 {
44 vec2_t res;
45 res.x = v1.x + v2.x;
46 res.y = v1.y + v2.y;
47 return res;
48 }
50 static inline vec2_t v2_sub(vec2_t v1, vec2_t v2)
51 {
52 vec2_t res;
53 res.x = v1.x - v2.x;
54 res.y = v1.y - v2.y;
55 return res;
56 }
58 static inline vec2_t v2_scale(vec2_t v, scalar_t s)
59 {
60 vec2_t res;
61 res.x = v.x * s;
62 res.y = v.y * s;
63 return res;
64 }
66 static inline scalar_t v2_dot(vec2_t v1, vec2_t v2)
67 {
68 return v1.x * v2.x + v1.y * v2.y;
69 }
71 static inline scalar_t v2_length(vec2_t v)
72 {
73 return sqrt(v.x * v.x + v.y * v.y);
74 }
76 static inline scalar_t v2_length_sq(vec2_t v)
77 {
78 return v.x * v.x + v.y * v.y;
79 }
81 static inline vec2_t v2_normalize(vec2_t v)
82 {
83 scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y);
84 v.x /= len;
85 v.y /= len;
86 return v;
87 }
89 static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t)
90 {
91 vec2_t res;
92 res.x = v1.x + (v2.x - v1.x) * t;
93 res.y = v1.y + (v2.y - v1.y) * t;
94 return res;
95 }
98 /* C 3D vector functions */
99 static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z)
100 {
101 vec3_t v;
102 v.x = x;
103 v.y = y;
104 v.z = z;
105 return v;
106 }
108 static inline void v3_print(FILE *fp, vec3_t v)
109 {
110 fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z);
111 }
113 static inline vec3_t v3_add(vec3_t v1, vec3_t v2)
114 {
115 v1.x += v2.x;
116 v1.y += v2.y;
117 v1.z += v2.z;
118 return v1;
119 }
121 static inline vec3_t v3_sub(vec3_t v1, vec3_t v2)
122 {
123 v1.x -= v2.x;
124 v1.y -= v2.y;
125 v1.z -= v2.z;
126 return v1;
127 }
129 static inline vec3_t v3_neg(vec3_t v)
130 {
131 v.x = -v.x;
132 v.y = -v.y;
133 v.z = -v.z;
134 return v;
135 }
137 static inline vec3_t v3_mul(vec3_t v1, vec3_t v2)
138 {
139 v1.x *= v2.x;
140 v1.y *= v2.y;
141 v1.z *= v2.z;
142 return v1;
143 }
145 static inline vec3_t v3_scale(vec3_t v1, scalar_t s)
146 {
147 v1.x *= s;
148 v1.y *= s;
149 v1.z *= s;
150 return v1;
151 }
153 static inline scalar_t v3_dot(vec3_t v1, vec3_t v2)
154 {
155 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
156 }
158 static inline vec3_t v3_cross(vec3_t v1, vec3_t v2)
159 {
160 vec3_t v;
161 v.x = v1.y * v2.z - v1.z * v2.y;
162 v.y = v1.z * v2.x - v1.x * v2.z;
163 v.z = v1.x * v2.y - v1.y * v2.x;
164 return v;
165 }
167 static inline scalar_t v3_length(vec3_t v)
168 {
169 return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
170 }
172 static inline scalar_t v3_length_sq(vec3_t v)
173 {
174 return v.x * v.x + v.y * v.y + v.z * v.z;
175 }
177 static inline vec3_t v3_normalize(vec3_t v)
178 {
179 scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
180 v.x /= len;
181 v.y /= len;
182 v.z /= len;
183 return v;
184 }
186 static inline vec3_t v3_transform(vec3_t v, mat4_t m)
187 {
188 vec3_t res;
189 res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3];
190 res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3];
191 res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3];
192 return res;
193 }
195 static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z)
196 {
197 void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t);
199 mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
200 m4_rotate(m, x, y, z);
201 return v3_transform(v, m);
202 }
204 static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
205 {
206 void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t);
208 mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
209 m4_rotate_axis(m, angle, x, y, z);
210 return v3_transform(v, m);
211 }
213 static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q)
214 {
215 quat_t quat_rotate_quat(quat_t, quat_t);
217 quat_t vq = v4_cons(v.x, v.y, v.z, 0.0);
218 quat_t res = quat_rotate_quat(vq, q);
219 return v3_cons(res.x, res.y, res.z);
220 }
222 static inline vec3_t v3_reflect(vec3_t v, vec3_t n)
223 {
224 scalar_t dot = v3_dot(v, n);
225 return v3_sub(v3_scale(n, dot * 2.0), v);
226 }
228 static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t)
229 {
230 v1.x += (v2.x - v1.x) * t;
231 v1.y += (v2.y - v1.y) * t;
232 v1.z += (v2.z - v1.z) * t;
233 return v1;
234 }
236 /* C 4D vector functions */
237 static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
238 {
239 vec4_t v;
240 v.x = x;
241 v.y = y;
242 v.z = z;
243 v.w = w;
244 return v;
245 }
247 static inline void v4_print(FILE *fp, vec4_t v)
248 {
249 fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w);
250 }
252 static inline vec4_t v4_add(vec4_t v1, vec4_t v2)
253 {
254 v1.x += v2.x;
255 v1.y += v2.y;
256 v1.z += v2.z;
257 v1.w += v2.w;
258 return v1;
259 }
261 static inline vec4_t v4_sub(vec4_t v1, vec4_t v2)
262 {
263 v1.x -= v2.x;
264 v1.y -= v2.y;
265 v1.z -= v2.z;
266 v1.w -= v2.w;
267 return v1;
268 }
270 static inline vec4_t v4_neg(vec4_t v)
271 {
272 v.x = -v.x;
273 v.y = -v.y;
274 v.z = -v.z;
275 v.w = -v.w;
276 return v;
277 }
279 static inline vec4_t v4_mul(vec4_t v1, vec4_t v2)
280 {
281 v1.x *= v2.x;
282 v1.y *= v2.y;
283 v1.z *= v2.z;
284 v1.w *= v2.w;
285 return v1;
286 }
288 static inline vec4_t v4_scale(vec4_t v, scalar_t s)
289 {
290 v.x *= s;
291 v.y *= s;
292 v.z *= s;
293 v.w *= s;
294 return v;
295 }
297 static inline scalar_t v4_dot(vec4_t v1, vec4_t v2)
298 {
299 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
300 }
302 static inline scalar_t v4_length(vec4_t v)
303 {
304 return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
305 }
307 static inline scalar_t v4_length_sq(vec4_t v)
308 {
309 return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
310 }
312 static inline vec4_t v4_normalize(vec4_t v)
313 {
314 scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
315 v.x /= len;
316 v.y /= len;
317 v.z /= len;
318 v.w /= len;
319 return v;
320 }
322 static inline vec4_t v4_transform(vec4_t v, mat4_t m)
323 {
324 vec4_t res;
325 res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w;
326 res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w;
327 res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w;
328 res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w;
329 return res;
330 }
332 #ifdef __cplusplus
333 } /* extern "C" */
336 /* --------------- C++ part -------------- */
338 inline scalar_t &Vector2::operator [](int elem)
339 {
340 return elem ? y : x;
341 }
343 inline const scalar_t &Vector2::operator [](int elem) const
344 {
345 return elem ? y : x;
346 }
348 inline Vector2 operator -(const Vector2 &vec)
349 {
350 return Vector2(-vec.x, -vec.y);
351 }
353 inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2)
354 {
355 return v1.x * v2.x + v1.y * v2.y;
356 }
358 inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2)
359 {
360 return Vector2(v1.x + v2.x, v1.y + v2.y);
361 }
363 inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2)
364 {
365 return Vector2(v1.x - v2.x, v1.y - v2.y);
366 }
368 inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2)
369 {
370 return Vector2(v1.x * v2.x, v1.y * v2.y);
371 }
373 inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2)
374 {
375 return Vector2(v1.x / v2.x, v1.y / v2.y);
376 }
378 inline bool operator ==(const Vector2 &v1, const Vector2 &v2)
379 {
380 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER);
381 }
383 inline void operator +=(Vector2 &v1, const Vector2 &v2)
384 {
385 v1.x += v2.x;
386 v1.y += v2.y;
387 }
389 inline void operator -=(Vector2 &v1, const Vector2 &v2)
390 {
391 v1.x -= v2.x;
392 v1.y -= v2.y;
393 }
395 inline void operator *=(Vector2 &v1, const Vector2 &v2)
396 {
397 v1.x *= v2.x;
398 v1.y *= v2.y;
399 }
401 inline void operator /=(Vector2 &v1, const Vector2 &v2)
402 {
403 v1.x /= v2.x;
404 v1.y /= v2.y;
405 }
407 inline Vector2 operator +(const Vector2 &vec, scalar_t scalar)
408 {
409 return Vector2(vec.x + scalar, vec.y + scalar);
410 }
412 inline Vector2 operator +(scalar_t scalar, const Vector2 &vec)
413 {
414 return Vector2(vec.x + scalar, vec.y + scalar);
415 }
417 inline Vector2 operator -(const Vector2 &vec, scalar_t scalar)
418 {
419 return Vector2(vec.x - scalar, vec.y - scalar);
420 }
422 inline Vector2 operator *(const Vector2 &vec, scalar_t scalar)
423 {
424 return Vector2(vec.x * scalar, vec.y * scalar);
425 }
427 inline Vector2 operator *(scalar_t scalar, const Vector2 &vec)
428 {
429 return Vector2(vec.x * scalar, vec.y * scalar);
430 }
432 inline Vector2 operator /(const Vector2 &vec, scalar_t scalar)
433 {
434 return Vector2(vec.x / scalar, vec.y / scalar);
435 }
437 inline void operator +=(Vector2 &vec, scalar_t scalar)
438 {
439 vec.x += scalar;
440 vec.y += scalar;
441 }
443 inline void operator -=(Vector2 &vec, scalar_t scalar)
444 {
445 vec.x -= scalar;
446 vec.y -= scalar;
447 }
449 inline void operator *=(Vector2 &vec, scalar_t scalar)
450 {
451 vec.x *= scalar;
452 vec.y *= scalar;
453 }
455 inline void operator /=(Vector2 &vec, scalar_t scalar)
456 {
457 vec.x /= scalar;
458 vec.y /= scalar;
459 }
461 inline scalar_t Vector2::length() const
462 {
463 return sqrt(x*x + y*y);
464 }
466 inline scalar_t Vector2::length_sq() const
467 {
468 return x*x + y*y;
469 }
471 inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t)
472 {
473 return a + (b - a) * t;
474 }
476 inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
477 const Vector2 &v2, const Vector2 &v3, scalar_t t)
478 {
479 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
480 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
481 return Vector2(x, y);
482 }
484 inline Vector2 bspline(const Vector2 &v0, const Vector2 &v1,
485 const Vector2 &v2, const Vector2 &v3, scalar_t t)
486 {
487 scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
488 scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
489 return Vector2(x, y);
490 }
493 /* ------------- Vector3 -------------- */
495 inline scalar_t &Vector3::operator [](int elem) {
496 return elem ? (elem == 1 ? y : z) : x;
497 }
499 inline const scalar_t &Vector3::operator [](int elem) const {
500 return elem ? (elem == 1 ? y : z) : x;
501 }
503 /* unary operations */
504 inline Vector3 operator -(const Vector3 &vec) {
505 return Vector3(-vec.x, -vec.y, -vec.z);
506 }
508 /* binary vector (op) vector operations */
509 inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) {
510 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
511 }
513 inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) {
514 return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x);
515 }
518 inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) {
519 return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
520 }
522 inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) {
523 return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
524 }
526 inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) {
527 return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
528 }
530 inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) {
531 return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
532 }
534 inline bool operator ==(const Vector3 &v1, const Vector3 &v2) {
535 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER);
536 }
538 inline void operator +=(Vector3 &v1, const Vector3 &v2) {
539 v1.x += v2.x;
540 v1.y += v2.y;
541 v1.z += v2.z;
542 }
544 inline void operator -=(Vector3 &v1, const Vector3 &v2) {
545 v1.x -= v2.x;
546 v1.y -= v2.y;
547 v1.z -= v2.z;
548 }
550 inline void operator *=(Vector3 &v1, const Vector3 &v2) {
551 v1.x *= v2.x;
552 v1.y *= v2.y;
553 v1.z *= v2.z;
554 }
556 inline void operator /=(Vector3 &v1, const Vector3 &v2) {
557 v1.x /= v2.x;
558 v1.y /= v2.y;
559 v1.z /= v2.z;
560 }
561 /* binary vector (op) scalar and scalar (op) vector operations */
562 inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) {
563 return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
564 }
566 inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) {
567 return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
568 }
570 inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) {
571 return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar);
572 }
574 inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) {
575 return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
576 }
578 inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) {
579 return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
580 }
582 inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) {
583 return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar);
584 }
586 inline void operator +=(Vector3 &vec, scalar_t scalar) {
587 vec.x += scalar;
588 vec.y += scalar;
589 vec.z += scalar;
590 }
592 inline void operator -=(Vector3 &vec, scalar_t scalar) {
593 vec.x -= scalar;
594 vec.y -= scalar;
595 vec.z -= scalar;
596 }
598 inline void operator *=(Vector3 &vec, scalar_t scalar) {
599 vec.x *= scalar;
600 vec.y *= scalar;
601 vec.z *= scalar;
602 }
604 inline void operator /=(Vector3 &vec, scalar_t scalar) {
605 vec.x /= scalar;
606 vec.y /= scalar;
607 vec.z /= scalar;
608 }
610 inline scalar_t Vector3::length() const {
611 return sqrt(x*x + y*y + z*z);
612 }
613 inline scalar_t Vector3::length_sq() const {
614 return x*x + y*y + z*z;
615 }
617 inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) {
618 return a + (b - a) * t;
619 }
621 inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
622 const Vector3 &v2, const Vector3 &v3, scalar_t t)
623 {
624 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
625 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
626 scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
627 return Vector3(x, y, z);
628 }
630 inline Vector3 bspline(const Vector3 &v0, const Vector3 &v1,
631 const Vector3 &v2, const Vector3 &v3, scalar_t t)
632 {
633 scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
634 scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
635 scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t);
636 return Vector3(x, y, z);
637 }
639 /* ----------- Vector4 ----------------- */
641 inline scalar_t &Vector4::operator [](int elem) {
642 return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
643 }
645 inline const scalar_t &Vector4::operator [](int elem) const {
646 return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
647 }
649 inline Vector4 operator -(const Vector4 &vec) {
650 return Vector4(-vec.x, -vec.y, -vec.z, -vec.w);
651 }
653 inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) {
654 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
655 }
657 inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) {
658 scalar_t a, b, c, d, e, f; /* Intermediate Values */
659 Vector4 result;
661 /* Calculate intermediate values. */
662 a = (v2.x * v3.y) - (v2.y * v3.x);
663 b = (v2.x * v3.z) - (v2.z * v3.x);
664 c = (v2.x * v3.w) - (v2.w * v3.x);
665 d = (v2.y * v3.z) - (v2.z * v3.y);
666 e = (v2.y * v3.w) - (v2.w * v3.y);
667 f = (v2.z * v3.w) - (v2.w * v3.z);
669 /* Calculate the result-vector components. */
670 result.x = (v1.y * f) - (v1.z * e) + (v1.w * d);
671 result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b);
672 result.z = (v1.x * e) - (v1.y * c) + (v1.w * a);
673 result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a);
674 return result;
675 }
677 inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) {
678 return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
679 }
681 inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) {
682 return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
683 }
685 inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) {
686 return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
687 }
689 inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) {
690 return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
691 }
693 inline bool operator ==(const Vector4 &v1, const Vector4 &v2) {
694 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) &&
695 (fabs(v1.y - v2.y) < XSMALL_NUMBER) &&
696 (fabs(v1.z - v2.z) < XSMALL_NUMBER) &&
697 (fabs(v1.w - v2.w) < XSMALL_NUMBER);
698 }
700 inline void operator +=(Vector4 &v1, const Vector4 &v2) {
701 v1.x += v2.x;
702 v1.y += v2.y;
703 v1.z += v2.z;
704 v1.w += v2.w;
705 }
707 inline void operator -=(Vector4 &v1, const Vector4 &v2) {
708 v1.x -= v2.x;
709 v1.y -= v2.y;
710 v1.z -= v2.z;
711 v1.w -= v2.w;
712 }
714 inline void operator *=(Vector4 &v1, const Vector4 &v2) {
715 v1.x *= v2.x;
716 v1.y *= v2.y;
717 v1.z *= v2.z;
718 v1.w *= v2.w;
719 }
721 inline void operator /=(Vector4 &v1, const Vector4 &v2) {
722 v1.x /= v2.x;
723 v1.y /= v2.y;
724 v1.z /= v2.z;
725 v1.w /= v2.w;
726 }
728 /* binary vector (op) scalar and scalar (op) vector operations */
729 inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) {
730 return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
731 }
733 inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) {
734 return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
735 }
737 inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) {
738 return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar);
739 }
741 inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) {
742 return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
743 }
745 inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) {
746 return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
747 }
749 inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) {
750 return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar);
751 }
753 inline void operator +=(Vector4 &vec, scalar_t scalar) {
754 vec.x += scalar;
755 vec.y += scalar;
756 vec.z += scalar;
757 vec.w += scalar;
758 }
760 inline void operator -=(Vector4 &vec, scalar_t scalar) {
761 vec.x -= scalar;
762 vec.y -= scalar;
763 vec.z -= scalar;
764 vec.w -= scalar;
765 }
767 inline void operator *=(Vector4 &vec, scalar_t scalar) {
768 vec.x *= scalar;
769 vec.y *= scalar;
770 vec.z *= scalar;
771 vec.w *= scalar;
772 }
774 inline void operator /=(Vector4 &vec, scalar_t scalar) {
775 vec.x /= scalar;
776 vec.y /= scalar;
777 vec.z /= scalar;
778 vec.w /= scalar;
779 }
781 inline scalar_t Vector4::length() const {
782 return sqrt(x*x + y*y + z*z + w*w);
783 }
784 inline scalar_t Vector4::length_sq() const {
785 return x*x + y*y + z*z + w*w;
786 }
788 inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t)
789 {
790 return v0 + (v1 - v0) * t;
791 }
793 inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
794 const Vector4 &v2, const Vector4 &v3, scalar_t t)
795 {
796 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
797 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
798 scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
799 scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t);
800 return Vector4(x, y, z, w);
801 }
803 inline Vector4 bspline(const Vector4 &v0, const Vector4 &v1,
804 const Vector4 &v2, const Vector4 &v3, scalar_t t)
805 {
806 scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t);
807 scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t);
808 scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t);
809 scalar_t w = bspline(v0.w, v1.w, v2.w, v3.w, t);
810 return Vector4(x, y, z, w);
811 }
812 #endif /* __cplusplus */