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