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 inline __int64 llrint(double f)
47 return static_cast<__int64>(f + 0.5);
50 #elif defined(__FreeBSD__)
52 inline long lrint(double f)
54 return static_cast<long>(f + 0.5);
57 inline long long llrint(double f)
59 return static_cast<long long>(f + 0.5);
62 #elif defined(__GNUC__)
64 // lrint is part of ISO C99
65 #define _ISOC9X_SOURCE 1
66 #define _ISOC99_SOURCE 1
68 #define __USE_ISOC9X 1
69 #define __USE_ISOC99 1
72 #error "unsupported platform"
80 //#include "debugging/debugging.h"
82 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
83 template<typename Element, typename OtherElement>
84 inline bool float_equal_epsilon(const Element& self, const OtherElement& other, const Element& epsilon)
86 return fabs(other - self) < epsilon;
89 /// \brief Returns the value midway between \p self and \p other.
90 template<typename Element>
91 inline Element float_mid(const Element& self, const Element& other)
93 return Element((self + other) * 0.5);
96 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
97 template<typename Element>
98 inline int float_to_integer(const Element& f)
103 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
104 template<typename Element, typename OtherElement>
105 inline Element float_snapped(const Element& f, const OtherElement& snap)
107 //return Element(float_to_integer(f / snap) * snap);
110 return Element(llrint(f / snap) * snap); // llrint has more significant bits
113 /// \brief Returns true if \p f has no decimal fraction part.
114 template<typename Element>
115 inline bool float_is_integer(const Element& f)
117 return f == Element(float_to_integer(f));
120 /// \brief Returns \p self modulated by the range [0, \p modulus)
121 /// \p self must be in the range [\p -modulus, \p modulus)
122 template<typename Element, typename ModulusElement>
123 inline Element float_mod_range(const Element& self, const ModulusElement& modulus)
125 return Element((self < 0.0) ? self + modulus : self);
128 /// \brief Returns \p self modulated by the range [0, \p modulus)
129 template<typename Element, typename ModulusElement>
130 inline Element float_mod(const Element& self, const ModulusElement& modulus)
132 return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
136 template<typename Element, typename OtherElement>
137 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
139 return BasicVector2<Element>(
140 Element(self.x() + other.x()),
141 Element(self.y() + other.y())
144 template<typename Element, typename OtherElement>
145 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
147 return vector2_added(self, other);
149 template<typename Element, typename OtherElement>
150 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
152 self.x() += Element(other.x());
153 self.y() += Element(other.y());
155 template<typename Element, typename OtherElement>
156 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
158 vector2_add(self, other);
162 template<typename Element, typename OtherElement>
163 inline BasicVector2<Element> vector2_subtracted(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
165 return BasicVector2<Element>(
166 Element(self.x() - other.x()),
167 Element(self.y() - other.y())
170 template<typename Element, typename OtherElement>
171 inline BasicVector2<Element> operator-(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
173 return vector2_subtracted(self, other);
175 template<typename Element, typename OtherElement>
176 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
178 self.x() -= Element(other.x());
179 self.y() -= lement(other.y());
181 template<typename Element, typename OtherElement>
182 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
184 vector2_subtract(self, other);
188 template<typename Element, typename OtherElement>
189 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
191 return BasicVector2<Element>(
192 Element(self.x() * other),
193 Element(self.y() * other)
196 template<typename Element, typename OtherElement>
197 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
199 return vector2_scaled(self, other);
201 template<typename Element, typename OtherElement>
202 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
204 self.x() *= Element(other);
205 self.y() *= Element(other);
207 template<typename Element, typename OtherElement>
208 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
210 vector2_scale(self, other);
214 template<typename Element, typename OtherElement>
215 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
217 return BasicVector2<Element>(
218 Element(self.x() * other.x()),
219 Element(self.y() * other.y())
222 template<typename Element, typename OtherElement>
223 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
225 return vector2_scaled(self, other);
227 template<typename Element, typename OtherElement>
228 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
230 self.x() *= Element(other.x());
231 self.y() *= Element(other.y());
233 template<typename Element, typename OtherElement>
234 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
236 vector2_scale(self, other);
239 template<typename Element, typename OtherElement>
240 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
242 return BasicVector2<Element>(
243 Element(self.x() / other.x()),
244 Element(self.y() / other.y())
247 template<typename Element, typename OtherElement>
248 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
250 return vector2_divided(self, other);
252 template<typename Element, typename OtherElement>
253 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
255 self.x() /= Element(other.x());
256 self.y() /= Element(other.y());
258 template<typename Element, typename OtherElement>
259 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
261 vector2_divide(self, other);
265 template<typename Element, typename OtherElement>
266 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
268 return BasicVector2<Element>(
269 Element(self.x() / other),
270 Element(self.y() / other)
273 template<typename Element, typename OtherElement>
274 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
276 return vector2_divided(self, other);
278 template<typename Element, typename OtherElement>
279 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
281 self.x() /= Element(other);
282 self.y() /= Element(other);
284 template<typename Element, typename OtherElement>
285 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
287 vector2_divide(self, other);
290 template<typename Element, typename OtherElement>
291 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
293 return self.x() * other.x() + self.y() * other.y();
296 template<typename Element>
297 inline double vector2_length_squared(const BasicVector2<Element>& self)
299 return vector2_dot(self, self);
302 template<typename Element>
303 inline double vector2_length(const BasicVector2<Element>& self)
305 return sqrt(vector2_length_squared(self));
308 template<typename Element, typename OtherElement>
309 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
311 return self.x() * other.y() - self.y() * other.x();
314 const Vector3 g_vector3_identity(0, 0, 0);
315 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
316 const Vector3 g_vector3_axis_x(1, 0, 0);
317 const Vector3 g_vector3_axis_y(0, 1, 0);
318 const Vector3 g_vector3_axis_z(0, 0, 1);
320 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
322 template<typename Element, typename OtherElement>
323 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
325 std::swap(self.x(), other.x());
326 std::swap(self.y(), other.y());
327 std::swap(self.z(), other.z());
330 template<typename Element, typename OtherElement>
331 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
333 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
335 template<typename Element, typename OtherElement>
336 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
338 return vector3_equal(self, other);
340 template<typename Element, typename OtherElement>
341 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
343 return !vector3_equal(self, other);
347 template<typename Element, typename OtherElement, typename Epsilon>
348 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
350 return float_equal_epsilon(self.x(), other.x(), epsilon)
351 && float_equal_epsilon(self.y(), other.y(), epsilon)
352 && float_equal_epsilon(self.z(), other.z(), epsilon);
357 template<typename Element, typename OtherElement>
358 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
360 return BasicVector3<Element>(
361 Element(self.x() + other.x()),
362 Element(self.y() + other.y()),
363 Element(self.z() + other.z())
366 template<typename Element, typename OtherElement>
367 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
369 return vector3_added(self, other);
371 template<typename Element, typename OtherElement>
372 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
374 self.x() += static_cast<Element>(other.x());
375 self.y() += static_cast<Element>(other.y());
376 self.z() += static_cast<Element>(other.z());
378 template<typename Element, typename OtherElement>
379 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
381 vector3_add(self, other);
384 template<typename Element, typename OtherElement>
385 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
387 return BasicVector3<Element>(
388 Element(self.x() - other.x()),
389 Element(self.y() - other.y()),
390 Element(self.z() - other.z())
393 template<typename Element, typename OtherElement>
394 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
396 return vector3_subtracted(self, other);
398 template<typename Element, typename OtherElement>
399 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
401 self.x() -= static_cast<Element>(other.x());
402 self.y() -= static_cast<Element>(other.y());
403 self.z() -= static_cast<Element>(other.z());
405 template<typename Element, typename OtherElement>
406 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
408 vector3_subtract(self, other);
411 template<typename Element, typename OtherElement>
412 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
414 return BasicVector3<Element>(
415 Element(self.x() * other.x()),
416 Element(self.y() * other.y()),
417 Element(self.z() * other.z())
420 template<typename Element, typename OtherElement>
421 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
423 return vector3_scaled(self, other);
425 template<typename Element, typename OtherElement>
426 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
428 self.x() *= static_cast<Element>(other.x());
429 self.y() *= static_cast<Element>(other.y());
430 self.z() *= static_cast<Element>(other.z());
432 template<typename Element, typename OtherElement>
433 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
435 vector3_scale(self, other);
438 template<typename Element, typename OtherElement>
439 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
441 return BasicVector3<Element>(
442 Element(self.x() * scale),
443 Element(self.y() * scale),
444 Element(self.z() * scale)
447 template<typename Element, typename OtherElement>
448 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
450 return vector3_scaled(self, scale);
452 template<typename Element, typename OtherElement>
453 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
455 self.x() *= static_cast<Element>(scale);
456 self.y() *= static_cast<Element>(scale);
457 self.z() *= static_cast<Element>(scale);
459 template<typename Element, typename OtherElement>
460 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
462 vector3_scale(self, scale);
465 template<typename Element, typename OtherElement>
466 inline BasicVector3<Element> vector3_divided(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_divided(self, other);
479 template<typename Element, typename OtherElement>
480 inline void vector3_divide(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_divide(self, other);
492 template<typename Element, typename OtherElement>
493 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
495 return BasicVector3<Element>(
496 Element(self.x() / divisor),
497 Element(self.y() / divisor),
498 Element(self.z() / divisor)
501 template<typename Element, typename OtherElement>
502 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
504 return vector3_divided(self, divisor);
506 template<typename Element, typename OtherElement>
507 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
509 self.x() /= static_cast<Element>(divisor);
510 self.y() /= static_cast<Element>(divisor);
511 self.z() /= static_cast<Element>(divisor);
513 template<typename Element, typename OtherElement>
514 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
516 vector3_divide(self, divisor);
519 template<typename Element, typename OtherElement>
520 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
522 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
525 template<typename Element>
526 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
528 return vector3_scaled(vector3_added(begin, end), 0.5);
531 template<typename Element, typename OtherElement>
532 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
534 return BasicVector3<Element>(
535 Element(self.y() * other.z() - self.z() * other.y()),
536 Element(self.z() * other.x() - self.x() * other.z()),
537 Element(self.x() * other.y() - self.y() * other.x())
541 template<typename Element>
542 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
544 return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
546 template<typename Element>
547 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
549 return vector3_negated(self);
552 template<typename Element>
553 inline void vector3_negate(BasicVector3<Element>& self)
555 self = vector3_negated(self);
558 template<typename Element>
559 inline double vector3_length_squared(const BasicVector3<Element>& self)
561 return vector3_dot(self, self);
564 template<typename Element>
565 inline double vector3_length(const BasicVector3<Element>& self)
567 return sqrt(vector3_length_squared(self));
570 template<typename Element>
571 inline Element float_divided(Element f, Element other)
573 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
577 template<typename Element>
578 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
580 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
583 template<typename Element>
584 inline void vector3_normalise(BasicVector3<Element>& self)
586 self = vector3_normalised(self);
590 template<typename Element>
591 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
593 return BasicVector3<Element>(
594 Element(float_to_integer(self.x())),
595 Element(float_to_integer(self.y())),
596 Element(float_to_integer(self.z()))
599 template<typename Element>
600 inline void vector3_snap(BasicVector3<Element>& self)
602 self = vector3_snapped(self);
604 template<typename Element, typename OtherElement>
605 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
607 return BasicVector3<Element>(
608 Element(float_snapped(self.x(), snap)),
609 Element(float_snapped(self.y(), snap)),
610 Element(float_snapped(self.z(), snap))
613 template<typename Element, typename OtherElement>
614 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
616 self = vector3_snapped(self, snap);
619 inline Vector3 vector3_for_spherical(double theta, double phi)
622 static_cast<float>(cos(theta) * cos(phi)),
623 static_cast<float>(sin(theta) * cos(phi)),
624 static_cast<float>(sin(phi))
631 template<typename Element, typename OtherElement>
632 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
634 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
636 template<typename Element, typename OtherElement>
637 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
639 return vector4_equal(self, other);
641 template<typename Element, typename OtherElement>
642 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
644 return !vector4_equal(self, other);
647 template<typename Element, typename OtherElement>
648 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
650 return float_equal_epsilon(self.x(), other.x(), epsilon)
651 && float_equal_epsilon(self.y(), other.y(), epsilon)
652 && float_equal_epsilon(self.z(), other.z(), epsilon)
653 && float_equal_epsilon(self.w(), other.w(), epsilon);
656 template<typename Element, typename OtherElement>
657 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
659 return BasicVector4<Element>(
660 float(self.x() + other.x()),
661 float(self.y() + other.y()),
662 float(self.z() + other.z()),
663 float(self.w() + other.w())
666 template<typename Element, typename OtherElement>
667 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
669 return vector4_added(self, other);
671 template<typename Element, typename OtherElement>
672 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
674 self.x() += static_cast<float>(other.x());
675 self.y() += static_cast<float>(other.y());
676 self.z() += static_cast<float>(other.z());
677 self.w() += static_cast<float>(other.w());
679 template<typename Element, typename OtherElement>
680 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
682 vector4_add(self, other);
685 template<typename Element, typename OtherElement>
686 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
688 return BasicVector4<Element>(
689 float(self.x() - other.x()),
690 float(self.y() - other.y()),
691 float(self.z() - other.z()),
692 float(self.w() - other.w())
695 template<typename Element, typename OtherElement>
696 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
698 return vector4_subtracted(self, other);
700 template<typename Element, typename OtherElement>
701 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
703 self.x() -= static_cast<float>(other.x());
704 self.y() -= static_cast<float>(other.y());
705 self.z() -= static_cast<float>(other.z());
706 self.w() -= static_cast<float>(other.w());
708 template<typename Element, typename OtherElement>
709 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
711 vector4_subtract(self, other);
714 template<typename Element, typename OtherElement>
715 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
717 return BasicVector4<Element>(
718 float(self.x() * other.x()),
719 float(self.y() * other.y()),
720 float(self.z() * other.z()),
721 float(self.w() * other.w())
724 template<typename Element, typename OtherElement>
725 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
727 return vector4_scaled(self, other);
729 template<typename Element, typename OtherElement>
730 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
732 self.x() *= static_cast<float>(other.x());
733 self.y() *= static_cast<float>(other.y());
734 self.z() *= static_cast<float>(other.z());
735 self.w() *= static_cast<float>(other.w());
737 template<typename Element, typename OtherElement>
738 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
740 vector4_scale(self, other);
743 template<typename Element, typename OtherElement>
744 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
746 return BasicVector4<Element>(
747 float(self.x() * scale),
748 float(self.y() * scale),
749 float(self.z() * scale),
750 float(self.w() * scale)
753 template<typename Element, typename OtherElement>
754 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
756 return vector4_scaled(self, scale);
758 template<typename Element, typename OtherElement>
759 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
761 self.x() *= static_cast<float>(scale);
762 self.y() *= static_cast<float>(scale);
763 self.z() *= static_cast<float>(scale);
764 self.w() *= static_cast<float>(scale);
766 template<typename Element, typename OtherElement>
767 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
769 vector4_scale(self, scale);
772 template<typename Element, typename OtherElement>
773 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
775 return BasicVector4<Element>(
776 float(self.x() / divisor),
777 float(self.y() / divisor),
778 float(self.z() / divisor),
779 float(self.w() / divisor)
782 template<typename Element, typename OtherElement>
783 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
785 return vector4_divided(self, divisor);
787 template<typename Element, typename OtherElement>
788 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
795 template<typename Element, typename OtherElement>
796 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
798 vector4_divide(self, divisor);
801 template<typename Element, typename OtherElement>
802 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
804 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
807 template<typename Element>
808 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
810 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);