]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/math/vector.h
Merge remote-tracking branch 'ttimo/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
30 #if defined ( _MSC_VER )
31
32 inline int lrint( double flt ){
33         int i;
34
35         _asm
36         {
37                 fld flt
38                 fistp i
39         };
40
41         return i;
42 }
43
44 inline __int64 llrint( double f ){
45         return static_cast<__int64>( f + 0.5 );
46 }
47
48 #elif defined( __FreeBSD__ )
49
50 inline long lrint( double f ){
51         return static_cast<long>( f + 0.5 );
52 }
53
54 inline long long llrint( double f ){
55         return static_cast<long long>( f + 0.5 );
56 }
57
58 #elif defined( __GNUC__ )
59
60 // lrint is part of ISO C99
61 #define _ISOC9X_SOURCE  1
62 #define _ISOC99_SOURCE  1
63
64 #define __USE_ISOC9X    1
65 #define __USE_ISOC99    1
66
67 #else
68 #error "unsupported platform"
69 #endif
70
71 #include <cmath>
72 #include <float.h>
73 #include <algorithm>
74
75
76 //#include "debugging/debugging.h"
77
78 /// \brief Returns true if \p self is equal to other \p other within \p epsilon.
79 template<typename Element, typename OtherElement>
80 inline bool float_equal_epsilon( const Element& self, const OtherElement& other, const Element& epsilon ){
81         return fabs( other - self ) < epsilon;
82 }
83
84 /// \brief Returns the value midway between \p self and \p other.
85 template<typename Element>
86 inline Element float_mid( const Element& self, const Element& other ){
87         return Element( ( self + other ) * 0.5 );
88 }
89
90 /// \brief Returns \p f rounded to the nearest integer. Note that this is not the same behaviour as casting from float to int.
91 template<typename Element>
92 inline int float_to_integer( const Element& f ){
93         return lrint( f );
94 }
95
96 /// \brief Returns \p f rounded to the nearest multiple of \p snap.
97 template<typename Element, typename OtherElement>
98 inline Element float_snapped( const Element& f, const OtherElement& snap ){
99         //return Element(float_to_integer(f / snap) * snap);
100         if ( snap == 0 ) {
101                 return f;
102         }
103         return Element( llrint( f / snap ) * snap ); // llrint has more significant bits
104 }
105
106 /// \brief Returns true if \p f has no decimal fraction part.
107 template<typename Element>
108 inline bool float_is_integer( const Element& f ){
109         return f == Element( float_to_integer( f ) );
110 }
111
112 /// \brief Returns \p self modulated by the range [0, \p modulus)
113 /// \p self must be in the range [\p -modulus, \p modulus)
114 template<typename Element, typename ModulusElement>
115 inline Element float_mod_range( const Element& self, const ModulusElement& modulus ){
116         return Element( ( self < 0.0 ) ? self + modulus : self );
117 }
118
119 /// \brief Returns \p self modulated by the range [0, \p modulus)
120 template<typename Element, typename ModulusElement>
121 inline Element float_mod( const Element& self, const ModulusElement& modulus ){
122         return float_mod_range( Element( fmod( static_cast<double>( self ), static_cast<double>( modulus ) ) ), modulus );
123 }
124
125
126 template<typename Element, typename OtherElement>
127 inline BasicVector2<Element> vector2_added( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
128         return BasicVector2<Element>(
129                            Element( self.x() + other.x() ),
130                            Element( self.y() + other.y() )
131                            );
132 }
133 template<typename Element, typename OtherElement>
134 inline BasicVector2<Element> operator+( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
135         return vector2_added( self, other );
136 }
137 template<typename Element, typename OtherElement>
138 inline void vector2_add( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
139         self.x() += Element( other.x() );
140         self.y() += Element( other.y() );
141 }
142 template<typename Element, typename OtherElement>
143 inline void operator+=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
144         vector2_add( self, other );
145 }
146
147
148 template<typename Element, typename OtherElement>
149 inline BasicVector2<Element> vector2_subtracted( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
150         return BasicVector2<Element>(
151                            Element( self.x() - other.x() ),
152                            Element( self.y() - other.y() )
153                            );
154 }
155 template<typename Element, typename OtherElement>
156 inline BasicVector2<Element> operator-( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
157         return vector2_subtracted( self, other );
158 }
159 template<typename Element, typename OtherElement>
160 inline void vector2_subtract( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
161         self.x() -= Element( other.x() );
162         self.y() -= lement( other.y() );
163 }
164 template<typename Element, typename OtherElement>
165 inline void operator-=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
166         vector2_subtract( self, other );
167 }
168
169
170 template<typename Element, typename OtherElement>
171 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, OtherElement other ){
172         return BasicVector2<Element>(
173                            Element( self.x() * other ),
174                            Element( self.y() * other )
175                            );
176 }
177 template<typename Element, typename OtherElement>
178 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, OtherElement other ){
179         return vector2_scaled( self, other );
180 }
181 template<typename Element, typename OtherElement>
182 inline void vector2_scale( BasicVector2<Element>& self, OtherElement other ){
183         self.x() *= Element( other );
184         self.y() *= Element( other );
185 }
186 template<typename Element, typename OtherElement>
187 inline void operator*=( BasicVector2<Element>& self, OtherElement other ){
188         vector2_scale( self, other );
189 }
190
191
192 template<typename Element, typename OtherElement>
193 inline BasicVector2<Element> vector2_scaled( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
194         return BasicVector2<Element>(
195                            Element( self.x() * other.x() ),
196                            Element( self.y() * other.y() )
197                            );
198 }
199 template<typename Element, typename OtherElement>
200 inline BasicVector2<Element> operator*( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
201         return vector2_scaled( self, other );
202 }
203 template<typename Element, typename OtherElement>
204 inline void vector2_scale( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
205         self.x() *= Element( other.x() );
206         self.y() *= Element( other.y() );
207 }
208 template<typename Element, typename OtherElement>
209 inline void operator*=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
210         vector2_scale( self, other );
211 }
212
213 template<typename Element, typename OtherElement>
214 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
215         return BasicVector2<Element>(
216                            Element( self.x() / other.x() ),
217                            Element( self.y() / other.y() )
218                            );
219 }
220 template<typename Element, typename OtherElement>
221 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
222         return vector2_divided( self, other );
223 }
224 template<typename Element, typename OtherElement>
225 inline void vector2_divide( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
226         self.x() /= Element( other.x() );
227         self.y() /= Element( other.y() );
228 }
229 template<typename Element, typename OtherElement>
230 inline void operator/=( BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
231         vector2_divide( self, other );
232 }
233
234
235 template<typename Element, typename OtherElement>
236 inline BasicVector2<Element> vector2_divided( const BasicVector2<Element>& self, OtherElement other ){
237         return BasicVector2<Element>(
238                            Element( self.x() / other ),
239                            Element( self.y() / other )
240                            );
241 }
242 template<typename Element, typename OtherElement>
243 inline BasicVector2<Element> operator/( const BasicVector2<Element>& self, OtherElement other ){
244         return vector2_divided( self, other );
245 }
246 template<typename Element, typename OtherElement>
247 inline void vector2_divide( BasicVector2<Element>& self, OtherElement other ){
248         self.x() /= Element( other );
249         self.y() /= Element( other );
250 }
251 template<typename Element, typename OtherElement>
252 inline void operator/=( BasicVector2<Element>& self, OtherElement other ){
253         vector2_divide( self, other );
254 }
255
256 template<typename Element, typename OtherElement>
257 inline double vector2_dot( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
258         return self.x() * other.x() + self.y() * other.y();
259 }
260
261 template<typename Element>
262 inline double vector2_length_squared( const BasicVector2<Element>& self ){
263         return vector2_dot( self, self );
264 }
265
266 template<typename Element>
267 inline double vector2_length( const BasicVector2<Element>& self ){
268         return sqrt( vector2_length_squared( self ) );
269 }
270
271 template<typename Element, typename OtherElement>
272 inline double vector2_cross( const BasicVector2<Element>& self, const BasicVector2<OtherElement>& other ){
273         return self.x() * other.y() - self.y() * other.x();
274 }
275
276 const Vector3 g_vector3_identity( 0, 0, 0 );
277 const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX );
278 const Vector3 g_vector3_axis_x( 1, 0, 0 );
279 const Vector3 g_vector3_axis_y( 0, 1, 0 );
280 const Vector3 g_vector3_axis_z( 0, 0, 1 );
281
282 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
283
284 template<typename Element, typename OtherElement>
285 inline void vector3_swap( BasicVector3<Element>& self, BasicVector3<OtherElement>& other ){
286         std::swap( self.x(), other.x() );
287         std::swap( self.y(), other.y() );
288         std::swap( self.z(), other.z() );
289 }
290
291 template<typename Element, typename OtherElement>
292 inline bool vector3_equal( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
293         return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
294 }
295 template<typename Element, typename OtherElement>
296 inline bool operator==( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
297         return vector3_equal( self, other );
298 }
299 template<typename Element, typename OtherElement>
300 inline bool operator!=( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
301         return !vector3_equal( self, other );
302 }
303
304
305 template<typename Element, typename OtherElement, typename Epsilon>
306 inline bool vector3_equal_epsilon( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other, Epsilon epsilon ){
307         return float_equal_epsilon( self.x(), other.x(), epsilon )
308                    && float_equal_epsilon( self.y(), other.y(), epsilon )
309                    && float_equal_epsilon( self.z(), other.z(), epsilon );
310 }
311
312
313
314 template<typename Element, typename OtherElement>
315 inline BasicVector3<Element> vector3_added( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
316         return BasicVector3<Element>(
317                            Element( self.x() + other.x() ),
318                            Element( self.y() + other.y() ),
319                            Element( self.z() + other.z() )
320                            );
321 }
322 template<typename Element, typename OtherElement>
323 inline BasicVector3<Element> operator+( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
324         return vector3_added( self, other );
325 }
326 template<typename Element, typename OtherElement>
327 inline void vector3_add( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
328         self.x() += static_cast<Element>( other.x() );
329         self.y() += static_cast<Element>( other.y() );
330         self.z() += static_cast<Element>( other.z() );
331 }
332 template<typename Element, typename OtherElement>
333 inline void operator+=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
334         vector3_add( self, other );
335 }
336
337 template<typename Element, typename OtherElement>
338 inline BasicVector3<Element> vector3_subtracted( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
339         return BasicVector3<Element>(
340                            Element( self.x() - other.x() ),
341                            Element( self.y() - other.y() ),
342                            Element( self.z() - other.z() )
343                            );
344 }
345 template<typename Element, typename OtherElement>
346 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
347         return vector3_subtracted( self, other );
348 }
349 template<typename Element, typename OtherElement>
350 inline void vector3_subtract( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
351         self.x() -= static_cast<Element>( other.x() );
352         self.y() -= static_cast<Element>( other.y() );
353         self.z() -= static_cast<Element>( other.z() );
354 }
355 template<typename Element, typename OtherElement>
356 inline void operator-=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
357         vector3_subtract( self, other );
358 }
359
360 template<typename Element, typename OtherElement>
361 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
362         return BasicVector3<Element>(
363                            Element( self.x() * other.x() ),
364                            Element( self.y() * other.y() ),
365                            Element( self.z() * other.z() )
366                            );
367 }
368 template<typename Element, typename OtherElement>
369 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
370         return vector3_scaled( self, other );
371 }
372 template<typename Element, typename OtherElement>
373 inline void vector3_scale( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
374         self.x() *= static_cast<Element>( other.x() );
375         self.y() *= static_cast<Element>( other.y() );
376         self.z() *= static_cast<Element>( other.z() );
377 }
378 template<typename Element, typename OtherElement>
379 inline void operator*=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
380         vector3_scale( self, other );
381 }
382
383 template<typename Element, typename OtherElement>
384 inline BasicVector3<Element> vector3_scaled( const BasicVector3<Element>& self, const OtherElement& scale ){
385         return BasicVector3<Element>(
386                            Element( self.x() * scale ),
387                            Element( self.y() * scale ),
388                            Element( self.z() * scale )
389                            );
390 }
391 template<typename Element, typename OtherElement>
392 inline BasicVector3<Element> operator*( const BasicVector3<Element>& self, const OtherElement& scale ){
393         return vector3_scaled( self, scale );
394 }
395 template<typename Element, typename OtherElement>
396 inline void vector3_scale( BasicVector3<Element>& self, const OtherElement& scale ){
397         self.x() *= static_cast<Element>( scale );
398         self.y() *= static_cast<Element>( scale );
399         self.z() *= static_cast<Element>( scale );
400 }
401 template<typename Element, typename OtherElement>
402 inline void operator*=( BasicVector3<Element>& self, const OtherElement& scale ){
403         vector3_scale( self, scale );
404 }
405
406 template<typename Element, typename OtherElement>
407 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
408         return BasicVector3<Element>(
409                            Element( self.x() / other.x() ),
410                            Element( self.y() / other.y() ),
411                            Element( self.z() / other.z() )
412                            );
413 }
414 template<typename Element, typename OtherElement>
415 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
416         return vector3_divided( self, other );
417 }
418 template<typename Element, typename OtherElement>
419 inline void vector3_divide( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
420         self.x() /= static_cast<Element>( other.x() );
421         self.y() /= static_cast<Element>( other.y() );
422         self.z() /= static_cast<Element>( other.z() );
423 }
424 template<typename Element, typename OtherElement>
425 inline void operator/=( BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
426         vector3_divide( self, other );
427 }
428
429 template<typename Element, typename OtherElement>
430 inline BasicVector3<Element> vector3_divided( const BasicVector3<Element>& self, const OtherElement& divisor ){
431         return BasicVector3<Element>(
432                            Element( self.x() / divisor ),
433                            Element( self.y() / divisor ),
434                            Element( self.z() / divisor )
435                            );
436 }
437 template<typename Element, typename OtherElement>
438 inline BasicVector3<Element> operator/( const BasicVector3<Element>& self, const OtherElement& divisor ){
439         return vector3_divided( self, divisor );
440 }
441 template<typename Element, typename OtherElement>
442 inline void vector3_divide( BasicVector3<Element>& self, const OtherElement& divisor ){
443         self.x() /= static_cast<Element>( divisor );
444         self.y() /= static_cast<Element>( divisor );
445         self.z() /= static_cast<Element>( divisor );
446 }
447 template<typename Element, typename OtherElement>
448 inline void operator/=( BasicVector3<Element>& self, const OtherElement& divisor ){
449         vector3_divide( self, divisor );
450 }
451
452 template<typename Element, typename OtherElement>
453 inline double vector3_dot( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
454         return self.x() * other.x() + self.y() * other.y() + self.z() * other.z();
455 }
456
457 template<typename Element>
458 inline BasicVector3<Element> vector3_mid( const BasicVector3<Element>& begin, const BasicVector3<Element>& end ){
459         return vector3_scaled( vector3_added( begin, end ), 0.5 );
460 }
461
462 template<typename Element, typename OtherElement>
463 inline BasicVector3<Element> vector3_cross( const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other ){
464         return BasicVector3<Element>(
465                            Element( self.y() * other.z() - self.z() * other.y() ),
466                            Element( self.z() * other.x() - self.x() * other.z() ),
467                            Element( self.x() * other.y() - self.y() * other.x() )
468                            );
469 }
470
471 template<typename Element>
472 inline BasicVector3<Element> vector3_negated( const BasicVector3<Element>& self ){
473         return BasicVector3<Element>( -self.x(), -self.y(), -self.z() );
474 }
475 template<typename Element>
476 inline BasicVector3<Element> operator-( const BasicVector3<Element>& self ){
477         return vector3_negated( self );
478 }
479
480 template<typename Element>
481 inline void vector3_negate( BasicVector3<Element>& self ){
482         self = vector3_negated( self );
483 }
484
485 template<typename Element>
486 inline double vector3_length_squared( const BasicVector3<Element>& self ){
487         return vector3_dot( self, self );
488 }
489
490 template<typename Element>
491 inline double vector3_length( const BasicVector3<Element>& self ){
492         return sqrt( vector3_length_squared( self ) );
493 }
494
495 template<typename Element>
496 inline Element float_divided( Element f, Element other ){
497         //ASSERT_MESSAGE(other != 0, "float_divided: invalid divisor");
498         return f / other;
499 }
500
501 template<typename Element>
502 inline BasicVector3<Element> vector3_normalised( const BasicVector3<Element>& self ){
503         return vector3_scaled( self, float_divided( 1.0, vector3_length( self ) ) );
504 }
505
506 template<typename Element>
507 inline void vector3_normalise( BasicVector3<Element>& self ){
508         self = vector3_normalised( self );
509 }
510
511
512 template<typename Element>
513 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self ){
514         return BasicVector3<Element>(
515                            Element( float_to_integer( self.x() ) ),
516                            Element( float_to_integer( self.y() ) ),
517                            Element( float_to_integer( self.z() ) )
518                            );
519 }
520 template<typename Element>
521 inline void vector3_snap( BasicVector3<Element>& self ){
522         self = vector3_snapped( self );
523 }
524 template<typename Element, typename OtherElement>
525 inline BasicVector3<Element> vector3_snapped( const BasicVector3<Element>& self, const OtherElement& snap ){
526         return BasicVector3<Element>(
527                            Element( float_snapped( self.x(), snap ) ),
528                            Element( float_snapped( self.y(), snap ) ),
529                            Element( float_snapped( self.z(), snap ) )
530                            );
531 }
532 template<typename Element, typename OtherElement>
533 inline void vector3_snap( BasicVector3<Element>& self, const OtherElement& snap ){
534         self = vector3_snapped( self, snap );
535 }
536
537 inline Vector3 vector3_for_spherical( double theta, double phi ){
538         return Vector3(
539                            static_cast<float>( cos( theta ) * cos( phi ) ),
540                            static_cast<float>( sin( theta ) * cos( phi ) ),
541                            static_cast<float>( sin( phi ) )
542                            );
543 }
544
545
546
547
548 template<typename Element, typename OtherElement>
549 inline bool vector4_equal( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
550         return self.x() == other.x() && self.y() == other.y() && self.z() == other.z() && self.w() == other.w();
551 }
552 template<typename Element, typename OtherElement>
553 inline bool operator==( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
554         return vector4_equal( self, other );
555 }
556 template<typename Element, typename OtherElement>
557 inline bool operator!=( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
558         return !vector4_equal( self, other );
559 }
560
561 template<typename Element, typename OtherElement>
562 inline bool vector4_equal_epsilon( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other, Element epsilon ){
563         return float_equal_epsilon( self.x(), other.x(), epsilon )
564                    && float_equal_epsilon( self.y(), other.y(), epsilon )
565                    && float_equal_epsilon( self.z(), other.z(), epsilon )
566                    && float_equal_epsilon( self.w(), other.w(), epsilon );
567 }
568
569 template<typename Element, typename OtherElement>
570 inline BasicVector4<Element> vector4_added( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
571         return BasicVector4<Element>(
572                            float(self.x() + other.x() ),
573                            float(self.y() + other.y() ),
574                            float(self.z() + other.z() ),
575                            float(self.w() + other.w() )
576                            );
577 }
578 template<typename Element, typename OtherElement>
579 inline BasicVector4<Element> operator+( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
580         return vector4_added( self, other );
581 }
582 template<typename Element, typename OtherElement>
583 inline void vector4_add( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
584         self.x() += static_cast<float>( other.x() );
585         self.y() += static_cast<float>( other.y() );
586         self.z() += static_cast<float>( other.z() );
587         self.w() += static_cast<float>( other.w() );
588 }
589 template<typename Element, typename OtherElement>
590 inline void operator+=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
591         vector4_add( self, other );
592 }
593
594 template<typename Element, typename OtherElement>
595 inline BasicVector4<Element> vector4_subtracted( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
596         return BasicVector4<Element>(
597                            float(self.x() - other.x() ),
598                            float(self.y() - other.y() ),
599                            float(self.z() - other.z() ),
600                            float(self.w() - other.w() )
601                            );
602 }
603 template<typename Element, typename OtherElement>
604 inline BasicVector4<Element> operator-( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
605         return vector4_subtracted( self, other );
606 }
607 template<typename Element, typename OtherElement>
608 inline void vector4_subtract( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
609         self.x() -= static_cast<float>( other.x() );
610         self.y() -= static_cast<float>( other.y() );
611         self.z() -= static_cast<float>( other.z() );
612         self.w() -= static_cast<float>( other.w() );
613 }
614 template<typename Element, typename OtherElement>
615 inline void operator-=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
616         vector4_subtract( self, other );
617 }
618
619 template<typename Element, typename OtherElement>
620 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
621         return BasicVector4<Element>(
622                            float(self.x() * other.x() ),
623                            float(self.y() * other.y() ),
624                            float(self.z() * other.z() ),
625                            float(self.w() * other.w() )
626                            );
627 }
628 template<typename Element, typename OtherElement>
629 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
630         return vector4_scaled( self, other );
631 }
632 template<typename Element, typename OtherElement>
633 inline void vector4_scale( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
634         self.x() *= static_cast<float>( other.x() );
635         self.y() *= static_cast<float>( other.y() );
636         self.z() *= static_cast<float>( other.z() );
637         self.w() *= static_cast<float>( other.w() );
638 }
639 template<typename Element, typename OtherElement>
640 inline void operator*=( BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
641         vector4_scale( self, other );
642 }
643
644 template<typename Element, typename OtherElement>
645 inline BasicVector4<Element> vector4_scaled( const BasicVector4<Element>& self, OtherElement scale ){
646         return BasicVector4<Element>(
647                            float(self.x() * scale),
648                            float(self.y() * scale),
649                            float(self.z() * scale),
650                            float(self.w() * scale)
651                            );
652 }
653 template<typename Element, typename OtherElement>
654 inline BasicVector4<Element> operator*( const BasicVector4<Element>& self, OtherElement scale ){
655         return vector4_scaled( self, scale );
656 }
657 template<typename Element, typename OtherElement>
658 inline void vector4_scale( BasicVector4<Element>& self, OtherElement scale ){
659         self.x() *= static_cast<float>( scale );
660         self.y() *= static_cast<float>( scale );
661         self.z() *= static_cast<float>( scale );
662         self.w() *= static_cast<float>( scale );
663 }
664 template<typename Element, typename OtherElement>
665 inline void operator*=( BasicVector4<Element>& self, OtherElement scale ){
666         vector4_scale( self, scale );
667 }
668
669 template<typename Element, typename OtherElement>
670 inline BasicVector4<Element> vector4_divided( const BasicVector4<Element>& self, OtherElement divisor ){
671         return BasicVector4<Element>(
672                            float(self.x() / divisor),
673                            float(self.y() / divisor),
674                            float(self.z() / divisor),
675                            float(self.w() / divisor)
676                            );
677 }
678 template<typename Element, typename OtherElement>
679 inline BasicVector4<Element> operator/( const BasicVector4<Element>& self, OtherElement divisor ){
680         return vector4_divided( self, divisor );
681 }
682 template<typename Element, typename OtherElement>
683 inline void vector4_divide( BasicVector4<Element>& self, OtherElement divisor ){
684         self.x() /= divisor;
685         self.y() /= divisor;
686         self.z() /= divisor;
687         self.w() /= divisor;
688 }
689 template<typename Element, typename OtherElement>
690 inline void operator/=( BasicVector4<Element>& self, OtherElement divisor ){
691         vector4_divide( self, divisor );
692 }
693
694 template<typename Element, typename OtherElement>
695 inline double vector4_dot( const BasicVector4<Element>& self, const BasicVector4<OtherElement>& other ){
696         return self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w();
697 }
698
699 template<typename Element>
700 inline BasicVector3<Element> vector4_projected( const BasicVector4<Element>& self ){
701         return vector3_scaled( vector4_to_vector3( self ), 1.0 / self[3] );
702 }
703
704 #endif