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);
98 return Element(llrint(f / snap) * snap); // llrint has more significant bits
101 /// \brief Returns true if \p f has no decimal fraction part.
102 template<typename Element>
103 inline bool float_is_integer(const Element& f)
105 return f == Element(float_to_integer(f));
108 /// \brief Returns \p self modulated by the range [0, \p modulus)
109 /// \p self must be in the range [\p -modulus, \p modulus)
110 template<typename Element, typename ModulusElement>
111 inline Element float_mod_range(const Element& self, const ModulusElement& modulus)
113 return Element((self < 0.0) ? self + modulus : self);
116 /// \brief Returns \p self modulated by the range [0, \p modulus)
117 template<typename Element, typename ModulusElement>
118 inline Element float_mod(const Element& self, const ModulusElement& modulus)
120 return float_mod_range(Element(fmod(static_cast<double>(self), static_cast<double>(modulus))), modulus);
124 template<typename Element, typename OtherElement>
125 inline BasicVector2<Element> vector2_added(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
127 return BasicVector2<Element>(
128 Element(self.x() + other.x()),
129 Element(self.y() + other.y())
132 template<typename Element, typename OtherElement>
133 inline BasicVector2<Element> operator+(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
135 return vector2_added(self, other);
137 template<typename Element, typename OtherElement>
138 inline void vector2_add(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
140 self.x() += Element(other.x());
141 self.y() += Element(other.y());
143 template<typename Element, typename OtherElement>
144 inline void operator+=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
146 vector2_add(self, other);
150 template<typename Element, typename OtherElement>
151 inline BasicVector2<Element> vector2_subtracted(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
153 return BasicVector2<Element>(
154 Element(self.x() - other.x()),
155 Element(self.y() - other.y())
158 template<typename Element, typename OtherElement>
159 inline BasicVector2<Element> operator-(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
161 return vector2_subtracted(self, other);
163 template<typename Element, typename OtherElement>
164 inline void vector2_subtract(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
166 self.x() -= Element(other.x());
167 self.y() -= lement(other.y());
169 template<typename Element, typename OtherElement>
170 inline void operator-=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
172 vector2_subtract(self, other);
176 template<typename Element, typename OtherElement>
177 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, OtherElement other)
179 return BasicVector2<Element>(
180 Element(self.x() * other),
181 Element(self.y() * other)
184 template<typename Element, typename OtherElement>
185 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, OtherElement other)
187 return vector2_scaled(self, other);
189 template<typename Element, typename OtherElement>
190 inline void vector2_scale(BasicVector2<Element>& self, OtherElement other)
192 self.x() *= Element(other);
193 self.y() *= Element(other);
195 template<typename Element, typename OtherElement>
196 inline void operator*=(BasicVector2<Element>& self, OtherElement other)
198 vector2_scale(self, other);
202 template<typename Element, typename OtherElement>
203 inline BasicVector2<Element> vector2_scaled(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
205 return BasicVector2<Element>(
206 Element(self.x() * other.x()),
207 Element(self.y() * other.y())
210 template<typename Element, typename OtherElement>
211 inline BasicVector2<Element> operator*(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
213 return vector2_scaled(self, other);
215 template<typename Element, typename OtherElement>
216 inline void vector2_scale(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
218 self.x() *= Element(other.x());
219 self.y() *= Element(other.y());
221 template<typename Element, typename OtherElement>
222 inline void operator*=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
224 vector2_scale(self, other);
227 template<typename Element, typename OtherElement>
228 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
230 return BasicVector2<Element>(
231 Element(self.x() / other.x()),
232 Element(self.y() / other.y())
235 template<typename Element, typename OtherElement>
236 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
238 return vector2_divided(self, other);
240 template<typename Element, typename OtherElement>
241 inline void vector2_divide(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
243 self.x() /= Element(other.x());
244 self.y() /= Element(other.y());
246 template<typename Element, typename OtherElement>
247 inline void operator/=(BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
249 vector2_divide(self, other);
253 template<typename Element, typename OtherElement>
254 inline BasicVector2<Element> vector2_divided(const BasicVector2<Element>& self, OtherElement other)
256 return BasicVector2<Element>(
257 Element(self.x() / other),
258 Element(self.y() / other)
261 template<typename Element, typename OtherElement>
262 inline BasicVector2<Element> operator/(const BasicVector2<Element>& self, OtherElement other)
264 return vector2_divided(self, other);
266 template<typename Element, typename OtherElement>
267 inline void vector2_divide(BasicVector2<Element>& self, OtherElement other)
269 self.x() /= Element(other);
270 self.y() /= Element(other);
272 template<typename Element, typename OtherElement>
273 inline void operator/=(BasicVector2<Element>& self, OtherElement other)
275 vector2_divide(self, other);
278 template<typename Element, typename OtherElement>
279 inline double vector2_dot(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
281 return self.x() * other.x() + self.y() * other.y();
284 template<typename Element>
285 inline double vector2_length_squared(const BasicVector2<Element>& self)
287 return vector2_dot(self, self);
290 template<typename Element>
291 inline double vector2_length(const BasicVector2<Element>& self)
293 return sqrt(vector2_length_squared(self));
296 template<typename Element, typename OtherElement>
297 inline double vector2_cross(const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other)
299 return self.x() * other.y() - self.y() * other.x();
302 const Vector3 g_vector3_identity(0, 0, 0);
303 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
304 const Vector3 g_vector3_axis_x(1, 0, 0);
305 const Vector3 g_vector3_axis_y(0, 1, 0);
306 const Vector3 g_vector3_axis_z(0, 0, 1);
308 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
310 template<typename Element, typename OtherElement>
311 inline void vector3_swap(BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
313 std::swap(self.x(), other.x());
314 std::swap(self.y(), other.y());
315 std::swap(self.z(), other.z());
318 template<typename Element, typename OtherElement>
319 inline bool vector3_equal(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
321 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
323 template<typename Element, typename OtherElement>
324 inline bool operator==(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
326 return vector3_equal(self, other);
328 template<typename Element, typename OtherElement>
329 inline bool operator!=(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
331 return !vector3_equal(self, other);
335 template<typename Element, typename OtherElement, typename Epsilon>
336 inline bool vector3_equal_epsilon(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon)
338 return float_equal_epsilon(self.x(), other.x(), epsilon)
339 && float_equal_epsilon(self.y(), other.y(), epsilon)
340 && float_equal_epsilon(self.z(), other.z(), epsilon);
345 template<typename Element, typename OtherElement>
346 inline BasicVector3<Element> vector3_added(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
348 return BasicVector3<Element>(
349 Element(self.x() + other.x()),
350 Element(self.y() + other.y()),
351 Element(self.z() + other.z())
354 template<typename Element, typename OtherElement>
355 inline BasicVector3<Element> operator+(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
357 return vector3_added(self, other);
359 template<typename Element, typename OtherElement>
360 inline void vector3_add(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
362 self.x() += static_cast<Element>(other.x());
363 self.y() += static_cast<Element>(other.y());
364 self.z() += static_cast<Element>(other.z());
366 template<typename Element, typename OtherElement>
367 inline void operator+=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
369 vector3_add(self, other);
372 template<typename Element, typename OtherElement>
373 inline BasicVector3<Element> vector3_subtracted(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
375 return BasicVector3<Element>(
376 Element(self.x() - other.x()),
377 Element(self.y() - other.y()),
378 Element(self.z() - other.z())
381 template<typename Element, typename OtherElement>
382 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
384 return vector3_subtracted(self, other);
386 template<typename Element, typename OtherElement>
387 inline void vector3_subtract(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
389 self.x() -= static_cast<Element>(other.x());
390 self.y() -= static_cast<Element>(other.y());
391 self.z() -= static_cast<Element>(other.z());
393 template<typename Element, typename OtherElement>
394 inline void operator-=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
396 vector3_subtract(self, other);
399 template<typename Element, typename OtherElement>
400 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
402 return BasicVector3<Element>(
403 Element(self.x() * other.x()),
404 Element(self.y() * other.y()),
405 Element(self.z() * other.z())
408 template<typename Element, typename OtherElement>
409 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
411 return vector3_scaled(self, other);
413 template<typename Element, typename OtherElement>
414 inline void vector3_scale(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
416 self.x() *= static_cast<Element>(other.x());
417 self.y() *= static_cast<Element>(other.y());
418 self.z() *= static_cast<Element>(other.z());
420 template<typename Element, typename OtherElement>
421 inline void operator*=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
423 vector3_scale(self, other);
426 template<typename Element, typename OtherElement>
427 inline BasicVector3<Element> vector3_scaled(const BasicVector3<Element>& self, const OtherElement& scale)
429 return BasicVector3<Element>(
430 Element(self.x() * scale),
431 Element(self.y() * scale),
432 Element(self.z() * scale)
435 template<typename Element, typename OtherElement>
436 inline BasicVector3<Element> operator*(const BasicVector3<Element>& self, const OtherElement& scale)
438 return vector3_scaled(self, scale);
440 template<typename Element, typename OtherElement>
441 inline void vector3_scale(BasicVector3<Element>& self, const OtherElement& scale)
443 self.x() *= static_cast<Element>(scale);
444 self.y() *= static_cast<Element>(scale);
445 self.z() *= static_cast<Element>(scale);
447 template<typename Element, typename OtherElement>
448 inline void operator*=(BasicVector3<Element>& self, const OtherElement& scale)
450 vector3_scale(self, scale);
453 template<typename Element, typename OtherElement>
454 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
456 return BasicVector3<Element>(
457 Element(self.x() / other.x()),
458 Element(self.y() / other.y()),
459 Element(self.z() / other.z())
462 template<typename Element, typename OtherElement>
463 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
465 return vector3_divided(self, other);
467 template<typename Element, typename OtherElement>
468 inline void vector3_divide(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
470 self.x() /= static_cast<Element>(other.x());
471 self.y() /= static_cast<Element>(other.y());
472 self.z() /= static_cast<Element>(other.z());
474 template<typename Element, typename OtherElement>
475 inline void operator/=(BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
477 vector3_divide(self, other);
480 template<typename Element, typename OtherElement>
481 inline BasicVector3<Element> vector3_divided(const BasicVector3<Element>& self, const OtherElement& divisor)
483 return BasicVector3<Element>(
484 Element(self.x() / divisor),
485 Element(self.y() / divisor),
486 Element(self.z() / divisor)
489 template<typename Element, typename OtherElement>
490 inline BasicVector3<Element> operator/(const BasicVector3<Element>& self, const OtherElement& divisor)
492 return vector3_divided(self, divisor);
494 template<typename Element, typename OtherElement>
495 inline void vector3_divide(BasicVector3<Element>& self, const OtherElement& divisor)
497 self.x() /= static_cast<Element>(divisor);
498 self.y() /= static_cast<Element>(divisor);
499 self.z() /= static_cast<Element>(divisor);
501 template<typename Element, typename OtherElement>
502 inline void operator/=(BasicVector3<Element>& self, const OtherElement& divisor)
504 vector3_divide(self, divisor);
507 template<typename Element, typename OtherElement>
508 inline double vector3_dot(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
510 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
513 template<typename Element>
514 inline BasicVector3<Element> vector3_mid(const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
516 return vector3_scaled(vector3_added(begin, end), 0.5);
519 template<typename Element, typename OtherElement>
520 inline BasicVector3<Element> vector3_cross(const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other)
522 return BasicVector3<Element>(
523 Element(self.y() * other.z() - self.z() * other.y()),
524 Element(self.z() * other.x() - self.x() * other.z()),
525 Element(self.x() * other.y() - self.y() * other.x())
529 template<typename Element>
530 inline BasicVector3<Element> vector3_negated(const BasicVector3<Element>& self)
532 return BasicVector3<Element>(-self.x(), -self.y(), -self.z());
534 template<typename Element>
535 inline BasicVector3<Element> operator-(const BasicVector3<Element>& self)
537 return vector3_negated(self);
540 template<typename Element>
541 inline void vector3_negate(BasicVector3<Element>& self)
543 self = vector3_negated(self);
546 template<typename Element>
547 inline double vector3_length_squared(const BasicVector3<Element>& self)
549 return vector3_dot(self, self);
552 template<typename Element>
553 inline double vector3_length(const BasicVector3<Element>& self)
555 return sqrt(vector3_length_squared(self));
558 template<typename Element>
559 inline Element float_divided(Element f, Element other)
561 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
565 template<typename Element>
566 inline BasicVector3<Element> vector3_normalised(const BasicVector3<Element>& self)
568 return vector3_scaled(self, float_divided(1.0, vector3_length(self)));
571 template<typename Element>
572 inline void vector3_normalise(BasicVector3<Element>& self)
574 self = vector3_normalised(self);
578 template<typename Element>
579 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self)
581 return BasicVector3<Element>(
582 Element(float_to_integer(self.x())),
583 Element(float_to_integer(self.y())),
584 Element(float_to_integer(self.z()))
587 template<typename Element>
588 inline void vector3_snap(BasicVector3<Element>& self)
590 self = vector3_snapped(self);
592 template<typename Element, typename OtherElement>
593 inline BasicVector3<Element> vector3_snapped(const BasicVector3<Element>& self, const OtherElement& snap)
595 return BasicVector3<Element>(
596 Element(float_snapped(self.x(), snap)),
597 Element(float_snapped(self.y(), snap)),
598 Element(float_snapped(self.z(), snap))
601 template<typename Element, typename OtherElement>
602 inline void vector3_snap(BasicVector3<Element>& self, const OtherElement& snap)
604 self = vector3_snapped(self, snap);
607 inline Vector3 vector3_for_spherical(double theta, double phi)
610 static_cast<float>(cos(theta) * cos(phi)),
611 static_cast<float>(sin(theta) * cos(phi)),
612 static_cast<float>(sin(phi))
619 template<typename Element, typename OtherElement>
620 inline bool vector4_equal(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
622 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
624 template<typename Element, typename OtherElement>
625 inline bool operator==(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
627 return vector4_equal(self, other);
629 template<typename Element, typename OtherElement>
630 inline bool operator!=(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
632 return !vector4_equal(self, other);
635 template<typename Element, typename OtherElement>
636 inline bool vector4_equal_epsilon(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon)
638 return float_equal_epsilon(self.x(), other.x(), epsilon)
639 && float_equal_epsilon(self.y(), other.y(), epsilon)
640 && float_equal_epsilon(self.z(), other.z(), epsilon)
641 && float_equal_epsilon(self.w(), other.w(), epsilon);
644 template<typename Element, typename OtherElement>
645 inline BasicVector4<Element> vector4_added(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
647 return BasicVector4<Element>(
648 float(self.x() + other.x()),
649 float(self.y() + other.y()),
650 float(self.z() + other.z()),
651 float(self.w() + other.w())
654 template<typename Element, typename OtherElement>
655 inline BasicVector4<Element> operator+(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
657 return vector4_added(self, other);
659 template<typename Element, typename OtherElement>
660 inline void vector4_add(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
662 self.x() += static_cast<float>(other.x());
663 self.y() += static_cast<float>(other.y());
664 self.z() += static_cast<float>(other.z());
665 self.w() += static_cast<float>(other.w());
667 template<typename Element, typename OtherElement>
668 inline void operator+=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
670 vector4_add(self, other);
673 template<typename Element, typename OtherElement>
674 inline BasicVector4<Element> vector4_subtracted(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
676 return BasicVector4<Element>(
677 float(self.x() - other.x()),
678 float(self.y() - other.y()),
679 float(self.z() - other.z()),
680 float(self.w() - other.w())
683 template<typename Element, typename OtherElement>
684 inline BasicVector4<Element> operator-(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
686 return vector4_subtracted(self, other);
688 template<typename Element, typename OtherElement>
689 inline void vector4_subtract(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
691 self.x() -= static_cast<float>(other.x());
692 self.y() -= static_cast<float>(other.y());
693 self.z() -= static_cast<float>(other.z());
694 self.w() -= static_cast<float>(other.w());
696 template<typename Element, typename OtherElement>
697 inline void operator-=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
699 vector4_subtract(self, other);
702 template<typename Element, typename OtherElement>
703 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
705 return BasicVector4<Element>(
706 float(self.x() * other.x()),
707 float(self.y() * other.y()),
708 float(self.z() * other.z()),
709 float(self.w() * other.w())
712 template<typename Element, typename OtherElement>
713 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
715 return vector4_scaled(self, other);
717 template<typename Element, typename OtherElement>
718 inline void vector4_scale(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
720 self.x() *= static_cast<float>(other.x());
721 self.y() *= static_cast<float>(other.y());
722 self.z() *= static_cast<float>(other.z());
723 self.w() *= static_cast<float>(other.w());
725 template<typename Element, typename OtherElement>
726 inline void operator*=(BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
728 vector4_scale(self, other);
731 template<typename Element, typename OtherElement>
732 inline BasicVector4<Element> vector4_scaled(const BasicVector4<Element>& self, OtherElement scale)
734 return BasicVector4<Element>(
735 float(self.x() * scale),
736 float(self.y() * scale),
737 float(self.z() * scale),
738 float(self.w() * scale)
741 template<typename Element, typename OtherElement>
742 inline BasicVector4<Element> operator*(const BasicVector4<Element>& self, OtherElement scale)
744 return vector4_scaled(self, scale);
746 template<typename Element, typename OtherElement>
747 inline void vector4_scale(BasicVector4<Element>& self, OtherElement scale)
749 self.x() *= static_cast<float>(scale);
750 self.y() *= static_cast<float>(scale);
751 self.z() *= static_cast<float>(scale);
752 self.w() *= static_cast<float>(scale);
754 template<typename Element, typename OtherElement>
755 inline void operator*=(BasicVector4<Element>& self, OtherElement scale)
757 vector4_scale(self, scale);
760 template<typename Element, typename OtherElement>
761 inline BasicVector4<Element> vector4_divided(const BasicVector4<Element>& self, OtherElement divisor)
763 return BasicVector4<Element>(
764 float(self.x() / divisor),
765 float(self.y() / divisor),
766 float(self.z() / divisor),
767 float(self.w() / divisor)
770 template<typename Element, typename OtherElement>
771 inline BasicVector4<Element> operator/(const BasicVector4<Element>& self, OtherElement divisor)
773 return vector4_divided(self, divisor);
775 template<typename Element, typename OtherElement>
776 inline void vector4_divide(BasicVector4<Element>& self, OtherElement divisor)
783 template<typename Element, typename OtherElement>
784 inline void operator/=(BasicVector4<Element>& self, OtherElement divisor)
786 vector4_divide(self, divisor);
789 template<typename Element, typename OtherElement>
790 inline double vector4_dot(const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other)
792 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
795 template<typename Element>
796 inline BasicVector3<Element> vector4_projected(const BasicVector4<Element>& self)
798 return vector3_scaled(vector4_to_vector3(self), 1.0 / self[3]);