2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
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.
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.
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
22 #if !defined(INCLUDED_MATH_VECTOR_H)
23 #define INCLUDED_MATH_VECTOR_H
26 /// \brief Vector data types and related operations.
30 #define lrint(dbl) ((int)((dbl) + 0.5))
31 #define lrintf(flt) ((int)((flt) + 0.5))
35 #if defined (_MSC_VER)
37 inline int lrint (double flt)
50 #else // lrint is part of ISO C99
52 #define _ISOC9X_SOURCE 1
53 #define _ISOC99_SOURCE 1
55 #define __USE_ISOC9X 1
56 #define __USE_ISOC99 1
65 //#include "debugging/debugging.h"
67 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
68 template<typename Element, typename OtherElement>
69 inline bool float_equal_epsilon(const Element& self, const OtherElement& other, const Element& epsilon)
71 return fabs(other - self) < epsilon;
74 /// \brief Returns the value midway between \p self and \p other.
75 template<typename Element>
76 inline Element float_mid(const Element& self, const Element& other)
78 return Element((self + other) * 0.5);
81 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
82 template<typename Element>
83 inline int float_to_integer(const Element& f)
88 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
89 template<typename Element, typename OtherElement>
90 inline Element float_snapped(const Element& f, const OtherElement& snap)
92 return Element(float_to_integer(f / snap) * snap);
95 /// \brief Returns true if \p f has no decimal fraction part.
96 template<typename Element>
97 inline bool float_is_integer(const Element& f)
99 return f == Element(float_to_integer(f));
102 /// \brief Returns \p self modulated by the range [0, \p modulus)
103 /// \p self must be in the range [\p -modulus, \p modulus)
104 template<typename Element, typename ModulusElement>
105 inline Element float_mod_range(const Element& self, const ModulusElement& modulus)
107 return Element((self < 0.0) ? self + modulus : self);
110 /// \brief Returns \p self modulated by the range [0, \p modulus)
111 template<typename Element, typename ModulusElement>
112 inline Element float_mod(const Element& self, const ModulusElement& modulus)
114 return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
118 template<typename Element>
121 Element m_elements[2];
126 BasicVector2(const Element& x_, const Element& y_)
134 return m_elements[0];
136 const Element& x() const
138 return m_elements[0];
142 return m_elements[1];
144 const Element& y() const
146 return m_elements[1];
149 const Element& operator[](std::size_t i) const
151 return m_elements[i];
153 Element& operator[](std::size_t i)
155 return m_elements[i];
160 template<typename Element, typename OtherElement>
161 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
163 return BasicVector2<Element>(
164 Element(self.x() + other.x()),
165 Element(self.y() + other.y())
168 template<typename Element, typename OtherElement>
169 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
171 return vector2_added(self, other);
173 template<typename Element, typename OtherElement>
174 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
176 self.x() += Element(other.x());
177 self.y() += Element(other.y());
179 template<typename Element, typename OtherElement>
180 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
182 vector2_add(self, other);
186 template<typename Element, typename OtherElement>
187 inline BasicVector2<Element> vector2_subtracted(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
189 return BasicVector2<Element>(
190 Element(self.x() - other.x()),
191 Element(self.y() - other.y())
194 template<typename Element, typename OtherElement>
195 inline BasicVector2<Element> operator-(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
197 return vector2_subtracted(self, other);
199 template<typename Element, typename OtherElement>
200 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
202 self.x() -= Element(other.x());
203 self.y() -= lement(other.y());
205 template<typename Element, typename OtherElement>
206 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
208 vector2_subtract(self, other);
212 template<typename Element, typename OtherElement>
213 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
215 return BasicVector2<Element>(
216 Element(self.x() * other),
217 Element(self.y() * other)
220 template<typename Element, typename OtherElement>
221 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
223 return vector2_scaled(self, other);
225 template<typename Element, typename OtherElement>
226 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
228 self.x() *= Element(other);
229 self.y() *= Element(other);
231 template<typename Element, typename OtherElement>
232 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
234 vector2_scale(self, other);
238 template<typename Element, typename OtherElement>
239 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
241 return BasicVector2<Element>(
242 Element(self.x() * other.x()),
243 Element(self.y() * other.y())
246 template<typename Element, typename OtherElement>
247 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
249 return vector2_scaled(self, other);
251 template<typename Element, typename OtherElement>
252 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
254 self.x() *= Element(other.x());
255 self.y() *= Element(other.y());
257 template<typename Element, typename OtherElement>
258 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
260 vector2_scale(self, other);
263 template<typename Element, typename OtherElement>
264 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
266 return BasicVector2<Element>(
267 Element(self.x() / other.x()),
268 Element(self.y() / other.y())
271 template<typename Element, typename OtherElement>
272 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
274 return vector2_divided(self, other);
276 template<typename Element, typename OtherElement>
277 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
279 self.x() /= Element(other.x());
280 self.y() /= Element(other.y());
282 template<typename Element, typename OtherElement>
283 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
285 vector2_divide(self, other);
289 template<typename Element, typename OtherElement>
290 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
292 return BasicVector2<Element>(
293 Element(self.x() / other),
294 Element(self.y() / other)
297 template<typename Element, typename OtherElement>
298 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
300 return vector2_divided(self, other);
302 template<typename Element, typename OtherElement>
303 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
305 self.x() /= Element(other);
306 self.y() /= Element(other);
308 template<typename Element, typename OtherElement>
309 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
311 vector2_divide(self, other);
314 template<typename Element, typename OtherElement>
315 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
317 return self.x() * other.x() + self.y() * other.y();
320 template<typename Element>
321 inline double vector2_length_squared(const BasicVector2<Element>& self)
323 return vector2_dot(self, self);
326 template<typename Element>
327 inline double vector2_length(const BasicVector2<Element>& self)
329 return sqrt(vector2_length_squared(self));
332 template<typename Element, typename OtherElement>
333 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
335 return self.x() * other.y() - self.y() * other.x();
338 typedef BasicVector2<float> Vector2;
340 /// \brief A 3-element vector.
341 template<typename Element>
344 Element m_elements[3];
350 template<typename OtherElement>
351 BasicVector3(const BasicVector3<OtherElement>& other)
353 x() = static_cast<Element>(other.x());
354 y() = static_cast<Element>(other.y());
355 z() = static_cast<Element>(other.z());
357 BasicVector3(const Element& x_, const Element& y_, const Element& z_)
366 return m_elements[0];
368 const Element& x() const
370 return m_elements[0];
374 return m_elements[1];
376 const Element& y() const
378 return m_elements[1];
382 return m_elements[2];
384 const Element& z() const
386 return m_elements[2];
389 const Element& operator[](std::size_t i) const
391 return m_elements[i];
393 Element& operator[](std::size_t i)
395 return m_elements[i];
398 operator BasicVector2<Element>&()
400 return reinterpret_cast<BasicVector2<Element>&>(*this);
402 operator const BasicVector2<Element>&() const
404 return reinterpret_cast<const BasicVector2<Element>&>(*this);
408 /// \brief A 3-element vector stored in single-precision floating-point.
409 typedef BasicVector3<float> Vector3;
411 const Vector3 g_vector3_identity(0, 0, 0);
412 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
413 const Vector3 g_vector3_axis_x(1, 0, 0);
414 const Vector3 g_vector3_axis_y(0, 1, 0);
415 const Vector3 g_vector3_axis_z(0, 0, 1);
417 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
419 template<typename Element>
420 inline Element* vector3_to_array(BasicVector3<Element>& self)
422 return reinterpret_cast<Element*>(&self);
424 template<typename Element>
425 inline const Element* vector3_to_array(const BasicVector3<Element>& self)
427 return reinterpret_cast<const Element*>(&self);
430 template<typename Element, typename OtherElement>
431 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
433 std::swap(self.x(), other.x());
434 std::swap(self.y(), other.y());
435 std::swap(self.z(), other.z());
438 template<typename Element, typename OtherElement>
439 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
441 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
443 template<typename Element, typename OtherElement>
444 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
446 return vector3_equal(self, other);
448 template<typename Element, typename OtherElement>
449 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
451 return !vector3_equal(self, other);
455 template<typename Element, typename OtherElement, typename Epsilon>
456 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
458 return float_equal_epsilon(self.x(), other.x(), epsilon)
459 && float_equal_epsilon(self.y(), other.y(), epsilon)
460 && float_equal_epsilon(self.z(), other.z(), epsilon);
465 template<typename Element, typename OtherElement>
466 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
468 return BasicVector3<Element>(
469 Element(self.x() + other.x()),
470 Element(self.y() + other.y()),
471 Element(self.z() + other.z())
474 template<typename Element, typename OtherElement>
475 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
477 return vector3_added(self, other);
479 template<typename Element, typename OtherElement>
480 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
482 self.x() += static_cast<Element>(other.x());
483 self.y() += static_cast<Element>(other.y());
484 self.z() += static_cast<Element>(other.z());
486 template<typename Element, typename OtherElement>
487 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
489 vector3_add(self, other);
492 template<typename Element, typename OtherElement>
493 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
495 return BasicVector3<Element>(
496 Element(self.x() - other.x()),
497 Element(self.y() - other.y()),
498 Element(self.z() - other.z())
501 template<typename Element, typename OtherElement>
502 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
504 return vector3_subtracted(self, other);
506 template<typename Element, typename OtherElement>
507 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
509 self.x() -= static_cast<Element>(other.x());
510 self.y() -= static_cast<Element>(other.y());
511 self.z() -= static_cast<Element>(other.z());
513 template<typename Element, typename OtherElement>
514 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
516 vector3_subtract(self, other);
519 template<typename Element, typename OtherElement>
520 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
522 return BasicVector3<Element>(
523 Element(self.x() * other.x()),
524 Element(self.y() * other.y()),
525 Element(self.z() * other.z())
528 template<typename Element, typename OtherElement>
529 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
531 return vector3_scaled(self, other);
533 template<typename Element, typename OtherElement>
534 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
536 self.x() *= static_cast<Element>(other.x());
537 self.y() *= static_cast<Element>(other.y());
538 self.z() *= static_cast<Element>(other.z());
540 template<typename Element, typename OtherElement>
541 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
543 vector3_scale(self, other);
546 template<typename Element, typename OtherElement>
547 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
549 return BasicVector3<Element>(
550 Element(self.x() * scale),
551 Element(self.y() * scale),
552 Element(self.z() * scale)
555 template<typename Element, typename OtherElement>
556 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
558 return vector3_scaled(self, scale);
560 template<typename Element, typename OtherElement>
561 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
563 self.x() *= static_cast<Element>(scale);
564 self.y() *= static_cast<Element>(scale);
565 self.z() *= static_cast<Element>(scale);
567 template<typename Element, typename OtherElement>
568 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
570 vector3_scale(self, scale);
573 template<typename Element, typename OtherElement>
574 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
576 return BasicVector3<Element>(
577 Element(self.x() / other.x()),
578 Element(self.y() / other.y()),
579 Element(self.z() / other.z())
582 template<typename Element, typename OtherElement>
583 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
585 return vector3_divided(self, other);
587 template<typename Element, typename OtherElement>
588 inline void vector3_divide(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
590 self.x() /= static_cast<Element>(other.x());
591 self.y() /= static_cast<Element>(other.y());
592 self.z() /= static_cast<Element>(other.z());
594 template<typename Element, typename OtherElement>
595 inline void operator/=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
597 vector3_divide(self, other);
600 template<typename Element, typename OtherElement>
601 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
603 return BasicVector3<Element>(
604 Element(self.x() / divisor),
605 Element(self.y() / divisor),
606 Element(self.z() / divisor)
609 template<typename Element, typename OtherElement>
610 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
612 return vector3_divided(self, divisor);
614 template<typename Element, typename OtherElement>
615 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
617 self.x() /= static_cast<Element>(divisor);
618 self.y() /= static_cast<Element>(divisor);
619 self.z() /= static_cast<Element>(divisor);
621 template<typename Element, typename OtherElement>
622 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
624 vector3_divide(self, divisor);
627 template<typename Element, typename OtherElement>
628 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
630 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
633 template<typename Element>
634 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
636 return vector3_scaled(vector3_added(begin, end), 0.5);
639 template<typename Element, typename OtherElement>
640 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
642 return BasicVector3<Element>(
643 Element(self.y() * other.z() - self.z() * other.y()),
644 Element(self.z() * other.x() - self.x() * other.z()),
645 Element(self.x() * other.y() - self.y() * other.x())
649 template<typename Element>
650 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
652 return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
654 template<typename Element>
655 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
657 return vector3_negated(self);
660 template<typename Element>
661 inline void vector3_negate(BasicVector3<Element>& self)
663 self = vector3_negated(self);
666 template<typename Element>
667 inline double vector3_length_squared(const BasicVector3<Element>& self)
669 return vector3_dot(self, self);
672 template<typename Element>
673 inline double vector3_length(const BasicVector3<Element>& self)
675 return sqrt(vector3_length_squared(self));
678 template<typename Element>
679 inline Element float_divided(Element f, Element other)
681 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
685 template<typename Element>
686 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
688 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
691 template<typename Element>
692 inline void vector3_normalise(BasicVector3<Element>& self)
694 self = vector3_normalised(self);
698 template<typename Element>
699 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
701 return BasicVector3<Element>(
702 Element(float_to_integer(self.x())),
703 Element(float_to_integer(self.y())),
704 Element(float_to_integer(self.z()))
707 template<typename Element>
708 inline void vector3_snap(BasicVector3<Element>& self)
710 self = vector3_snapped(self);
712 template<typename Element, typename OtherElement>
713 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
715 return BasicVector3<Element>(
716 Element(float_snapped(self.x(), snap)),
717 Element(float_snapped(self.y(), snap)),
718 Element(float_snapped(self.z(), snap))
721 template<typename Element, typename OtherElement>
722 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
724 self = vector3_snapped(self, snap);
727 inline Vector3 vector3_for_spherical(double theta, double phi)
730 static_cast<float>(cos(theta) * cos(phi)),
731 static_cast<float>(sin(theta) * cos(phi)),
732 static_cast<float>(sin(phi))
737 /// \brief A 4-element vector.
738 template<typename Element>
741 Element m_elements[4];
747 BasicVector4(Element x_, Element y_, Element z_, Element w_)
754 BasicVector4(const BasicVector3<Element>& self, Element w_)
764 return m_elements[0];
768 return m_elements[0];
772 return m_elements[1];
776 return m_elements[1];
780 return m_elements[2];
784 return m_elements[2];
788 return m_elements[3];
792 return m_elements[3];
795 Element index(std::size_t i) const
797 return m_elements[i];
799 Element& index(std::size_t i)
801 return m_elements[i];
803 Element operator[](std::size_t i) const
805 return m_elements[i];
807 Element& operator[](std::size_t i)
809 return m_elements[i];
812 operator BasicVector3<Element>&()
814 return reinterpret_cast<BasicVector3<Element>&>(*this);
816 operator const BasicVector3<Element>&() const
818 return reinterpret_cast<const BasicVector3<Element>&>(*this);
821 bool operator==(const BasicVector4& other) const
823 return x() == other.x() && y() == other.y() && z() == other.z() && w() == other.w();
827 /// \brief A 4-element vector stored in single-precision floating-point.
828 typedef BasicVector4<float> Vector4;
831 template<typename Element, typename OtherElement>
832 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
834 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
836 template<typename Element, typename OtherElement>
837 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
839 return vector4_equal(self, other);
841 template<typename Element, typename OtherElement>
842 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
844 return !vector4_equal(self, other);
847 template<typename Element, typename OtherElement>
848 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
850 return float_equal_epsilon(self.x(), other.x(), epsilon)
851 && float_equal_epsilon(self.y(), other.y(), epsilon)
852 && float_equal_epsilon(self.z(), other.z(), epsilon)
853 && float_equal_epsilon(self.w(), other.w(), epsilon);
856 template<typename Element>
857 inline Element* vector4_to_array(BasicVector4<Element>& self)
859 return reinterpret_cast<Element*>(&self);
861 template<typename Element>
862 inline const float* vector4_to_array(const BasicVector4<Element>& self)
864 return reinterpret_cast<const Element*>(&self);
867 template<typename Element>
868 inline Vector3& vector4_to_vector3(BasicVector4<Element>& self)
870 return reinterpret_cast<BasicVector3<Element>&>(self);
872 template<typename Element>
873 inline const Vector3& vector4_to_vector3(const BasicVector4<Element>& self)
875 return reinterpret_cast<const BasicVector3<Element>&>(self);
878 template<typename Element, typename OtherElement>
879 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
881 return BasicVector4<Element>(
882 float(self.x() + other.x()),
883 float(self.y() + other.y()),
884 float(self.z() + other.z()),
885 float(self.w() + other.w())
888 template<typename Element, typename OtherElement>
889 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
891 return vector4_added(self, other);
893 template<typename Element, typename OtherElement>
894 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
896 self.x() += static_cast<float>(other.x());
897 self.y() += static_cast<float>(other.y());
898 self.z() += static_cast<float>(other.z());
899 self.w() += static_cast<float>(other.w());
901 template<typename Element, typename OtherElement>
902 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
904 vector4_add(self, other);
907 template<typename Element, typename OtherElement>
908 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
910 return BasicVector4<Element>(
911 float(self.x() - other.x()),
912 float(self.y() - other.y()),
913 float(self.z() - other.z()),
914 float(self.w() - other.w())
917 template<typename Element, typename OtherElement>
918 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
920 return vector4_subtracted(self, other);
922 template<typename Element, typename OtherElement>
923 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
925 self.x() -= static_cast<float>(other.x());
926 self.y() -= static_cast<float>(other.y());
927 self.z() -= static_cast<float>(other.z());
928 self.w() -= static_cast<float>(other.w());
930 template<typename Element, typename OtherElement>
931 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
933 vector4_subtract(self, other);
936 template<typename Element, typename OtherElement>
937 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
939 return BasicVector4<Element>(
940 float(self.x() * other.x()),
941 float(self.y() * other.y()),
942 float(self.z() * other.z()),
943 float(self.w() * other.w())
946 template<typename Element, typename OtherElement>
947 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
949 return vector4_scaled(self, other);
951 template<typename Element, typename OtherElement>
952 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
954 self.x() *= static_cast<float>(other.x());
955 self.y() *= static_cast<float>(other.y());
956 self.z() *= static_cast<float>(other.z());
957 self.w() *= static_cast<float>(other.w());
959 template<typename Element, typename OtherElement>
960 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
962 vector4_scale(self, other);
965 template<typename Element, typename OtherElement>
966 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
968 return BasicVector4<Element>(
969 float(self.x() * scale),
970 float(self.y() * scale),
971 float(self.z() * scale),
972 float(self.w() * scale)
975 template<typename Element, typename OtherElement>
976 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
978 return vector4_scaled(self, scale);
980 template<typename Element, typename OtherElement>
981 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
983 self.x() *= static_cast<float>(scale);
984 self.y() *= static_cast<float>(scale);
985 self.z() *= static_cast<float>(scale);
986 self.w() *= static_cast<float>(scale);
988 template<typename Element, typename OtherElement>
989 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
991 vector4_scale(self, scale);
994 template<typename Element, typename OtherElement>
995 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
997 return BasicVector4<Element>(
998 float(self.x() / divisor),
999 float(self.y() / divisor),
1000 float(self.z() / divisor),
1001 float(self.w() / divisor)
1004 template<typename Element, typename OtherElement>
1005 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
1007 return vector4_divided(self, divisor);
1009 template<typename Element, typename OtherElement>
1010 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
1012 self.x() /= divisor;
1013 self.y() /= divisor;
1014 self.z() /= divisor;
1015 self.w() /= divisor;
1017 template<typename Element, typename OtherElement>
1018 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
1020 vector4_divide(self, divisor);
1023 template<typename Element, typename OtherElement>
1024 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
1026 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
1029 template<typename Element>
1030 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
1032 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);