Blender V2.61 - r43446
|
00001 00004 /****************************************************************************** 00005 * 00006 * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method 00007 * Copyright 2003-2006 Nils Thuerey 00008 * 00009 * Basic vector class used everywhere, either blitz or inlined GRAPA class 00010 * 00011 *****************************************************************************/ 00012 #ifndef NTL_VECTOR3DIM_H 00013 #define NTL_VECTOR3DIM_H 00014 00015 // this serves as the main include file 00016 // for all kinds of stuff that might be required 00017 // under windos there seem to be strange 00018 // errors when including the STL header too 00019 // late... 00020 #include <iostream> 00021 #include <map> 00022 #include <vector> 00023 #include <string> 00024 #include <sstream> 00025 #include <math.h> 00026 #include <string.h> 00027 #include <stdio.h> 00028 #include <stdlib.h> 00029 00030 // hack for MSVC6.0 compiler 00031 #ifdef _MSC_VER 00032 #if _MSC_VER < 1300 00033 #define for if(false); else for 00034 #define map std::map 00035 #define vector std::vector 00036 #define string std::string 00037 // use this define for MSVC6 stuff hereafter 00038 #define USE_MSVC6FIXES 00039 #else // _MSC_VER < 1300 , 7.0 or higher 00040 using std::map; 00041 using std::vector; 00042 using std::string; 00043 #endif 00044 #else // not MSVC6 00045 // for proper compilers... 00046 using std::map; 00047 using std::vector; 00048 using std::string; 00049 #endif // MSVC6 00050 00051 #ifdef __APPLE_CC__ 00052 // apple 00053 #else 00054 #ifdef WIN32 00055 00056 // windows values missing, see below 00057 #ifndef snprintf 00058 #define snprintf _snprintf 00059 #endif 00060 #ifndef bool 00061 #define bool int 00062 #endif 00063 #ifndef false 00064 #define false 0 00065 #endif 00066 #ifndef true 00067 #define true 1 00068 #endif 00069 00070 #else // WIN32 00071 00072 // floating point limits for linux,*bsd etc... 00073 #include <float.h> 00074 00075 #endif // WIN32 00076 #endif // __APPLE_CC__ 00077 00078 // windos, hardcoded limits for now... 00079 // for e.g. MSVC compiler... 00080 // some of these defines can be needed 00081 // for linux systems as well (e.g. FLT_MAX) 00082 #ifndef __FLT_MAX__ 00083 # ifdef FLT_MAX // try to use it instead 00084 # define __FLT_MAX__ FLT_MAX 00085 # else // FLT_MAX 00086 # define __FLT_MAX__ 3.402823466e+38f 00087 # endif // FLT_MAX 00088 #endif // __FLT_MAX__ 00089 #ifndef __DBL_MAX__ 00090 # ifdef DBL_MAX // try to use it instead 00091 # define __DBL_MAX__ DBL_MAX 00092 # else // DBL_MAX 00093 # define __DBL_MAX__ 1.7976931348623158e+308 00094 # endif // DBL_MAX 00095 #endif // __DBL_MAX__ 00096 00097 #ifndef M_PI 00098 #define M_PI 3.1415926536 00099 #define M_E 2.7182818284 00100 #endif 00101 00102 // make sure elbeem plugin def is valid 00103 #if ELBEEM_BLENDER==1 00104 #ifndef ELBEEM_PLUGIN 00105 #define ELBEEM_PLUGIN 1 00106 #endif // !ELBEEM_PLUGIN 00107 #endif // ELBEEM_BLENDER==1 00108 00109 // make sure GUI support is disabled for plugin use 00110 #if ELBEEM_PLUGIN==1 00111 #ifndef NOGUI 00112 #define NOGUI 1 00113 #endif // !NOGUI 00114 #endif // ELBEEM_PLUGIN==1 00115 00116 00117 // basic inlined vector class 00118 template<class Scalar> 00119 class ntlVector3Dim 00120 { 00121 public: 00122 // Constructor 00123 inline ntlVector3Dim(void ); 00124 // Copy-Constructor 00125 inline ntlVector3Dim(const ntlVector3Dim<Scalar> &v ); 00126 inline ntlVector3Dim(const float *); 00127 inline ntlVector3Dim(const double *); 00128 // construct a vector from one Scalar 00129 inline ntlVector3Dim(Scalar); 00130 // construct a vector from three Scalars 00131 inline ntlVector3Dim(Scalar, Scalar, Scalar); 00132 00133 // get address of array for OpenGL 00134 Scalar *getAddress() { return value; } 00135 00136 // Assignment operator 00137 inline const ntlVector3Dim<Scalar>& operator= (const ntlVector3Dim<Scalar>& v); 00138 // Assignment operator 00139 inline const ntlVector3Dim<Scalar>& operator= (Scalar s); 00140 // Assign and add operator 00141 inline const ntlVector3Dim<Scalar>& operator+= (const ntlVector3Dim<Scalar>& v); 00142 // Assign and add operator 00143 inline const ntlVector3Dim<Scalar>& operator+= (Scalar s); 00144 // Assign and sub operator 00145 inline const ntlVector3Dim<Scalar>& operator-= (const ntlVector3Dim<Scalar>& v); 00146 // Assign and sub operator 00147 inline const ntlVector3Dim<Scalar>& operator-= (Scalar s); 00148 // Assign and mult operator 00149 inline const ntlVector3Dim<Scalar>& operator*= (const ntlVector3Dim<Scalar>& v); 00150 // Assign and mult operator 00151 inline const ntlVector3Dim<Scalar>& operator*= (Scalar s); 00152 // Assign and div operator 00153 inline const ntlVector3Dim<Scalar>& operator/= (const ntlVector3Dim<Scalar>& v); 00154 // Assign and div operator 00155 inline const ntlVector3Dim<Scalar>& operator/= (Scalar s); 00156 00157 00158 // unary operator 00159 inline ntlVector3Dim<Scalar> operator- () const; 00160 00161 // binary operator add 00162 inline ntlVector3Dim<Scalar> operator+ (const ntlVector3Dim<Scalar>&) const; 00163 // binary operator add 00164 inline ntlVector3Dim<Scalar> operator+ (Scalar) const; 00165 // binary operator sub 00166 inline ntlVector3Dim<Scalar> operator- (const ntlVector3Dim<Scalar>&) const; 00167 // binary operator sub 00168 inline ntlVector3Dim<Scalar> operator- (Scalar) const; 00169 // binary operator mult 00170 inline ntlVector3Dim<Scalar> operator* (const ntlVector3Dim<Scalar>&) const; 00171 // binary operator mult 00172 inline ntlVector3Dim<Scalar> operator* (Scalar) const; 00173 // binary operator div 00174 inline ntlVector3Dim<Scalar> operator/ (const ntlVector3Dim<Scalar>&) const; 00175 // binary operator div 00176 inline ntlVector3Dim<Scalar> operator/ (Scalar) const; 00177 00178 // Projection normal to a vector 00179 inline ntlVector3Dim<Scalar> getOrthogonalntlVector3Dim() const; 00180 // Project into a plane 00181 inline const ntlVector3Dim<Scalar>& projectNormalTo(const ntlVector3Dim<Scalar> &v); 00182 00183 // minimize 00184 inline const ntlVector3Dim<Scalar> &minimize(const ntlVector3Dim<Scalar> &); 00185 // maximize 00186 inline const ntlVector3Dim<Scalar> &maximize(const ntlVector3Dim<Scalar> &); 00187 00188 // access operator 00189 inline Scalar& operator[](unsigned int i); 00190 // access operator 00191 inline const Scalar& operator[](unsigned int i) const; 00192 00193 protected: 00194 00195 private: 00196 Scalar value[3]; //< Storage of vector values 00197 }; 00198 00199 00200 00201 00202 //------------------------------------------------------------------------------ 00203 // STREAM FUNCTIONS 00204 //------------------------------------------------------------------------------ 00205 00206 00207 00209 extern const char *globVecFormatStr; 00210 00211 /************************************************************************* 00212 Outputs the object in human readable form using the format 00213 [x,y,z] 00214 */ 00215 template<class Scalar> 00216 std::ostream& 00217 operator<<( std::ostream& os, const ntlVector3Dim<Scalar>& i ) 00218 { 00219 char buf[256]; 00220 snprintf(buf,256,globVecFormatStr,i[0],i[1],i[2]); 00221 os << string(buf); 00222 //os << '[' << i[0] << ", " << i[1] << ", " << i[2] << ']'; 00223 return os; 00224 } 00225 00226 00227 00228 /************************************************************************* 00229 Reads the contents of the object from a stream using the same format 00230 as the output operator. 00231 */ 00232 template<class Scalar> 00233 std::istream& 00234 operator>>( std::istream& is, ntlVector3Dim<Scalar>& i ) 00235 { 00236 char c; 00237 char dummy[3]; 00238 is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c; 00239 return is; 00240 } 00241 00242 00243 //------------------------------------------------------------------------------ 00244 // VECTOR inline FUNCTIONS 00245 //------------------------------------------------------------------------------ 00246 00247 00248 00249 /************************************************************************* 00250 Constructor. 00251 */ 00252 template<class Scalar> 00253 inline ntlVector3Dim<Scalar>::ntlVector3Dim( void ) 00254 { 00255 value[0] = value[1] = value[2] = 0; 00256 } 00257 00258 00259 00260 /************************************************************************* 00261 Copy-Constructor. 00262 */ 00263 template<class Scalar> 00264 inline ntlVector3Dim<Scalar>::ntlVector3Dim( const ntlVector3Dim<Scalar> &v ) 00265 { 00266 value[0] = v.value[0]; 00267 value[1] = v.value[1]; 00268 value[2] = v.value[2]; 00269 } 00270 template<class Scalar> 00271 inline ntlVector3Dim<Scalar>::ntlVector3Dim( const float *fvalue) 00272 { 00273 value[0] = (Scalar)fvalue[0]; 00274 value[1] = (Scalar)fvalue[1]; 00275 value[2] = (Scalar)fvalue[2]; 00276 } 00277 template<class Scalar> 00278 inline ntlVector3Dim<Scalar>::ntlVector3Dim( const double *fvalue) 00279 { 00280 value[0] = (Scalar)fvalue[0]; 00281 value[1] = (Scalar)fvalue[1]; 00282 value[2] = (Scalar)fvalue[2]; 00283 } 00284 00285 00286 00287 /************************************************************************* 00288 Constructor for a vector from a single Scalar. All components of 00289 the vector get the same value. 00290 \param s The value to set 00291 \return The new vector 00292 */ 00293 template<class Scalar> 00294 inline ntlVector3Dim<Scalar>::ntlVector3Dim(Scalar s ) 00295 { 00296 value[0]= s; 00297 value[1]= s; 00298 value[2]= s; 00299 } 00300 00301 00302 /************************************************************************* 00303 Constructor for a vector from three Scalars. 00304 \param s1 The value for the first vector component 00305 \param s2 The value for the second vector component 00306 \param s3 The value for the third vector component 00307 \return The new vector 00308 */ 00309 template<class Scalar> 00310 inline ntlVector3Dim<Scalar>::ntlVector3Dim(Scalar s1, Scalar s2, Scalar s3) 00311 { 00312 value[0]= s1; 00313 value[1]= s2; 00314 value[2]= s3; 00315 } 00316 00317 00318 /************************************************************************* 00319 Compute the vector product of two 3D vectors 00320 \param v Second vector to compute the product with 00321 \return A new vector with the product values 00322 */ 00323 /*template<class Scalar> 00324 inline ntlVector3Dim<Scalar> 00325 ntlVector3Dim<Scalar>::operator^( const ntlVector3Dim<Scalar> &v ) const 00326 { 00327 return ntlVector3Dim<Scalar>(value[1]*v.value[2] - value[2]*v.value[1], 00328 value[2]*v.value[0] - value[0]*v.value[2], 00329 value[0]*v.value[1] - value[1]*v.value[0]); 00330 }*/ 00331 00332 00333 /************************************************************************* 00334 Copy a ntlVector3Dim componentwise. 00335 \param v vector with values to be copied 00336 \return Reference to self 00337 */ 00338 template<class Scalar> 00339 inline const ntlVector3Dim<Scalar>& 00340 ntlVector3Dim<Scalar>::operator=( const ntlVector3Dim<Scalar> &v ) 00341 { 00342 value[0] = v.value[0]; 00343 value[1] = v.value[1]; 00344 value[2] = v.value[2]; 00345 return *this; 00346 } 00347 00348 00349 /************************************************************************* 00350 Copy a Scalar to each component. 00351 \param s The value to copy 00352 \return Reference to self 00353 */ 00354 template<class Scalar> 00355 inline const ntlVector3Dim<Scalar>& 00356 ntlVector3Dim<Scalar>::operator=(Scalar s) 00357 { 00358 value[0] = s; 00359 value[1] = s; 00360 value[2] = s; 00361 return *this; 00362 } 00363 00364 00365 /************************************************************************* 00366 Add another ntlVector3Dim componentwise. 00367 \param v vector with values to be added 00368 \return Reference to self 00369 */ 00370 template<class Scalar> 00371 inline const ntlVector3Dim<Scalar>& 00372 ntlVector3Dim<Scalar>::operator+=( const ntlVector3Dim<Scalar> &v ) 00373 { 00374 value[0] += v.value[0]; 00375 value[1] += v.value[1]; 00376 value[2] += v.value[2]; 00377 return *this; 00378 } 00379 00380 00381 /************************************************************************* 00382 Add a Scalar value to each component. 00383 \param s Value to add 00384 \return Reference to self 00385 */ 00386 template<class Scalar> 00387 inline const ntlVector3Dim<Scalar>& 00388 ntlVector3Dim<Scalar>::operator+=(Scalar s) 00389 { 00390 value[0] += s; 00391 value[1] += s; 00392 value[2] += s; 00393 return *this; 00394 } 00395 00396 00397 /************************************************************************* 00398 Subtract another vector componentwise. 00399 \param v vector of values to subtract 00400 \return Reference to self 00401 */ 00402 template<class Scalar> 00403 inline const ntlVector3Dim<Scalar>& 00404 ntlVector3Dim<Scalar>::operator-=( const ntlVector3Dim<Scalar> &v ) 00405 { 00406 value[0] -= v.value[0]; 00407 value[1] -= v.value[1]; 00408 value[2] -= v.value[2]; 00409 return *this; 00410 } 00411 00412 00413 /************************************************************************* 00414 Subtract a Scalar value from each component. 00415 \param s Value to subtract 00416 \return Reference to self 00417 */ 00418 template<class Scalar> 00419 inline const ntlVector3Dim<Scalar>& 00420 ntlVector3Dim<Scalar>::operator-=(Scalar s) 00421 { 00422 value[0]-= s; 00423 value[1]-= s; 00424 value[2]-= s; 00425 return *this; 00426 } 00427 00428 00429 /************************************************************************* 00430 Multiply with another vector componentwise. 00431 \param v vector of values to multiply with 00432 \return Reference to self 00433 */ 00434 template<class Scalar> 00435 inline const ntlVector3Dim<Scalar>& 00436 ntlVector3Dim<Scalar>::operator*=( const ntlVector3Dim<Scalar> &v ) 00437 { 00438 value[0] *= v.value[0]; 00439 value[1] *= v.value[1]; 00440 value[2] *= v.value[2]; 00441 return *this; 00442 } 00443 00444 00445 /************************************************************************* 00446 Multiply each component with a Scalar value. 00447 \param s Value to multiply with 00448 \return Reference to self 00449 */ 00450 template<class Scalar> 00451 inline const ntlVector3Dim<Scalar>& 00452 ntlVector3Dim<Scalar>::operator*=(Scalar s) 00453 { 00454 value[0] *= s; 00455 value[1] *= s; 00456 value[2] *= s; 00457 return *this; 00458 } 00459 00460 00461 /************************************************************************* 00462 Divide by another ntlVector3Dim componentwise. 00463 \param v vector of values to divide by 00464 \return Reference to self 00465 */ 00466 template<class Scalar> 00467 inline const ntlVector3Dim<Scalar>& 00468 ntlVector3Dim<Scalar>::operator/=( const ntlVector3Dim<Scalar> &v ) 00469 { 00470 value[0] /= v.value[0]; 00471 value[1] /= v.value[1]; 00472 value[2] /= v.value[2]; 00473 return *this; 00474 } 00475 00476 00477 /************************************************************************* 00478 Divide each component by a Scalar value. 00479 \param s Value to divide by 00480 \return Reference to self 00481 */ 00482 template<class Scalar> 00483 inline const ntlVector3Dim<Scalar>& 00484 ntlVector3Dim<Scalar>::operator/=(Scalar s) 00485 { 00486 value[0] /= s; 00487 value[1] /= s; 00488 value[2] /= s; 00489 return *this; 00490 } 00491 00492 00493 //------------------------------------------------------------------------------ 00494 // unary operators 00495 //------------------------------------------------------------------------------ 00496 00497 00498 /************************************************************************* 00499 Build componentwise the negative this vector. 00500 \return The new (negative) vector 00501 */ 00502 template<class Scalar> 00503 inline ntlVector3Dim<Scalar> 00504 ntlVector3Dim<Scalar>::operator-() const 00505 { 00506 return ntlVector3Dim<Scalar>(-value[0], -value[1], -value[2]); 00507 } 00508 00509 00510 00511 //------------------------------------------------------------------------------ 00512 // binary operators 00513 //------------------------------------------------------------------------------ 00514 00515 00516 /************************************************************************* 00517 Build a vector with another vector added componentwise. 00518 \param v The second vector to add 00519 \return The sum vector 00520 */ 00521 template<class Scalar> 00522 inline ntlVector3Dim<Scalar> 00523 ntlVector3Dim<Scalar>::operator+( const ntlVector3Dim<Scalar> &v ) const 00524 { 00525 return ntlVector3Dim<Scalar>(value[0]+v.value[0], 00526 value[1]+v.value[1], 00527 value[2]+v.value[2]); 00528 } 00529 00530 00531 /************************************************************************* 00532 Build a vector with a Scalar value added to each component. 00533 \param s The Scalar value to add 00534 \return The sum vector 00535 */ 00536 template<class Scalar> 00537 inline ntlVector3Dim<Scalar> 00538 ntlVector3Dim<Scalar>::operator+(Scalar s) const 00539 { 00540 return ntlVector3Dim<Scalar>(value[0]+s, 00541 value[1]+s, 00542 value[2]+s); 00543 } 00544 00545 00546 /************************************************************************* 00547 Build a vector with another vector subtracted componentwise. 00548 \param v The second vector to subtract 00549 \return The difference vector 00550 */ 00551 template<class Scalar> 00552 inline ntlVector3Dim<Scalar> 00553 ntlVector3Dim<Scalar>::operator-( const ntlVector3Dim<Scalar> &v ) const 00554 { 00555 return ntlVector3Dim<Scalar>(value[0]-v.value[0], 00556 value[1]-v.value[1], 00557 value[2]-v.value[2]); 00558 } 00559 00560 00561 /************************************************************************* 00562 Build a vector with a Scalar value subtracted componentwise. 00563 \param s The Scalar value to subtract 00564 \return The difference vector 00565 */ 00566 template<class Scalar> 00567 inline ntlVector3Dim<Scalar> 00568 ntlVector3Dim<Scalar>::operator-(Scalar s ) const 00569 { 00570 return ntlVector3Dim<Scalar>(value[0]-s, 00571 value[1]-s, 00572 value[2]-s); 00573 } 00574 00575 00576 00577 /************************************************************************* 00578 Build a vector with another vector multiplied by componentwise. 00579 \param v The second vector to muliply with 00580 \return The product vector 00581 */ 00582 template<class Scalar> 00583 inline ntlVector3Dim<Scalar> 00584 ntlVector3Dim<Scalar>::operator*( const ntlVector3Dim<Scalar>& v) const 00585 { 00586 return ntlVector3Dim<Scalar>(value[0]*v.value[0], 00587 value[1]*v.value[1], 00588 value[2]*v.value[2]); 00589 } 00590 00591 00592 /************************************************************************* 00593 Build a ntlVector3Dim with a Scalar value multiplied to each component. 00594 \param s The Scalar value to multiply with 00595 \return The product vector 00596 */ 00597 template<class Scalar> 00598 inline ntlVector3Dim<Scalar> 00599 ntlVector3Dim<Scalar>::operator*(Scalar s) const 00600 { 00601 return ntlVector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s); 00602 } 00603 00604 00605 /************************************************************************* 00606 Build a vector divided componentwise by another vector. 00607 \param v The second vector to divide by 00608 \return The ratio vector 00609 */ 00610 template<class Scalar> 00611 inline ntlVector3Dim<Scalar> 00612 ntlVector3Dim<Scalar>::operator/(const ntlVector3Dim<Scalar>& v) const 00613 { 00614 return ntlVector3Dim<Scalar>(value[0]/v.value[0], 00615 value[1]/v.value[1], 00616 value[2]/v.value[2]); 00617 } 00618 00619 00620 00621 /************************************************************************* 00622 Build a vector divided componentwise by a Scalar value. 00623 \param s The Scalar value to divide by 00624 \return The ratio vector 00625 */ 00626 template<class Scalar> 00627 inline ntlVector3Dim<Scalar> 00628 ntlVector3Dim<Scalar>::operator/(Scalar s) const 00629 { 00630 return ntlVector3Dim<Scalar>(value[0]/s, 00631 value[1]/s, 00632 value[2]/s); 00633 } 00634 00635 00636 00637 00638 00639 /************************************************************************* 00640 Get a particular component of the vector. 00641 \param i Number of Scalar to get 00642 \return Reference to the component 00643 */ 00644 template<class Scalar> 00645 inline Scalar& 00646 ntlVector3Dim<Scalar>::operator[]( unsigned int i ) 00647 { 00648 return value[i]; 00649 } 00650 00651 00652 /************************************************************************* 00653 Get a particular component of a constant vector. 00654 \param i Number of Scalar to get 00655 \return Reference to the component 00656 */ 00657 template<class Scalar> 00658 inline const Scalar& 00659 ntlVector3Dim<Scalar>::operator[]( unsigned int i ) const 00660 { 00661 return value[i]; 00662 } 00663 00664 00665 00666 //------------------------------------------------------------------------------ 00667 // BLITZ compatibility functions 00668 //------------------------------------------------------------------------------ 00669 00670 00671 00672 /************************************************************************* 00673 Compute the scalar product with another vector. 00674 \param v The second vector to work with 00675 \return The value of the scalar product 00676 */ 00677 template<class Scalar> 00678 inline Scalar dot(const ntlVector3Dim<Scalar> &t, const ntlVector3Dim<Scalar> &v ) 00679 { 00680 //return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2]; 00681 return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2])); 00682 } 00683 00684 00685 /************************************************************************* 00686 Calculate the cross product of this and another vector 00687 */ 00688 template<class Scalar> 00689 inline ntlVector3Dim<Scalar> cross(const ntlVector3Dim<Scalar> &t, const ntlVector3Dim<Scalar> &v) 00690 { 00691 ntlVector3Dim<Scalar> cp( 00692 ((t[1]*v[2]) - (t[2]*v[1])), 00693 ((t[2]*v[0]) - (t[0]*v[2])), 00694 ((t[0]*v[1]) - (t[1]*v[0])) ); 00695 return cp; 00696 } 00697 00698 00699 00700 00701 /************************************************************************* 00702 Compute a vector that is orthonormal to self. Nothing else can be assumed 00703 for the direction of the new vector. 00704 \return The orthonormal vector 00705 */ 00706 template<class Scalar> 00707 ntlVector3Dim<Scalar> 00708 ntlVector3Dim<Scalar>::getOrthogonalntlVector3Dim() const 00709 { 00710 // Determine the component with max. absolute value 00711 int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1; 00712 max= (fabs(value[max]) > fabs(value[2])) ? max : 2; 00713 00714 /************************************************************************* 00715 Choose another axis than the one with max. component and project 00716 orthogonal to self 00717 */ 00718 ntlVector3Dim<Scalar> vec(0.0); 00719 vec[(max+1)%3]= 1; 00720 vec.normalize(); 00721 vec.projectNormalTo(this->getNormalized()); 00722 return vec; 00723 } 00724 00725 00726 /************************************************************************* 00727 Projects the vector into a plane normal to the given vector, which must 00728 have unit length. Self is modified. 00729 \param v The plane normal 00730 \return The projected vector 00731 */ 00732 template<class Scalar> 00733 inline const ntlVector3Dim<Scalar>& 00734 ntlVector3Dim<Scalar>::projectNormalTo(const ntlVector3Dim<Scalar> &v) 00735 { 00736 Scalar sprod = dot(*this,v); 00737 value[0]= value[0] - v.value[0] * sprod; 00738 value[1]= value[1] - v.value[1] * sprod; 00739 value[2]= value[2] - v.value[2] * sprod; 00740 return *this; 00741 } 00742 00743 00744 00745 //------------------------------------------------------------------------------ 00746 // Other helper functions 00747 //------------------------------------------------------------------------------ 00748 00749 00750 00751 /************************************************************************* 00752 Minimize the vector, i.e. set each entry of the vector to the minimum 00753 of both values. 00754 \param pnt The second vector to compare with 00755 \return Reference to the modified self 00756 */ 00757 template<class Scalar> 00758 inline const ntlVector3Dim<Scalar> & 00759 ntlVector3Dim<Scalar>::minimize(const ntlVector3Dim<Scalar> &pnt) 00760 { 00761 for (unsigned int i = 0; i < 3; i++) 00762 value[i] = MIN(value[i],pnt[i]); 00763 return *this; 00764 } 00765 00766 00767 00768 /************************************************************************* 00769 Maximize the vector, i.e. set each entry of the vector to the maximum 00770 of both values. 00771 \param pnt The second vector to compare with 00772 \return Reference to the modified self 00773 */ 00774 template<class Scalar> 00775 inline const ntlVector3Dim<Scalar> & 00776 ntlVector3Dim<Scalar>::maximize(const ntlVector3Dim<Scalar> &pnt) 00777 { 00778 for (unsigned int i = 0; i < 3; i++) 00779 value[i] = MAX(value[i],pnt[i]); 00780 return *this; 00781 } 00782 00783 00784 00785 00786 // ---- 00787 00788 // a 3D vector with double precision 00789 typedef ntlVector3Dim<double> ntlVec3d; 00790 00791 // a 3D vector with single precision 00792 typedef ntlVector3Dim<float> ntlVec3f; 00793 00794 // a 3D integer vector 00795 typedef ntlVector3Dim<int> ntlVec3i; 00796 00797 // Color uses single precision fp values 00798 typedef ntlVec3f ntlColor; 00799 00800 /* convert a float to double vector */ 00801 template<class T> inline ntlVec3d vec2D(T v) { return ntlVec3d(v[0],v[1],v[2]); } 00802 template<class T> inline ntlVec3f vec2F(T v) { return ntlVec3f(v[0],v[1],v[2]); } 00803 template<class T> inline ntlColor vec2Col(T v) { return ntlColor(v[0],v[1],v[2]); } 00804 00805 00806 00807 /************************************************************************/ 00808 // graphics vector typing 00809 00810 00811 // use which fp-precision for raytracing? 1=float, 2=double 00812 00813 /* VECTOR_EPSILON is the minimal vector length 00814 In order to be able to discriminate floating point values near zero, and 00815 to be sure not to fail a comparison because of roundoff errors, use this 00816 value as a threshold. */ 00817 00818 // use which fp-precision for graphics? 1=float, 2=double 00819 #ifdef PRECISION_GFX_SINGLE 00820 #define GFX_PRECISION 1 00821 #else 00822 #ifdef PRECISION_GFX_DOUBLE 00823 #define GFX_PRECISION 2 00824 #else 00825 // standard precision for graphics 00826 #ifndef GFX_PRECISION 00827 #define GFX_PRECISION 1 00828 #endif 00829 #endif 00830 #endif 00831 00832 #if GFX_PRECISION==1 00833 typedef float gfxReal; 00834 #define GFX_REAL_MAX __FLT_MAX__ 00835 //#define vecF2Gfx(x) (x) 00836 //#define vecGfx2F(x) (x) 00837 //#define vecD2Gfx(x) vecD2F(x) 00838 //#define vecGfx2D(x) vecF2D(x) 00839 #define VECTOR_EPSILON (1e-5f) 00840 #else 00841 typedef double gfxReal; 00842 #define GFX_REAL_MAX __DBL_MAX__ 00843 //#define vecF2Gfx(x) vecD2F(x) 00844 //#define vecGfx2F(x) vecF2D(x) 00845 //#define vecD2Gfx(x) (x) 00846 //#define vecGfx2D(x) (x) 00847 #define VECTOR_EPSILON (1e-10) 00848 #endif 00849 00850 /* fixed double prec. type, for epxlicitly double values */ 00851 typedef double gfxDouble; 00852 00853 // a 3D vector for graphics output, typically float? 00854 typedef ntlVector3Dim<gfxReal> ntlVec3Gfx; 00855 00856 template<class T> inline ntlVec3Gfx vec2G(T v) { return ntlVec3Gfx(v[0],v[1],v[2]); } 00857 00858 /* get minimal vector length value that can be discriminated. */ 00859 //inline double getVecEpsilon() { return (double)VECTOR_EPSILON; } 00860 inline gfxReal getVecEpsilon() { return (gfxReal)VECTOR_EPSILON; } 00861 00862 #define HAVE_GFXTYPES 00863 00864 00865 00866 00867 /************************************************************************/ 00868 // HELPER FUNCTIONS, independent of implementation 00869 /************************************************************************/ 00870 00871 #define VECTOR_TYPE ntlVector3Dim<Scalar> 00872 00873 00874 /************************************************************************* 00875 Compute the length (norm) of the vector. 00876 \return The value of the norm 00877 */ 00878 template<class Scalar> 00879 inline Scalar norm( const VECTOR_TYPE &v) 00880 { 00881 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00882 return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l); 00883 } 00884 00885 00886 /************************************************************************* 00887 Same as getNorm but doesnt sqrt 00888 */ 00889 template<class Scalar> 00890 inline Scalar normNoSqrt( const VECTOR_TYPE &v) 00891 { 00892 return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00893 } 00894 00895 00896 /************************************************************************* 00897 Compute a normalized vector based on this vector. 00898 \return The new normalized vector 00899 */ 00900 template<class Scalar> 00901 inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v) 00902 { 00903 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00904 if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) 00905 return v; /* normalized "enough"... */ 00906 else if (l > VECTOR_EPSILON*VECTOR_EPSILON) 00907 { 00908 Scalar fac = 1./sqrt(l); 00909 return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac); 00910 } 00911 else 00912 return VECTOR_TYPE((Scalar)0); 00913 } 00914 00915 00916 /************************************************************************* 00917 Compute the norm of the vector and normalize it. 00918 \return The value of the norm 00919 */ 00920 template<class Scalar> 00921 inline Scalar normalize( VECTOR_TYPE &v) 00922 { 00923 Scalar norm; 00924 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00925 if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) { 00926 norm = 1.; 00927 } else if (l > VECTOR_EPSILON*VECTOR_EPSILON) { 00928 norm = sqrt(l); 00929 Scalar fac = 1./norm; 00930 v[0] *= fac; 00931 v[1] *= fac; 00932 v[2] *= fac; 00933 } else { 00934 v[0]= v[1]= v[2]= 0; 00935 norm = 0.; 00936 } 00937 return (Scalar)norm; 00938 } 00939 00940 00941 /************************************************************************* 00942 Compute a vector, that is self (as an incoming 00943 vector) reflected at a surface with a distinct normal vector. Note 00944 that the normal is reversed, if the scalar product with it is positive. 00945 \param n The surface normal 00946 \return The new reflected vector 00947 */ 00948 template<class Scalar> 00949 inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n) 00950 { 00951 VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n; 00952 return ( t - nn * (2.0 * dot(nn, t)) ); 00953 } 00954 00955 00956 00957 /************************************************************************* 00958 * My own refraction calculation 00959 * Taken from Glassner's book, section 5.2 (Heckberts method) 00960 */ 00961 template<class Scalar> 00962 inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl) 00963 { 00964 Scalar eta = nair / nt; 00965 Scalar n = -dot(t, normal); 00966 Scalar tt = 1.0 + eta*eta* (n*n-1.0); 00967 if(tt<0.0) { 00968 // we have total reflection! 00969 refRefl = 1; 00970 } else { 00971 // normal reflection 00972 tt = eta*n - sqrt(tt); 00973 return( t*eta + normal*tt ); 00974 } 00975 return t; 00976 } 00977 /*double eta = nair / nt; 00978 double n = -((*this) | normal); 00979 double t = 1.0 + eta*eta* (n*n-1.0); 00980 if(t<0.0) { 00981 // we have total reflection! 00982 refRefl = 1; 00983 } else { 00984 // normal reflection 00985 t = eta*n - sqrt(t); 00986 return( (*this)*eta + normal*t ); 00987 } 00988 return (*this);*/ 00989 00990 00991 /************************************************************************* 00992 Test two ntlVector3Dims for equality based on the equality of their 00993 values within a small threshold. 00994 \param c The second vector to compare 00995 \return TRUE if both are equal 00996 \sa getEpsilon() 00997 */ 00998 template<class Scalar> 00999 inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c) 01000 { 01001 return (ABS(v[0]-c[0]) + 01002 ABS(v[1]-c[1]) + 01003 ABS(v[2]-c[2]) < VECTOR_EPSILON); 01004 } 01005 01006 01007 /************************************************************************* 01008 * Assume this vector is an RGB color, and convert it to HSV 01009 */ 01010 template<class Scalar> 01011 inline void rgbToHsv( VECTOR_TYPE &V ) 01012 { 01013 Scalar h=0,s=0,v=0; 01014 Scalar maxrgb, minrgb, delta; 01015 // convert to hsv... 01016 maxrgb = V[0]; 01017 int maxindex = 1; 01018 if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; } 01019 if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; } 01020 minrgb = V[0]; 01021 if(V[2] < minrgb) minrgb = V[2]; 01022 if(V[1] < minrgb) minrgb = V[1]; 01023 01024 v = maxrgb; 01025 delta = maxrgb-minrgb; 01026 01027 if(maxrgb > 0) s = delta/maxrgb; 01028 else s = 0; 01029 01030 h = 0; 01031 if(s > 0) { 01032 if(maxindex == 1) { 01033 h = ((V[1]-V[2])/delta) + 0.0; } 01034 if(maxindex == 2) { 01035 h = ((V[2]-V[0])/delta) + 2.0; } 01036 if(maxindex == 3) { 01037 h = ((V[0]-V[1])/delta) + 4.0; } 01038 h *= 60.0; 01039 if(h < 0.0) h += 360.0; 01040 } 01041 01042 V[0] = h; 01043 V[1] = s; 01044 V[2] = v; 01045 } 01046 01047 /************************************************************************* 01048 * Assume this vector is HSV and convert to RGB 01049 */ 01050 template<class Scalar> 01051 inline void hsvToRgb( VECTOR_TYPE &V ) 01052 { 01053 Scalar h = V[0], s = V[1], v = V[2]; 01054 Scalar r=0,g=0,b=0; 01055 Scalar p,q,t, fracth; 01056 int floorh; 01057 // ...and back to rgb 01058 if(s == 0) { 01059 r = g = b = v; } 01060 else { 01061 h /= 60.0; 01062 floorh = (int)h; 01063 fracth = h - floorh; 01064 p = v * (1.0 - s); 01065 q = v * (1.0 - (s * fracth)); 01066 t = v * (1.0 - (s * (1.0 - fracth))); 01067 switch (floorh) { 01068 case 0: r = v; g = t; b = p; break; 01069 case 1: r = q; g = v; b = p; break; 01070 case 2: r = p; g = v; b = t; break; 01071 case 3: r = p; g = q; b = v; break; 01072 case 4: r = t; g = p; b = v; break; 01073 case 5: r = v; g = p; b = q; break; 01074 } 01075 } 01076 01077 V[0] = r; 01078 V[1] = g; 01079 V[2] = b; 01080 } 01081 01082 01083 01084 01085 #endif /* NTL_VECTOR3DIM_HH */