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