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);
108 return Element(llrint(f / snap) * snap); // llrint has more significant bits
111 /// \brief Returns true if \p f has no decimal fraction part.
112 template<typename Element>
113 inline bool float_is_integer(const Element& f)
115 return f == Element(float_to_integer(f));
118 /// \brief Returns \p self modulated by the range [0, \p modulus)
119 /// \p self must be in the range [\p -modulus, \p modulus)
120 template<typename Element, typename ModulusElement>
121 inline Element float_mod_range(const Element& self, const ModulusElement& modulus)
123 return Element((self < 0.0) ? self + modulus : self);
126 /// \brief Returns \p self modulated by the range [0, \p modulus)
127 template<typename Element, typename ModulusElement>
128 inline Element float_mod(const Element& self, const ModulusElement& modulus)
130 return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
134 template<typename Element, typename OtherElement>
135 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
137 return BasicVector2<Element>(
138 Element(self.x() + other.x()),
139 Element(self.y() + other.y())
142 template<typename Element, typename OtherElement>
143 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
145 return vector2_added(self, other);
147 template<typename Element, typename OtherElement>
148 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
150 self.x() += Element(other.x());
151 self.y() += Element(other.y());
153 template<typename Element, typename OtherElement>
154 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
156 vector2_add(self, other);
160 template<typename Element, typename OtherElement>
161 inline BasicVector2<Element> vector2_subtracted(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_subtracted(self, other);
173 template<typename Element, typename OtherElement>
174 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
176 self.x() -= Element(other.x());
177 self.y() -= lement(other.y());
179 template<typename Element, typename OtherElement>
180 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
182 vector2_subtract(self, other);
186 template<typename Element, typename OtherElement>
187 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
189 return BasicVector2<Element>(
190 Element(self.x() * other),
191 Element(self.y() * other)
194 template<typename Element, typename OtherElement>
195 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
197 return vector2_scaled(self, other);
199 template<typename Element, typename OtherElement>
200 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
202 self.x() *= Element(other);
203 self.y() *= Element(other);
205 template<typename Element, typename OtherElement>
206 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
208 vector2_scale(self, other);
212 template<typename Element, typename OtherElement>
213 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
215 return BasicVector2<Element>(
216 Element(self.x() * other.x()),
217 Element(self.y() * other.y())
220 template<typename Element, typename OtherElement>
221 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
223 return vector2_scaled(self, other);
225 template<typename Element, typename OtherElement>
226 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
228 self.x() *= Element(other.x());
229 self.y() *= Element(other.y());
231 template<typename Element, typename OtherElement>
232 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
234 vector2_scale(self, other);
237 template<typename Element, typename OtherElement>
238 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
240 return BasicVector2<Element>(
241 Element(self.x() / other.x()),
242 Element(self.y() / other.y())
245 template<typename Element, typename OtherElement>
246 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
248 return vector2_divided(self, other);
250 template<typename Element, typename OtherElement>
251 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
253 self.x() /= Element(other.x());
254 self.y() /= Element(other.y());
256 template<typename Element, typename OtherElement>
257 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
259 vector2_divide(self, other);
263 template<typename Element, typename OtherElement>
264 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
266 return BasicVector2<Element>(
267 Element(self.x() / other),
268 Element(self.y() / other)
271 template<typename Element, typename OtherElement>
272 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
274 return vector2_divided(self, other);
276 template<typename Element, typename OtherElement>
277 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
279 self.x() /= Element(other);
280 self.y() /= Element(other);
282 template<typename Element, typename OtherElement>
283 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
285 vector2_divide(self, other);
288 template<typename Element, typename OtherElement>
289 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
291 return self.x() * other.x() + self.y() * other.y();
294 template<typename Element>
295 inline double vector2_length_squared(const BasicVector2<Element>& self)
297 return vector2_dot(self, self);
300 template<typename Element>
301 inline double vector2_length(const BasicVector2<Element>& self)
303 return sqrt(vector2_length_squared(self));
306 template<typename Element, typename OtherElement>
307 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
309 return self.x() * other.y() - self.y() * other.x();
312 const Vector3 g_vector3_identity(0, 0, 0);
313 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
314 const Vector3 g_vector3_axis_x(1, 0, 0);
315 const Vector3 g_vector3_axis_y(0, 1, 0);
316 const Vector3 g_vector3_axis_z(0, 0, 1);
318 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
320 template<typename Element, typename OtherElement>
321 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
323 std::swap(self.x(), other.x());
324 std::swap(self.y(), other.y());
325 std::swap(self.z(), other.z());
328 template<typename Element, typename OtherElement>
329 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
331 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
333 template<typename Element, typename OtherElement>
334 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
336 return vector3_equal(self, other);
338 template<typename Element, typename OtherElement>
339 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
341 return !vector3_equal(self, other);
345 template<typename Element, typename OtherElement, typename Epsilon>
346 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
348 return float_equal_epsilon(self.x(), other.x(), epsilon)
349 && float_equal_epsilon(self.y(), other.y(), epsilon)
350 && float_equal_epsilon(self.z(), other.z(), epsilon);
355 template<typename Element, typename OtherElement>
356 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
358 return BasicVector3<Element>(
359 Element(self.x() + other.x()),
360 Element(self.y() + other.y()),
361 Element(self.z() + other.z())
364 template<typename Element, typename OtherElement>
365 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
367 return vector3_added(self, other);
369 template<typename Element, typename OtherElement>
370 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
372 self.x() += static_cast<Element>(other.x());
373 self.y() += static_cast<Element>(other.y());
374 self.z() += static_cast<Element>(other.z());
376 template<typename Element, typename OtherElement>
377 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
379 vector3_add(self, other);
382 template<typename Element, typename OtherElement>
383 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
385 return BasicVector3<Element>(
386 Element(self.x() - other.x()),
387 Element(self.y() - other.y()),
388 Element(self.z() - other.z())
391 template<typename Element, typename OtherElement>
392 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
394 return vector3_subtracted(self, other);
396 template<typename Element, typename OtherElement>
397 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
399 self.x() -= static_cast<Element>(other.x());
400 self.y() -= static_cast<Element>(other.y());
401 self.z() -= static_cast<Element>(other.z());
403 template<typename Element, typename OtherElement>
404 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
406 vector3_subtract(self, other);
409 template<typename Element, typename OtherElement>
410 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
412 return BasicVector3<Element>(
413 Element(self.x() * other.x()),
414 Element(self.y() * other.y()),
415 Element(self.z() * other.z())
418 template<typename Element, typename OtherElement>
419 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
421 return vector3_scaled(self, other);
423 template<typename Element, typename OtherElement>
424 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
426 self.x() *= static_cast<Element>(other.x());
427 self.y() *= static_cast<Element>(other.y());
428 self.z() *= static_cast<Element>(other.z());
430 template<typename Element, typename OtherElement>
431 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
433 vector3_scale(self, other);
436 template<typename Element, typename OtherElement>
437 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
439 return BasicVector3<Element>(
440 Element(self.x() * scale),
441 Element(self.y() * scale),
442 Element(self.z() * scale)
445 template<typename Element, typename OtherElement>
446 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
448 return vector3_scaled(self, scale);
450 template<typename Element, typename OtherElement>
451 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
453 self.x() *= static_cast<Element>(scale);
454 self.y() *= static_cast<Element>(scale);
455 self.z() *= static_cast<Element>(scale);
457 template<typename Element, typename OtherElement>
458 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
460 vector3_scale(self, scale);
463 template<typename Element, typename OtherElement>
464 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
466 return BasicVector3<Element>(
467 Element(self.x() / other.x()),
468 Element(self.y() / other.y()),
469 Element(self.z() / other.z())
472 template<typename Element, typename OtherElement>
473 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
475 return vector3_divided(self, other);
477 template<typename Element, typename OtherElement>
478 inline void vector3_divide(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
480 self.x() /= static_cast<Element>(other.x());
481 self.y() /= static_cast<Element>(other.y());
482 self.z() /= static_cast<Element>(other.z());
484 template<typename Element, typename OtherElement>
485 inline void operator/=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
487 vector3_divide(self, other);
490 template<typename Element, typename OtherElement>
491 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
493 return BasicVector3<Element>(
494 Element(self.x() / divisor),
495 Element(self.y() / divisor),
496 Element(self.z() / divisor)
499 template<typename Element, typename OtherElement>
500 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
502 return vector3_divided(self, divisor);
504 template<typename Element, typename OtherElement>
505 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
507 self.x() /= static_cast<Element>(divisor);
508 self.y() /= static_cast<Element>(divisor);
509 self.z() /= static_cast<Element>(divisor);
511 template<typename Element, typename OtherElement>
512 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
514 vector3_divide(self, divisor);
517 template<typename Element, typename OtherElement>
518 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
520 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
523 template<typename Element>
524 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
526 return vector3_scaled(vector3_added(begin, end), 0.5);
529 template<typename Element, typename OtherElement>
530 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
532 return BasicVector3<Element>(
533 Element(self.y() * other.z() - self.z() * other.y()),
534 Element(self.z() * other.x() - self.x() * other.z()),
535 Element(self.x() * other.y() - self.y() * other.x())
539 template<typename Element>
540 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
542 return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
544 template<typename Element>
545 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
547 return vector3_negated(self);
550 template<typename Element>
551 inline void vector3_negate(BasicVector3<Element>& self)
553 self = vector3_negated(self);
556 template<typename Element>
557 inline double vector3_length_squared(const BasicVector3<Element>& self)
559 return vector3_dot(self, self);
562 template<typename Element>
563 inline double vector3_length(const BasicVector3<Element>& self)
565 return sqrt(vector3_length_squared(self));
568 template<typename Element>
569 inline Element float_divided(Element f, Element other)
571 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
575 template<typename Element>
576 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
578 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
581 template<typename Element>
582 inline void vector3_normalise(BasicVector3<Element>& self)
584 self = vector3_normalised(self);
588 template<typename Element>
589 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
591 return BasicVector3<Element>(
592 Element(float_to_integer(self.x())),
593 Element(float_to_integer(self.y())),
594 Element(float_to_integer(self.z()))
597 template<typename Element>
598 inline void vector3_snap(BasicVector3<Element>& self)
600 self = vector3_snapped(self);
602 template<typename Element, typename OtherElement>
603 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
605 return BasicVector3<Element>(
606 Element(float_snapped(self.x(), snap)),
607 Element(float_snapped(self.y(), snap)),
608 Element(float_snapped(self.z(), snap))
611 template<typename Element, typename OtherElement>
612 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
614 self = vector3_snapped(self, snap);
617 inline Vector3 vector3_for_spherical(double theta, double phi)
620 static_cast<float>(cos(theta) * cos(phi)),
621 static_cast<float>(sin(theta) * cos(phi)),
622 static_cast<float>(sin(phi))
629 template<typename Element, typename OtherElement>
630 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
632 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
634 template<typename Element, typename OtherElement>
635 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
637 return vector4_equal(self, other);
639 template<typename Element, typename OtherElement>
640 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
642 return !vector4_equal(self, other);
645 template<typename Element, typename OtherElement>
646 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
648 return float_equal_epsilon(self.x(), other.x(), epsilon)
649 && float_equal_epsilon(self.y(), other.y(), epsilon)
650 && float_equal_epsilon(self.z(), other.z(), epsilon)
651 && float_equal_epsilon(self.w(), other.w(), epsilon);
654 template<typename Element, typename OtherElement>
655 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
657 return BasicVector4<Element>(
658 float(self.x() + other.x()),
659 float(self.y() + other.y()),
660 float(self.z() + other.z()),
661 float(self.w() + other.w())
664 template<typename Element, typename OtherElement>
665 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
667 return vector4_added(self, other);
669 template<typename Element, typename OtherElement>
670 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
672 self.x() += static_cast<float>(other.x());
673 self.y() += static_cast<float>(other.y());
674 self.z() += static_cast<float>(other.z());
675 self.w() += static_cast<float>(other.w());
677 template<typename Element, typename OtherElement>
678 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
680 vector4_add(self, other);
683 template<typename Element, typename OtherElement>
684 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
686 return BasicVector4<Element>(
687 float(self.x() - other.x()),
688 float(self.y() - other.y()),
689 float(self.z() - other.z()),
690 float(self.w() - other.w())
693 template<typename Element, typename OtherElement>
694 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
696 return vector4_subtracted(self, other);
698 template<typename Element, typename OtherElement>
699 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
701 self.x() -= static_cast<float>(other.x());
702 self.y() -= static_cast<float>(other.y());
703 self.z() -= static_cast<float>(other.z());
704 self.w() -= static_cast<float>(other.w());
706 template<typename Element, typename OtherElement>
707 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
709 vector4_subtract(self, other);
712 template<typename Element, typename OtherElement>
713 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
715 return BasicVector4<Element>(
716 float(self.x() * other.x()),
717 float(self.y() * other.y()),
718 float(self.z() * other.z()),
719 float(self.w() * other.w())
722 template<typename Element, typename OtherElement>
723 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
725 return vector4_scaled(self, other);
727 template<typename Element, typename OtherElement>
728 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
730 self.x() *= static_cast<float>(other.x());
731 self.y() *= static_cast<float>(other.y());
732 self.z() *= static_cast<float>(other.z());
733 self.w() *= static_cast<float>(other.w());
735 template<typename Element, typename OtherElement>
736 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
738 vector4_scale(self, other);
741 template<typename Element, typename OtherElement>
742 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
744 return BasicVector4<Element>(
745 float(self.x() * scale),
746 float(self.y() * scale),
747 float(self.z() * scale),
748 float(self.w() * scale)
751 template<typename Element, typename OtherElement>
752 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
754 return vector4_scaled(self, scale);
756 template<typename Element, typename OtherElement>
757 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
759 self.x() *= static_cast<float>(scale);
760 self.y() *= static_cast<float>(scale);
761 self.z() *= static_cast<float>(scale);
762 self.w() *= static_cast<float>(scale);
764 template<typename Element, typename OtherElement>
765 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
767 vector4_scale(self, scale);
770 template<typename Element, typename OtherElement>
771 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
773 return BasicVector4<Element>(
774 float(self.x() / divisor),
775 float(self.y() / divisor),
776 float(self.z() / divisor),
777 float(self.w() / divisor)
780 template<typename Element, typename OtherElement>
781 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
783 return vector4_divided(self, divisor);
785 template<typename Element, typename OtherElement>
786 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
793 template<typename Element, typename OtherElement>
794 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
796 vector4_divide(self, divisor);
799 template<typename Element, typename OtherElement>
800 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
802 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
805 template<typename Element>
806 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
808 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);