00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include <cmath>
00026 #include <cstring>
00027 #include <iostream>
00028 #include <cassert>
00029 #include <limits>
00030
00031 #include "cinder/CinderMath.h"
00032
00033 namespace cinder {
00034
00035 template<typename T, typename Y>
00036 struct VEC3CONV {
00037 static T getX( const Y &v ) { return static_cast<T>( v.x ); }
00038 static T getY( const Y &v ) { return static_cast<T>( v.y ); }
00039 static T getZ( const Y &v ) { return static_cast<T>( v.z ); }
00040 };
00041
00042 template<typename T>
00043 class Vec2
00044 {
00045 public:
00046 T x,y;
00047
00048 typedef T TYPE;
00049 static const int DIM = 2;
00050
00051 Vec2() {}
00052 Vec2( T nx, T ny ) : x( nx ), y( ny ) {}
00053 Vec2( const Vec2<T>& src ) : x( src.x ), y( src.y ) {}
00054 explicit Vec2( const T *d ) : x( d[0] ), y( d[1] ) {}
00055
00056 template<typename FromT>
00057 Vec2( const Vec2<FromT>& src )
00058 : x( static_cast<T>( src.x ) ),y( static_cast<T>( src.y ) )
00059 {}
00060
00061 void set( T ax, T ay )
00062 {
00063 x = ax; y = ay;
00064 }
00065
00066 void set( const Vec2<T> &rhs )
00067 {
00068 x = rhs.x; y = rhs.y;
00069 }
00070
00071
00072 template<typename FromT>
00073 Vec2<T>& operator=( const Vec2<FromT>& rhs )
00074 {
00075 x = static_cast<T>( rhs.x );
00076 y = static_cast<T>( rhs.y );
00077 return * this;
00078 }
00079
00080 Vec2<T>& operator=( const Vec2<T>& rhs )
00081 {
00082 x = rhs.x;
00083 y = rhs.y;
00084 return * this;
00085 }
00086
00087 T& operator[]( int n )
00088 {
00089 assert( n >= 0 && n <= 1 );
00090 return (&x)[n];
00091 }
00092
00093 const T& operator[]( int n ) const
00094 {
00095 assert( n >= 0 && n <= 1 );
00096 return (&x)[n];
00097 }
00098
00099 const Vec2<T> operator+( const Vec2<T>& rhs ) const { return Vec2<T>( x + rhs.x, y + rhs.y ); }
00100 const Vec2<T> operator-( const Vec2<T>& rhs ) const { return Vec2<T>( x - rhs.x, y - rhs.y ); }
00101 const Vec2<T> operator*( const Vec2<T>& rhs ) const { return Vec2<T>( x * rhs.x, y * rhs.y ); }
00102 const Vec2<T> operator/( const Vec2<T>& rhs ) const { return Vec2<T>( x / rhs.x, y / rhs.y ); }
00103 Vec2<T>& operator+=( const Vec2<T>& rhs ) { x += rhs.x; y += rhs.y; return *this; }
00104 Vec2<T>& operator-=( const Vec2<T>& rhs ) { x -= rhs.x; y -= rhs.y; return *this; }
00105 Vec2<T>& operator*=( const Vec2<T>& rhs ) { x *= rhs.x; y *= rhs.y; return *this; }
00106 Vec2<T>& operator/=( const Vec2<T>& rhs ) { x /= rhs.x; y /= rhs.y; return *this; }
00107 const Vec2<T> operator/( T rhs ) const { return Vec2<T>( x / rhs, y / rhs ); }
00108 Vec2<T>& operator+=( T rhs ) { x += rhs; y += rhs; return *this; }
00109 Vec2<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; return *this; }
00110 Vec2<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; return *this; }
00111 Vec2<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; return *this; }
00112
00113 Vec2<T> operator-() const { return Vec2<T>( -x, -y ); }
00114
00115 bool operator==( const Vec2<T> &rhs ) const
00116 {
00117 return ( x == rhs.x ) && ( y == rhs.y );
00118 }
00119
00120 bool operator!=( const Vec2<T> &rhs ) const
00121 {
00122 return ! ( *this == rhs );
00123 }
00124
00125 T dot( const Vec2<T> &rhs ) const
00126 {
00127 return x * rhs.x + y * rhs.y;
00128 }
00129
00130 T distance( const Vec2<T> &rhs ) const
00131 {
00132 return ( *this - rhs ).length();
00133 }
00134
00135 T distanceSquared( const Vec2<T> &rhs ) const
00136 {
00137 return ( *this - rhs ).lengthSquared();
00138 }
00139
00140 T length() const
00141 {
00142 return (T)std::sqrt( x*x + y*y );
00143 }
00144
00145 void normalize()
00146 {
00147 T invS = ((T)1) / length();
00148 x *= invS;
00149 y *= invS;
00150 }
00151
00152 Vec2<T> normalized() const
00153 {
00154 T invS = ((T)1) / length();
00155 return Vec2<T>( x * invS, y * invS );
00156 }
00157
00158
00159 void safeNormalize()
00160 {
00161 T s = lengthSquared();
00162 if( s > 0 ) {
00163 T invL = ((T)1) / math<T>::sqrt( s );
00164 x *= invL;
00165 y *= invL;
00166 }
00167 }
00168
00169 Vec2<T> safeNormalized()
00170 {
00171 T s = lengthSquared();
00172 if( s > 0 ) {
00173 T invL = ((T)1) / math<T>::sqrt( s );
00174 return Vec2<T>( x * invL, y * invL );
00175 }
00176 else
00177 return Vec2<T>::zero();
00178 }
00179
00180 T lengthSquared() const
00181 {
00182 return x * x + y * y;
00183 }
00184
00185 void invert()
00186 {
00187 x - -x;
00188 y = -y;
00189 }
00190
00191 Vec2<T> inverse()
00192 {
00193 return Vec2<T>( -x, -y );
00194 }
00195
00196 Vec2<T> lerp( T fact, const Vec2<T>& r ) const
00197 {
00198 return (*this) + ( r - (*this) ) * fact;
00199 }
00200
00201 static Vec2<T> max()
00202 {
00203 return Vec2<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00204 }
00205
00206 static Vec2<T> zero()
00207 {
00208 return Vec2<T>( static_cast<T>( 0 ), static_cast<T>( 0 ) );
00209 }
00210
00211 static Vec2<T> one()
00212 {
00213 return Vec2<T>( static_cast<T>( 1 ), static_cast<T>( 1 ) );
00214 }
00215
00216 operator T*(){ return (T*) this; }
00217 operator const T*() const { return (const T*) this; }
00218
00219 friend std::ostream& operator<<( std::ostream& lhs, const Vec2<T>& rhs )
00220 {
00221 lhs << "[" << rhs.x << "," << rhs.y << "]";
00222 return lhs;
00223 }
00224
00225 static Vec2<T> xAxis() { return Vec2<T>( 1, 0 ); }
00226 static Vec2<T> yAxis() { return Vec2<T>( 0, 1 ); }
00227 };
00228
00229 template<typename T>
00230 class Vec3
00231 {
00232 public:
00233 T x,y,z;
00234
00235 typedef T TYPE;
00236 static const int DIM = 3;
00237
00238 Vec3() {}
00239 Vec3( T nx, T ny, T nz )
00240 : x( nx ), y( ny ), z( nz )
00241 {}
00242 Vec3( const Vec3<T> &src )
00243 : x( src.x ), y( src.y ), z( src.z )
00244 {}
00245 Vec3( const Vec2<T> &v2, T aZ )
00246 : x( v2.x ), y ( v2.y ), z( aZ )
00247 {}
00248 explicit Vec3( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ) {}
00249 template<typename FromT>
00250 Vec3( const Vec3<FromT> &src )
00251 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) )
00252 {}
00253 template<typename Y>
00254 explicit Vec3( const Y &v )
00255 : 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 ) )
00256 {
00257 }
00258
00259 void set( T ax, T ay, T az )
00260 {
00261 x = ax; y = ay; z = az;
00262 }
00263
00264 void set( const Vec3<T> &rhs )
00265 {
00266 x = rhs.x; y = rhs.y; z = rhs.z;
00267 }
00268
00269 Vec3<T>& operator=( const Vec3<T> &rhs )
00270 {
00271 x = rhs.x;
00272 y = rhs.y;
00273 z = rhs.z;
00274 return * this;
00275 }
00276
00277 template<typename FromT>
00278 Vec3<T>& operator=( const Vec3<FromT> &rhs )
00279 {
00280 x = static_cast<T>( rhs.x );
00281 y = static_cast<T>( rhs.y );
00282 z = static_cast<T>( rhs.z );
00283 return * this;
00284 }
00285
00286 T& operator[]( int n )
00287 {
00288 assert( n >= 0 && n <= 2 );
00289 return (&x)[n];
00290 }
00291
00292 const T& operator[]( int n ) const
00293 {
00294 assert( n >= 0 && n <= 2 );
00295 return (&x)[n];
00296 }
00297
00298 const Vec3<T> operator+( const Vec3<T>& rhs ) const { return Vec3<T>( x + rhs.x, y + rhs.y, z + rhs.z ); }
00299 const Vec3<T> operator-( const Vec3<T>& rhs ) const { return Vec3<T>( x - rhs.x, y - rhs.y, z - rhs.z ); }
00300 const Vec3<T> operator*( const Vec3<T>& rhs ) const { return Vec3<T>( x * rhs.x, y * rhs.y, z * rhs.z ); }
00301 const Vec3<T> operator/( const Vec3<T>& rhs ) const { return Vec3<T>( x / rhs.x, y / rhs.y, z / rhs.z ); }
00302 Vec3<T>& operator+=( const Vec3<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
00303 Vec3<T>& operator-=( const Vec3<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
00304 Vec3<T>& operator*=( const Vec3<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this; }
00305 Vec3<T>& operator/=( const Vec3<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; return *this; }
00306 const Vec3<T> operator/( T rhs ) const { T invRhs = static_cast<T>( 1.0 ) / rhs; return Vec3<T>( x * invRhs, y * invRhs, z * invRhs ); }
00307 Vec3<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; return *this; }
00308 Vec3<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; return *this; }
00309 Vec3<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; return *this; }
00310 Vec3<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; return *this; }
00311
00312 Vec3<T> operator-() const { return Vec3<T>( -x, -y, -z ); }
00313
00314 bool operator==( const Vec3<T>& rhs ) const
00315 {
00316 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z );
00317 }
00318
00319 bool operator!=( const Vec3<T>& rhs ) const
00320 {
00321 return !( *this == rhs );
00322 }
00323
00324 T dot( const Vec3<T> &rhs ) const
00325 {
00326 return x*rhs.x + y*rhs.y + z*rhs.z;
00327 }
00328
00329 Vec3<T> cross( const Vec3<T> &rhs ) const
00330 {
00331 return Vec3<T>( y * rhs.z - rhs.y * z, z * rhs.x - rhs.z * x, x * rhs.y - rhs.x * y );
00332 }
00333
00334 T distance( const Vec3<T> &rhs ) const
00335 {
00336 return ( *this - rhs ).length();
00337 }
00338
00339 T distanceSquared( const Vec3<T> &rhs ) const
00340 {
00341 return ( *this - rhs ).lengthSquared();
00342 }
00343
00344 T length() const
00345 {
00346 return (T)std::sqrt( x*x + y*y + z*z );
00347 }
00348
00349 T lengthSquared() const
00350 {
00351 return x*x + y*y + z*z;
00352 }
00353
00354 void invert()
00355 {
00356 x - -x; y = -y; z = -z;
00357 }
00358
00359 Vec3<T> inverse()
00360 {
00361 return Vec3<T>( -x, -y, -z );
00362 }
00363
00364 void normalize()
00365 {
00366 T invS = ((T)1) / length();
00367 x *= invS;
00368 y *= invS;
00369 z *= invS;
00370 }
00371
00372 Vec3<T> normalized() const
00373 {
00374 T invS = ((T)1) / length();
00375 return Vec3<T>( x * invS, y * invS, z * invS );
00376 }
00377
00378
00379 void safeNormalize()
00380 {
00381 T s = lengthSquared();
00382 if( s > 0 ) {
00383 T invS = ((T)1) / math<T>::sqrt( s );
00384 x *= invS;
00385 y *= invS;
00386 z *= invS;
00387 }
00388 }
00389
00390 Vec3<T> safeNormalized()
00391 {
00392 T s = lengthSquared();
00393 if( s > 0 ) {
00394 float invS = ((T)1) / math<T>::sqrt( s );
00395 return Vec3<T>( x * invS, y * invS, z * invS );
00396 }
00397 else
00398 return *this;
00399 }
00400
00401 Vec3<T> randomOrthogonal() const
00402 {
00403 if( dot( Vec3<T>::xAxis() ) >= (T)0.01 ) {
00404 return cross( Vec3<T>::xAxis() );
00405 }
00406 else
00407 return cross( Vec3<T>::yAxis() );
00408 }
00409
00410 void rotate( T ax, T ay, T az )
00411 {
00412 T a = cos( toRadians( ax ) );
00413 T b = sin( toRadians( ax ) );
00414 T c = cos( toRadians( ay ) );
00415 T d = sin( toRadians( ay ) );
00416 T e = cos( toRadians( az ) );
00417 T f = sin( toRadians( az ) );
00418 T nx = c*e*x - c*f*y + d*z;
00419 T ny = ( a*f + b*d*e ) * x + (a*e - b*d*f) * y - b*c*z;
00420 T nz = ( b*f - a*d*e ) * x + (a*d*f + b*e) * y + a*c*z;
00421 x = nx;
00422 y = ny;
00423 z = nz;
00424 }
00425
00426 Vec3<T> lerp( T fact, const Vec3<T> &rhs ) const
00427 {
00428 return (*this) + (rhs - (*this)) * fact;
00429 }
00430
00431 void lerpEq( T fact, const Vec3<T> &rhs )
00432 {
00433 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; z = z + ( rhs.z - z ) * fact;
00434 }
00435
00436 static Vec3<T> max()
00437 {
00438 return Vec3<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00439 }
00440
00441 static Vec3<T> zero()
00442 {
00443 return Vec3<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00444 }
00445
00446 static Vec3<T> one()
00447 {
00448 return Vec3<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) );
00449 }
00450
00451 Vec3<T> slerp( T fact, const Vec3<T> &r ) const
00452 {
00453 T cosAlpha, alpha, sinAlpha;
00454 T t1, t2;
00455 Vec3<T> result;
00456
00457
00458 cosAlpha = this->dot( r );
00459
00460
00461 alpha = math<T>::acos( cosAlpha );
00462
00463
00464 sinAlpha = math<T>::sin( alpha );
00465
00466
00467 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha;
00468 t2 = math<T>::sin( fact * alpha ) / sinAlpha;
00469
00470
00471 return *this * t1 + r * t2;
00472 }
00473
00474
00475 Vec3<T> squad( T t, const Vec3<T> &tangentA, const Vec3<T> &tangentB, const Vec3<T> &end )
00476 {
00477 Vec3<T> r1 = this->slerp( t, end );
00478 Vec3<T> r2 = tangentA.slerp( t, tangentB );
00479 return r1.slerp( 2 * t * (1-t), r2 );
00480 }
00481
00482 operator T*(){ return (T*) this; }
00483 operator const T*() const { return (const T*) this; }
00484
00485 friend std::ostream& operator<<( std::ostream& lhs, const Vec3<T> rhs )
00486 {
00487 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "]";
00488 return lhs;
00489 }
00490
00491 static Vec3<T> xAxis() { return Vec3<T>( 1, 0, 0 ); }
00492 static Vec3<T> yAxis() { return Vec3<T>( 0, 1, 0 ); }
00493 static Vec3<T> zAxis() { return Vec3<T>( 0, 0, 1 ); }
00494 };
00495
00496 template <class T>
00497 class Vec4{
00498 public:
00499 T x,y,z,w;
00500
00501 typedef T TYPE;
00502 static const int DIM = 4;
00503
00504 Vec4()
00505 : x( 0 ), y( 0 ), z( 0 ), w( 0 )
00506 {}
00507 Vec4( T nx, T ny, T nz, T nw )
00508 : x( nx ), y( ny ), z( nz ), w( nw )
00509 {}
00510 Vec4( const Vec3<T>& src, T aW )
00511 : x( src.x ), y( src.y ), z( src.z ), w( aW )
00512 {}
00513 Vec4( const Vec4<T>& src )
00514 : x( src.x ), y( src.y ), z( src.z ), w( src.w )
00515 {}
00516 template<typename FromT>
00517 Vec4( const Vec4<FromT>& src )
00518 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) ),w( static_cast<T>( src.w ) )
00519 {}
00520 explicit Vec4( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ), w( d[3] ) {}
00521
00522 Vec4<T>& operator=( const Vec4<T>& rhs )
00523 {
00524 x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w;
00525 return *this;
00526 }
00527
00528 template<typename FromT>
00529 Vec4<T>& operator=( const Vec4<FromT>& rhs )
00530 {
00531 x = static_cast<T>(rhs.x); y = static_cast<T>(rhs.y); z = static_cast<T>(rhs.z); w = static_cast<T>(rhs.w);
00532 return *this;
00533 }
00534
00535 T& operator[]( int n )
00536 {
00537 assert( n >= 0 && n <= 3 );
00538 return (&x)[n];
00539 }
00540
00541 const T& operator[]( int n ) const
00542 {
00543 assert( n >= 0 && n <= 3 );
00544 return (&x)[n];
00545 }
00546
00547 const Vec4<T> operator+( const Vec4<T>& rhs ) const { return Vec4<T>( x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w ); }
00548 const Vec4<T> operator-( const Vec4<T>& rhs ) const { return Vec4<T>( x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w ); }
00549 const Vec4<T> operator*( const Vec4<T>& rhs ) const { return Vec4<T>( x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w ); }
00550 const Vec4<T> operator/( const Vec4<T>& rhs ) const { return Vec4<T>( x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w ); }
00551 Vec4<T>& operator+=( const Vec4<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this; }
00552 Vec4<T>& operator-=( const Vec4<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this; }
00553 Vec4<T>& operator*=( const Vec4<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this; }
00554 Vec4<T>& operator/=( const Vec4<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; w /= rhs.w; return *this; }
00555 const Vec4<T> operator/( T rhs ) const { return Vec4<T>( x / rhs, y / rhs, z / rhs, w / rhs ); }
00556 Vec4<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; w += rhs; return *this; }
00557 Vec4<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; w -= rhs; return * this; }
00558 Vec4<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; w *= rhs; return * this; }
00559 Vec4<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; w /= rhs; return * this; }
00560
00561 Vec4<T> operator-() const { return Vec4<T>( -x, -y, -z, -w ); }
00562
00563 bool operator==( const Vec4<T>& rhs ) const
00564 {
00565 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ) && ( w == rhs.w );
00566 }
00567
00568 bool operator!=( const Vec4<T>& rhs ) const { return ! (*this == rhs); }
00569
00570 T length() const
00571 {
00572 return (T)std::sqrt(x * x + y * y + z * z + w * w);
00573 }
00574
00575 void normalize()
00576 {
00577 T invS = ((T)1) / length();
00578 x *= invS;
00579 y *= invS;
00580 z *= invS;
00581 w *= invS;
00582 }
00583
00584
00585 void safeNormalize()
00586 {
00587 T s = lengthSquared();
00588 if( s > 0 ) {
00589 T invS = ((T)1) / math<T>::sqrt( s );
00590 x *= invS;
00591 y *= invS;
00592 z *= invS;
00593 w *= invS;
00594 }
00595 }
00596
00597 T lengthSquared() const
00598 {
00599 return x * x + y * y + z * z + w * w;
00600 }
00601
00602 Vec4<T> lerp( T fact, const Vec4<T>& r ) const
00603 {
00604 return (*this) + ( r - (*this) ) * fact;
00605 }
00606
00607 static Vec4<T> max()
00608 {
00609 return Vec4<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00610 }
00611
00612 static Vec4<T> zero()
00613 {
00614 return Vec4<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00615 }
00616
00617 static Vec4<T> one()
00618 {
00619 return Vec4<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) );
00620 }
00621
00622 operator T*(){ return (T*) this; }
00623 operator const T*() const { return (const T*) this; }
00624
00625 friend std::ostream& operator<<( std::ostream& lhs, const Vec4<T>& rhs )
00626 {
00627 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "," << rhs.w << "]";
00628 return lhs;
00629 }
00630
00631 static Vec4<T> xAxis() { return Vec4<T>( 1, 0, 0, 0 ); }
00632 static Vec4<T> yAxis() { return Vec4<T>( 0, 1, 0, 0 ); }
00633 static Vec4<T> zAxis() { return Vec4<T>( 0, 0, 1, 0 ); }
00634 static Vec4<T> wAxis() { return Vec4<T>( 0, 0, 0, 1 ); }
00635 };
00636
00637 template<typename T,typename Y> inline Vec2<T> operator *( Y s, const Vec2<T> &v ) { return Vec2<T>( v.x * s, v.y * s ); }
00638 template<typename T,typename Y> inline Vec2<T> operator *( const Vec2<T> &v, Y s ) { return Vec2<T>( v.x * s, v.y * s ); }
00639 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 ); }
00640 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 ); }
00641 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 ); }
00642 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 ); }
00643
00644
00645 typedef Vec2<float> Vec2f;
00646 typedef Vec2<double> Vec2d;
00647 typedef Vec3<float> Vec3f;
00648 typedef Vec3<double> Vec3d;
00649 typedef Vec4<float> Vec4f;
00650 typedef Vec4<double> Vec4d;
00651 typedef Vec2<int> Vec2i;
00652
00653 }