00001 /* 00002 Copyright (c) 2010, The Cinder Project 00003 All rights reserved. 00004 00005 This code is designed for use with the Cinder C++ library, http://libcinder.org 00006 00007 Portions Copyright (c) 2010, The Barbarian Group 00008 All rights reserved. 00009 00010 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00011 the following conditions are met: 00012 00013 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00014 the following disclaimer. 00015 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00016 the following disclaimer in the documentation and/or other materials provided with the distribution. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00019 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00021 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00022 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00023 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00024 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #pragma once 00029 00030 #include <cmath> 00031 #include <cstring> 00032 #include <iostream> 00033 #include <cassert> 00034 #include <limits> 00035 00036 #include "cinder/CinderMath.h" 00037 00038 namespace cinder { 00039 00041 template<typename T> 00042 struct VECTRAIT { 00043 typedef float DIST; 00044 }; 00045 00046 template<> 00047 struct VECTRAIT<double> { 00048 typedef double DIST; 00049 }; 00050 00051 template<> 00052 struct VECTRAIT<int32_t> { 00053 typedef float DIST; 00054 }; 00055 00056 template<typename T, typename Y> 00057 struct VEC3CONV { 00058 static T getX( const Y &v ) { return static_cast<T>( v.x ); } 00059 static T getY( const Y &v ) { return static_cast<T>( v.y ); } 00060 static T getZ( const Y &v ) { return static_cast<T>( v.z ); } 00061 }; 00062 00064 00065 template<typename T> class Vec3; 00066 00067 template<typename T> 00068 class Vec2 00069 { 00070 public: 00071 T x,y; 00072 00073 typedef T TYPE; 00074 typedef typename VECTRAIT<T>::DIST DIST; 00075 static const int DIM = 2; 00076 00077 Vec2() {} 00078 Vec2( T nx, T ny ) : x( nx ), y( ny ) {} 00079 Vec2( const Vec2<T>& src ) : x( src.x ), y( src.y ) {} 00080 explicit Vec2( const T *d ) : x( d[0] ), y( d[1] ) {} 00081 00082 template<typename FromT> 00083 Vec2( const Vec2<FromT>& src ) 00084 : x( static_cast<T>( src.x ) ),y( static_cast<T>( src.y ) ) 00085 {} 00086 00087 void set( T ax, T ay ) 00088 { 00089 x = ax; y = ay; 00090 } 00091 00092 void set( const Vec2<T> &rhs ) 00093 { 00094 x = rhs.x; y = rhs.y; 00095 } 00096 00097 // Operators 00098 template<typename FromT> 00099 Vec2<T>& operator=( const Vec2<FromT>& rhs ) 00100 { 00101 x = static_cast<T>( rhs.x ); 00102 y = static_cast<T>( rhs.y ); 00103 return * this; 00104 } 00105 00106 Vec2<T>& operator=( const Vec2<T>& rhs ) 00107 { 00108 x = rhs.x; 00109 y = rhs.y; 00110 return * this; 00111 } 00112 00113 T& operator[]( int n ) 00114 { 00115 assert( n >= 0 && n <= 1 ); 00116 return (&x)[n]; 00117 } 00118 00119 const T& operator[]( int n ) const 00120 { 00121 assert( n >= 0 && n <= 1 ); 00122 return (&x)[n]; 00123 } 00124 00125 const Vec2<T> operator+( const Vec2<T>& rhs ) const { return Vec2<T>( x + rhs.x, y + rhs.y ); } 00126 const Vec2<T> operator-( const Vec2<T>& rhs ) const { return Vec2<T>( x - rhs.x, y - rhs.y ); } 00127 const Vec2<T> operator*( const Vec2<T>& rhs ) const { return Vec2<T>( x * rhs.x, y * rhs.y ); } 00128 const Vec2<T> operator/( const Vec2<T>& rhs ) const { return Vec2<T>( x / rhs.x, y / rhs.y ); } 00129 Vec2<T>& operator+=( const Vec2<T>& rhs ) { x += rhs.x; y += rhs.y; return *this; } 00130 Vec2<T>& operator-=( const Vec2<T>& rhs ) { x -= rhs.x; y -= rhs.y; return *this; } 00131 Vec2<T>& operator*=( const Vec2<T>& rhs ) { x *= rhs.x; y *= rhs.y; return *this; } 00132 Vec2<T>& operator/=( const Vec2<T>& rhs ) { x /= rhs.x; y /= rhs.y; return *this; } 00133 const Vec2<T> operator/( T rhs ) const { return Vec2<T>( x / rhs, y / rhs ); } 00134 Vec2<T>& operator+=( T rhs ) { x += rhs; y += rhs; return *this; } 00135 Vec2<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; return *this; } 00136 Vec2<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; return *this; } 00137 Vec2<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; return *this; } 00138 00139 Vec2<T> operator-() const { return Vec2<T>( -x, -y ); } // unary negation 00140 00141 bool operator==( const Vec2<T> &rhs ) const 00142 { 00143 return ( x == rhs.x ) && ( y == rhs.y ); 00144 } 00145 00146 bool operator!=( const Vec2<T> &rhs ) const 00147 { 00148 return ! ( *this == rhs ); 00149 } 00150 00151 T dot( const Vec2<T> &rhs ) const 00152 { 00153 return x * rhs.x + y * rhs.y; 00154 } 00155 00157 T cross( const Vec2<T> &rhs ) const 00158 { 00159 return x * rhs.y - y * rhs.x; 00160 } 00161 00162 DIST distance( const Vec2<T> &rhs ) const 00163 { 00164 return ( *this - rhs ).length(); 00165 } 00166 00167 T distanceSquared( const Vec2<T> &rhs ) const 00168 { 00169 return ( *this - rhs ).lengthSquared(); 00170 } 00171 00172 DIST length() const 00173 { 00174 return math<DIST>::sqrt( x*x + y*y ); 00175 } 00176 00177 void normalize() 00178 { 00179 DIST invS = 1 / length(); 00180 x *= invS; 00181 y *= invS; 00182 } 00183 00184 Vec2<T> normalized() const 00185 { 00186 DIST invS = 1 / length(); 00187 return Vec2<T>( x * invS, y * invS ); 00188 } 00189 00190 // tests for zero-length 00191 void safeNormalize() 00192 { 00193 T s = lengthSquared(); 00194 if( s > 0 ) { 00195 DIST invL = 1 / math<DIST>::sqrt( s ); 00196 x *= invL; 00197 y *= invL; 00198 } 00199 } 00200 00201 Vec2<T> safeNormalized() const 00202 { 00203 T s = lengthSquared(); 00204 if( s > 0 ) { 00205 DIST invL = 1 / math<DIST>::sqrt( s ); 00206 return Vec2<T>( x * invL, y * invL ); 00207 } 00208 else 00209 return Vec2<T>::zero(); 00210 } 00211 00212 void rotate( DIST radians ) 00213 { 00214 T cosa = math<T>::cos( radians ); 00215 T sina = math<T>::sin( radians ); 00216 T rx = x * cosa - y * sina; 00217 y = x * sina + y * cosa; 00218 x = rx; 00219 } 00220 00221 T lengthSquared() const 00222 { 00223 return x * x + y * y; 00224 } 00225 00227 void limit( DIST maxLength ) 00228 { 00229 T lengthSquared = x * x + y * y; 00230 00231 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00232 DIST ratio = maxLength / math<DIST>::sqrt( lengthSquared ); 00233 x *= ratio; 00234 y *= ratio; 00235 } 00236 } 00237 00239 Vec2<T> limited( T maxLength ) const 00240 { 00241 T lengthSquared = x * x + y * y; 00242 00243 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00244 DIST ratio = maxLength / math<DIST>::sqrt( lengthSquared ); 00245 return Vec2<T>( x * ratio, y * ratio ); 00246 } 00247 else 00248 return *this; 00249 } 00250 00251 void invert() 00252 { 00253 x = -x; 00254 y = -y; 00255 } 00256 00257 Vec2<T> inverse() const 00258 { 00259 return Vec2<T>( -x, -y ); 00260 } 00261 00262 Vec2<T> lerp( T fact, const Vec2<T>& r ) const 00263 { 00264 return (*this) + ( r - (*this) ) * fact; 00265 } 00266 00267 void lerpEq( T fact, const Vec2<T> &rhs ) 00268 { 00269 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; 00270 } 00271 00272 // GLSL inspired swizzling functions. 00273 Vec2<T> xx() const { return Vec2<T>(x, x); } 00274 Vec2<T> xy() const { return Vec2<T>(x, y); } 00275 Vec2<T> yx() const { return Vec2<T>(y, x); } 00276 Vec2<T> yy() const { return Vec2<T>(y, y); } 00277 00278 Vec3<T> xxx() const { return Vec3<T>(x, x, x); } 00279 Vec3<T> xxy() const { return Vec3<T>(x, x, y); } 00280 Vec3<T> xyx() const { return Vec3<T>(x, y, x); } 00281 Vec3<T> xyy() const { return Vec3<T>(x, y, y); } 00282 Vec3<T> yxx() const { return Vec3<T>(y, x, x); } 00283 Vec3<T> yxy() const { return Vec3<T>(y, x, y); } 00284 Vec3<T> yyx() const { return Vec3<T>(y, y, x); } 00285 Vec3<T> yyy() const { return Vec3<T>(y, y, y); } 00286 00287 static Vec2<T> max() 00288 { 00289 return Vec2<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max() ); 00290 } 00291 00292 static Vec2<T> zero() 00293 { 00294 return Vec2<T>( 0, 0 ); 00295 } 00296 00297 static Vec2<T> one() 00298 { 00299 return Vec2<T>( 1, 1 ); 00300 } 00301 00302 operator T*(){ return (T*) this; } 00303 operator const T*() const { return (const T*) this; } 00304 00305 friend std::ostream& operator<<( std::ostream& lhs, const Vec2<T>& rhs ) 00306 { 00307 lhs << "[" << rhs.x << "," << rhs.y << "]"; 00308 return lhs; 00309 } 00310 00311 static Vec2<T> xAxis() { return Vec2<T>( 1, 0 ); } 00312 static Vec2<T> yAxis() { return Vec2<T>( 0, 1 ); } 00313 00314 static Vec2<T> NaN() { return Vec2<T>( math<T>::NaN(), math<T>::NaN() ); } 00315 }; 00316 00317 template<typename T> 00318 class Vec3 00319 { 00320 public: 00321 T x,y,z; 00322 00323 typedef T TYPE; 00324 static const int DIM = 3; 00325 00326 Vec3() {} 00327 Vec3( T nx, T ny, T nz ) 00328 : x( nx ), y( ny ), z( nz ) 00329 {} 00330 Vec3( const Vec3<T> &src ) 00331 : x( src.x ), y( src.y ), z( src.z ) 00332 {} 00333 Vec3( const Vec2<T> &v2, T aZ ) 00334 : x( v2.x ), y( v2.y ), z( aZ ) 00335 {} 00336 explicit Vec3( const Vec2<T> &v2 ) 00337 : x( v2.x ), y( v2.y ), z( 0 ) 00338 {} 00339 explicit Vec3( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ) {} 00340 template<typename FromT> 00341 Vec3( const Vec3<FromT> &src ) 00342 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) ) 00343 {} 00344 template<typename Y> 00345 explicit Vec3( const Y &v ) 00346 : x( VEC3CONV<Vec3<typename T::TYPE>,Y>::getX( v ) ), y( VEC3CONV<typename T::TYPE,Y>::getY( v ) ), z( VEC3CONV<typename T::TYPE,Y>::getZ( v ) ) 00347 { 00348 } 00349 00350 void set( T ax, T ay, T az ) 00351 { 00352 x = ax; y = ay; z = az; 00353 } 00354 00355 void set( const Vec3<T> &rhs ) 00356 { 00357 x = rhs.x; y = rhs.y; z = rhs.z; 00358 } 00359 00360 Vec3<T>& operator=( const Vec3<T> &rhs ) 00361 { 00362 x = rhs.x; 00363 y = rhs.y; 00364 z = rhs.z; 00365 return * this; 00366 } 00367 00368 template<typename FromT> 00369 Vec3<T>& operator=( const Vec3<FromT> &rhs ) 00370 { 00371 x = static_cast<T>( rhs.x ); 00372 y = static_cast<T>( rhs.y ); 00373 z = static_cast<T>( rhs.z ); 00374 return * this; 00375 } 00376 00377 T& operator[]( int n ) 00378 { 00379 assert( n >= 0 && n <= 2 ); 00380 return (&x)[n]; 00381 } 00382 00383 const T& operator[]( int n ) const 00384 { 00385 assert( n >= 0 && n <= 2 ); 00386 return (&x)[n]; 00387 } 00388 00389 const Vec3<T> operator+( const Vec3<T>& rhs ) const { return Vec3<T>( x + rhs.x, y + rhs.y, z + rhs.z ); } 00390 const Vec3<T> operator-( const Vec3<T>& rhs ) const { return Vec3<T>( x - rhs.x, y - rhs.y, z - rhs.z ); } 00391 const Vec3<T> operator*( const Vec3<T>& rhs ) const { return Vec3<T>( x * rhs.x, y * rhs.y, z * rhs.z ); } 00392 const Vec3<T> operator/( const Vec3<T>& rhs ) const { return Vec3<T>( x / rhs.x, y / rhs.y, z / rhs.z ); } 00393 Vec3<T>& operator+=( const Vec3<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; } 00394 Vec3<T>& operator-=( const Vec3<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; } 00395 Vec3<T>& operator*=( const Vec3<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this; } 00396 Vec3<T>& operator/=( const Vec3<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; return *this; } 00397 const Vec3<T> operator/( T rhs ) const { T invRhs = static_cast<T>( 1.0 ) / rhs; return Vec3<T>( x * invRhs, y * invRhs, z * invRhs ); } 00398 Vec3<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; return *this; } 00399 Vec3<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; return *this; } 00400 Vec3<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; return *this; } 00401 Vec3<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; return *this; } 00402 00403 Vec3<T> operator-() const { return Vec3<T>( -x, -y, -z ); } // unary negation 00404 00405 bool operator==( const Vec3<T>& rhs ) const 00406 { 00407 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ); 00408 } 00409 00410 bool operator!=( const Vec3<T>& rhs ) const 00411 { 00412 return !( *this == rhs ); 00413 } 00414 00415 T dot( const Vec3<T> &rhs ) const 00416 { 00417 return x*rhs.x + y*rhs.y + z*rhs.z; 00418 } 00419 00420 Vec3<T> cross( const Vec3<T> &rhs ) const 00421 { 00422 return Vec3<T>( y * rhs.z - rhs.y * z, z * rhs.x - rhs.z * x, x * rhs.y - rhs.x * y ); 00423 } 00424 00425 T distance( const Vec3<T> &rhs ) const 00426 { 00427 return ( *this - rhs ).length(); 00428 } 00429 00430 T distanceSquared( const Vec3<T> &rhs ) const 00431 { 00432 return ( *this - rhs ).lengthSquared(); 00433 } 00434 00435 T length() const 00436 { 00437 return math<T>::sqrt( x*x + y*y + z*z ); 00438 } 00439 00440 T lengthSquared() const 00441 { 00442 return x*x + y*y + z*z; 00443 } 00444 00446 void limit( T maxLength ) 00447 { 00448 T lengthSquared = x * x + y * y + z * z; 00449 00450 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00451 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00452 x *= ratio; 00453 y *= ratio; 00454 z *= ratio; 00455 } 00456 } 00457 00459 Vec3<T> limited( T maxLength ) const 00460 { 00461 T lengthSquared = x * x + y * y + z * z; 00462 00463 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00464 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00465 return Vec3<T>( x * ratio, y * ratio, z * ratio ); 00466 } 00467 else 00468 return *this; 00469 } 00470 00471 void invert() 00472 { 00473 x = -x; y = -y; z = -z; 00474 } 00475 00476 Vec3<T> inverse() const 00477 { 00478 return Vec3<T>( -x, -y, -z ); 00479 } 00480 00481 void normalize() 00482 { 00483 T invS = ((T)1) / length(); 00484 x *= invS; 00485 y *= invS; 00486 z *= invS; 00487 } 00488 00489 Vec3<T> normalized() const 00490 { 00491 T invS = ((T)1) / length(); 00492 return Vec3<T>( x * invS, y * invS, z * invS ); 00493 } 00494 00495 // tests for zero-length 00496 void safeNormalize() 00497 { 00498 T s = lengthSquared(); 00499 if( s > 0 ) { 00500 T invS = ((T)1) / math<T>::sqrt( s ); 00501 x *= invS; 00502 y *= invS; 00503 z *= invS; 00504 } 00505 } 00506 00507 Vec3<T> safeNormalized() const 00508 { 00509 T s = lengthSquared(); 00510 if( s > 0 ) { 00511 float invS = ((T)1) / math<T>::sqrt( s ); 00512 return Vec3<T>( x * invS, y * invS, z * invS ); 00513 } 00514 else 00515 return *this; 00516 } 00517 00518 Vec3<T> randomOrthogonal() const 00519 { 00520 if( dot( Vec3<T>::xAxis() ) >= (T)0.01 ) { 00521 return cross( Vec3<T>::xAxis() ); 00522 } 00523 else 00524 return cross( Vec3<T>::yAxis() ); 00525 } 00526 00527 void rotateX( T angle ) 00528 { 00529 T sina = math<T>::sin(angle); 00530 T cosa = math<T>::cos(angle); 00531 T ry = y * cosa - z * sina; 00532 T rz = y * sina + z * cosa; 00533 y = ry; 00534 z = rz; 00535 } 00536 00537 void rotateY( T angle ) 00538 { 00539 T sina = math<T>::sin(angle); 00540 T cosa = math<T>::cos(angle); 00541 T rx = x * cosa - z * sina; 00542 T rz = x * sina + z * cosa; 00543 x = rx; 00544 z = rz; 00545 } 00546 00547 void rotateZ( T angle ) 00548 { 00549 T sina = math<T>::sin(angle); 00550 T cosa = math<T>::cos(angle); 00551 T rx = x * cosa - y * sina; 00552 T ry = x * sina + y * cosa; 00553 x = rx; 00554 y = ry; 00555 } 00556 00557 void rotate( Vec3<T> axis, T angle ) 00558 { 00559 T cosa = math<T>::cos(angle); 00560 T sina = math<T>::sin(angle); 00561 00562 T rx = (cosa + (1 - cosa) * axis.x * axis.x) * x; 00563 rx += ((1 - cosa) * axis.x * axis.y - axis.z * sina) * y; 00564 rx += ((1 - cosa) * axis.x * axis.z + axis.y * sina) * z; 00565 00566 T ry = ((1 - cosa) * axis.x * axis.y + axis.z * sina) * x; 00567 ry += (cosa + (1 - cosa) * axis.y * axis.y) * y; 00568 ry += ((1 - cosa) * axis.y * axis.z - axis.x * sina) * z; 00569 00570 T rz = ((1 - cosa) * axis.x * axis.z - axis.y * sina) * x; 00571 rz += ((1 - cosa) * axis.y * axis.z + axis.x * sina) * y; 00572 rz += (cosa + (1 - cosa) * axis.z * axis.z) * z; 00573 00574 x = rx; 00575 y = ry; 00576 z = rz; 00577 } 00578 00579 Vec3<T> lerp( T fact, const Vec3<T> &rhs ) const 00580 { 00581 return (*this) + (rhs - (*this)) * fact; 00582 } 00583 00584 void lerpEq( T fact, const Vec3<T> &rhs ) 00585 { 00586 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; z = z + ( rhs.z - z ) * fact; 00587 } 00588 00589 static Vec3<T> max() 00590 { 00591 return Vec3<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() ); 00592 } 00593 00594 static Vec3<T> zero() 00595 { 00596 return Vec3<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ); 00597 } 00598 00599 static Vec3<T> one() 00600 { 00601 return Vec3<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) ); 00602 } 00603 00604 Vec3<T> slerp( T fact, const Vec3<T> &r ) const 00605 { 00606 T cosAlpha, alpha, sinAlpha; 00607 T t1, t2; 00608 Vec3<T> result; 00609 00610 // get cosine of angle between vectors (-1 -> 1) 00611 cosAlpha = this->dot( r ); 00612 00613 // get angle (0 -> pi) 00614 alpha = math<T>::acos( cosAlpha ); 00615 00616 // get sine of angle between vectors (0 -> 1) 00617 sinAlpha = math<T>::sin( alpha ); 00618 00619 // this breaks down when sinAlpha = 0, i.e. alpha = 0 or pi 00620 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha; 00621 t2 = math<T>::sin( fact * alpha ) / sinAlpha; 00622 00623 // interpolate src vectors 00624 return *this * t1 + r * t2; 00625 } 00626 00627 // derived from but not equivalent to Quaternion::squad 00628 Vec3<T> squad( T t, const Vec3<T> &tangentA, const Vec3<T> &tangentB, const Vec3<T> &end ) const 00629 { 00630 Vec3<T> r1 = this->slerp( t, end ); 00631 Vec3<T> r2 = tangentA.slerp( t, tangentB ); 00632 return r1.slerp( 2 * t * (1-t), r2 ); 00633 } 00634 00635 // GLSL inspired swizzling functions. 00636 Vec2<T> xx() const { return Vec2<T>(x, x); } 00637 Vec2<T> xy() const { return Vec2<T>(x, y); } 00638 Vec2<T> xz() const { return Vec2<T>(x, z); } 00639 Vec2<T> yx() const { return Vec2<T>(y, x); } 00640 Vec2<T> yy() const { return Vec2<T>(y, y); } 00641 Vec2<T> yz() const { return Vec2<T>(y, z); } 00642 Vec2<T> zx() const { return Vec2<T>(z, x); } 00643 Vec2<T> zy() const { return Vec2<T>(z, y); } 00644 Vec2<T> zz() const { return Vec2<T>(z, z); } 00645 00646 Vec3<T> xxx() const { return Vec3<T>(x, x, x); } 00647 Vec3<T> xxy() const { return Vec3<T>(x, x, y); } 00648 Vec3<T> xxz() const { return Vec3<T>(x, x, z); } 00649 Vec3<T> xyx() const { return Vec3<T>(x, y, x); } 00650 Vec3<T> xyy() const { return Vec3<T>(x, y, y); } 00651 Vec3<T> xyz() const { return Vec3<T>(x, y, z); } 00652 Vec3<T> xzx() const { return Vec3<T>(x, z, x); } 00653 Vec3<T> xzy() const { return Vec3<T>(x, z, y); } 00654 Vec3<T> xzz() const { return Vec3<T>(x, z, z); } 00655 Vec3<T> yxx() const { return Vec3<T>(y, x, x); } 00656 Vec3<T> yxy() const { return Vec3<T>(y, x, y); } 00657 Vec3<T> yxz() const { return Vec3<T>(y, x, z); } 00658 Vec3<T> yyx() const { return Vec3<T>(y, y, x); } 00659 Vec3<T> yyy() const { return Vec3<T>(y, y, y); } 00660 Vec3<T> yyz() const { return Vec3<T>(y, y, z); } 00661 Vec3<T> yzx() const { return Vec3<T>(y, z, x); } 00662 Vec3<T> yzy() const { return Vec3<T>(y, z, y); } 00663 Vec3<T> yzz() const { return Vec3<T>(y, z, z); } 00664 Vec3<T> zxx() const { return Vec3<T>(z, x, x); } 00665 Vec3<T> zxy() const { return Vec3<T>(z, x, y); } 00666 Vec3<T> zxz() const { return Vec3<T>(z, x, z); } 00667 Vec3<T> zyx() const { return Vec3<T>(z, y, x); } 00668 Vec3<T> zyy() const { return Vec3<T>(z, y, y); } 00669 Vec3<T> zyz() const { return Vec3<T>(z, y, z); } 00670 Vec3<T> zzx() const { return Vec3<T>(z, z, x); } 00671 Vec3<T> zzy() const { return Vec3<T>(z, z, y); } 00672 Vec3<T> zzz() const { return Vec3<T>(z, z, z); } 00673 00674 operator T*(){ return (T*) this; } 00675 operator const T*() const { return (const T*) this; } 00676 00677 friend std::ostream& operator<<( std::ostream& lhs, const Vec3<T> rhs ) 00678 { 00679 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "]"; 00680 return lhs; 00681 } 00682 00683 static Vec3<T> xAxis() { return Vec3<T>( 1, 0, 0 ); } 00684 static Vec3<T> yAxis() { return Vec3<T>( 0, 1, 0 ); } 00685 static Vec3<T> zAxis() { return Vec3<T>( 0, 0, 1 ); } 00686 00687 static Vec3<T> NaN() { return Vec3<T>( math<T>::NaN(), math<T>::NaN(), math<T>::NaN() ); } 00688 }; 00689 00690 template <class T> 00691 class Vec4 00692 { 00693 public: 00694 T x,y,z,w; 00695 00696 typedef T TYPE; 00697 static const int DIM = 4; 00698 00699 Vec4() 00700 : x( 0 ), y( 0 ), z( 0 ), w( 0 ) 00701 {} 00702 Vec4( T nx, T ny, T nz, T nw = 0 ) 00703 : x( nx ), y( ny ), z( nz ), w( nw ) 00704 {} 00705 Vec4( const Vec3<T>& src, T aW = 0 ) 00706 : x( src.x ), y( src.y ), z( src.z ), w( aW ) 00707 {} 00708 Vec4( const Vec4<T>& src ) 00709 : x( src.x ), y( src.y ), z( src.z ), w( src.w ) 00710 {} 00711 template<typename FromT> 00712 Vec4( const Vec4<FromT>& src ) 00713 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) ),w( static_cast<T>( src.w ) ) 00714 {} 00715 explicit Vec4( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ), w( d[3] ) {} 00716 00717 Vec4<T>& operator=( const Vec4<T>& rhs ) 00718 { 00719 x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w; 00720 return *this; 00721 } 00722 00723 template<typename FromT> 00724 Vec4<T>& operator=( const Vec4<FromT>& rhs ) 00725 { 00726 x = static_cast<T>(rhs.x); y = static_cast<T>(rhs.y); z = static_cast<T>(rhs.z); w = static_cast<T>(rhs.w); 00727 return *this; 00728 } 00729 00730 T& operator[]( int n ) 00731 { 00732 assert( n >= 0 && n <= 3 ); 00733 return (&x)[n]; 00734 } 00735 00736 const T& operator[]( int n ) const 00737 { 00738 assert( n >= 0 && n <= 3 ); 00739 return (&x)[n]; 00740 } 00741 00742 const Vec4<T> operator+( const Vec4<T>& rhs ) const { return Vec4<T>( x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w ); } 00743 const Vec4<T> operator-( const Vec4<T>& rhs ) const { return Vec4<T>( x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w ); } 00744 const Vec4<T> operator*( const Vec4<T>& rhs ) const { return Vec4<T>( x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w ); } 00745 const Vec4<T> operator/( const Vec4<T>& rhs ) const { return Vec4<T>( x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w ); } 00746 Vec4<T>& operator+=( const Vec4<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this; } 00747 Vec4<T>& operator-=( const Vec4<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this; } 00748 Vec4<T>& operator*=( const Vec4<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this; } 00749 Vec4<T>& operator/=( const Vec4<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; w /= rhs.w; return *this; } 00750 const Vec4<T> operator/( T rhs ) const { return Vec4<T>( x / rhs, y / rhs, z / rhs, w / rhs ); } 00751 Vec4<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; w += rhs; return *this; } 00752 Vec4<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; w -= rhs; return * this; } 00753 Vec4<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; w *= rhs; return * this; } 00754 Vec4<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; w /= rhs; return * this; } 00755 00756 Vec4<T> operator-() const { return Vec4<T>( -x, -y, -z, -w ); } // unary negation 00757 00758 bool operator==( const Vec4<T>& rhs ) const 00759 { 00760 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ) && ( w == rhs.w ); 00761 } 00762 00763 bool operator!=( const Vec4<T>& rhs ) const 00764 { 00765 return ! (*this == rhs); 00766 } 00767 00768 T dot( const Vec4<T> &rhs ) const 00769 { 00770 return x*rhs.x + y*rhs.y + z*rhs.z; 00771 } 00772 00773 Vec4<T> cross( const Vec4<T> &rhs ) const 00774 { 00775 return Vec4<T>( y*rhs.z - rhs.y*z, z*rhs.x - rhs.z*x, x*rhs.y - rhs.x*y ); 00776 } 00777 00778 T distance( const Vec4<T> &rhs ) const 00779 { 00780 return ( *this - rhs ).length(); 00781 } 00782 00783 T distanceSquared( const Vec4<T> &rhs ) const 00784 { 00785 return ( *this - rhs ).lengthSquared(); 00786 } 00787 00788 T length() const 00789 { 00790 // For most vector operations, this assumes w to be zero. 00791 return math<T>::sqrt( x*x + y*y + z*z + w*w ); 00792 } 00793 00794 T lengthSquared() const 00795 { 00796 // For most vector operations, this assumes w to be zero. 00797 return x*x + y*y + z*z + w*w; 00798 } 00799 00800 void normalize() 00801 { 00802 T invS = ((T)1) / length(); 00803 x *= invS; 00804 y *= invS; 00805 z *= invS; 00806 w *= invS; 00807 } 00808 00809 Vec4<T> normalized() const 00810 { 00811 T invS = ((T)1) / length(); 00812 return Vec4<T>( x*invS, y*invS, z*invS, w*invS ); 00813 } 00814 00815 // Tests for zero-length 00816 void safeNormalize() 00817 { 00818 T s = lengthSquared(); 00819 if( s > 0 ) { 00820 T invS = ((T)1) / math<T>::sqrt( s ); 00821 x *= invS; 00822 y *= invS; 00823 z *= invS; 00824 w = (T)0; 00825 } 00826 } 00827 00829 void limit( T maxLength ) 00830 { 00831 T lenSq = lengthSquared(); 00832 00833 if( ( lenSq > maxLength * maxLength ) && ( lenSq > 0 ) ) { 00834 T ratio = maxLength / math<T>::sqrt( lenSq ); 00835 x *= ratio; 00836 y *= ratio; 00837 z *= ratio; 00838 w *= ratio; 00839 } 00840 00841 /* 00842 T lengthSquared = x * x + y * y + z * z + w * w; 00843 00844 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00845 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00846 x *= ratio; 00847 y *= ratio; 00848 z *= ratio; 00849 w *= ratio; 00850 } 00851 */ 00852 } 00853 00855 Vec4<T> limited( T maxLength ) const 00856 { 00857 T lenSq = lengthSquared(); 00858 00859 if( ( lenSq > maxLength * maxLength ) && ( lenSq > 0 ) ) { 00860 T ratio = maxLength / math<T>::sqrt( lenSq ); 00861 return Vec4<T>( x * ratio, y * ratio, z * ratio, w * ratio ); 00862 } 00863 else 00864 return *this; 00865 00866 /* 00867 T lengthSquared = x * x + y * y + z * z + w * w; 00868 00869 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00870 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00871 return Vec4<T>( x * ratio, y * ratio, z * ratio, w * ratio ); 00872 } 00873 else 00874 return *this; 00875 */ 00876 } 00877 00878 void invert() 00879 { 00880 x = -x; y = -y; z = -z; w = -w; 00881 } 00882 00883 Vec4<T> inverse() const 00884 { 00885 return Vec4<T>( -x, -y, -z, -w ); 00886 } 00887 00888 Vec4<T> lerp( T fact, const Vec4<T>& r ) const 00889 { 00890 return (*this) + ( r - (*this) ) * fact; 00891 } 00892 00893 void lerpEq( T fact, const Vec4<T> &rhs ) 00894 { 00895 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; z = z + ( rhs.z - z ) * fact; w = w + ( rhs.w - w ) * fact; 00896 } 00897 00898 static Vec4<T> max() 00899 { 00900 return Vec4<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() ); 00901 } 00902 00903 static Vec4<T> zero() 00904 { 00905 return Vec4<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ); 00906 } 00907 00908 static Vec4<T> one() 00909 { 00910 return Vec4<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) ); 00911 } 00912 00913 Vec4<T> slerp( T fact, const Vec3<T> &r ) const 00914 { 00915 T cosAlpha, alpha, sinAlpha; 00916 T t1, t2; 00917 Vec4<T> result; 00918 00919 // get cosine of angle between vectors (-1 -> 1) 00920 cosAlpha = this->dot( r ); 00921 00922 // get angle (0 -> pi) 00923 alpha = math<T>::acos( cosAlpha ); 00924 00925 // get sine of angle between vectors (0 -> 1) 00926 sinAlpha = math<T>::sin( alpha ); 00927 00928 // this breaks down when sinAlpha = 0, i.e. alpha = 0 or pi 00929 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha; 00930 t2 = math<T>::sin( fact * alpha ) / sinAlpha; 00931 00932 // interpolate src vectors 00933 return *this * t1 + r * t2; 00934 } 00935 00936 // derived from but not equivalent to Quaternion::squad 00937 Vec4<T> squad( T t, const Vec4<T> &tangentA, const Vec4<T> &tangentB, const Vec4<T> &end ) const 00938 { 00939 Vec4<T> r1 = this->slerp( t, end ); 00940 Vec4<T> r2 = tangentA.slerp( t, tangentB ); 00941 return r1.slerp( 2 * t * (1-t), r2 ); 00942 } 00943 00944 // GLSL inspired swizzling functions. 00945 Vec2<T> xx() const { return Vec2<T>(x, x); } 00946 Vec2<T> xy() const { return Vec2<T>(x, y); } 00947 Vec2<T> xz() const { return Vec2<T>(x, z); } 00948 Vec2<T> yx() const { return Vec2<T>(y, x); } 00949 Vec2<T> yy() const { return Vec2<T>(y, y); } 00950 Vec2<T> yz() const { return Vec2<T>(y, z); } 00951 Vec2<T> zx() const { return Vec2<T>(z, x); } 00952 Vec2<T> zy() const { return Vec2<T>(z, y); } 00953 Vec2<T> zz() const { return Vec2<T>(z, z); } 00954 00955 Vec3<T> xxx() const { return Vec3<T>(x, x, x); } 00956 Vec3<T> xxy() const { return Vec3<T>(x, x, y); } 00957 Vec3<T> xxz() const { return Vec3<T>(x, x, z); } 00958 Vec3<T> xyx() const { return Vec3<T>(x, y, x); } 00959 Vec3<T> xyy() const { return Vec3<T>(x, y, y); } 00960 Vec3<T> xyz() const { return Vec3<T>(x, y, z); } 00961 Vec3<T> xzx() const { return Vec3<T>(x, z, x); } 00962 Vec3<T> xzy() const { return Vec3<T>(x, z, y); } 00963 Vec3<T> xzz() const { return Vec3<T>(x, z, z); } 00964 Vec3<T> yxx() const { return Vec3<T>(y, x, x); } 00965 Vec3<T> yxy() const { return Vec3<T>(y, x, y); } 00966 Vec3<T> yxz() const { return Vec3<T>(y, x, z); } 00967 Vec3<T> yyx() const { return Vec3<T>(y, y, x); } 00968 Vec3<T> yyy() const { return Vec3<T>(y, y, y); } 00969 Vec3<T> yyz() const { return Vec3<T>(y, y, z); } 00970 Vec3<T> yzx() const { return Vec3<T>(y, z, x); } 00971 Vec3<T> yzy() const { return Vec3<T>(y, z, y); } 00972 Vec3<T> yzz() const { return Vec3<T>(y, z, z); } 00973 Vec3<T> zxx() const { return Vec3<T>(z, x, x); } 00974 Vec3<T> zxy() const { return Vec3<T>(z, x, y); } 00975 Vec3<T> zxz() const { return Vec3<T>(z, x, z); } 00976 Vec3<T> zyx() const { return Vec3<T>(z, y, x); } 00977 Vec3<T> zyy() const { return Vec3<T>(z, y, y); } 00978 Vec3<T> zyz() const { return Vec3<T>(z, y, z); } 00979 Vec3<T> zzx() const { return Vec3<T>(z, z, x); } 00980 Vec3<T> zzy() const { return Vec3<T>(z, z, y); } 00981 Vec3<T> zzz() const { return Vec3<T>(z, z, z); } 00982 00983 Vec4<T> xxxx() const { return Vec4<T>(x, x, x, x); } 00984 Vec4<T> xxxy() const { return Vec4<T>(x, x, x, y); } 00985 Vec4<T> xxxz() const { return Vec4<T>(x, x, x, z); } 00986 Vec4<T> xxxw() const { return Vec4<T>(x, x, x, w); } 00987 Vec4<T> xxyx() const { return Vec4<T>(x, x, y, x); } 00988 Vec4<T> xxyy() const { return Vec4<T>(x, x, y, y); } 00989 Vec4<T> xxyz() const { return Vec4<T>(x, x, y, z); } 00990 Vec4<T> xxyw() const { return Vec4<T>(x, x, y, w); } 00991 Vec4<T> xxzx() const { return Vec4<T>(x, x, z, x); } 00992 Vec4<T> xxzy() const { return Vec4<T>(x, x, z, y); } 00993 Vec4<T> xxzz() const { return Vec4<T>(x, x, z, z); } 00994 Vec4<T> xxzw() const { return Vec4<T>(x, x, z, w); } 00995 Vec4<T> xxwx() const { return Vec4<T>(x, x, w, x); } 00996 Vec4<T> xxwy() const { return Vec4<T>(x, x, w, y); } 00997 Vec4<T> xxwz() const { return Vec4<T>(x, x, w, z); } 00998 Vec4<T> xxww() const { return Vec4<T>(x, x, w, w); } 00999 Vec4<T> xyxx() const { return Vec4<T>(x, y, x, x); } 01000 Vec4<T> xyxy() const { return Vec4<T>(x, y, x, y); } 01001 Vec4<T> xyxz() const { return Vec4<T>(x, y, x, z); } 01002 Vec4<T> xyxw() const { return Vec4<T>(x, y, x, w); } 01003 Vec4<T> xyyx() const { return Vec4<T>(x, y, y, x); } 01004 Vec4<T> xyyy() const { return Vec4<T>(x, y, y, y); } 01005 Vec4<T> xyyz() const { return Vec4<T>(x, y, y, z); } 01006 Vec4<T> xyyw() const { return Vec4<T>(x, y, y, w); } 01007 Vec4<T> xyzx() const { return Vec4<T>(x, y, z, x); } 01008 Vec4<T> xyzy() const { return Vec4<T>(x, y, z, y); } 01009 Vec4<T> xyzz() const { return Vec4<T>(x, y, z, z); } 01010 Vec4<T> xyzw() const { return Vec4<T>(x, y, z, w); } 01011 Vec4<T> xywx() const { return Vec4<T>(x, y, w, x); } 01012 Vec4<T> xywy() const { return Vec4<T>(x, y, w, y); } 01013 Vec4<T> xywz() const { return Vec4<T>(x, y, w, z); } 01014 Vec4<T> xyww() const { return Vec4<T>(x, y, w, w); } 01015 Vec4<T> xzxx() const { return Vec4<T>(x, z, x, x); } 01016 Vec4<T> xzxy() const { return Vec4<T>(x, z, x, y); } 01017 Vec4<T> xzxz() const { return Vec4<T>(x, z, x, z); } 01018 Vec4<T> xzxw() const { return Vec4<T>(x, z, x, w); } 01019 Vec4<T> xzyx() const { return Vec4<T>(x, z, y, x); } 01020 Vec4<T> xzyy() const { return Vec4<T>(x, z, y, y); } 01021 Vec4<T> xzyz() const { return Vec4<T>(x, z, y, z); } 01022 Vec4<T> xzyw() const { return Vec4<T>(x, z, y, w); } 01023 Vec4<T> xzzx() const { return Vec4<T>(x, z, z, x); } 01024 Vec4<T> xzzy() const { return Vec4<T>(x, z, z, y); } 01025 Vec4<T> xzzz() const { return Vec4<T>(x, z, z, z); } 01026 Vec4<T> xzzw() const { return Vec4<T>(x, z, z, w); } 01027 Vec4<T> xzwx() const { return Vec4<T>(x, z, w, x); } 01028 Vec4<T> xzwy() const { return Vec4<T>(x, z, w, y); } 01029 Vec4<T> xzwz() const { return Vec4<T>(x, z, w, z); } 01030 Vec4<T> xzww() const { return Vec4<T>(x, z, w, w); } 01031 Vec4<T> xwxx() const { return Vec4<T>(x, w, x, x); } 01032 Vec4<T> xwxy() const { return Vec4<T>(x, w, x, y); } 01033 Vec4<T> xwxz() const { return Vec4<T>(x, w, x, z); } 01034 Vec4<T> xwxw() const { return Vec4<T>(x, w, x, w); } 01035 Vec4<T> xwyx() const { return Vec4<T>(x, w, y, x); } 01036 Vec4<T> xwyy() const { return Vec4<T>(x, w, y, y); } 01037 Vec4<T> xwyz() const { return Vec4<T>(x, w, y, z); } 01038 Vec4<T> xwyw() const { return Vec4<T>(x, w, y, w); } 01039 Vec4<T> xwzx() const { return Vec4<T>(x, w, z, x); } 01040 Vec4<T> xwzy() const { return Vec4<T>(x, w, z, y); } 01041 Vec4<T> xwzz() const { return Vec4<T>(x, w, z, z); } 01042 Vec4<T> xwzw() const { return Vec4<T>(x, w, z, w); } 01043 Vec4<T> xwwx() const { return Vec4<T>(x, w, w, x); } 01044 Vec4<T> xwwy() const { return Vec4<T>(x, w, w, y); } 01045 Vec4<T> xwwz() const { return Vec4<T>(x, w, w, z); } 01046 Vec4<T> xwww() const { return Vec4<T>(x, w, w, w); } 01047 Vec4<T> yxxx() const { return Vec4<T>(y, x, x, x); } 01048 Vec4<T> yxxy() const { return Vec4<T>(y, x, x, y); } 01049 Vec4<T> yxxz() const { return Vec4<T>(y, x, x, z); } 01050 Vec4<T> yxxw() const { return Vec4<T>(y, x, x, w); } 01051 Vec4<T> yxyx() const { return Vec4<T>(y, x, y, x); } 01052 Vec4<T> yxyy() const { return Vec4<T>(y, x, y, y); } 01053 Vec4<T> yxyz() const { return Vec4<T>(y, x, y, z); } 01054 Vec4<T> yxyw() const { return Vec4<T>(y, x, y, w); } 01055 Vec4<T> yxzx() const { return Vec4<T>(y, x, z, x); } 01056 Vec4<T> yxzy() const { return Vec4<T>(y, x, z, y); } 01057 Vec4<T> yxzz() const { return Vec4<T>(y, x, z, z); } 01058 Vec4<T> yxzw() const { return Vec4<T>(y, x, z, w); } 01059 Vec4<T> yxwx() const { return Vec4<T>(y, x, w, x); } 01060 Vec4<T> yxwy() const { return Vec4<T>(y, x, w, y); } 01061 Vec4<T> yxwz() const { return Vec4<T>(y, x, w, z); } 01062 Vec4<T> yxww() const { return Vec4<T>(y, x, w, w); } 01063 Vec4<T> yyxx() const { return Vec4<T>(y, y, x, x); } 01064 Vec4<T> yyxy() const { return Vec4<T>(y, y, x, y); } 01065 Vec4<T> yyxz() const { return Vec4<T>(y, y, x, z); } 01066 Vec4<T> yyxw() const { return Vec4<T>(y, y, x, w); } 01067 Vec4<T> yyyx() const { return Vec4<T>(y, y, y, x); } 01068 Vec4<T> yyyy() const { return Vec4<T>(y, y, y, y); } 01069 Vec4<T> yyyz() const { return Vec4<T>(y, y, y, z); } 01070 Vec4<T> yyyw() const { return Vec4<T>(y, y, y, w); } 01071 Vec4<T> yyzx() const { return Vec4<T>(y, y, z, x); } 01072 Vec4<T> yyzy() const { return Vec4<T>(y, y, z, y); } 01073 Vec4<T> yyzz() const { return Vec4<T>(y, y, z, z); } 01074 Vec4<T> yyzw() const { return Vec4<T>(y, y, z, w); } 01075 Vec4<T> yywx() const { return Vec4<T>(y, y, w, x); } 01076 Vec4<T> yywy() const { return Vec4<T>(y, y, w, y); } 01077 Vec4<T> yywz() const { return Vec4<T>(y, y, w, z); } 01078 Vec4<T> yyww() const { return Vec4<T>(y, y, w, w); } 01079 Vec4<T> yzxx() const { return Vec4<T>(y, z, x, x); } 01080 Vec4<T> yzxy() const { return Vec4<T>(y, z, x, y); } 01081 Vec4<T> yzxz() const { return Vec4<T>(y, z, x, z); } 01082 Vec4<T> yzxw() const { return Vec4<T>(y, z, x, w); } 01083 Vec4<T> yzyx() const { return Vec4<T>(y, z, y, x); } 01084 Vec4<T> yzyy() const { return Vec4<T>(y, z, y, y); } 01085 Vec4<T> yzyz() const { return Vec4<T>(y, z, y, z); } 01086 Vec4<T> yzyw() const { return Vec4<T>(y, z, y, w); } 01087 Vec4<T> yzzx() const { return Vec4<T>(y, z, z, x); } 01088 Vec4<T> yzzy() const { return Vec4<T>(y, z, z, y); } 01089 Vec4<T> yzzz() const { return Vec4<T>(y, z, z, z); } 01090 Vec4<T> yzzw() const { return Vec4<T>(y, z, z, w); } 01091 Vec4<T> yzwx() const { return Vec4<T>(y, z, w, x); } 01092 Vec4<T> yzwy() const { return Vec4<T>(y, z, w, y); } 01093 Vec4<T> yzwz() const { return Vec4<T>(y, z, w, z); } 01094 Vec4<T> yzww() const { return Vec4<T>(y, z, w, w); } 01095 Vec4<T> ywxx() const { return Vec4<T>(y, w, x, x); } 01096 Vec4<T> ywxy() const { return Vec4<T>(y, w, x, y); } 01097 Vec4<T> ywxz() const { return Vec4<T>(y, w, x, z); } 01098 Vec4<T> ywxw() const { return Vec4<T>(y, w, x, w); } 01099 Vec4<T> ywyx() const { return Vec4<T>(y, w, y, x); } 01100 Vec4<T> ywyy() const { return Vec4<T>(y, w, y, y); } 01101 Vec4<T> ywyz() const { return Vec4<T>(y, w, y, z); } 01102 Vec4<T> ywyw() const { return Vec4<T>(y, w, y, w); } 01103 Vec4<T> ywzx() const { return Vec4<T>(y, w, z, x); } 01104 Vec4<T> ywzy() const { return Vec4<T>(y, w, z, y); } 01105 Vec4<T> ywzz() const { return Vec4<T>(y, w, z, z); } 01106 Vec4<T> ywzw() const { return Vec4<T>(y, w, z, w); } 01107 Vec4<T> ywwx() const { return Vec4<T>(y, w, w, x); } 01108 Vec4<T> ywwy() const { return Vec4<T>(y, w, w, y); } 01109 Vec4<T> ywwz() const { return Vec4<T>(y, w, w, z); } 01110 Vec4<T> ywww() const { return Vec4<T>(y, w, w, w); } 01111 Vec4<T> zxxx() const { return Vec4<T>(z, x, x, x); } 01112 Vec4<T> zxxy() const { return Vec4<T>(z, x, x, y); } 01113 Vec4<T> zxxz() const { return Vec4<T>(z, x, x, z); } 01114 Vec4<T> zxxw() const { return Vec4<T>(z, x, x, w); } 01115 Vec4<T> zxyx() const { return Vec4<T>(z, x, y, x); } 01116 Vec4<T> zxyy() const { return Vec4<T>(z, x, y, y); } 01117 Vec4<T> zxyz() const { return Vec4<T>(z, x, y, z); } 01118 Vec4<T> zxyw() const { return Vec4<T>(z, x, y, w); } 01119 Vec4<T> zxzx() const { return Vec4<T>(z, x, z, x); } 01120 Vec4<T> zxzy() const { return Vec4<T>(z, x, z, y); } 01121 Vec4<T> zxzz() const { return Vec4<T>(z, x, z, z); } 01122 Vec4<T> zxzw() const { return Vec4<T>(z, x, z, w); } 01123 Vec4<T> zxwx() const { return Vec4<T>(z, x, w, x); } 01124 Vec4<T> zxwy() const { return Vec4<T>(z, x, w, y); } 01125 Vec4<T> zxwz() const { return Vec4<T>(z, x, w, z); } 01126 Vec4<T> zxww() const { return Vec4<T>(z, x, w, w); } 01127 Vec4<T> zyxx() const { return Vec4<T>(z, y, x, x); } 01128 Vec4<T> zyxy() const { return Vec4<T>(z, y, x, y); } 01129 Vec4<T> zyxz() const { return Vec4<T>(z, y, x, z); } 01130 Vec4<T> zyxw() const { return Vec4<T>(z, y, x, w); } 01131 Vec4<T> zyyx() const { return Vec4<T>(z, y, y, x); } 01132 Vec4<T> zyyy() const { return Vec4<T>(z, y, y, y); } 01133 Vec4<T> zyyz() const { return Vec4<T>(z, y, y, z); } 01134 Vec4<T> zyyw() const { return Vec4<T>(z, y, y, w); } 01135 Vec4<T> zyzx() const { return Vec4<T>(z, y, z, x); } 01136 Vec4<T> zyzy() const { return Vec4<T>(z, y, z, y); } 01137 Vec4<T> zyzz() const { return Vec4<T>(z, y, z, z); } 01138 Vec4<T> zyzw() const { return Vec4<T>(z, y, z, w); } 01139 Vec4<T> zywx() const { return Vec4<T>(z, y, w, x); } 01140 Vec4<T> zywy() const { return Vec4<T>(z, y, w, y); } 01141 Vec4<T> zywz() const { return Vec4<T>(z, y, w, z); } 01142 Vec4<T> zyww() const { return Vec4<T>(z, y, w, w); } 01143 Vec4<T> zzxx() const { return Vec4<T>(z, z, x, x); } 01144 Vec4<T> zzxy() const { return Vec4<T>(z, z, x, y); } 01145 Vec4<T> zzxz() const { return Vec4<T>(z, z, x, z); } 01146 Vec4<T> zzxw() const { return Vec4<T>(z, z, x, w); } 01147 Vec4<T> zzyx() const { return Vec4<T>(z, z, y, x); } 01148 Vec4<T> zzyy() const { return Vec4<T>(z, z, y, y); } 01149 Vec4<T> zzyz() const { return Vec4<T>(z, z, y, z); } 01150 Vec4<T> zzyw() const { return Vec4<T>(z, z, y, w); } 01151 Vec4<T> zzzx() const { return Vec4<T>(z, z, z, x); } 01152 Vec4<T> zzzy() const { return Vec4<T>(z, z, z, y); } 01153 Vec4<T> zzzz() const { return Vec4<T>(z, z, z, z); } 01154 Vec4<T> zzzw() const { return Vec4<T>(z, z, z, w); } 01155 Vec4<T> zzwx() const { return Vec4<T>(z, z, w, x); } 01156 Vec4<T> zzwy() const { return Vec4<T>(z, z, w, y); } 01157 Vec4<T> zzwz() const { return Vec4<T>(z, z, w, z); } 01158 Vec4<T> zzww() const { return Vec4<T>(z, z, w, w); } 01159 Vec4<T> zwxx() const { return Vec4<T>(z, w, x, x); } 01160 Vec4<T> zwxy() const { return Vec4<T>(z, w, x, y); } 01161 Vec4<T> zwxz() const { return Vec4<T>(z, w, x, z); } 01162 Vec4<T> zwxw() const { return Vec4<T>(z, w, x, w); } 01163 Vec4<T> zwyx() const { return Vec4<T>(z, w, y, x); } 01164 Vec4<T> zwyy() const { return Vec4<T>(z, w, y, y); } 01165 Vec4<T> zwyz() const { return Vec4<T>(z, w, y, z); } 01166 Vec4<T> zwyw() const { return Vec4<T>(z, w, y, w); } 01167 Vec4<T> zwzx() const { return Vec4<T>(z, w, z, x); } 01168 Vec4<T> zwzy() const { return Vec4<T>(z, w, z, y); } 01169 Vec4<T> zwzz() const { return Vec4<T>(z, w, z, z); } 01170 Vec4<T> zwzw() const { return Vec4<T>(z, w, z, w); } 01171 Vec4<T> zwwx() const { return Vec4<T>(z, w, w, x); } 01172 Vec4<T> zwwy() const { return Vec4<T>(z, w, w, y); } 01173 Vec4<T> zwwz() const { return Vec4<T>(z, w, w, z); } 01174 Vec4<T> zwww() const { return Vec4<T>(z, w, w, w); } 01175 Vec4<T> wxxx() const { return Vec4<T>(w, x, x, x); } 01176 Vec4<T> wxxy() const { return Vec4<T>(w, x, x, y); } 01177 Vec4<T> wxxz() const { return Vec4<T>(w, x, x, z); } 01178 Vec4<T> wxxw() const { return Vec4<T>(w, x, x, w); } 01179 Vec4<T> wxyx() const { return Vec4<T>(w, x, y, x); } 01180 Vec4<T> wxyy() const { return Vec4<T>(w, x, y, y); } 01181 Vec4<T> wxyz() const { return Vec4<T>(w, x, y, z); } 01182 Vec4<T> wxyw() const { return Vec4<T>(w, x, y, w); } 01183 Vec4<T> wxzx() const { return Vec4<T>(w, x, z, x); } 01184 Vec4<T> wxzy() const { return Vec4<T>(w, x, z, y); } 01185 Vec4<T> wxzz() const { return Vec4<T>(w, x, z, z); } 01186 Vec4<T> wxzw() const { return Vec4<T>(w, x, z, w); } 01187 Vec4<T> wxwx() const { return Vec4<T>(w, x, w, x); } 01188 Vec4<T> wxwy() const { return Vec4<T>(w, x, w, y); } 01189 Vec4<T> wxwz() const { return Vec4<T>(w, x, w, z); } 01190 Vec4<T> wxww() const { return Vec4<T>(w, x, w, w); } 01191 Vec4<T> wyxx() const { return Vec4<T>(w, y, x, x); } 01192 Vec4<T> wyxy() const { return Vec4<T>(w, y, x, y); } 01193 Vec4<T> wyxz() const { return Vec4<T>(w, y, x, z); } 01194 Vec4<T> wyxw() const { return Vec4<T>(w, y, x, w); } 01195 Vec4<T> wyyx() const { return Vec4<T>(w, y, y, x); } 01196 Vec4<T> wyyy() const { return Vec4<T>(w, y, y, y); } 01197 Vec4<T> wyyz() const { return Vec4<T>(w, y, y, z); } 01198 Vec4<T> wyyw() const { return Vec4<T>(w, y, y, w); } 01199 Vec4<T> wyzx() const { return Vec4<T>(w, y, z, x); } 01200 Vec4<T> wyzy() const { return Vec4<T>(w, y, z, y); } 01201 Vec4<T> wyzz() const { return Vec4<T>(w, y, z, z); } 01202 Vec4<T> wyzw() const { return Vec4<T>(w, y, z, w); } 01203 Vec4<T> wywx() const { return Vec4<T>(w, y, w, x); } 01204 Vec4<T> wywy() const { return Vec4<T>(w, y, w, y); } 01205 Vec4<T> wywz() const { return Vec4<T>(w, y, w, z); } 01206 Vec4<T> wyww() const { return Vec4<T>(w, y, w, w); } 01207 Vec4<T> wzxx() const { return Vec4<T>(w, z, x, x); } 01208 Vec4<T> wzxy() const { return Vec4<T>(w, z, x, y); } 01209 Vec4<T> wzxz() const { return Vec4<T>(w, z, x, z); } 01210 Vec4<T> wzxw() const { return Vec4<T>(w, z, x, w); } 01211 Vec4<T> wzyx() const { return Vec4<T>(w, z, y, x); } 01212 Vec4<T> wzyy() const { return Vec4<T>(w, z, y, y); } 01213 Vec4<T> wzyz() const { return Vec4<T>(w, z, y, z); } 01214 Vec4<T> wzyw() const { return Vec4<T>(w, z, y, w); } 01215 Vec4<T> wzzx() const { return Vec4<T>(w, z, z, x); } 01216 Vec4<T> wzzy() const { return Vec4<T>(w, z, z, y); } 01217 Vec4<T> wzzz() const { return Vec4<T>(w, z, z, z); } 01218 Vec4<T> wzzw() const { return Vec4<T>(w, z, z, w); } 01219 Vec4<T> wzwx() const { return Vec4<T>(w, z, w, x); } 01220 Vec4<T> wzwy() const { return Vec4<T>(w, z, w, y); } 01221 Vec4<T> wzwz() const { return Vec4<T>(w, z, w, z); } 01222 Vec4<T> wzww() const { return Vec4<T>(w, z, w, w); } 01223 Vec4<T> wwxx() const { return Vec4<T>(w, w, x, x); } 01224 Vec4<T> wwxy() const { return Vec4<T>(w, w, x, y); } 01225 Vec4<T> wwxz() const { return Vec4<T>(w, w, x, z); } 01226 Vec4<T> wwxw() const { return Vec4<T>(w, w, x, w); } 01227 Vec4<T> wwyx() const { return Vec4<T>(w, w, y, x); } 01228 Vec4<T> wwyy() const { return Vec4<T>(w, w, y, y); } 01229 Vec4<T> wwyz() const { return Vec4<T>(w, w, y, z); } 01230 Vec4<T> wwyw() const { return Vec4<T>(w, w, y, w); } 01231 Vec4<T> wwzx() const { return Vec4<T>(w, w, z, x); } 01232 Vec4<T> wwzy() const { return Vec4<T>(w, w, z, y); } 01233 Vec4<T> wwzz() const { return Vec4<T>(w, w, z, z); } 01234 Vec4<T> wwzw() const { return Vec4<T>(w, w, z, w); } 01235 Vec4<T> wwwx() const { return Vec4<T>(w, w, w, x); } 01236 Vec4<T> wwwy() const { return Vec4<T>(w, w, w, y); } 01237 Vec4<T> wwwz() const { return Vec4<T>(w, w, w, z); } 01238 Vec4<T> wwww() const { return Vec4<T>(w, w, w, w); } 01239 01240 operator T*(){ return (T*) this; } 01241 operator const T*() const { return (const T*) this; } 01242 01243 friend std::ostream& operator<<( std::ostream& lhs, const Vec4<T>& rhs ) 01244 { 01245 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "," << rhs.w << "]"; 01246 return lhs; 01247 } 01248 01249 static Vec4<T> xAxis() { return Vec4<T>( 1, 0, 0, 0 ); } 01250 static Vec4<T> yAxis() { return Vec4<T>( 0, 1, 0, 0 ); } 01251 static Vec4<T> zAxis() { return Vec4<T>( 0, 0, 1, 0 ); } 01252 static Vec4<T> wAxis() { return Vec4<T>( 0, 0, 0, 1 ); } 01253 01254 static Vec4<T> NaN() { return Vec4<T>( math<T>::NaN(), math<T>::NaN(), math<T>::NaN(), math<T>::NaN() ); } 01255 }; 01256 01258 template<typename T> 01259 Vec2<T> toPolar( Vec2<T> car ) 01260 { 01261 const T epsilon = (T)0.0000001; 01262 T theta; 01263 if( math<T>::abs( car.x ) < epsilon ) { // x == 0 01264 if( math<T>::abs( car.y ) < epsilon ) theta = 0; 01265 else if( car.y > 0 ) theta = (T)M_PI / 2; 01266 else theta = ( (T)M_PI * 3 ) / 2; 01267 } 01268 else if ( car.x > 0 ) { 01269 if( car.y < 0 ) theta = math<T>::atan( car.y / car.x ) + 2 * (T)M_PI; 01270 else theta = math<T>::atan( car.y / car.x ); 01271 } 01272 else // car.x < 0 01273 theta = (math<T>::atan( car.y / car.x ) + M_PI ); 01274 01275 return Vec2<T>( car.length(), theta ); 01276 } 01277 01279 template<typename T> 01280 Vec2<T> fromPolar( Vec2<T> pol ) 01281 { 01282 return Vec2<T>( math<T>::cos( pol.y ) * pol.x , math<T>::sin( pol.y ) * pol.x ); 01283 } 01284 01285 template<typename T,typename Y> inline Vec2<T> operator *( Y s, const Vec2<T> &v ) { return Vec2<T>( v.x * s, v.y * s ); } 01286 template<typename T,typename Y> inline Vec2<T> operator *( const Vec2<T> &v, Y s ) { return Vec2<T>( v.x * s, v.y * s ); } 01287 template<typename T,typename Y> inline Vec3<T> operator *( Y s, const Vec3<T> &v ) { return Vec3<T>( v.x * s, v.y * s, v.z * s ); } 01288 template<typename T,typename Y> inline Vec3<T> operator *( const Vec3<T> &v, Y s ) { return Vec3<T>( v.x * s, v.y * s, v.z * s ); } 01289 template<typename T,typename Y> inline Vec4<T> operator *( Y s, const Vec4<T> &v ) { return Vec4<T>( v.x * s, v.y * s, v.z * s, v.w * s ); } 01290 template<typename T,typename Y> inline Vec4<T> operator *( const Vec4<T> &v, Y s ) { return Vec4<T>( v.x * s, v.y * s, v.z * s, v.w * s ); } 01291 01292 template <typename T> T dot( const Vec2<T>& a, const Vec2<T>& b ) { return a.dot( b ); } 01293 template <typename T> T dot( const Vec3<T>& a, const Vec3<T>& b ) { return a.dot( b ); } 01294 template <typename T> T dot( const Vec4<T>& a, const Vec4<T>& b ) { return a.dot( b ); } 01295 01296 template <typename T> Vec3<T> cross( const Vec3<T>& a, const Vec3<T>& b ) { return a.cross( b ); } 01297 template <typename T> Vec4<T> cross( const Vec4<T>& a, const Vec4<T>& b ) { return a.cross( b ); } 01298 01299 template <typename T> bool isNaN( const Vec2<T>& a ) { return isNaN( a.x ) || isNaN( a.y ); } 01300 template <typename T> bool isNaN( const Vec3<T>& a ) { return isNaN( a.x ) || isNaN( a.y ) || isNaN( a.z ); } 01301 template <typename T> bool isNaN( const Vec4<T>& a ) { return isNaN( a.x ) || isNaN( a.y ) || isNaN( a.z ) || isNaN( a.w ); } 01302 01303 typedef Vec2<float> Vec2f; 01304 typedef Vec2<double> Vec2d; 01305 typedef Vec3<float> Vec3f; 01306 typedef Vec3<double> Vec3d; 01307 typedef Vec4<float> Vec4f; 01308 typedef Vec4<double> Vec4d; 01309 typedef Vec2<int> Vec2i; 01310 01311 } // namespace cinder