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