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.
28 #include "generic/vector.h"
30 #if defined (_MSC_VER)
32 inline int lrint (double flt)
45 #elif defined(__FreeBSD__)
47 inline int lrint(double f)
49 return static_cast<int>(f + 0.5);
52 #elif defined(__GNUC__)
54 // lrint is part of ISO C99
55 #define _ISOC9X_SOURCE 1
56 #define _ISOC99_SOURCE 1
58 #define __USE_ISOC9X 1
59 #define __USE_ISOC99 1
62 #error "unsupported platform"
70 //#include "debugging/debugging.h"
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)
76 return fabs(other - self) < epsilon;
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)
83 return Element((self + other) * 0.5);
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)
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)
97 return Element(float_to_integer(f / snap) * snap);
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)
104 return f == Element(float_to_integer(f));
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)
112 return Element((self < 0.0) ? self + modulus : self);
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)
119 return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
123 template<typename Element, typename OtherElement>
124 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
126 return BasicVector2<Element>(
127 Element(self.x() + other.x()),
128 Element(self.y() + other.y())
131 template<typename Element, typename OtherElement>
132 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
134 return vector2_added(self, other);
136 template<typename Element, typename OtherElement>
137 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
139 self.x() += Element(other.x());
140 self.y() += Element(other.y());
142 template<typename Element, typename OtherElement>
143 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
145 vector2_add(self, other);
149 template<typename Element, typename OtherElement>
150 inline BasicVector2<Element> vector2_subtracted(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
152 return BasicVector2<Element>(
153 Element(self.x() - other.x()),
154 Element(self.y() - other.y())
157 template<typename Element, typename OtherElement>
158 inline BasicVector2<Element> operator-(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
160 return vector2_subtracted(self, other);
162 template<typename Element, typename OtherElement>
163 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
165 self.x() -= Element(other.x());
166 self.y() -= lement(other.y());
168 template<typename Element, typename OtherElement>
169 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
171 vector2_subtract(self, other);
175 template<typename Element, typename OtherElement>
176 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
178 return BasicVector2<Element>(
179 Element(self.x() * other),
180 Element(self.y() * other)
183 template<typename Element, typename OtherElement>
184 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
186 return vector2_scaled(self, other);
188 template<typename Element, typename OtherElement>
189 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
191 self.x() *= Element(other);
192 self.y() *= Element(other);
194 template<typename Element, typename OtherElement>
195 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
197 vector2_scale(self, other);
201 template<typename Element, typename OtherElement>
202 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
204 return BasicVector2<Element>(
205 Element(self.x() * other.x()),
206 Element(self.y() * other.y())
209 template<typename Element, typename OtherElement>
210 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
212 return vector2_scaled(self, other);
214 template<typename Element, typename OtherElement>
215 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
217 self.x() *= Element(other.x());
218 self.y() *= Element(other.y());
220 template<typename Element, typename OtherElement>
221 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
223 vector2_scale(self, other);
226 template<typename Element, typename OtherElement>
227 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
229 return BasicVector2<Element>(
230 Element(self.x() / other.x()),
231 Element(self.y() / other.y())
234 template<typename Element, typename OtherElement>
235 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
237 return vector2_divided(self, other);
239 template<typename Element, typename OtherElement>
240 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
242 self.x() /= Element(other.x());
243 self.y() /= Element(other.y());
245 template<typename Element, typename OtherElement>
246 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
248 vector2_divide(self, other);
252 template<typename Element, typename OtherElement>
253 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
255 return BasicVector2<Element>(
256 Element(self.x() / other),
257 Element(self.y() / other)
260 template<typename Element, typename OtherElement>
261 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
263 return vector2_divided(self, other);
265 template<typename Element, typename OtherElement>
266 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
268 self.x() /= Element(other);
269 self.y() /= Element(other);
271 template<typename Element, typename OtherElement>
272 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
274 vector2_divide(self, other);
277 template<typename Element, typename OtherElement>
278 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
280 return self.x() * other.x() + self.y() * other.y();
283 template<typename Element>
284 inline double vector2_length_squared(const BasicVector2<Element>& self)
286 return vector2_dot(self, self);
289 template<typename Element>
290 inline double vector2_length(const BasicVector2<Element>& self)
292 return sqrt(vector2_length_squared(self));
295 template<typename Element, typename OtherElement>
296 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
298 return self.x() * other.y() - self.y() * other.x();
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);
307 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
309 template<typename Element, typename OtherElement>
310 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
312 std::swap(self.x(), other.x());
313 std::swap(self.y(), other.y());
314 std::swap(self.z(), other.z());
317 template<typename Element, typename OtherElement>
318 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
320 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
322 template<typename Element, typename OtherElement>
323 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
325 return vector3_equal(self, other);
327 template<typename Element, typename OtherElement>
328 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
330 return !vector3_equal(self, other);
334 template<typename Element, typename OtherElement, typename Epsilon>
335 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
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);
344 template<typename Element, typename OtherElement>
345 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
347 return BasicVector3<Element>(
348 Element(self.x() + other.x()),
349 Element(self.y() + other.y()),
350 Element(self.z() + other.z())
353 template<typename Element, typename OtherElement>
354 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
356 return vector3_added(self, other);
358 template<typename Element, typename OtherElement>
359 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
361 self.x() += static_cast<Element>(other.x());
362 self.y() += static_cast<Element>(other.y());
363 self.z() += static_cast<Element>(other.z());
365 template<typename Element, typename OtherElement>
366 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
368 vector3_add(self, other);
371 template<typename Element, typename OtherElement>
372 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
374 return BasicVector3<Element>(
375 Element(self.x() - other.x()),
376 Element(self.y() - other.y()),
377 Element(self.z() - other.z())
380 template<typename Element, typename OtherElement>
381 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
383 return vector3_subtracted(self, other);
385 template<typename Element, typename OtherElement>
386 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
388 self.x() -= static_cast<Element>(other.x());
389 self.y() -= static_cast<Element>(other.y());
390 self.z() -= static_cast<Element>(other.z());
392 template<typename Element, typename OtherElement>
393 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
395 vector3_subtract(self, other);
398 template<typename Element, typename OtherElement>
399 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
401 return BasicVector3<Element>(
402 Element(self.x() * other.x()),
403 Element(self.y() * other.y()),
404 Element(self.z() * other.z())
407 template<typename Element, typename OtherElement>
408 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
410 return vector3_scaled(self, other);
412 template<typename Element, typename OtherElement>
413 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
415 self.x() *= static_cast<Element>(other.x());
416 self.y() *= static_cast<Element>(other.y());
417 self.z() *= static_cast<Element>(other.z());
419 template<typename Element, typename OtherElement>
420 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
422 vector3_scale(self, other);
425 template<typename Element, typename OtherElement>
426 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
428 return BasicVector3<Element>(
429 Element(self.x() * scale),
430 Element(self.y() * scale),
431 Element(self.z() * scale)
434 template<typename Element, typename OtherElement>
435 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
437 return vector3_scaled(self, scale);
439 template<typename Element, typename OtherElement>
440 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
442 self.x() *= static_cast<Element>(scale);
443 self.y() *= static_cast<Element>(scale);
444 self.z() *= static_cast<Element>(scale);
446 template<typename Element, typename OtherElement>
447 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
449 vector3_scale(self, scale);
452 template<typename Element, typename OtherElement>
453 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
455 return BasicVector3<Element>(
456 Element(self.x() / other.x()),
457 Element(self.y() / other.y()),
458 Element(self.z() / other.z())
461 template<typename Element, typename OtherElement>
462 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
464 return vector3_divided(self, other);
466 template<typename Element, typename OtherElement>
467 inline void vector3_divide(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
469 self.x() /= static_cast<Element>(other.x());
470 self.y() /= static_cast<Element>(other.y());
471 self.z() /= static_cast<Element>(other.z());
473 template<typename Element, typename OtherElement>
474 inline void operator/=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
476 vector3_divide(self, other);
479 template<typename Element, typename OtherElement>
480 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
482 return BasicVector3<Element>(
483 Element(self.x() / divisor),
484 Element(self.y() / divisor),
485 Element(self.z() / divisor)
488 template<typename Element, typename OtherElement>
489 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
491 return vector3_divided(self, divisor);
493 template<typename Element, typename OtherElement>
494 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
496 self.x() /= static_cast<Element>(divisor);
497 self.y() /= static_cast<Element>(divisor);
498 self.z() /= static_cast<Element>(divisor);
500 template<typename Element, typename OtherElement>
501 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
503 vector3_divide(self, divisor);
506 template<typename Element, typename OtherElement>
507 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
509 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
512 template<typename Element>
513 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
515 return vector3_scaled(vector3_added(begin, end), 0.5);
518 template<typename Element, typename OtherElement>
519 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
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())
528 template<typename Element>
529 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
531 return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
533 template<typename Element>
534 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
536 return vector3_negated(self);
539 template<typename Element>
540 inline void vector3_negate(BasicVector3<Element>& self)
542 self = vector3_negated(self);
545 template<typename Element>
546 inline double vector3_length_squared(const BasicVector3<Element>& self)
548 return vector3_dot(self, self);
551 template<typename Element>
552 inline double vector3_length(const BasicVector3<Element>& self)
554 return sqrt(vector3_length_squared(self));
557 template<typename Element>
558 inline Element float_divided(Element f, Element other)
560 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
564 template<typename Element>
565 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
567 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
570 template<typename Element>
571 inline void vector3_normalise(BasicVector3<Element>& self)
573 self = vector3_normalised(self);
577 template<typename Element>
578 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
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()))
586 template<typename Element>
587 inline void vector3_snap(BasicVector3<Element>& self)
589 self = vector3_snapped(self);
591 template<typename Element, typename OtherElement>
592 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
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))
600 template<typename Element, typename OtherElement>
601 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
603 self = vector3_snapped(self, snap);
606 inline Vector3 vector3_for_spherical(double theta, double phi)
609 static_cast<float>(cos(theta) * cos(phi)),
610 static_cast<float>(sin(theta) * cos(phi)),
611 static_cast<float>(sin(phi))
618 template<typename Element, typename OtherElement>
619 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
621 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
623 template<typename Element, typename OtherElement>
624 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
626 return vector4_equal(self, other);
628 template<typename Element, typename OtherElement>
629 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
631 return !vector4_equal(self, other);
634 template<typename Element, typename OtherElement>
635 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
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);
643 template<typename Element, typename OtherElement>
644 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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())
653 template<typename Element, typename OtherElement>
654 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
656 return vector4_added(self, other);
658 template<typename Element, typename OtherElement>
659 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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());
666 template<typename Element, typename OtherElement>
667 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
669 vector4_add(self, other);
672 template<typename Element, typename OtherElement>
673 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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())
682 template<typename Element, typename OtherElement>
683 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
685 return vector4_subtracted(self, other);
687 template<typename Element, typename OtherElement>
688 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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());
695 template<typename Element, typename OtherElement>
696 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
698 vector4_subtract(self, other);
701 template<typename Element, typename OtherElement>
702 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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())
711 template<typename Element, typename OtherElement>
712 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
714 return vector4_scaled(self, other);
716 template<typename Element, typename OtherElement>
717 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
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());
724 template<typename Element, typename OtherElement>
725 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
727 vector4_scale(self, other);
730 template<typename Element, typename OtherElement>
731 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
733 return BasicVector4<Element>(
734 float(self.x() * scale),
735 float(self.y() * scale),
736 float(self.z() * scale),
737 float(self.w() * scale)
740 template<typename Element, typename OtherElement>
741 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
743 return vector4_scaled(self, scale);
745 template<typename Element, typename OtherElement>
746 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
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);
753 template<typename Element, typename OtherElement>
754 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
756 vector4_scale(self, scale);
759 template<typename Element, typename OtherElement>
760 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
762 return BasicVector4<Element>(
763 float(self.x() / divisor),
764 float(self.y() / divisor),
765 float(self.z() / divisor),
766 float(self.w() / divisor)
769 template<typename Element, typename OtherElement>
770 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
772 return vector4_divided(self, divisor);
774 template<typename Element, typename OtherElement>
775 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
782 template<typename Element, typename OtherElement>
783 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
785 vector4_divide(self, divisor);
788 template<typename Element, typename OtherElement>
789 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
791 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
794 template<typename Element>
795 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
797 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);