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 );
49 #elif GDEF_COMPILER_GNU
51 // lrint is part of ISO C99
52 #define _ISOC9X_SOURCE 1
53 #define _ISOC99_SOURCE 1
55 #define __USE_ISOC9X 1
56 #define __USE_ISOC99 1
59 #error "unsupported platform"
67 //#include "debugging/debugging.h"
69 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
70 template<typename Element, typename OtherElement>
71 inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){
72 return fabs( other - self ) < epsilon;
75 /// \brief Returns the value midway between \p self and \p other.
76 template<typename Element>
77 inline Element float_mid( const Element& self, const Element& other ){
78 return Element( ( self + other ) * 0.5 );
81 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
82 template<typename Element>
83 inline int float_to_integer( const Element& f ){
87 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
88 template<typename Element, typename OtherElement>
89 inline Element float_snapped( const Element& f, const OtherElement& snap ){
90 //return Element(float_to_integer(f / snap) * snap);
94 return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
97 /// \brief Returns true if \p f has no decimal fraction part.
98 template<typename Element>
99 inline bool float_is_integer( const Element& f ){
100 return f == Element( float_to_integer( f ) );
103 /// \brief Returns \p self modulated by the range [0, \p modulus)
104 /// \p self must be in the range [\p -modulus, \p modulus)
105 template<typename Element, typename ModulusElement>
106 inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){
107 return Element( ( self < 0.0 ) ? self + modulus : self );
110 /// \brief Returns \p self modulated by the range [0, \p modulus)
111 template<typename Element, typename ModulusElement>
112 inline Element float_mod( const Element& self, const ModulusElement& modulus ){
113 return float_mod_range( Element( fmod( static_cast<double>( self ), static_cast<double>( modulus ) ) ), modulus );
117 template<typename Element, typename OtherElement>
118 inline BasicVector2<Element> vector2_added( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
119 return BasicVector2<Element>(
120 Element( self.x() + other.x() ),
121 Element( self.y() + other.y() )
124 template<typename Element, typename OtherElement>
125 inline BasicVector2<Element> operator+( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
126 return vector2_added( self, other );
128 template<typename Element, typename OtherElement>
129 inline void vector2_add( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
130 self.x() += Element( other.x() );
131 self.y() += Element( other.y() );
133 template<typename Element, typename OtherElement>
134 inline void operator+=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
135 vector2_add( self, other );
139 template<typename Element, typename OtherElement>
140 inline BasicVector2<Element> vector2_subtracted( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
141 return BasicVector2<Element>(
142 Element( self.x() - other.x() ),
143 Element( self.y() - other.y() )
146 template<typename Element, typename OtherElement>
147 inline BasicVector2<Element> operator-( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
148 return vector2_subtracted( self, other );
150 template<typename Element, typename OtherElement>
151 inline void vector2_subtract( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
152 self.x() -= Element( other.x() );
153 self.y() -= lement( other.y() );
155 template<typename Element, typename OtherElement>
156 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
157 vector2_subtract( self, other );
161 template<typename Element, typename OtherElement>
162 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, OtherElement other ){
163 return BasicVector2<Element>(
164 Element( self.x() * other ),
165 Element( self.y() * other )
168 template<typename Element, typename OtherElement>
169 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
170 return vector2_scaled( self, other );
172 template<typename Element, typename OtherElement>
173 inline void vector2_scale( BasicVector2<Element>& self, OtherElement other ){
174 self.x() *= Element( other );
175 self.y() *= Element( other );
177 template<typename Element, typename OtherElement>
178 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
179 vector2_scale( self, other );
183 template<typename Element, typename OtherElement>
184 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
185 return BasicVector2<Element>(
186 Element( self.x() * other.x() ),
187 Element( self.y() * other.y() )
190 template<typename Element, typename OtherElement>
191 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
192 return vector2_scaled( self, other );
194 template<typename Element, typename OtherElement>
195 inline void vector2_scale( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
196 self.x() *= Element( other.x() );
197 self.y() *= Element( other.y() );
199 template<typename Element, typename OtherElement>
200 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
201 vector2_scale( self, other );
204 template<typename Element, typename OtherElement>
205 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
206 return BasicVector2<Element>(
207 Element( self.x() / other.x() ),
208 Element( self.y() / other.y() )
211 template<typename Element, typename OtherElement>
212 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
213 return vector2_divided( self, other );
215 template<typename Element, typename OtherElement>
216 inline void vector2_divide( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
217 self.x() /= Element( other.x() );
218 self.y() /= Element( other.y() );
220 template<typename Element, typename OtherElement>
221 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
222 vector2_divide( self, other );
226 template<typename Element, typename OtherElement>
227 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, OtherElement other ){
228 return BasicVector2<Element>(
229 Element( self.x() / other ),
230 Element( self.y() / other )
233 template<typename Element, typename OtherElement>
234 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
235 return vector2_divided( self, other );
237 template<typename Element, typename OtherElement>
238 inline void vector2_divide( BasicVector2<Element>& self, OtherElement other ){
239 self.x() /= Element( other );
240 self.y() /= Element( other );
242 template<typename Element, typename OtherElement>
243 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
244 vector2_divide( self, other );
247 template<typename Element, typename OtherElement>
248 inline double vector2_dot( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
249 return self.x() * other.x() + self.y() * other.y();
252 template<typename Element>
253 inline double vector2_length_squared( const BasicVector2<Element>& self ){
254 return vector2_dot( self, self );
257 template<typename Element>
258 inline double vector2_length( const BasicVector2<Element>& self ){
259 return sqrt( vector2_length_squared( self ) );
262 template<typename Element, typename OtherElement>
263 inline double vector2_cross( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
264 return self.x() * other.y() - self.y() * other.x();
267 const Vector3 g_vector3_identity( 0, 0, 0 );
268 const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX );
269 const Vector3 g_vector3_axis_x( 1, 0, 0 );
270 const Vector3 g_vector3_axis_y( 0, 1, 0 );
271 const Vector3 g_vector3_axis_z( 0, 0, 1 );
273 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
275 template<typename Element, typename OtherElement>
276 inline void vector3_swap( BasicVector3<Element>& self, BasicVector3<OtherElement>& other ){
277 std::swap( self.x(), other.x() );
278 std::swap( self.y(), other.y() );
279 std::swap( self.z(), other.z() );
282 template<typename Element, typename OtherElement>
283 inline bool vector3_equal( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
284 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
286 template<typename Element, typename OtherElement>
287 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
288 return vector3_equal( self, other );
290 template<typename Element, typename OtherElement>
291 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
292 return !vector3_equal( self, other );
296 template<typename Element, typename OtherElement, typename Epsilon>
297 inline bool vector3_equal_epsilon( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon ){
298 return float_equal_epsilon( self.x(), other.x(), epsilon )
299 && float_equal_epsilon( self.y(), other.y(), epsilon )
300 && float_equal_epsilon( self.z(), other.z(), epsilon );
305 template<typename Element, typename OtherElement>
306 inline BasicVector3<Element> vector3_added( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
307 return BasicVector3<Element>(
308 Element( self.x() + other.x() ),
309 Element( self.y() + other.y() ),
310 Element( self.z() + other.z() )
313 template<typename Element, typename OtherElement>
314 inline BasicVector3<Element> operator+( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
315 return vector3_added( self, other );
317 template<typename Element, typename OtherElement>
318 inline void vector3_add( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
319 self.x() += static_cast<Element>( other.x() );
320 self.y() += static_cast<Element>( other.y() );
321 self.z() += static_cast<Element>( other.z() );
323 template<typename Element, typename OtherElement>
324 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
325 vector3_add( self, other );
328 template<typename Element, typename OtherElement>
329 inline BasicVector3<Element> vector3_subtracted( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
330 return BasicVector3<Element>(
331 Element( self.x() - other.x() ),
332 Element( self.y() - other.y() ),
333 Element( self.z() - other.z() )
336 template<typename Element, typename OtherElement>
337 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
338 return vector3_subtracted( self, other );
340 template<typename Element, typename OtherElement>
341 inline void vector3_subtract( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
342 self.x() -= static_cast<Element>( other.x() );
343 self.y() -= static_cast<Element>( other.y() );
344 self.z() -= static_cast<Element>( other.z() );
346 template<typename Element, typename OtherElement>
347 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
348 vector3_subtract( self, other );
351 template<typename Element, typename OtherElement>
352 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
353 return BasicVector3<Element>(
354 Element( self.x() * other.x() ),
355 Element( self.y() * other.y() ),
356 Element( self.z() * other.z() )
359 template<typename Element, typename OtherElement>
360 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
361 return vector3_scaled( self, other );
363 template<typename Element, typename OtherElement>
364 inline void vector3_scale( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
365 self.x() *= static_cast<Element>( other.x() );
366 self.y() *= static_cast<Element>( other.y() );
367 self.z() *= static_cast<Element>( other.z() );
369 template<typename Element, typename OtherElement>
370 inline void operator*=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
371 vector3_scale( self, other );
374 template<typename Element, typename OtherElement>
375 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const OtherElement& scale ){
376 return BasicVector3<Element>(
377 Element( self.x() * scale ),
378 Element( self.y() * scale ),
379 Element( self.z() * scale )
382 template<typename Element, typename OtherElement>
383 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
384 return vector3_scaled( self, scale );
386 template<typename Element, typename OtherElement>
387 inline void vector3_scale( BasicVector3<Element>& self, const OtherElement& scale ){
388 self.x() *= static_cast<Element>( scale );
389 self.y() *= static_cast<Element>( scale );
390 self.z() *= static_cast<Element>( scale );
392 template<typename Element, typename OtherElement>
393 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
394 vector3_scale( self, scale );
397 template<typename Element, typename OtherElement>
398 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
399 return BasicVector3<Element>(
400 Element( self.x() / other.x() ),
401 Element( self.y() / other.y() ),
402 Element( self.z() / other.z() )
405 template<typename Element, typename OtherElement>
406 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
407 return vector3_divided( self, other );
409 template<typename Element, typename OtherElement>
410 inline void vector3_divide( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
411 self.x() /= static_cast<Element>( other.x() );
412 self.y() /= static_cast<Element>( other.y() );
413 self.z() /= static_cast<Element>( other.z() );
415 template<typename Element, typename OtherElement>
416 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
417 vector3_divide( self, other );
420 template<typename Element, typename OtherElement>
421 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const OtherElement& divisor ){
422 return BasicVector3<Element>(
423 Element( self.x() / divisor ),
424 Element( self.y() / divisor ),
425 Element( self.z() / divisor )
428 template<typename Element, typename OtherElement>
429 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
430 return vector3_divided( self, divisor );
432 template<typename Element, typename OtherElement>
433 inline void vector3_divide( BasicVector3<Element>& self, const OtherElement& divisor ){
434 self.x() /= static_cast<Element>( divisor );
435 self.y() /= static_cast<Element>( divisor );
436 self.z() /= static_cast<Element>( divisor );
438 template<typename Element, typename OtherElement>
439 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
440 vector3_divide( self, divisor );
443 template<typename Element, typename OtherElement>
444 inline double vector3_dot( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
445 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
448 template<typename Element>
449 inline BasicVector3<Element> vector3_mid( const BasicVector3<Element>& begin, const BasicVector3<Element>& end ){
450 return vector3_scaled( vector3_added( begin, end ), 0.5 );
453 template<typename Element, typename OtherElement>
454 inline BasicVector3<Element> vector3_cross( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
455 return BasicVector3<Element>(
456 Element( self.y() * other.z() - self.z() * other.y() ),
457 Element( self.z() * other.x() - self.x() * other.z() ),
458 Element( self.x() * other.y() - self.y() * other.x() )
462 template<typename Element>
463 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
464 return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
466 template<typename Element>
467 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
468 return vector3_negated( self );
471 template<typename Element>
472 inline void vector3_negate( BasicVector3<Element>& self ){
473 self = vector3_negated( self );
476 template<typename Element>
477 inline double vector3_length_squared( const BasicVector3<Element>& self ){
478 return vector3_dot( self, self );
481 template<typename Element>
482 inline double vector3_length( const BasicVector3<Element>& self ){
483 return sqrt( vector3_length_squared( self ) );
486 template<typename Element>
487 inline Element float_divided( Element f, Element other ){
488 //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
492 template<typename Element>
493 inline BasicVector3<Element> vector3_normalised( const BasicVector3<Element>& self ){
494 return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) );
497 template<typename Element>
498 inline void vector3_normalise( BasicVector3<Element>& self ){
499 self = vector3_normalised( self );
503 template<typename Element>
504 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self ){
505 return BasicVector3<Element>(
506 Element( float_to_integer( self.x() ) ),
507 Element( float_to_integer( self.y() ) ),
508 Element( float_to_integer( self.z() ) )
511 template<typename Element>
512 inline void vector3_snap( BasicVector3<Element>& self ){
513 self = vector3_snapped( self );
515 template<typename Element, typename OtherElement>
516 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self, const OtherElement& snap ){
517 return BasicVector3<Element>(
518 Element( float_snapped( self.x(), snap ) ),
519 Element( float_snapped( self.y(), snap ) ),
520 Element( float_snapped( self.z(), snap ) )
523 template<typename Element, typename OtherElement>
524 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
525 self = vector3_snapped( self, snap );
528 inline Vector3 vector3_for_spherical( double theta, double phi ){
530 static_cast<float>( cos( theta ) * cos( phi ) ),
531 static_cast<float>( sin( theta ) * cos( phi ) ),
532 static_cast<float>( sin( phi ) )
539 template<typename Element, typename OtherElement>
540 inline bool vector4_equal( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
541 return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
543 template<typename Element, typename OtherElement>
544 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
545 return vector4_equal( self, other );
547 template<typename Element, typename OtherElement>
548 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
549 return !vector4_equal( self, other );
552 template<typename Element, typename OtherElement>
553 inline bool vector4_equal_epsilon( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon ){
554 return float_equal_epsilon( self.x(), other.x(), epsilon )
555 && float_equal_epsilon( self.y(), other.y(), epsilon )
556 && float_equal_epsilon( self.z(), other.z(), epsilon )
557 && float_equal_epsilon( self.w(), other.w(), epsilon );
560 template<typename Element, typename OtherElement>
561 inline BasicVector4<Element> vector4_added( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
562 return BasicVector4<Element>(
563 float(self.x() + other.x() ),
564 float(self.y() + other.y() ),
565 float(self.z() + other.z() ),
566 float(self.w() + other.w() )
569 template<typename Element, typename OtherElement>
570 inline BasicVector4<Element> operator+( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
571 return vector4_added( self, other );
573 template<typename Element, typename OtherElement>
574 inline void vector4_add( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
575 self.x() += static_cast<float>( other.x() );
576 self.y() += static_cast<float>( other.y() );
577 self.z() += static_cast<float>( other.z() );
578 self.w() += static_cast<float>( other.w() );
580 template<typename Element, typename OtherElement>
581 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
582 vector4_add( self, other );
585 template<typename Element, typename OtherElement>
586 inline BasicVector4<Element> vector4_subtracted( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
587 return BasicVector4<Element>(
588 float(self.x() - other.x() ),
589 float(self.y() - other.y() ),
590 float(self.z() - other.z() ),
591 float(self.w() - other.w() )
594 template<typename Element, typename OtherElement>
595 inline BasicVector4<Element> operator-( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
596 return vector4_subtracted( self, other );
598 template<typename Element, typename OtherElement>
599 inline void vector4_subtract( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
600 self.x() -= static_cast<float>( other.x() );
601 self.y() -= static_cast<float>( other.y() );
602 self.z() -= static_cast<float>( other.z() );
603 self.w() -= static_cast<float>( other.w() );
605 template<typename Element, typename OtherElement>
606 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
607 vector4_subtract( self, other );
610 template<typename Element, typename OtherElement>
611 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
612 return BasicVector4<Element>(
613 float(self.x() * other.x() ),
614 float(self.y() * other.y() ),
615 float(self.z() * other.z() ),
616 float(self.w() * other.w() )
619 template<typename Element, typename OtherElement>
620 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
621 return vector4_scaled( self, other );
623 template<typename Element, typename OtherElement>
624 inline void vector4_scale( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
625 self.x() *= static_cast<float>( other.x() );
626 self.y() *= static_cast<float>( other.y() );
627 self.z() *= static_cast<float>( other.z() );
628 self.w() *= static_cast<float>( other.w() );
630 template<typename Element, typename OtherElement>
631 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
632 vector4_scale( self, other );
635 template<typename Element, typename OtherElement>
636 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, OtherElement scale ){
637 return BasicVector4<Element>(
638 float(self.x() * scale),
639 float(self.y() * scale),
640 float(self.z() * scale),
641 float(self.w() * scale)
644 template<typename Element, typename OtherElement>
645 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
646 return vector4_scaled( self, scale );
648 template<typename Element, typename OtherElement>
649 inline void vector4_scale( BasicVector4<Element>& self, OtherElement scale ){
650 self.x() *= static_cast<float>( scale );
651 self.y() *= static_cast<float>( scale );
652 self.z() *= static_cast<float>( scale );
653 self.w() *= static_cast<float>( scale );
655 template<typename Element, typename OtherElement>
656 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
657 vector4_scale( self, scale );
660 template<typename Element, typename OtherElement>
661 inline BasicVector4<Element> vector4_divided( const BasicVector4<Element>& self, OtherElement divisor ){
662 return BasicVector4<Element>(
663 float(self.x() / divisor),
664 float(self.y() / divisor),
665 float(self.z() / divisor),
666 float(self.w() / divisor)
669 template<typename Element, typename OtherElement>
670 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
671 return vector4_divided( self, divisor );
673 template<typename Element, typename OtherElement>
674 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
680 template<typename Element, typename OtherElement>
681 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
682 vector4_divide( self, divisor );
685 template<typename Element, typename OtherElement>
686 inline double vector4_dot( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
687 return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
690 template<typename Element>
691 inline BasicVector3<Element> vector4_projected( const BasicVector4<Element>& self ){
692 return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] );