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"
29 #include "globaldefs.h"
31 #if GDEF_COMPILER_MSVC
33 inline int lrint( double flt ){
45 inline __int64 llrint( double f ){
46 return static_cast<__int64>( f + 0.5 );
51 inline long lrint( double f ){
52 return static_cast<long>( f + 0.5 );
55 inline long long llrint( double f ){
56 return static_cast<long long>( f + 0.5 );
59 #elif GDEF_COMPILER_GNU
61 // lrint is part of ISO C99
62 #define _ISOC9X_SOURCE 1
63 #define _ISOC99_SOURCE 1
65 #define __USE_ISOC9X 1
66 #define __USE_ISOC99 1
69 #error "unsupported platform"
77 //#include "debugging/debugging.h"
79 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
80 template<typename Element, typename OtherElement>
81 inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){
82 return fabs( other - self ) < epsilon;
85 /// \brief Returns the value midway between \p self and \p other.
86 template<typename Element>
87 inline Element float_mid( const Element& self, const Element& other ){
88 return Element( ( self + other ) * 0.5 );
91 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
92 template<typename Element>
93 inline int float_to_integer( const Element& f ){
97 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
98 template<typename Element, typename OtherElement>
99 inline Element float_snapped( const Element& f, const OtherElement& snap ){
100 //return Element(float_to_integer(f / snap) * snap);
104 return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
107 /// \brief Returns true if \p f has no decimal fraction part.
108 template<typename Element>
109 inline bool float_is_integer( const Element& f ){
110 return f == Element( float_to_integer( f ) );
113 /// \brief Returns \p self modulated by the range [0, \p modulus)
114 /// \p self must be in the range [\p -modulus, \p modulus)
115 template<typename Element, typename ModulusElement>
116 inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){
117 return Element( ( self < 0.0 ) ? self + modulus : self );
120 /// \brief Returns \p self modulated by the range [0, \p modulus)
121 template<typename Element, typename ModulusElement>
122 inline Element float_mod( const Element& self, const ModulusElement& modulus ){
123 return float_mod_range( Element( fmod( static_cast<double>( self ), static_cast<double>( modulus ) ) ), modulus );
127 template<typename Element, typename OtherElement>
128 inline BasicVector2<Element> vector2_added( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
129 return BasicVector2<Element>(
130 Element( self.x() + other.x() ),
131 Element( self.y() + other.y() )
134 template<typename Element, typename OtherElement>
135 inline BasicVector2<Element> operator+( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
136 return vector2_added( self, other );
138 template<typename Element, typename OtherElement>
139 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 ){
145 vector2_add( self, other );
149 template<typename Element, typename OtherElement>
150 inline BasicVector2<Element> vector2_subtracted( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
151 return BasicVector2<Element>(
152 Element( self.x() - other.x() ),
153 Element( self.y() - other.y() )
156 template<typename Element, typename OtherElement>
157 inline BasicVector2<Element> operator-( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
158 return vector2_subtracted( self, other );
160 template<typename Element, typename OtherElement>
161 inline void vector2_subtract( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
162 self.x() -= Element( other.x() );
163 self.y() -= lement( other.y() );
165 template<typename Element, typename OtherElement>
166 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
167 vector2_subtract( self, other );
171 template<typename Element, typename OtherElement>
172 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, OtherElement other ){
173 return BasicVector2<Element>(
174 Element( self.x() * other ),
175 Element( self.y() * other )
178 template<typename Element, typename OtherElement>
179 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
180 return vector2_scaled( self, other );
182 template<typename Element, typename OtherElement>
183 inline void vector2_scale( BasicVector2<Element>& self, OtherElement other ){
184 self.x() *= Element( other );
185 self.y() *= Element( other );
187 template<typename Element, typename OtherElement>
188 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
189 vector2_scale( self, other );
193 template<typename Element, typename OtherElement>
194 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
195 return BasicVector2<Element>(
196 Element( self.x() * other.x() ),
197 Element( self.y() * other.y() )
200 template<typename Element, typename OtherElement>
201 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
202 return vector2_scaled( self, other );
204 template<typename Element, typename OtherElement>
205 inline void vector2_scale( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
206 self.x() *= Element( other.x() );
207 self.y() *= Element( other.y() );
209 template<typename Element, typename OtherElement>
210 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
211 vector2_scale( self, other );
214 template<typename Element, typename OtherElement>
215 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
216 return BasicVector2<Element>(
217 Element( self.x() / other.x() ),
218 Element( self.y() / other.y() )
221 template<typename Element, typename OtherElement>
222 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
223 return vector2_divided( self, other );
225 template<typename Element, typename OtherElement>
226 inline void vector2_divide( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
227 self.x() /= Element( other.x() );
228 self.y() /= Element( other.y() );
230 template<typename Element, typename OtherElement>
231 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
232 vector2_divide( self, other );
236 template<typename Element, typename OtherElement>
237 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, OtherElement other ){
238 return BasicVector2<Element>(
239 Element( self.x() / other ),
240 Element( self.y() / other )
243 template<typename Element, typename OtherElement>
244 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
245 return vector2_divided( self, other );
247 template<typename Element, typename OtherElement>
248 inline void vector2_divide( BasicVector2<Element>& self, OtherElement other ){
249 self.x() /= Element( other );
250 self.y() /= Element( other );
252 template<typename Element, typename OtherElement>
253 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
254 vector2_divide( self, other );
257 template<typename Element, typename OtherElement>
258 inline double vector2_dot( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
259 return self.x() * other.x() + self.y() * other.y();
262 template<typename Element>
263 inline double vector2_length_squared( const BasicVector2<Element>& self ){
264 return vector2_dot( self, self );
267 template<typename Element>
268 inline double vector2_length( const BasicVector2<Element>& self ){
269 return sqrt( vector2_length_squared( self ) );
272 template<typename Element, typename OtherElement>
273 inline double vector2_cross( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
274 return self.x() * other.y() - self.y() * other.x();
277 const Vector3 g_vector3_identity( 0, 0, 0 );
278 const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX );
279 const Vector3 g_vector3_axis_x( 1, 0, 0 );
280 const Vector3 g_vector3_axis_y( 0, 1, 0 );
281 const Vector3 g_vector3_axis_z( 0, 0, 1 );
283 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
285 template<typename Element, typename OtherElement>
286 inline void vector3_swap( BasicVector3<Element>& self, BasicVector3<OtherElement>& other ){
287 std::swap( self.x(), other.x() );
288 std::swap( self.y(), other.y() );
289 std::swap( self.z(), other.z() );
292 template<typename Element, typename OtherElement>
293 inline bool vector3_equal( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
294 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
296 template<typename Element, typename OtherElement>
297 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
298 return vector3_equal( self, other );
300 template<typename Element, typename OtherElement>
301 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
302 return !vector3_equal( self, other );
306 template<typename Element, typename OtherElement, typename Epsilon>
307 inline bool vector3_equal_epsilon( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon ){
308 return float_equal_epsilon( self.x(), other.x(), epsilon )
309 && float_equal_epsilon( self.y(), other.y(), epsilon )
310 && float_equal_epsilon( self.z(), other.z(), epsilon );
315 template<typename Element, typename OtherElement>
316 inline BasicVector3<Element> vector3_added( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
317 return BasicVector3<Element>(
318 Element( self.x() + other.x() ),
319 Element( self.y() + other.y() ),
320 Element( self.z() + other.z() )
323 template<typename Element, typename OtherElement>
324 inline BasicVector3<Element> operator+( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
325 return vector3_added( self, other );
327 template<typename Element, typename OtherElement>
328 inline void vector3_add( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
329 self.x() += static_cast<Element>( other.x() );
330 self.y() += static_cast<Element>( other.y() );
331 self.z() += static_cast<Element>( other.z() );
333 template<typename Element, typename OtherElement>
334 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
335 vector3_add( self, other );
338 template<typename Element, typename OtherElement>
339 inline BasicVector3<Element> vector3_subtracted( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
340 return BasicVector3<Element>(
341 Element( self.x() - other.x() ),
342 Element( self.y() - other.y() ),
343 Element( self.z() - other.z() )
346 template<typename Element, typename OtherElement>
347 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
348 return vector3_subtracted( self, other );
350 template<typename Element, typename OtherElement>
351 inline void vector3_subtract( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
352 self.x() -= static_cast<Element>( other.x() );
353 self.y() -= static_cast<Element>( other.y() );
354 self.z() -= static_cast<Element>( other.z() );
356 template<typename Element, typename OtherElement>
357 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
358 vector3_subtract( self, other );
361 template<typename Element, typename OtherElement>
362 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
363 return BasicVector3<Element>(
364 Element( self.x() * other.x() ),
365 Element( self.y() * other.y() ),
366 Element( self.z() * other.z() )
369 template<typename Element, typename OtherElement>
370 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
371 return vector3_scaled( self, other );
373 template<typename Element, typename OtherElement>
374 inline void vector3_scale( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
375 self.x() *= static_cast<Element>( other.x() );
376 self.y() *= static_cast<Element>( other.y() );
377 self.z() *= static_cast<Element>( other.z() );
379 template<typename Element, typename OtherElement>
380 inline void operator*=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
381 vector3_scale( self, other );
384 template<typename Element, typename OtherElement>
385 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const OtherElement& scale ){
386 return BasicVector3<Element>(
387 Element( self.x() * scale ),
388 Element( self.y() * scale ),
389 Element( self.z() * scale )
392 template<typename Element, typename OtherElement>
393 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
394 return vector3_scaled( self, scale );
396 template<typename Element, typename OtherElement>
397 inline void vector3_scale( BasicVector3<Element>& self, const OtherElement& scale ){
398 self.x() *= static_cast<Element>( scale );
399 self.y() *= static_cast<Element>( scale );
400 self.z() *= static_cast<Element>( scale );
402 template<typename Element, typename OtherElement>
403 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
404 vector3_scale( self, scale );
407 template<typename Element, typename OtherElement>
408 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
409 return BasicVector3<Element>(
410 Element( self.x() / other.x() ),
411 Element( self.y() / other.y() ),
412 Element( self.z() / other.z() )
415 template<typename Element, typename OtherElement>
416 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
417 return vector3_divided( self, other );
419 template<typename Element, typename OtherElement>
420 inline void vector3_divide( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
421 self.x() /= static_cast<Element>( other.x() );
422 self.y() /= static_cast<Element>( other.y() );
423 self.z() /= static_cast<Element>( other.z() );
425 template<typename Element, typename OtherElement>
426 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
427 vector3_divide( self, other );
430 template<typename Element, typename OtherElement>
431 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const OtherElement& divisor ){
432 return BasicVector3<Element>(
433 Element( self.x() / divisor ),
434 Element( self.y() / divisor ),
435 Element( self.z() / divisor )
438 template<typename Element, typename OtherElement>
439 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
440 return vector3_divided( self, divisor );
442 template<typename Element, typename OtherElement>
443 inline void vector3_divide( BasicVector3<Element>& self, const OtherElement& divisor ){
444 self.x() /= static_cast<Element>( divisor );
445 self.y() /= static_cast<Element>( divisor );
446 self.z() /= static_cast<Element>( divisor );
448 template<typename Element, typename OtherElement>
449 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
450 vector3_divide( self, divisor );
453 template<typename Element, typename OtherElement>
454 inline double vector3_dot( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
455 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
458 template<typename Element>
459 inline BasicVector3<Element> vector3_mid( const BasicVector3<Element>& begin, const BasicVector3<Element>& end ){
460 return vector3_scaled( vector3_added( begin, end ), 0.5 );
463 template<typename Element, typename OtherElement>
464 inline BasicVector3<Element> vector3_cross( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
465 return BasicVector3<Element>(
466 Element( self.y() * other.z() - self.z() * other.y() ),
467 Element( self.z() * other.x() - self.x() * other.z() ),
468 Element( self.x() * other.y() - self.y() * other.x() )
472 template<typename Element>
473 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
474 return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
476 template<typename Element>
477 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
478 return vector3_negated( self );
481 template<typename Element>
482 inline void vector3_negate( BasicVector3<Element>& self ){
483 self = vector3_negated( self );
486 template<typename Element>
487 inline double vector3_length_squared( const BasicVector3<Element>& self ){
488 return vector3_dot( self, self );
491 template<typename Element>
492 inline double vector3_length( const BasicVector3<Element>& self ){
493 return sqrt( vector3_length_squared( self ) );
496 template<typename Element>
497 inline Element float_divided( Element f, Element other ){
498 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
502 template<typename Element>
503 inline BasicVector3<Element> vector3_normalised( const BasicVector3<Element>& self ){
504 return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) );
507 template<typename Element>
508 inline void vector3_normalise( BasicVector3<Element>& self ){
509 self = vector3_normalised( self );
513 template<typename Element>
514 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self ){
515 return BasicVector3<Element>(
516 Element( float_to_integer( self.x() ) ),
517 Element( float_to_integer( self.y() ) ),
518 Element( float_to_integer( self.z() ) )
521 template<typename Element>
522 inline void vector3_snap( BasicVector3<Element>& self ){
523 self = vector3_snapped( self );
525 template<typename Element, typename OtherElement>
526 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self, const OtherElement& snap ){
527 return BasicVector3<Element>(
528 Element( float_snapped( self.x(), snap ) ),
529 Element( float_snapped( self.y(), snap ) ),
530 Element( float_snapped( self.z(), snap ) )
533 template<typename Element, typename OtherElement>
534 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
535 self = vector3_snapped( self, snap );
538 inline Vector3 vector3_for_spherical( double theta, double phi ){
540 static_cast<float>( cos( theta ) * cos( phi ) ),
541 static_cast<float>( sin( theta ) * cos( phi ) ),
542 static_cast<float>( sin( phi ) )
549 template<typename Element, typename OtherElement>
550 inline bool vector4_equal( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
551 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
553 template<typename Element, typename OtherElement>
554 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
555 return vector4_equal( self, other );
557 template<typename Element, typename OtherElement>
558 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
559 return !vector4_equal( self, other );
562 template<typename Element, typename OtherElement>
563 inline bool vector4_equal_epsilon( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon ){
564 return float_equal_epsilon( self.x(), other.x(), epsilon )
565 && float_equal_epsilon( self.y(), other.y(), epsilon )
566 && float_equal_epsilon( self.z(), other.z(), epsilon )
567 && float_equal_epsilon( self.w(), other.w(), epsilon );
570 template<typename Element, typename OtherElement>
571 inline BasicVector4<Element> vector4_added( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
572 return BasicVector4<Element>(
573 float(self.x() + other.x() ),
574 float(self.y() + other.y() ),
575 float(self.z() + other.z() ),
576 float(self.w() + other.w() )
579 template<typename Element, typename OtherElement>
580 inline BasicVector4<Element> operator+( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
581 return vector4_added( self, other );
583 template<typename Element, typename OtherElement>
584 inline void vector4_add( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
585 self.x() += static_cast<float>( other.x() );
586 self.y() += static_cast<float>( other.y() );
587 self.z() += static_cast<float>( other.z() );
588 self.w() += static_cast<float>( other.w() );
590 template<typename Element, typename OtherElement>
591 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
592 vector4_add( self, other );
595 template<typename Element, typename OtherElement>
596 inline BasicVector4<Element> vector4_subtracted( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
597 return BasicVector4<Element>(
598 float(self.x() - other.x() ),
599 float(self.y() - other.y() ),
600 float(self.z() - other.z() ),
601 float(self.w() - other.w() )
604 template<typename Element, typename OtherElement>
605 inline BasicVector4<Element> operator-( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
606 return vector4_subtracted( self, other );
608 template<typename Element, typename OtherElement>
609 inline void vector4_subtract( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
610 self.x() -= static_cast<float>( other.x() );
611 self.y() -= static_cast<float>( other.y() );
612 self.z() -= static_cast<float>( other.z() );
613 self.w() -= static_cast<float>( other.w() );
615 template<typename Element, typename OtherElement>
616 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
617 vector4_subtract( self, other );
620 template<typename Element, typename OtherElement>
621 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
622 return BasicVector4<Element>(
623 float(self.x() * other.x() ),
624 float(self.y() * other.y() ),
625 float(self.z() * other.z() ),
626 float(self.w() * other.w() )
629 template<typename Element, typename OtherElement>
630 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
631 return vector4_scaled( self, other );
633 template<typename Element, typename OtherElement>
634 inline void vector4_scale( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
635 self.x() *= static_cast<float>( other.x() );
636 self.y() *= static_cast<float>( other.y() );
637 self.z() *= static_cast<float>( other.z() );
638 self.w() *= static_cast<float>( other.w() );
640 template<typename Element, typename OtherElement>
641 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
642 vector4_scale( self, other );
645 template<typename Element, typename OtherElement>
646 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, OtherElement scale ){
647 return BasicVector4<Element>(
648 float(self.x() * scale),
649 float(self.y() * scale),
650 float(self.z() * scale),
651 float(self.w() * scale)
654 template<typename Element, typename OtherElement>
655 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
656 return vector4_scaled( self, scale );
658 template<typename Element, typename OtherElement>
659 inline void vector4_scale( BasicVector4<Element>& self, OtherElement scale ){
660 self.x() *= static_cast<float>( scale );
661 self.y() *= static_cast<float>( scale );
662 self.z() *= static_cast<float>( scale );
663 self.w() *= static_cast<float>( scale );
665 template<typename Element, typename OtherElement>
666 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
667 vector4_scale( self, scale );
670 template<typename Element, typename OtherElement>
671 inline BasicVector4<Element> vector4_divided( const BasicVector4<Element>& self, OtherElement divisor ){
672 return BasicVector4<Element>(
673 float(self.x() / divisor),
674 float(self.y() / divisor),
675 float(self.z() / divisor),
676 float(self.w() / divisor)
679 template<typename Element, typename OtherElement>
680 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
681 return vector4_divided( self, divisor );
683 template<typename Element, typename OtherElement>
684 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
690 template<typename Element, typename OtherElement>
691 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
692 vector4_divide( self, divisor );
695 template<typename Element, typename OtherElement>
696 inline double vector4_dot( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
697 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
700 template<typename Element>
701 inline BasicVector3<Element> vector4_projected( const BasicVector4<Element>& self ){
702 return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] );