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 ){
44 inline __int64 llrint( double f ){
45 return static_cast<__int64>( f + 0.5 );
48 #elif defined( __FreeBSD__ )
50 inline long lrint( double f ){
51 return static_cast<long>( f + 0.5 );
54 inline long long llrint( double f ){
55 return static_cast<long long>( f + 0.5 );
58 #elif defined( __GNUC__ )
60 // lrint is part of ISO C99
61 #define _ISOC9X_SOURCE 1
62 #define _ISOC99_SOURCE 1
64 #define __USE_ISOC9X 1
65 #define __USE_ISOC99 1
68 #error "unsupported platform"
76 //#include "debugging/debugging.h"
78 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
79 template<typename Element, typename OtherElement>
80 inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){
81 return fabs( other - self ) < epsilon;
84 /// \brief Returns the value midway between \p self and \p other.
85 template<typename Element>
86 inline Element float_mid( const Element& self, const Element& other ){
87 return Element( ( self + other ) * 0.5 );
90 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
91 template<typename Element>
92 inline int float_to_integer( const Element& f ){
96 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
97 template<typename Element, typename OtherElement>
98 inline Element float_snapped( const Element& f, const OtherElement& snap ){
99 //return Element(float_to_integer(f / snap) * snap);
103 return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
106 /// \brief Returns true if \p f has no decimal fraction part.
107 template<typename Element>
108 inline bool float_is_integer( const Element& f ){
109 return f == Element( float_to_integer( f ) );
112 /// \brief Returns \p self modulated by the range [0, \p modulus)
113 /// \p self must be in the range [\p -modulus, \p modulus)
114 template<typename Element, typename ModulusElement>
115 inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){
116 return Element( ( self < 0.0 ) ? self + modulus : self );
119 /// \brief Returns \p self modulated by the range [0, \p modulus)
120 template<typename Element, typename ModulusElement>
121 inline Element float_mod( const Element& self, const ModulusElement& modulus ){
122 return float_mod_range( Element( fmod( static_cast<double>( self ), static_cast<double>( modulus ) ) ), modulus );
126 template<typename Element, typename OtherElement>
127 inline BasicVector2<Element> vector2_added( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
128 return BasicVector2<Element>(
129 Element( self.x() + other.x() ),
130 Element( self.y() + other.y() )
133 template<typename Element, typename OtherElement>
134 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 ){
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 ){
144 vector2_add( self, other );
148 template<typename Element, typename OtherElement>
149 inline BasicVector2<Element> vector2_subtracted( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
150 return BasicVector2<Element>(
151 Element( self.x() - other.x() ),
152 Element( self.y() - other.y() )
155 template<typename Element, typename OtherElement>
156 inline BasicVector2<Element> operator-( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
157 return vector2_subtracted( self, other );
159 template<typename Element, typename OtherElement>
160 inline void vector2_subtract( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
161 self.x() -= Element( other.x() );
162 self.y() -= lement( other.y() );
164 template<typename Element, typename OtherElement>
165 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
166 vector2_subtract( self, other );
170 template<typename Element, typename OtherElement>
171 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, OtherElement other ){
172 return BasicVector2<Element>(
173 Element( self.x() * other ),
174 Element( self.y() * other )
177 template<typename Element, typename OtherElement>
178 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
179 return vector2_scaled( self, other );
181 template<typename Element, typename OtherElement>
182 inline void vector2_scale( BasicVector2<Element>& self, OtherElement other ){
183 self.x() *= Element( other );
184 self.y() *= Element( other );
186 template<typename Element, typename OtherElement>
187 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
188 vector2_scale( self, other );
192 template<typename Element, typename OtherElement>
193 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
194 return BasicVector2<Element>(
195 Element( self.x() * other.x() ),
196 Element( self.y() * other.y() )
199 template<typename Element, typename OtherElement>
200 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
201 return vector2_scaled( self, other );
203 template<typename Element, typename OtherElement>
204 inline void vector2_scale( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
205 self.x() *= Element( other.x() );
206 self.y() *= Element( other.y() );
208 template<typename Element, typename OtherElement>
209 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
210 vector2_scale( self, other );
213 template<typename Element, typename OtherElement>
214 inline BasicVector2<Element> vector2_divided( 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 ){
222 return vector2_divided( self, other );
224 template<typename Element, typename OtherElement>
225 inline void vector2_divide( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
226 self.x() /= Element( other.x() );
227 self.y() /= Element( other.y() );
229 template<typename Element, typename OtherElement>
230 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
231 vector2_divide( self, other );
235 template<typename Element, typename OtherElement>
236 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, OtherElement other ){
237 return BasicVector2<Element>(
238 Element( self.x() / other ),
239 Element( self.y() / other )
242 template<typename Element, typename OtherElement>
243 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
244 return vector2_divided( self, other );
246 template<typename Element, typename OtherElement>
247 inline void vector2_divide( BasicVector2<Element>& self, OtherElement other ){
248 self.x() /= Element( other );
249 self.y() /= Element( other );
251 template<typename Element, typename OtherElement>
252 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
253 vector2_divide( self, other );
256 template<typename Element, typename OtherElement>
257 inline double vector2_dot( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
258 return self.x() * other.x() + self.y() * other.y();
261 template<typename Element>
262 inline double vector2_length_squared( const BasicVector2<Element>& self ){
263 return vector2_dot( self, self );
266 template<typename Element>
267 inline double vector2_length( const BasicVector2<Element>& self ){
268 return sqrt( vector2_length_squared( self ) );
271 template<typename Element, typename OtherElement>
272 inline double vector2_cross( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
273 return self.x() * other.y() - self.y() * other.x();
276 const Vector3 g_vector3_identity( 0, 0, 0 );
277 const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX );
278 const Vector3 g_vector3_axis_x( 1, 0, 0 );
279 const Vector3 g_vector3_axis_y( 0, 1, 0 );
280 const Vector3 g_vector3_axis_z( 0, 0, 1 );
282 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
284 template<typename Element, typename OtherElement>
285 inline void vector3_swap( BasicVector3<Element>& self, BasicVector3<OtherElement>& other ){
286 std::swap( self.x(), other.x() );
287 std::swap( self.y(), other.y() );
288 std::swap( self.z(), other.z() );
291 template<typename Element, typename OtherElement>
292 inline bool vector3_equal( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
293 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
295 template<typename Element, typename OtherElement>
296 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
297 return vector3_equal( self, other );
299 template<typename Element, typename OtherElement>
300 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
301 return !vector3_equal( self, other );
305 template<typename Element, typename OtherElement, typename Epsilon>
306 inline bool vector3_equal_epsilon( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon ){
307 return float_equal_epsilon( self.x(), other.x(), epsilon )
308 && float_equal_epsilon( self.y(), other.y(), epsilon )
309 && float_equal_epsilon( self.z(), other.z(), epsilon );
314 template<typename Element, typename OtherElement>
315 inline BasicVector3<Element> vector3_added( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
316 return BasicVector3<Element>(
317 Element( self.x() + other.x() ),
318 Element( self.y() + other.y() ),
319 Element( self.z() + other.z() )
322 template<typename Element, typename OtherElement>
323 inline BasicVector3<Element> operator+( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
324 return vector3_added( self, other );
326 template<typename Element, typename OtherElement>
327 inline void vector3_add( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
328 self.x() += static_cast<Element>( other.x() );
329 self.y() += static_cast<Element>( other.y() );
330 self.z() += static_cast<Element>( other.z() );
332 template<typename Element, typename OtherElement>
333 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
334 vector3_add( self, other );
337 template<typename Element, typename OtherElement>
338 inline BasicVector3<Element> vector3_subtracted( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
339 return BasicVector3<Element>(
340 Element( self.x() - other.x() ),
341 Element( self.y() - other.y() ),
342 Element( self.z() - other.z() )
345 template<typename Element, typename OtherElement>
346 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
347 return vector3_subtracted( self, other );
349 template<typename Element, typename OtherElement>
350 inline void vector3_subtract( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
351 self.x() -= static_cast<Element>( other.x() );
352 self.y() -= static_cast<Element>( other.y() );
353 self.z() -= static_cast<Element>( other.z() );
355 template<typename Element, typename OtherElement>
356 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
357 vector3_subtract( self, other );
360 template<typename Element, typename OtherElement>
361 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
362 return BasicVector3<Element>(
363 Element( self.x() * other.x() ),
364 Element( self.y() * other.y() ),
365 Element( self.z() * other.z() )
368 template<typename Element, typename OtherElement>
369 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
370 return vector3_scaled( self, other );
372 template<typename Element, typename OtherElement>
373 inline void vector3_scale( 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 ){
380 vector3_scale( self, other );
383 template<typename Element, typename OtherElement>
384 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const OtherElement& scale ){
385 return BasicVector3<Element>(
386 Element( self.x() * scale ),
387 Element( self.y() * scale ),
388 Element( self.z() * scale )
391 template<typename Element, typename OtherElement>
392 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
393 return vector3_scaled( self, scale );
395 template<typename Element, typename OtherElement>
396 inline void vector3_scale( BasicVector3<Element>& self, const OtherElement& scale ){
397 self.x() *= static_cast<Element>( scale );
398 self.y() *= static_cast<Element>( scale );
399 self.z() *= static_cast<Element>( scale );
401 template<typename Element, typename OtherElement>
402 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
403 vector3_scale( self, scale );
406 template<typename Element, typename OtherElement>
407 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
408 return BasicVector3<Element>(
409 Element( self.x() / other.x() ),
410 Element( self.y() / other.y() ),
411 Element( self.z() / other.z() )
414 template<typename Element, typename OtherElement>
415 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
416 return vector3_divided( self, other );
418 template<typename Element, typename OtherElement>
419 inline void vector3_divide( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
420 self.x() /= static_cast<Element>( other.x() );
421 self.y() /= static_cast<Element>( other.y() );
422 self.z() /= static_cast<Element>( other.z() );
424 template<typename Element, typename OtherElement>
425 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
426 vector3_divide( self, other );
429 template<typename Element, typename OtherElement>
430 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const OtherElement& divisor ){
431 return BasicVector3<Element>(
432 Element( self.x() / divisor ),
433 Element( self.y() / divisor ),
434 Element( self.z() / divisor )
437 template<typename Element, typename OtherElement>
438 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
439 return vector3_divided( self, divisor );
441 template<typename Element, typename OtherElement>
442 inline void vector3_divide( BasicVector3<Element>& self, const OtherElement& divisor ){
443 self.x() /= static_cast<Element>( divisor );
444 self.y() /= static_cast<Element>( divisor );
445 self.z() /= static_cast<Element>( divisor );
447 template<typename Element, typename OtherElement>
448 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
449 vector3_divide( self, divisor );
452 template<typename Element, typename OtherElement>
453 inline double vector3_dot( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
454 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
457 template<typename Element>
458 inline BasicVector3<Element> vector3_mid( const BasicVector3<Element>& begin, const BasicVector3<Element>& end ){
459 return vector3_scaled( vector3_added( begin, end ), 0.5 );
462 template<typename Element, typename OtherElement>
463 inline BasicVector3<Element> vector3_cross( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
464 return BasicVector3<Element>(
465 Element( self.y() * other.z() - self.z() * other.y() ),
466 Element( self.z() * other.x() - self.x() * other.z() ),
467 Element( self.x() * other.y() - self.y() * other.x() )
471 template<typename Element>
472 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
473 return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
475 template<typename Element>
476 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
477 return vector3_negated( self );
480 template<typename Element>
481 inline void vector3_negate( BasicVector3<Element>& self ){
482 self = vector3_negated( self );
485 template<typename Element>
486 inline double vector3_length_squared( const BasicVector3<Element>& self ){
487 return vector3_dot( self, self );
490 template<typename Element>
491 inline double vector3_length( const BasicVector3<Element>& self ){
492 return sqrt( vector3_length_squared( self ) );
495 template<typename Element>
496 inline Element float_divided( Element f, Element other ){
497 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
501 template<typename Element>
502 inline BasicVector3<Element> vector3_normalised( const BasicVector3<Element>& self ){
503 return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) );
506 template<typename Element>
507 inline void vector3_normalise( BasicVector3<Element>& self ){
508 self = vector3_normalised( self );
512 template<typename Element>
513 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self ){
514 return BasicVector3<Element>(
515 Element( float_to_integer( self.x() ) ),
516 Element( float_to_integer( self.y() ) ),
517 Element( float_to_integer( self.z() ) )
520 template<typename Element>
521 inline void vector3_snap( BasicVector3<Element>& self ){
522 self = vector3_snapped( self );
524 template<typename Element, typename OtherElement>
525 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self, const OtherElement& snap ){
526 return BasicVector3<Element>(
527 Element( float_snapped( self.x(), snap ) ),
528 Element( float_snapped( self.y(), snap ) ),
529 Element( float_snapped( self.z(), snap ) )
532 template<typename Element, typename OtherElement>
533 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
534 self = vector3_snapped( self, snap );
537 inline Vector3 vector3_for_spherical( double theta, double phi ){
539 static_cast<float>( cos( theta ) * cos( phi ) ),
540 static_cast<float>( sin( theta ) * cos( phi ) ),
541 static_cast<float>( sin( phi ) )
548 template<typename Element, typename OtherElement>
549 inline bool vector4_equal( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
550 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
552 template<typename Element, typename OtherElement>
553 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
554 return vector4_equal( self, other );
556 template<typename Element, typename OtherElement>
557 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
558 return !vector4_equal( self, other );
561 template<typename Element, typename OtherElement>
562 inline bool vector4_equal_epsilon( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon ){
563 return float_equal_epsilon( self.x(), other.x(), epsilon )
564 && float_equal_epsilon( self.y(), other.y(), epsilon )
565 && float_equal_epsilon( self.z(), other.z(), epsilon )
566 && float_equal_epsilon( self.w(), other.w(), epsilon );
569 template<typename Element, typename OtherElement>
570 inline BasicVector4<Element> vector4_added( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
571 return BasicVector4<Element>(
572 float(self.x() + other.x() ),
573 float(self.y() + other.y() ),
574 float(self.z() + other.z() ),
575 float(self.w() + other.w() )
578 template<typename Element, typename OtherElement>
579 inline BasicVector4<Element> operator+( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
580 return vector4_added( self, other );
582 template<typename Element, typename OtherElement>
583 inline void vector4_add( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
584 self.x() += static_cast<float>( other.x() );
585 self.y() += static_cast<float>( other.y() );
586 self.z() += static_cast<float>( other.z() );
587 self.w() += static_cast<float>( other.w() );
589 template<typename Element, typename OtherElement>
590 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
591 vector4_add( self, other );
594 template<typename Element, typename OtherElement>
595 inline BasicVector4<Element> vector4_subtracted( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
596 return BasicVector4<Element>(
597 float(self.x() - other.x() ),
598 float(self.y() - other.y() ),
599 float(self.z() - other.z() ),
600 float(self.w() - other.w() )
603 template<typename Element, typename OtherElement>
604 inline BasicVector4<Element> operator-( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
605 return vector4_subtracted( self, other );
607 template<typename Element, typename OtherElement>
608 inline void vector4_subtract( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
609 self.x() -= static_cast<float>( other.x() );
610 self.y() -= static_cast<float>( other.y() );
611 self.z() -= static_cast<float>( other.z() );
612 self.w() -= static_cast<float>( other.w() );
614 template<typename Element, typename OtherElement>
615 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
616 vector4_subtract( self, other );
619 template<typename Element, typename OtherElement>
620 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
621 return BasicVector4<Element>(
622 float(self.x() * other.x() ),
623 float(self.y() * other.y() ),
624 float(self.z() * other.z() ),
625 float(self.w() * other.w() )
628 template<typename Element, typename OtherElement>
629 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
630 return vector4_scaled( self, other );
632 template<typename Element, typename OtherElement>
633 inline void vector4_scale( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
634 self.x() *= static_cast<float>( other.x() );
635 self.y() *= static_cast<float>( other.y() );
636 self.z() *= static_cast<float>( other.z() );
637 self.w() *= static_cast<float>( other.w() );
639 template<typename Element, typename OtherElement>
640 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
641 vector4_scale( self, other );
644 template<typename Element, typename OtherElement>
645 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, OtherElement scale ){
646 return BasicVector4<Element>(
647 float(self.x() * scale),
648 float(self.y() * scale),
649 float(self.z() * scale),
650 float(self.w() * scale)
653 template<typename Element, typename OtherElement>
654 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
655 return vector4_scaled( self, scale );
657 template<typename Element, typename OtherElement>
658 inline void vector4_scale( BasicVector4<Element>& self, OtherElement scale ){
659 self.x() *= static_cast<float>( scale );
660 self.y() *= static_cast<float>( scale );
661 self.z() *= static_cast<float>( scale );
662 self.w() *= static_cast<float>( scale );
664 template<typename Element, typename OtherElement>
665 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
666 vector4_scale( self, scale );
669 template<typename Element, typename OtherElement>
670 inline BasicVector4<Element> vector4_divided( const BasicVector4<Element>& self, OtherElement divisor ){
671 return BasicVector4<Element>(
672 float(self.x() / divisor),
673 float(self.y() / divisor),
674 float(self.z() / divisor),
675 float(self.w() / divisor)
678 template<typename Element, typename OtherElement>
679 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
680 return vector4_divided( self, divisor );
682 template<typename Element, typename OtherElement>
683 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
689 template<typename Element, typename OtherElement>
690 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
691 vector4_divide( self, divisor );
694 template<typename Element, typename OtherElement>
695 inline double vector4_dot( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
696 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
699 template<typename Element>
700 inline BasicVector3<Element> vector4_projected( const BasicVector4<Element>& self ){
701 return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] );