]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/extra/netradiant-src/libs/math/vector.h
Include netRadiant source in this GIT
[voretournament/voretournament.git] / misc / mediasource / extra / netradiant-src / libs / math / vector.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_MATH_VECTOR_H)
23 #define INCLUDED_MATH_VECTOR_H
24
25 /// \file
26 /// \brief Vector data types and related operations.
27
28 #include "generic/vector.h"
29
30 #if defined (_MSC_VER)
31
32 inline int lrint (double flt)
33 {
34   int i;
35
36         _asm
37         {
38     fld flt
39                 fistp i
40   };
41                         
42         return i;
43
44
45 inline __int64 llrint(double f)
46 {
47   return static_cast<__int64>(f + 0.5);
48 }
49
50 #elif defined(__FreeBSD__)
51
52 inline long lrint(double f)
53 {
54   return static_cast<long>(f + 0.5);
55 }
56
57 inline long long llrint(double f)
58 {
59   return static_cast<long long>(f + 0.5);
60 }
61
62 #elif defined(__GNUC__)
63
64  // lrint is part of ISO C99
65 #define _ISOC9X_SOURCE  1
66 #define _ISOC99_SOURCE  1
67
68 #define __USE_ISOC9X    1
69 #define __USE_ISOC99    1
70
71 #else
72 #error "unsupported platform"
73 #endif
74
75 #include <cmath>
76 #include <float.h>
77 #include <algorithm>
78
79
80 //#include "debugging/debugging.h"
81
82 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
83 template<typename Element, typename OtherElement>
84 inline bool float_equal_epsilon(const Element& self, const OtherElement& other, const Element& epsilon)
85 {
86   return fabs(other - self) < epsilon;
87 }
88
89 /// \brief Returns the value midway between \p self and \p other.
90 template<typename Element>
91 inline Element float_mid(const Element& self, const Element& other)
92 {
93   return Element((self + other) * 0.5);
94 }
95
96 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
97 template<typename Element>
98 inline int float_to_integer(const Element& f)
99 {
100   return lrint(f);
101 }
102
103 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
104 template<typename Element, typename OtherElement>
105 inline Element float_snapped(const Element& f, const OtherElement& snap)
106 {
107   //return Element(float_to_integer(f / snap) * snap);
108   if(snap == 0)
109         return f;
110   return Element(llrint(f / snap) * snap); // llrint has more significant bits
111 }
112
113 /// \brief Returns true if \p f has no decimal fraction part.
114 template<typename Element>
115 inline bool float_is_integer(const Element& f)
116 {
117   return f == Element(float_to_integer(f));
118 }
119
120 /// \brief Returns \p self modulated by the range [0, \p modulus)
121 /// \p self must be in the range [\p -modulus, \p modulus)
122 template<typename Element, typename ModulusElement>
123 inline Element float_mod_range(const Element& self, const ModulusElement& modulus)
124 {
125   return Element((self < 0.0) ? self + modulus : self);
126 }
127
128 /// \brief Returns \p self modulated by the range [0, \p modulus)
129 template<typename Element, typename ModulusElement>
130 inline Element float_mod(const Element& self, const ModulusElement& modulus)
131 {
132   return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
133 }
134
135
136 template<typename Element, typename OtherElement>
137 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
138 {
139   return BasicVector2<Element>(
140     Element(self.x() + other.x()),
141     Element(self.y() + other.y())
142   );
143 }
144 template<typename Element, typename OtherElement>
145 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
146 {
147   return vector2_added(self, other);
148 }
149 template<typename Element, typename OtherElement>
150 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
151 {
152   self.x() += Element(other.x());
153   self.y() += Element(other.y());
154 }
155 template<typename Element, typename OtherElement>
156 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
157 {
158   vector2_add(self, other);
159 }
160
161
162 template<typename Element, typename OtherElement>
163 inline BasicVector2<Element> vector2_subtracted(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
164 {
165   return BasicVector2<Element>(
166     Element(self.x() - other.x()),
167     Element(self.y() - other.y())
168   );
169 }
170 template<typename Element, typename OtherElement>
171 inline BasicVector2<Element> operator-(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
172 {
173   return vector2_subtracted(self, other);
174 }
175 template<typename Element, typename OtherElement>
176 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
177 {
178   self.x() -= Element(other.x());
179   self.y() -= lement(other.y());
180 }
181 template<typename Element, typename OtherElement>
182 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
183 {
184   vector2_subtract(self, other);
185 }
186
187
188 template<typename Element, typename OtherElement>
189 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
190 {
191   return BasicVector2<Element>(
192     Element(self.x() * other),
193     Element(self.y() * other)
194   );
195 }
196 template<typename Element, typename OtherElement>
197 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
198 {
199   return vector2_scaled(self, other);
200 }
201 template<typename Element, typename OtherElement>
202 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
203 {
204   self.x() *= Element(other);
205   self.y() *= Element(other);
206 }
207 template<typename Element, typename OtherElement>
208 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
209 {
210   vector2_scale(self, other);
211 }
212
213
214 template<typename Element, typename OtherElement>
215 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
216 {
217   return BasicVector2<Element>(
218     Element(self.x() * other.x()),
219     Element(self.y() * other.y())
220   );
221 }
222 template<typename Element, typename OtherElement>
223 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
224 {
225   return vector2_scaled(self, other);
226 }
227 template<typename Element, typename OtherElement>
228 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
229 {
230   self.x() *= Element(other.x());
231   self.y() *= Element(other.y());
232 }
233 template<typename Element, typename OtherElement>
234 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
235 {
236   vector2_scale(self, other);
237 }
238
239 template<typename Element, typename OtherElement>
240 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
241 {
242   return BasicVector2<Element>(
243     Element(self.x() / other.x()),
244     Element(self.y() / other.y())
245   );
246 }
247 template<typename Element, typename OtherElement>
248 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
249 {
250   return vector2_divided(self, other);
251 }
252 template<typename Element, typename OtherElement>
253 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
254 {
255   self.x() /= Element(other.x());
256   self.y() /= Element(other.y());
257 }
258 template<typename Element, typename OtherElement>
259 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
260 {
261   vector2_divide(self, other);
262 }
263
264
265 template<typename Element, typename OtherElement>
266 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
267 {
268   return BasicVector2<Element>(
269     Element(self.x() / other),
270     Element(self.y() / other)
271   );
272 }
273 template<typename Element, typename OtherElement>
274 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
275 {
276   return vector2_divided(self, other);
277 }
278 template<typename Element, typename OtherElement>
279 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
280 {
281   self.x() /= Element(other);
282   self.y() /= Element(other);
283 }
284 template<typename Element, typename OtherElement>
285 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
286 {
287   vector2_divide(self, other);
288 }
289
290 template<typename Element, typename OtherElement>
291 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
292 {
293   return self.x() * other.x() + self.y() * other.y();
294 }
295
296 template<typename Element>
297 inline double vector2_length_squared(const BasicVector2<Element>& self)
298 {
299   return vector2_dot(self, self);
300 }
301
302 template<typename Element>
303 inline double vector2_length(const BasicVector2<Element>& self)
304 {
305   return sqrt(vector2_length_squared(self));
306 }
307
308 template<typename Element, typename OtherElement>
309 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
310 {
311   return self.x() * other.y() - self.y() * other.x();
312 }
313
314 const Vector3 g_vector3_identity(0, 0, 0);
315 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
316 const Vector3 g_vector3_axis_x(1, 0, 0);
317 const Vector3 g_vector3_axis_y(0, 1, 0);
318 const Vector3 g_vector3_axis_z(0, 0, 1);
319
320 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
321
322 template<typename Element, typename OtherElement>
323 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
324 {
325   std::swap(self.x(), other.x());
326   std::swap(self.y(), other.y());
327   std::swap(self.z(), other.z());
328 }
329
330 template<typename Element, typename OtherElement>
331 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
332 {
333   return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
334 }
335 template<typename Element, typename OtherElement>
336 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
337 {
338   return vector3_equal(self, other);
339 }
340 template<typename Element, typename OtherElement>
341 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
342 {
343   return !vector3_equal(self, other);
344 }
345
346
347 template<typename Element, typename OtherElement, typename Epsilon>
348 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
349 {
350   return float_equal_epsilon(self.x(), other.x(), epsilon)
351     && float_equal_epsilon(self.y(), other.y(), epsilon)
352     && float_equal_epsilon(self.z(), other.z(), epsilon);
353 }
354
355
356
357 template<typename Element, typename OtherElement>
358 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
359 {
360   return BasicVector3<Element>(
361     Element(self.x() + other.x()),
362     Element(self.y() + other.y()),
363     Element(self.z() + other.z())
364   );
365 }
366 template<typename Element, typename OtherElement>
367 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
368 {
369   return vector3_added(self, other);
370 }
371 template<typename Element, typename OtherElement>
372 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
373 {
374   self.x() += static_cast<Element>(other.x());
375   self.y() += static_cast<Element>(other.y());
376   self.z() += static_cast<Element>(other.z());
377 }
378 template<typename Element, typename OtherElement>
379 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
380 {
381   vector3_add(self, other);
382 }
383
384 template<typename Element, typename OtherElement>
385 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
386 {
387   return BasicVector3<Element>(
388     Element(self.x() - other.x()),
389     Element(self.y() - other.y()),
390     Element(self.z() - other.z())
391   );
392 }
393 template<typename Element, typename OtherElement>
394 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
395 {
396   return vector3_subtracted(self, other);
397 }
398 template<typename Element, typename OtherElement>
399 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
400 {
401   self.x() -= static_cast<Element>(other.x());
402   self.y() -= static_cast<Element>(other.y());
403   self.z() -= static_cast<Element>(other.z());
404 }
405 template<typename Element, typename OtherElement>
406 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
407 {
408   vector3_subtract(self, other);
409 }
410
411 template<typename Element, typename OtherElement>
412 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
413 {
414   return BasicVector3<Element>(
415     Element(self.x() * other.x()),
416     Element(self.y() * other.y()),
417     Element(self.z() * other.z())
418   );
419 }
420 template<typename Element, typename OtherElement>
421 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
422 {
423   return vector3_scaled(self, other);
424 }
425 template<typename Element, typename OtherElement>
426 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
427 {
428   self.x() *= static_cast<Element>(other.x());
429   self.y() *= static_cast<Element>(other.y());
430   self.z() *= static_cast<Element>(other.z());
431 }
432 template<typename Element, typename OtherElement>
433 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
434 {
435   vector3_scale(self, other);
436 }
437
438 template<typename Element, typename OtherElement>
439 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
440 {
441   return BasicVector3<Element>(
442     Element(self.x() * scale),
443     Element(self.y() * scale),
444     Element(self.z() * scale)
445   );
446 }
447 template<typename Element, typename OtherElement>
448 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
449 {
450   return vector3_scaled(self, scale);
451 }
452 template<typename Element, typename OtherElement>
453 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
454 {
455   self.x() *= static_cast<Element>(scale);
456   self.y() *= static_cast<Element>(scale);
457   self.z() *= static_cast<Element>(scale);
458 }
459 template<typename Element, typename OtherElement>
460 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
461 {
462   vector3_scale(self, scale);
463 }
464
465 template<typename Element, typename OtherElement>
466 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
467 {
468   return BasicVector3<Element>(
469     Element(self.x() / other.x()),
470     Element(self.y() / other.y()),
471     Element(self.z() / other.z())
472   );
473 }
474 template<typename Element, typename OtherElement>
475 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
476 {
477   return vector3_divided(self, other);
478 }
479 template<typename Element, typename OtherElement>
480 inline void vector3_divide(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
481 {
482   self.x() /= static_cast<Element>(other.x());
483   self.y() /= static_cast<Element>(other.y());
484   self.z() /= static_cast<Element>(other.z());
485 }
486 template<typename Element, typename OtherElement>
487 inline void operator/=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
488 {
489   vector3_divide(self, other);
490 }
491
492 template<typename Element, typename OtherElement>
493 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
494 {
495   return BasicVector3<Element>(
496     Element(self.x() / divisor),
497     Element(self.y() / divisor),
498     Element(self.z() / divisor)
499   );
500 }
501 template<typename Element, typename OtherElement>
502 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
503 {
504   return vector3_divided(self, divisor);
505 }
506 template<typename Element, typename OtherElement>
507 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
508 {
509   self.x() /= static_cast<Element>(divisor);
510   self.y() /= static_cast<Element>(divisor);
511   self.z() /= static_cast<Element>(divisor);
512 }
513 template<typename Element, typename OtherElement>
514 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
515 {
516   vector3_divide(self, divisor);
517 }
518
519 template<typename Element, typename OtherElement>
520 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
521 {
522   return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
523 }
524
525 template<typename Element>
526 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
527 {
528   return vector3_scaled(vector3_added(begin, end), 0.5);
529 }
530
531 template<typename Element, typename OtherElement>
532 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
533 {
534   return BasicVector3<Element>(
535     Element(self.y() * other.z() - self.z() * other.y()),
536     Element(self.z() * other.x() - self.x() * other.z()),
537     Element(self.x() * other.y() - self.y() * other.x())
538   );
539 }
540
541 template<typename Element>
542 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
543 {
544   return BasicVector3<Element>(-self.x(), -self.y(), -self.z()); 
545 }
546 template<typename Element>
547 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
548 {
549   return vector3_negated(self); 
550 }
551
552 template<typename Element>
553 inline void vector3_negate(BasicVector3<Element>& self)
554 {
555   self = vector3_negated(self);
556 }
557
558 template<typename Element>
559 inline double vector3_length_squared(const BasicVector3<Element>& self)
560 {
561   return vector3_dot(self, self);
562 }
563
564 template<typename Element>
565 inline double vector3_length(const BasicVector3<Element>& self)
566 {
567   return sqrt(vector3_length_squared(self));
568 }
569
570 template<typename Element>
571 inline Element float_divided(Element f, Element other)
572 {
573   //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
574   return f / other;
575 }
576
577 template<typename Element>
578 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
579 {
580   return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
581 }
582
583 template<typename Element>
584 inline void vector3_normalise(BasicVector3<Element>& self)
585 {
586   self = vector3_normalised(self);
587 }
588
589
590 template<typename Element>
591 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
592 {
593   return BasicVector3<Element>(
594     Element(float_to_integer(self.x())),
595     Element(float_to_integer(self.y())),
596     Element(float_to_integer(self.z()))
597   );
598 }
599 template<typename Element>
600 inline void vector3_snap(BasicVector3<Element>& self)
601 {
602   self = vector3_snapped(self);
603 }
604 template<typename Element, typename OtherElement>
605 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
606 {
607   return BasicVector3<Element>(
608     Element(float_snapped(self.x(), snap)),
609     Element(float_snapped(self.y(), snap)),
610     Element(float_snapped(self.z(), snap))
611   );
612 }
613 template<typename Element, typename OtherElement>
614 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
615 {
616   self = vector3_snapped(self, snap);
617 }
618
619 inline Vector3 vector3_for_spherical(double theta, double phi)
620 {
621   return Vector3(
622     static_cast<float>(cos(theta) * cos(phi)),
623     static_cast<float>(sin(theta) * cos(phi)),
624     static_cast<float>(sin(phi))
625   );
626 }
627
628
629
630
631 template<typename Element, typename OtherElement>
632 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
633 {
634   return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
635 }
636 template<typename Element, typename OtherElement>
637 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
638 {
639   return vector4_equal(self, other);
640 }
641 template<typename Element, typename OtherElement>
642 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
643 {
644   return !vector4_equal(self, other);
645 }
646
647 template<typename Element, typename OtherElement>
648 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
649 {
650   return float_equal_epsilon(self.x(), other.x(), epsilon)
651     && float_equal_epsilon(self.y(), other.y(), epsilon)
652     && float_equal_epsilon(self.z(), other.z(), epsilon)
653     && float_equal_epsilon(self.w(), other.w(), epsilon);
654 }
655
656 template<typename Element, typename OtherElement>
657 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
658 {
659   return BasicVector4<Element>(
660     float(self.x() + other.x()),
661     float(self.y() + other.y()),
662     float(self.z() + other.z()),
663     float(self.w() + other.w())
664   );
665 }
666 template<typename Element, typename OtherElement>
667 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
668 {
669   return vector4_added(self, other);
670 }
671 template<typename Element, typename OtherElement>
672 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
673 {
674   self.x() += static_cast<float>(other.x());
675   self.y() += static_cast<float>(other.y());
676   self.z() += static_cast<float>(other.z());
677   self.w() += static_cast<float>(other.w());
678 }
679 template<typename Element, typename OtherElement>
680 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
681 {
682   vector4_add(self, other);
683 }
684
685 template<typename Element, typename OtherElement>
686 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
687 {
688   return BasicVector4<Element>(
689     float(self.x() - other.x()),
690     float(self.y() - other.y()),
691     float(self.z() - other.z()),
692     float(self.w() - other.w())
693   );
694 }
695 template<typename Element, typename OtherElement>
696 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
697 {
698   return vector4_subtracted(self, other);
699 }
700 template<typename Element, typename OtherElement>
701 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
702 {
703   self.x() -= static_cast<float>(other.x());
704   self.y() -= static_cast<float>(other.y());
705   self.z() -= static_cast<float>(other.z());
706   self.w() -= static_cast<float>(other.w());
707 }
708 template<typename Element, typename OtherElement>
709 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
710 {
711   vector4_subtract(self, other);
712 }
713
714 template<typename Element, typename OtherElement>
715 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
716 {
717   return BasicVector4<Element>(
718     float(self.x() * other.x()),
719     float(self.y() * other.y()),
720     float(self.z() * other.z()),
721     float(self.w() * other.w())
722   );
723 }
724 template<typename Element, typename OtherElement>
725 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
726 {
727   return vector4_scaled(self, other);
728 }
729 template<typename Element, typename OtherElement>
730 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
731 {
732   self.x() *= static_cast<float>(other.x());
733   self.y() *= static_cast<float>(other.y());
734   self.z() *= static_cast<float>(other.z());
735   self.w() *= static_cast<float>(other.w());
736 }
737 template<typename Element, typename OtherElement>
738 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
739 {
740   vector4_scale(self, other);
741 }
742
743 template<typename Element, typename OtherElement>
744 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
745 {
746   return BasicVector4<Element>(
747     float(self.x() * scale),
748     float(self.y() * scale),
749     float(self.z() * scale),
750     float(self.w() * scale)
751   );
752 }
753 template<typename Element, typename OtherElement>
754 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
755 {
756   return vector4_scaled(self, scale);
757 }
758 template<typename Element, typename OtherElement>
759 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
760 {
761   self.x() *= static_cast<float>(scale);
762   self.y() *= static_cast<float>(scale);
763   self.z() *= static_cast<float>(scale);
764   self.w() *= static_cast<float>(scale);
765 }
766 template<typename Element, typename OtherElement>
767 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
768 {
769   vector4_scale(self, scale);
770 }
771
772 template<typename Element, typename OtherElement>
773 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
774 {
775   return BasicVector4<Element>(
776     float(self.x() / divisor),
777     float(self.y() / divisor),
778     float(self.z() / divisor),
779     float(self.w() / divisor)
780   );
781 }
782 template<typename Element, typename OtherElement>
783 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
784 {
785   return vector4_divided(self, divisor);
786 }
787 template<typename Element, typename OtherElement>
788 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
789 {
790   self.x() /= divisor;
791   self.y() /= divisor;
792   self.z() /= divisor;
793   self.w() /= divisor;
794 }
795 template<typename Element, typename OtherElement>
796 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
797 {
798   vector4_divide(self, divisor);
799 }
800
801 template<typename Element, typename OtherElement>
802 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
803 {
804   return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
805 }
806
807 template<typename Element>
808 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
809 {
810   return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);
811 }
812
813 #endif