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());
655 template<typename Element>
656 inline void vector3_negate(BasicVector3<Element>& self)
658 self = vector3_negated(self);
661 template<typename Element>
662 inline double vector3_length_squared(const BasicVector3<Element>& self)
664 return vector3_dot(self, self);
667 template<typename Element>
668 inline double vector3_length(const BasicVector3<Element>& self)
670 return sqrt(vector3_length_squared(self));
673 template<typename Element>
674 inline Element float_divided(Element f, Element other)
676 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
680 template<typename Element>
681 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
683 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
686 template<typename Element>
687 inline void vector3_normalise(BasicVector3<Element>& self)
689 self = vector3_normalised(self);
693 template<typename Element>
694 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
696 return BasicVector3<Element>(
697 Element(float_to_integer(self.x())),
698 Element(float_to_integer(self.y())),
699 Element(float_to_integer(self.z()))
702 template<typename Element>
703 inline void vector3_snap(BasicVector3<Element>& self)
705 self = vector3_snapped(self);
707 template<typename Element, typename OtherElement>
708 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
710 return BasicVector3<Element>(
711 Element(float_snapped(self.x(), snap)),
712 Element(float_snapped(self.y(), snap)),
713 Element(float_snapped(self.z(), snap))
716 template<typename Element, typename OtherElement>
717 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
719 self = vector3_snapped(self, snap);
722 inline Vector3 vector3_for_spherical(double theta, double phi)
725 static_cast<float>(cos(theta) * cos(phi)),
726 static_cast<float>(sin(theta) * cos(phi)),
727 static_cast<float>(sin(phi))
732 /// \brief A 4-element vector.
733 template<typename Element>
736 Element m_elements[4];
742 BasicVector4(Element x_, Element y_, Element z_, Element w_)
749 BasicVector4(const BasicVector3<Element>& self, Element w_)
759 return m_elements[0];
763 return m_elements[0];
767 return m_elements[1];
771 return m_elements[1];
775 return m_elements[2];
779 return m_elements[2];
783 return m_elements[3];
787 return m_elements[3];
790 Element index(std::size_t i) const
792 return m_elements[i];
794 Element& index(std::size_t i)
796 return m_elements[i];
798 Element operator[](std::size_t i) const
800 return m_elements[i];
802 Element& operator[](std::size_t i)
804 return m_elements[i];
807 operator BasicVector3<Element>&()
809 return reinterpret_cast<BasicVector3<Element>&>(*this);
811 operator const BasicVector3<Element>&() const
813 return reinterpret_cast<const BasicVector3<Element>&>(*this);
816 bool operator==(const BasicVector4& other) const
818 return x() == other.x() && y() == other.y() && z() == other.z() && w() == other.w();
822 /// \brief A 4-element vector stored in single-precision floating-point.
823 typedef BasicVector4<float> Vector4;
826 template<typename Element, typename OtherElement>
827 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
829 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
831 template<typename Element, typename OtherElement>
832 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
834 return vector4_equal(self, other);
836 template<typename Element, typename OtherElement>
837 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
839 return !vector4_equal(self, other);
842 template<typename Element, typename OtherElement>
843 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
845 return float_equal_epsilon(self.x(), other.x(), epsilon)
846 && float_equal_epsilon(self.y(), other.y(), epsilon)
847 && float_equal_epsilon(self.z(), other.z(), epsilon)
848 && float_equal_epsilon(self.w(), other.w(), epsilon);
851 template<typename Element>
852 inline Element* vector4_to_array(BasicVector4<Element>& self)
854 return reinterpret_cast<Element*>(&self);
856 template<typename Element>
857 inline const float* vector4_to_array(const BasicVector4<Element>& self)
859 return reinterpret_cast<const Element*>(&self);
862 template<typename Element>
863 inline Vector3& vector4_to_vector3(BasicVector4<Element>& self)
865 return reinterpret_cast<BasicVector3<Element>&>(self);
867 template<typename Element>
868 inline const Vector3& vector4_to_vector3(const BasicVector4<Element>& self)
870 return reinterpret_cast<const BasicVector3<Element>&>(self);
873 template<typename Element, typename OtherElement>
874 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
876 return BasicVector4<Element>(
877 float(self.x() + other.x()),
878 float(self.y() + other.y()),
879 float(self.z() + other.z()),
880 float(self.w() + other.w())
883 template<typename Element, typename OtherElement>
884 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
886 return vector4_added(self, other);
888 template<typename Element, typename OtherElement>
889 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
891 self.x() += static_cast<float>(other.x());
892 self.y() += static_cast<float>(other.y());
893 self.z() += static_cast<float>(other.z());
894 self.w() += static_cast<float>(other.w());
896 template<typename Element, typename OtherElement>
897 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
899 vector4_add(self, other);
902 template<typename Element, typename OtherElement>
903 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
905 return BasicVector4<Element>(
906 float(self.x() - other.x()),
907 float(self.y() - other.y()),
908 float(self.z() - other.z()),
909 float(self.w() - other.w())
912 template<typename Element, typename OtherElement>
913 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
915 return vector4_subtracted(self, other);
917 template<typename Element, typename OtherElement>
918 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
920 self.x() -= static_cast<float>(other.x());
921 self.y() -= static_cast<float>(other.y());
922 self.z() -= static_cast<float>(other.z());
923 self.w() -= static_cast<float>(other.w());
925 template<typename Element, typename OtherElement>
926 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
928 vector4_subtract(self, other);
931 template<typename Element, typename OtherElement>
932 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
934 return BasicVector4<Element>(
935 float(self.x() * other.x()),
936 float(self.y() * other.y()),
937 float(self.z() * other.z()),
938 float(self.w() * other.w())
941 template<typename Element, typename OtherElement>
942 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
944 return vector4_scaled(self, other);
946 template<typename Element, typename OtherElement>
947 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
949 self.x() *= static_cast<float>(other.x());
950 self.y() *= static_cast<float>(other.y());
951 self.z() *= static_cast<float>(other.z());
952 self.w() *= static_cast<float>(other.w());
954 template<typename Element, typename OtherElement>
955 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
957 vector4_scale(self, other);
960 template<typename Element, typename OtherElement>
961 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
963 return BasicVector4<Element>(
964 float(self.x() * scale),
965 float(self.y() * scale),
966 float(self.z() * scale),
967 float(self.w() * scale)
970 template<typename Element, typename OtherElement>
971 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
973 return vector4_scaled(self, scale);
975 template<typename Element, typename OtherElement>
976 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
978 self.x() *= static_cast<float>(scale);
979 self.y() *= static_cast<float>(scale);
980 self.z() *= static_cast<float>(scale);
981 self.w() *= static_cast<float>(scale);
983 template<typename Element, typename OtherElement>
984 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
986 vector4_scale(self, scale);
989 template<typename Element, typename OtherElement>
990 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
992 return BasicVector4<Element>(
993 float(self.x() / divisor),
994 float(self.y() / divisor),
995 float(self.z() / divisor),
996 float(self.w() / divisor)
999 template<typename Element, typename OtherElement>
1000 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
1002 return vector4_divided(self, divisor);
1004 template<typename Element, typename OtherElement>
1005 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
1007 self.x() /= divisor;
1008 self.y() /= divisor;
1009 self.z() /= divisor;
1010 self.w() /= divisor;
1012 template<typename Element, typename OtherElement>
1013 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
1015 vector4_divide(self, divisor);
1018 template<typename Element, typename OtherElement>
1019 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
1021 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
1024 template<typename Element>
1025 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
1027 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);