goat3d
view libs/vmath/vector.inl @ 27:4deb0b12fe14
wtf... corrupted heap?
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 29 Sep 2013 08:20:19 +0300 |
parents | |
children | 9ba3e2fb8a33 |
line source
1 /*
2 libvmath - a vector math library
3 Copyright (C) 2004-2011 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 /* C 2D vector functions */
26 static inline vec2_t v2_cons(scalar_t x, scalar_t y)
27 {
28 vec2_t v;
29 v.x = x;
30 v.y = y;
31 return v;
32 }
34 static inline void v2_print(FILE *fp, vec2_t v)
35 {
36 fprintf(fp, "[ %.4f %.4f ]", v.x, v.y);
37 }
39 static inline vec2_t v2_add(vec2_t v1, vec2_t v2)
40 {
41 vec2_t res;
42 res.x = v1.x + v2.x;
43 res.y = v1.y + v2.y;
44 return res;
45 }
47 static inline vec2_t v2_sub(vec2_t v1, vec2_t v2)
48 {
49 vec2_t res;
50 res.x = v1.x - v2.x;
51 res.y = v1.y - v2.y;
52 return res;
53 }
55 static inline vec2_t v2_scale(vec2_t v, scalar_t s)
56 {
57 vec2_t res;
58 res.x = v.x * s;
59 res.y = v.y * s;
60 return res;
61 }
63 static inline scalar_t v2_dot(vec2_t v1, vec2_t v2)
64 {
65 return v1.x * v2.x + v1.y * v2.y;
66 }
68 static inline scalar_t v2_length(vec2_t v)
69 {
70 return sqrt(v.x * v.x + v.y * v.y);
71 }
73 static inline scalar_t v2_length_sq(vec2_t v)
74 {
75 return v.x * v.x + v.y * v.y;
76 }
78 static inline vec2_t v2_normalize(vec2_t v)
79 {
80 scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y);
81 v.x /= len;
82 v.y /= len;
83 return v;
84 }
86 static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t)
87 {
88 vec2_t res;
89 res.x = v1.x + (v2.x - v1.x) * t;
90 res.y = v1.y + (v2.y - v1.y) * t;
91 return res;
92 }
95 /* C 3D vector functions */
96 static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z)
97 {
98 vec3_t v;
99 v.x = x;
100 v.y = y;
101 v.z = z;
102 return v;
103 }
105 static inline void v3_print(FILE *fp, vec3_t v)
106 {
107 fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z);
108 }
110 static inline vec3_t v3_add(vec3_t v1, vec3_t v2)
111 {
112 v1.x += v2.x;
113 v1.y += v2.y;
114 v1.z += v2.z;
115 return v1;
116 }
118 static inline vec3_t v3_sub(vec3_t v1, vec3_t v2)
119 {
120 v1.x -= v2.x;
121 v1.y -= v2.y;
122 v1.z -= v2.z;
123 return v1;
124 }
126 static inline vec3_t v3_neg(vec3_t v)
127 {
128 v.x = -v.x;
129 v.y = -v.y;
130 v.z = -v.z;
131 return v;
132 }
134 static inline vec3_t v3_mul(vec3_t v1, vec3_t v2)
135 {
136 v1.x *= v2.x;
137 v1.y *= v2.y;
138 v1.z *= v2.z;
139 return v1;
140 }
142 static inline vec3_t v3_scale(vec3_t v1, scalar_t s)
143 {
144 v1.x *= s;
145 v1.y *= s;
146 v1.z *= s;
147 return v1;
148 }
150 static inline scalar_t v3_dot(vec3_t v1, vec3_t v2)
151 {
152 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
153 }
155 static inline vec3_t v3_cross(vec3_t v1, vec3_t v2)
156 {
157 vec3_t v;
158 v.x = v1.y * v2.z - v1.z * v2.y;
159 v.y = v1.z * v2.x - v1.x * v2.z;
160 v.z = v1.x * v2.y - v1.y * v2.x;
161 return v;
162 }
164 static inline scalar_t v3_length(vec3_t v)
165 {
166 return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
167 }
169 static inline scalar_t v3_length_sq(vec3_t v)
170 {
171 return v.x * v.x + v.y * v.y + v.z * v.z;
172 }
174 static inline vec3_t v3_normalize(vec3_t v)
175 {
176 scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
177 v.x /= len;
178 v.y /= len;
179 v.z /= len;
180 return v;
181 }
183 static inline vec3_t v3_transform(vec3_t v, mat4_t m)
184 {
185 vec3_t res;
186 res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3];
187 res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3];
188 res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3];
189 return res;
190 }
192 static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z)
193 {
194 void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t);
196 mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
197 m4_rotate(m, x, y, z);
198 return v3_transform(v, m);
199 }
201 static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
202 {
203 void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t);
205 mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
206 m4_rotate_axis(m, angle, x, y, z);
207 return v3_transform(v, m);
208 }
210 static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q)
211 {
212 quat_t quat_rotate_quat(quat_t, quat_t);
214 quat_t vq = v4_cons(v.x, v.y, v.z, 0.0);
215 quat_t res = quat_rotate_quat(vq, q);
216 return v3_cons(res.x, res.y, res.z);
217 }
219 static inline vec3_t v3_reflect(vec3_t v, vec3_t n)
220 {
221 scalar_t dot = v3_dot(v, n);
222 return v3_sub(v3_scale(n, dot * 2.0), v);
223 }
225 static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t)
226 {
227 v1.x += (v2.x - v1.x) * t;
228 v1.y += (v2.y - v1.y) * t;
229 v1.z += (v2.z - v1.z) * t;
230 return v1;
231 }
233 /* C 4D vector functions */
234 static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
235 {
236 vec4_t v;
237 v.x = x;
238 v.y = y;
239 v.z = z;
240 v.w = w;
241 return v;
242 }
244 static inline void v4_print(FILE *fp, vec4_t v)
245 {
246 fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w);
247 }
249 static inline vec4_t v4_add(vec4_t v1, vec4_t v2)
250 {
251 v1.x += v2.x;
252 v1.y += v2.y;
253 v1.z += v2.z;
254 v1.w += v2.w;
255 return v1;
256 }
258 static inline vec4_t v4_sub(vec4_t v1, vec4_t v2)
259 {
260 v1.x -= v2.x;
261 v1.y -= v2.y;
262 v1.z -= v2.z;
263 v1.w -= v2.w;
264 return v1;
265 }
267 static inline vec4_t v4_neg(vec4_t v)
268 {
269 v.x = -v.x;
270 v.y = -v.y;
271 v.z = -v.z;
272 v.w = -v.w;
273 return v;
274 }
276 static inline vec4_t v4_mul(vec4_t v1, vec4_t v2)
277 {
278 v1.x *= v2.x;
279 v1.y *= v2.y;
280 v1.z *= v2.z;
281 v1.w *= v2.w;
282 return v1;
283 }
285 static inline vec4_t v4_scale(vec4_t v, scalar_t s)
286 {
287 v.x *= s;
288 v.y *= s;
289 v.z *= s;
290 v.w *= s;
291 return v;
292 }
294 static inline scalar_t v4_dot(vec4_t v1, vec4_t v2)
295 {
296 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
297 }
299 static inline scalar_t v4_length(vec4_t v)
300 {
301 return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
302 }
304 static inline scalar_t v4_length_sq(vec4_t v)
305 {
306 return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
307 }
309 static inline vec4_t v4_normalize(vec4_t v)
310 {
311 scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
312 v.x /= len;
313 v.y /= len;
314 v.z /= len;
315 v.w /= len;
316 return v;
317 }
319 static inline vec4_t v4_transform(vec4_t v, mat4_t m)
320 {
321 vec4_t res;
322 res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w;
323 res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w;
324 res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w;
325 res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w;
326 return res;
327 }
329 #ifdef __cplusplus
330 } /* extern "C" */
333 /* --------------- C++ part -------------- */
335 inline scalar_t &Vector2::operator [](int elem) {
336 return elem ? y : x;
337 }
339 inline const scalar_t &Vector2::operator [](int elem) const {
340 return elem ? y : x;
341 }
343 inline Vector2 operator -(const Vector2 &vec) {
344 return Vector2(-vec.x, -vec.y);
345 }
347 inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2) {
348 return v1.x * v2.x + v1.y * v2.y;
349 }
351 inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2) {
352 return Vector2(v1.x + v2.x, v1.y + v2.y);
353 }
355 inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2) {
356 return Vector2(v1.x - v2.x, v1.y - v2.y);
357 }
359 inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2) {
360 return Vector2(v1.x * v2.x, v1.y * v2.y);
361 }
363 inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2) {
364 return Vector2(v1.x / v2.x, v1.y / v2.y);
365 }
367 inline bool operator ==(const Vector2 &v1, const Vector2 &v2) {
368 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER);
369 }
371 inline void operator +=(Vector2 &v1, const Vector2 &v2) {
372 v1.x += v2.x;
373 v1.y += v2.y;
374 }
376 inline void operator -=(Vector2 &v1, const Vector2 &v2) {
377 v1.x -= v2.x;
378 v1.y -= v2.y;
379 }
381 inline void operator *=(Vector2 &v1, const Vector2 &v2) {
382 v1.x *= v2.x;
383 v1.y *= v2.y;
384 }
386 inline void operator /=(Vector2 &v1, const Vector2 &v2) {
387 v1.x /= v2.x;
388 v1.y /= v2.y;
389 }
391 inline Vector2 operator +(const Vector2 &vec, scalar_t scalar) {
392 return Vector2(vec.x + scalar, vec.y + scalar);
393 }
395 inline Vector2 operator +(scalar_t scalar, const Vector2 &vec) {
396 return Vector2(vec.x + scalar, vec.y + scalar);
397 }
399 inline Vector2 operator -(scalar_t scalar, const Vector2 &vec) {
400 return Vector2(vec.x - scalar, vec.y - scalar);
401 }
403 inline Vector2 operator *(const Vector2 &vec, scalar_t scalar) {
404 return Vector2(vec.x * scalar, vec.y * scalar);
405 }
407 inline Vector2 operator *(scalar_t scalar, const Vector2 &vec) {
408 return Vector2(vec.x * scalar, vec.y * scalar);
409 }
411 inline Vector2 operator /(const Vector2 &vec, scalar_t scalar) {
412 return Vector2(vec.x / scalar, vec.y / scalar);
413 }
415 inline void operator +=(Vector2 &vec, scalar_t scalar) {
416 vec.x += scalar;
417 vec.y += scalar;
418 }
420 inline void operator -=(Vector2 &vec, scalar_t scalar) {
421 vec.x -= scalar;
422 vec.y -= scalar;
423 }
425 inline void operator *=(Vector2 &vec, scalar_t scalar) {
426 vec.x *= scalar;
427 vec.y *= scalar;
428 }
430 inline void operator /=(Vector2 &vec, scalar_t scalar) {
431 vec.x /= scalar;
432 vec.y /= scalar;
433 }
435 inline scalar_t Vector2::length() const {
436 return sqrt(x*x + y*y);
437 }
439 inline scalar_t Vector2::length_sq() const {
440 return x*x + y*y;
441 }
443 inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t)
444 {
445 return a + (b - a) * t;
446 }
448 inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
449 const Vector2 &v2, const Vector2 &v3, scalar_t t)
450 {
451 scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
452 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
453 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
454 return Vector2(x, y);
455 }
458 /* ------------- Vector3 -------------- */
460 inline scalar_t &Vector3::operator [](int elem) {
461 return elem ? (elem == 1 ? y : z) : x;
462 }
464 inline const scalar_t &Vector3::operator [](int elem) const {
465 return elem ? (elem == 1 ? y : z) : x;
466 }
468 /* unary operations */
469 inline Vector3 operator -(const Vector3 &vec) {
470 return Vector3(-vec.x, -vec.y, -vec.z);
471 }
473 /* binary vector (op) vector operations */
474 inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) {
475 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
476 }
478 inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) {
479 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);
480 }
483 inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) {
484 return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
485 }
487 inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) {
488 return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
489 }
491 inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) {
492 return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
493 }
495 inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) {
496 return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
497 }
499 inline bool operator ==(const Vector3 &v1, const Vector3 &v2) {
500 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER);
501 }
503 inline void operator +=(Vector3 &v1, const Vector3 &v2) {
504 v1.x += v2.x;
505 v1.y += v2.y;
506 v1.z += v2.z;
507 }
509 inline void operator -=(Vector3 &v1, const Vector3 &v2) {
510 v1.x -= v2.x;
511 v1.y -= v2.y;
512 v1.z -= v2.z;
513 }
515 inline void operator *=(Vector3 &v1, const Vector3 &v2) {
516 v1.x *= v2.x;
517 v1.y *= v2.y;
518 v1.z *= v2.z;
519 }
521 inline void operator /=(Vector3 &v1, const Vector3 &v2) {
522 v1.x /= v2.x;
523 v1.y /= v2.y;
524 v1.z /= v2.z;
525 }
526 /* binary vector (op) scalar and scalar (op) vector operations */
527 inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) {
528 return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
529 }
531 inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) {
532 return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
533 }
535 inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) {
536 return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar);
537 }
539 inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) {
540 return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
541 }
543 inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) {
544 return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
545 }
547 inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) {
548 return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar);
549 }
551 inline void operator +=(Vector3 &vec, scalar_t scalar) {
552 vec.x += scalar;
553 vec.y += scalar;
554 vec.z += scalar;
555 }
557 inline void operator -=(Vector3 &vec, scalar_t scalar) {
558 vec.x -= scalar;
559 vec.y -= scalar;
560 vec.z -= scalar;
561 }
563 inline void operator *=(Vector3 &vec, scalar_t scalar) {
564 vec.x *= scalar;
565 vec.y *= scalar;
566 vec.z *= scalar;
567 }
569 inline void operator /=(Vector3 &vec, scalar_t scalar) {
570 vec.x /= scalar;
571 vec.y /= scalar;
572 vec.z /= scalar;
573 }
575 inline scalar_t Vector3::length() const {
576 return sqrt(x*x + y*y + z*z);
577 }
578 inline scalar_t Vector3::length_sq() const {
579 return x*x + y*y + z*z;
580 }
582 inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) {
583 return a + (b - a) * t;
584 }
586 inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
587 const Vector3 &v2, const Vector3 &v3, scalar_t t)
588 {
589 scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
590 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
591 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
592 scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
593 return Vector3(x, y, z);
594 }
596 /* ----------- Vector4 ----------------- */
598 inline scalar_t &Vector4::operator [](int elem) {
599 return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
600 }
602 inline const scalar_t &Vector4::operator [](int elem) const {
603 return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
604 }
606 inline Vector4 operator -(const Vector4 &vec) {
607 return Vector4(-vec.x, -vec.y, -vec.z, -vec.w);
608 }
610 inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) {
611 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
612 }
614 inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) {
615 scalar_t a, b, c, d, e, f; /* Intermediate Values */
616 Vector4 result;
618 /* Calculate intermediate values. */
619 a = (v2.x * v3.y) - (v2.y * v3.x);
620 b = (v2.x * v3.z) - (v2.z * v3.x);
621 c = (v2.x * v3.w) - (v2.w * v3.x);
622 d = (v2.y * v3.z) - (v2.z * v3.y);
623 e = (v2.y * v3.w) - (v2.w * v3.y);
624 f = (v2.z * v3.w) - (v2.w * v3.z);
626 /* Calculate the result-vector components. */
627 result.x = (v1.y * f) - (v1.z * e) + (v1.w * d);
628 result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b);
629 result.z = (v1.x * e) - (v1.y * c) + (v1.w * a);
630 result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a);
631 return result;
632 }
634 inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) {
635 return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
636 }
638 inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) {
639 return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
640 }
642 inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) {
643 return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
644 }
646 inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) {
647 return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
648 }
650 inline bool operator ==(const Vector4 &v1, const Vector4 &v2) {
651 return (fabs(v1.x - v2.x) < XSMALL_NUMBER) &&
652 (fabs(v1.y - v2.y) < XSMALL_NUMBER) &&
653 (fabs(v1.z - v2.z) < XSMALL_NUMBER) &&
654 (fabs(v1.w - v2.w) < XSMALL_NUMBER);
655 }
657 inline void operator +=(Vector4 &v1, const Vector4 &v2) {
658 v1.x += v2.x;
659 v1.y += v2.y;
660 v1.z += v2.z;
661 v1.w += v2.w;
662 }
664 inline void operator -=(Vector4 &v1, const Vector4 &v2) {
665 v1.x -= v2.x;
666 v1.y -= v2.y;
667 v1.z -= v2.z;
668 v1.w -= v2.w;
669 }
671 inline void operator *=(Vector4 &v1, const Vector4 &v2) {
672 v1.x *= v2.x;
673 v1.y *= v2.y;
674 v1.z *= v2.z;
675 v1.w *= v2.w;
676 }
678 inline void operator /=(Vector4 &v1, const Vector4 &v2) {
679 v1.x /= v2.x;
680 v1.y /= v2.y;
681 v1.z /= v2.z;
682 v1.w /= v2.w;
683 }
685 /* binary vector (op) scalar and scalar (op) vector operations */
686 inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) {
687 return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
688 }
690 inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) {
691 return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
692 }
694 inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) {
695 return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar);
696 }
698 inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) {
699 return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
700 }
702 inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) {
703 return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
704 }
706 inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) {
707 return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar);
708 }
710 inline void operator +=(Vector4 &vec, scalar_t scalar) {
711 vec.x += scalar;
712 vec.y += scalar;
713 vec.z += scalar;
714 vec.w += scalar;
715 }
717 inline void operator -=(Vector4 &vec, scalar_t scalar) {
718 vec.x -= scalar;
719 vec.y -= scalar;
720 vec.z -= scalar;
721 vec.w -= scalar;
722 }
724 inline void operator *=(Vector4 &vec, scalar_t scalar) {
725 vec.x *= scalar;
726 vec.y *= scalar;
727 vec.z *= scalar;
728 vec.w *= scalar;
729 }
731 inline void operator /=(Vector4 &vec, scalar_t scalar) {
732 vec.x /= scalar;
733 vec.y /= scalar;
734 vec.z /= scalar;
735 vec.w /= scalar;
736 }
738 inline scalar_t Vector4::length() const {
739 return sqrt(x*x + y*y + z*z + w*w);
740 }
741 inline scalar_t Vector4::length_sq() const {
742 return x*x + y*y + z*z + w*w;
743 }
745 inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t)
746 {
747 return v0 + (v1 - v0) * t;
748 }
750 inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
751 const Vector4 &v2, const Vector4 &v3, scalar_t t)
752 {
753 scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
754 scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
755 scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
756 scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
757 scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t);
758 return Vector4(x, y, z, w);
759 }
761 #endif /* __cplusplus */