]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/math/vector.h
Merge branch 'fix-fast' into 'master'
[xonotic/netradiant.git] / libs / math / vector.h
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
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.
11
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.
16
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
20  */
21
22 #if !defined( INCLUDED_MATH_VECTOR_H )
23 #define INCLUDED_MATH_VECTOR_H
24
25 /// \file
26 /// \brief Vector data types and related operations.
27
28 #include "generic/vector.h"
29 #include "globaldefs.h"
30
31 #if GDEF_COMPILER_MSVC
32
33 inline int lrint( double flt ){
34         int i;
35
36         _asm
37         {
38                 fld flt
39                 fistp i
40         };
41
42         return i;
43 }
44
45 inline __int64 llrint( double f ){
46         return static_cast<__int64>( f + 0.5 );
47 }
48
49 #elif GDEF_OS_BSD
50
51 inline long lrint( double f ){
52         return static_cast<long>( f + 0.5 );
53 }
54
55 inline long long llrint( double f ){
56         return static_cast<long long>( f + 0.5 );
57 }
58
59 #elif GDEF_COMPILER_GNU
60
61 // lrint is part of ISO C99
62 #define _ISOC9X_SOURCE  1
63 #define _ISOC99_SOURCE  1
64
65 #define __USE_ISOC9X    1
66 #define __USE_ISOC99    1
67
68 #else
69 #error "unsupported platform"
70 #endif
71
72 #include <cmath>
73 #include <float.h>
74 #include <algorithm>
75
76
77 //#include "debugging/debugging.h"
78
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;
83 }
84
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 );
89 }
90
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 ){
94         return lrint( f );
95 }
96
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);
101         if ( snap == 0 ) {
102                 return f;
103         }
104         return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
105 }
106
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 ) );
111 }
112
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 );
118 }
119
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 );
124 }
125
126
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() )
132                            );
133 }
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 );
137 }
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() );
142 }
143 template<typename Element, typename OtherElement>
144 inline void operator+=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
145         vector2_add( self, other );
146 }
147
148
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() )
154                            );
155 }
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 );
159 }
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() );
164 }
165 template<typename Element, typename OtherElement>
166 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
167         vector2_subtract( self, other );
168 }
169
170
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 )
176                            );
177 }
178 template<typename Element, typename OtherElement>
179 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
180         return vector2_scaled( self, other );
181 }
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 );
186 }
187 template<typename Element, typename OtherElement>
188 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
189         vector2_scale( self, other );
190 }
191
192
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() )
198                            );
199 }
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 );
203 }
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() );
208 }
209 template<typename Element, typename OtherElement>
210 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
211         vector2_scale( self, other );
212 }
213
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() )
219                            );
220 }
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 );
224 }
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() );
229 }
230 template<typename Element, typename OtherElement>
231 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
232         vector2_divide( self, other );
233 }
234
235
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 )
241                            );
242 }
243 template<typename Element, typename OtherElement>
244 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
245         return vector2_divided( self, other );
246 }
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 );
251 }
252 template<typename Element, typename OtherElement>
253 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
254         vector2_divide( self, other );
255 }
256
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();
260 }
261
262 template<typename Element>
263 inline double vector2_length_squared( const BasicVector2<Element>& self ){
264         return vector2_dot( self, self );
265 }
266
267 template<typename Element>
268 inline double vector2_length( const BasicVector2<Element>& self ){
269         return sqrt( vector2_length_squared( self ) );
270 }
271
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();
275 }
276
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 );
282
283 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
284
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() );
290 }
291
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();
295 }
296 template<typename Element, typename OtherElement>
297 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
298         return vector3_equal( self, other );
299 }
300 template<typename Element, typename OtherElement>
301 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
302         return !vector3_equal( self, other );
303 }
304
305
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 );
311 }
312
313
314
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() )
321                            );
322 }
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 );
326 }
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() );
332 }
333 template<typename Element, typename OtherElement>
334 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
335         vector3_add( self, other );
336 }
337
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() )
344                            );
345 }
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 );
349 }
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() );
355 }
356 template<typename Element, typename OtherElement>
357 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
358         vector3_subtract( self, other );
359 }
360
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() )
367                            );
368 }
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 );
372 }
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() );
378 }
379 template<typename Element, typename OtherElement>
380 inline void operator*=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
381         vector3_scale( self, other );
382 }
383
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 )
390                            );
391 }
392 template<typename Element, typename OtherElement>
393 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
394         return vector3_scaled( self, scale );
395 }
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 );
401 }
402 template<typename Element, typename OtherElement>
403 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
404         vector3_scale( self, scale );
405 }
406
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() )
413                            );
414 }
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 );
418 }
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() );
424 }
425 template<typename Element, typename OtherElement>
426 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
427         vector3_divide( self, other );
428 }
429
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 )
436                            );
437 }
438 template<typename Element, typename OtherElement>
439 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
440         return vector3_divided( self, divisor );
441 }
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 );
447 }
448 template<typename Element, typename OtherElement>
449 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
450         vector3_divide( self, divisor );
451 }
452
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();
456 }
457
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 );
461 }
462
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() )
469                            );
470 }
471
472 template<typename Element>
473 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
474         return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
475 }
476 template<typename Element>
477 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
478         return vector3_negated( self );
479 }
480
481 template<typename Element>
482 inline void vector3_negate( BasicVector3<Element>& self ){
483         self = vector3_negated( self );
484 }
485
486 template<typename Element>
487 inline double vector3_length_squared( const BasicVector3<Element>& self ){
488         return vector3_dot( self, self );
489 }
490
491 template<typename Element>
492 inline double vector3_length( const BasicVector3<Element>& self ){
493         return sqrt( vector3_length_squared( self ) );
494 }
495
496 template<typename Element>
497 inline Element float_divided( Element f, Element other ){
498         //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
499         return f / other;
500 }
501
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 ) ) );
505 }
506
507 template<typename Element>
508 inline void vector3_normalise( BasicVector3<Element>& self ){
509         self = vector3_normalised( self );
510 }
511
512
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() ) )
519                            );
520 }
521 template<typename Element>
522 inline void vector3_snap( BasicVector3<Element>& self ){
523         self = vector3_snapped( self );
524 }
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 ) )
531                            );
532 }
533 template<typename Element, typename OtherElement>
534 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
535         self = vector3_snapped( self, snap );
536 }
537
538 inline Vector3 vector3_for_spherical( double theta, double phi ){
539         return Vector3(
540                            static_cast<float>( cos( theta ) * cos( phi ) ),
541                            static_cast<float>( sin( theta ) * cos( phi ) ),
542                            static_cast<float>( sin( phi ) )
543                            );
544 }
545
546
547
548
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();
552 }
553 template<typename Element, typename OtherElement>
554 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
555         return vector4_equal( self, other );
556 }
557 template<typename Element, typename OtherElement>
558 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
559         return !vector4_equal( self, other );
560 }
561
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 );
568 }
569
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() )
577                            );
578 }
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 );
582 }
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() );
589 }
590 template<typename Element, typename OtherElement>
591 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
592         vector4_add( self, other );
593 }
594
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() )
602                            );
603 }
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 );
607 }
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() );
614 }
615 template<typename Element, typename OtherElement>
616 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
617         vector4_subtract( self, other );
618 }
619
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() )
627                            );
628 }
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 );
632 }
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() );
639 }
640 template<typename Element, typename OtherElement>
641 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
642         vector4_scale( self, other );
643 }
644
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)
652                            );
653 }
654 template<typename Element, typename OtherElement>
655 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
656         return vector4_scaled( self, scale );
657 }
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 );
664 }
665 template<typename Element, typename OtherElement>
666 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
667         vector4_scale( self, scale );
668 }
669
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)
677                            );
678 }
679 template<typename Element, typename OtherElement>
680 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
681         return vector4_divided( self, divisor );
682 }
683 template<typename Element, typename OtherElement>
684 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
685         self.x() /= divisor;
686         self.y() /= divisor;
687         self.z() /= divisor;
688         self.w() /= divisor;
689 }
690 template<typename Element, typename OtherElement>
691 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
692         vector4_divide( self, divisor );
693 }
694
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();
698 }
699
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] );
703 }
704
705 #endif