]> git.xonotic.org Git - xonotic/netradiant.git/blob - libs/math/vector.h
Merge commit 'a8f1237884e3741541e891724fbae07f8ff7d3b8' into master-merge
[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_COMPILER_GNU
50
51 // lrint is part of ISO C99
52 #define _ISOC9X_SOURCE  1
53 #define _ISOC99_SOURCE  1
54
55 #define __USE_ISOC9X    1
56 #define __USE_ISOC99    1
57
58 #else
59 #error "unsupported platform"
60 #endif
61
62 #include <cmath>
63 #include <float.h>
64 #include <algorithm>
65
66
67 //#include "debugging/debugging.h"
68
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;
73 }
74
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 );
79 }
80
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 ){
84         return lrint( f );
85 }
86
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);
91         if ( snap == 0 ) {
92                 return f;
93         }
94         return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
95 }
96
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 ) );
101 }
102
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 );
108 }
109
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 );
114 }
115
116
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() )
122                            );
123 }
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 );
127 }
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() );
132 }
133 template<typename Element, typename OtherElement>
134 inline void operator+=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
135         vector2_add( self, other );
136 }
137
138
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() )
144                            );
145 }
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 );
149 }
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() );
154 }
155 template<typename Element, typename OtherElement>
156 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
157         vector2_subtract( self, other );
158 }
159
160
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 )
166                            );
167 }
168 template<typename Element, typename OtherElement>
169 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
170         return vector2_scaled( self, other );
171 }
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 );
176 }
177 template<typename Element, typename OtherElement>
178 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
179         vector2_scale( self, other );
180 }
181
182
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() )
188                            );
189 }
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 );
193 }
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() );
198 }
199 template<typename Element, typename OtherElement>
200 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
201         vector2_scale( self, other );
202 }
203
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() )
209                            );
210 }
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 );
214 }
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() );
219 }
220 template<typename Element, typename OtherElement>
221 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
222         vector2_divide( self, other );
223 }
224
225
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 )
231                            );
232 }
233 template<typename Element, typename OtherElement>
234 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
235         return vector2_divided( self, other );
236 }
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 );
241 }
242 template<typename Element, typename OtherElement>
243 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
244         vector2_divide( self, other );
245 }
246
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();
250 }
251
252 template<typename Element>
253 inline double vector2_length_squared( const BasicVector2<Element>& self ){
254         return vector2_dot( self, self );
255 }
256
257 template<typename Element>
258 inline double vector2_length( const BasicVector2<Element>& self ){
259         return sqrt( vector2_length_squared( self ) );
260 }
261
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();
265 }
266
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 );
272
273 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
274
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() );
280 }
281
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();
285 }
286 template<typename Element, typename OtherElement>
287 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
288         return vector3_equal( self, other );
289 }
290 template<typename Element, typename OtherElement>
291 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
292         return !vector3_equal( self, other );
293 }
294
295
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 );
301 }
302
303
304
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() )
311                            );
312 }
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 );
316 }
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() );
322 }
323 template<typename Element, typename OtherElement>
324 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
325         vector3_add( self, other );
326 }
327
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() )
334                            );
335 }
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 );
339 }
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() );
345 }
346 template<typename Element, typename OtherElement>
347 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
348         vector3_subtract( self, other );
349 }
350
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() )
357                            );
358 }
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 );
362 }
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() );
368 }
369 template<typename Element, typename OtherElement>
370 inline void operator*=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
371         vector3_scale( self, other );
372 }
373
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 )
380                            );
381 }
382 template<typename Element, typename OtherElement>
383 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
384         return vector3_scaled( self, scale );
385 }
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 );
391 }
392 template<typename Element, typename OtherElement>
393 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
394         vector3_scale( self, scale );
395 }
396
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() )
403                            );
404 }
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 );
408 }
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() );
414 }
415 template<typename Element, typename OtherElement>
416 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
417         vector3_divide( self, other );
418 }
419
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 )
426                            );
427 }
428 template<typename Element, typename OtherElement>
429 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
430         return vector3_divided( self, divisor );
431 }
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 );
437 }
438 template<typename Element, typename OtherElement>
439 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
440         vector3_divide( self, divisor );
441 }
442
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();
446 }
447
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 );
451 }
452
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() )
459                            );
460 }
461
462 template<typename Element>
463 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
464         return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
465 }
466 template<typename Element>
467 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
468         return vector3_negated( self );
469 }
470
471 template<typename Element>
472 inline void vector3_negate( BasicVector3<Element>& self ){
473         self = vector3_negated( self );
474 }
475
476 template<typename Element>
477 inline double vector3_length_squared( const BasicVector3<Element>& self ){
478         return vector3_dot( self, self );
479 }
480
481 template<typename Element>
482 inline double vector3_length( const BasicVector3<Element>& self ){
483         return sqrt( vector3_length_squared( self ) );
484 }
485
486 template<typename Element>
487 inline Element float_divided( Element f, Element other ){
488         //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
489         return f / other;
490 }
491
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 ) ) );
495 }
496
497 template<typename Element>
498 inline void vector3_normalise( BasicVector3<Element>& self ){
499         self = vector3_normalised( self );
500 }
501
502
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() ) )
509                            );
510 }
511 template<typename Element>
512 inline void vector3_snap( BasicVector3<Element>& self ){
513         self = vector3_snapped( self );
514 }
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 ) )
521                            );
522 }
523 template<typename Element, typename OtherElement>
524 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
525         self = vector3_snapped( self, snap );
526 }
527
528 inline Vector3 vector3_for_spherical( double theta, double phi ){
529         return Vector3(
530                            static_cast<float>( cos( theta ) * cos( phi ) ),
531                            static_cast<float>( sin( theta ) * cos( phi ) ),
532                            static_cast<float>( sin( phi ) )
533                            );
534 }
535
536
537
538
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();
542 }
543 template<typename Element, typename OtherElement>
544 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
545         return vector4_equal( self, other );
546 }
547 template<typename Element, typename OtherElement>
548 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
549         return !vector4_equal( self, other );
550 }
551
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 );
558 }
559
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() )
567                            );
568 }
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 );
572 }
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() );
579 }
580 template<typename Element, typename OtherElement>
581 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
582         vector4_add( self, other );
583 }
584
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() )
592                            );
593 }
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 );
597 }
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() );
604 }
605 template<typename Element, typename OtherElement>
606 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
607         vector4_subtract( self, other );
608 }
609
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() )
617                            );
618 }
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 );
622 }
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() );
629 }
630 template<typename Element, typename OtherElement>
631 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
632         vector4_scale( self, other );
633 }
634
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)
642                            );
643 }
644 template<typename Element, typename OtherElement>
645 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
646         return vector4_scaled( self, scale );
647 }
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 );
654 }
655 template<typename Element, typename OtherElement>
656 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
657         vector4_scale( self, scale );
658 }
659
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)
667                            );
668 }
669 template<typename Element, typename OtherElement>
670 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
671         return vector4_divided( self, divisor );
672 }
673 template<typename Element, typename OtherElement>
674 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
675         self.x() /= divisor;
676         self.y() /= divisor;
677         self.z() /= divisor;
678         self.w() /= divisor;
679 }
680 template<typename Element, typename OtherElement>
681 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
682         vector4_divide( self, divisor );
683 }
684
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();
688 }
689
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] );
693 }
694
695 #endif