colmodel.h

Go to the documentation of this file.
00001 /* MAINTAINER: Petko CURRENT EDITOR: Bernard */
00002 #ifndef _COLMODEL_H
00003 #define _COLMODEL_H
00004 
00005 #include "GLVector.h"
00006 #include "GLQuaternion.h"
00007 
00008 
00009 inline double absD(double d)
00010 {
00011         return (d >=0)? d : -d;
00012 }
00013 
00014 
00015  /*@{ */
00017 
00018 const int BOTTOM_FRONT_LEFT     = 0;
00019 const int BOTTOM_FRONT_RIGHT= 1;
00020 const int BOTTOM_BACK_RIGHT     = 2;
00021 const int BOTTOM_BACK_LEFT      = 3;
00022 const int TOP_FRONT_LEFT        = 4;
00023 const int TOP_FRONT_RIGHT       = 5;
00024 const int TOP_BACK_RIGHT        = 6;
00025 const int TOP_BACK_LEFT         = 7;
00026 
00027 
00031 class CDBox
00032 {
00033 public:
00034         CDBox(){};
00035         virtual ~CDBox(){};
00036 
00043         GLVector3d mVertex[8];
00044 
00048         void zeroize()
00049         {
00050                 for (int i = 0; i < 8; i++ ) mVertex[i].set( 0, 0, 0 );
00051         }
00052 
00058         void translate( const GLVector3d translation )
00059         {
00060                 for (int i = 0; i < 8; i++ ) mVertex[i]+= translation;
00061         }
00062 
00066         void rotate( GLQuaterniond rotation )
00067         {
00068                 for (int i = 0; i < 8; i++ ) mVertex[i] = rotation.rotateVector( mVertex[i] );
00069         }
00070 
00071         
00078         double getMin(int cordinate) const
00079         {
00080                 double min = mVertex[0].val[cordinate];
00081                 for (int i = 1; i < 8; i++) if (mVertex[i].val[cordinate] < min) min = mVertex[i].val[cordinate];
00082                 return min;
00083         }
00084                 
00091         double getMax(int cordinate) const
00092         {
00093                 double max = mVertex[0].val[cordinate];
00094                 for (int i = 1; i < 8; i++) if (mVertex[i].val[cordinate] > max) max = mVertex[i].val[cordinate];
00095                 return max;
00096         }
00097 
00105         bool quickCheckCollision( const CDBox & box ) const
00106         {
00107                 for (int i = 0; i < 3; i++)
00108                 {
00109                         if (getMax(i) <= box.getMin(i) ||
00110                                 getMin(i) >= box.getMax(i)) return false;
00111                 }
00112                 return true;
00113         }
00114 
00125         void project(const GLVector3d &normal, double &min, double &max) const
00126         {
00127                 min = max = normal.dot(mVertex[0]);
00128                 for (int i = 1; i < 8; i++)
00129                 {
00130                         double d = normal.dot(mVertex[i]);
00131                         if (d < min) min = d;
00132                         if (d > max) max = d;
00133                 }
00134         }
00135 
00149         double trySepparatingAxis(const CDBox & box, int a1, int a2, int b1, int b2, GLVector3d &normal) const
00150         {
00151                 // compute normal vector of seprarating plane
00152                 normal = mVertex[a1]-mVertex[a2];
00153                 normal.cross(box.mVertex[b1]-box.mVertex[b2]);
00154                 
00155                 // Test for zero vector. The normalization
00156                 // isn't needed to decide the collision but it isn't possible
00157                 // to directly comprare values returned by this function without
00158                 // normalization.
00159                 // The length test is needed to avoid divison by zero :-)
00160                 if (normal.length() == 0) 
00161                 {
00162                         return 100000000;               
00163                 }
00164                 normal.normalize();
00165         
00166                 return projectAndCompare(*this, box, normal);
00167         }
00168 
00183         double trySepparatingAxisSelf(const CDBox & box, int a1, int a2, int b1, int b2, GLVector3d &normal) const
00184         {
00185                 // compute normal vector of seprarating plane
00186                 normal = mVertex[a1]-mVertex[a2];
00187                 normal.cross(mVertex[b1]-mVertex[b2]);
00188                 
00189                 // Test for zero vector. The normalization
00190                 // isn't needed to decide the collision but it isn't possible
00191                 // to directly comprare values returned by this function without
00192                 // normalization.
00193                 // The length test is needed to avoid divison by zero :-)
00194                 if (normal.length() == 0) 
00195                 {
00196                         return 100000000;               
00197                 }
00198                 normal.normalize();
00199         
00200                 return projectAndCompare(*this, box, normal);
00201         }
00202 
00212         static double projectAndCompare(const CDBox & box1, const CDBox & box2, const GLVector3d &normal)
00213         {               
00214                 // Get min / max for first box
00215                 double min1, max1;
00216                 box1.project(normal, min1, max1);
00217                 
00218                 // Get min / max for second box
00219                 double min2, max2;
00220                 box2.project(normal, min2, max2);
00221         
00222                 // Decide the colision
00223                 if (min2 >= max1 || min1 >= max2) 
00224                 {
00225                         return 0; // No collision
00226                 }
00227                 
00228                 if ( max1 - min2 > max2 - min1 ) return max2 - min1;
00229                 return min2 - max1;
00230         }
00231 
00232 };
00233 
00234 
00241 class CollisionModel
00242 {
00243 public:
00244         CollisionModel();
00245         virtual ~CollisionModel(){};
00246 
00254         bool checkCollision( const CollisionModel & model )
00255         {
00256                 return computeMinimalAvoidVector(model, mAvoidVector);
00257         }
00258         
00265         const GLVector3d & getAvoidVector()
00266         {
00267                 return mAvoidVector;
00268         }
00269 
00280         bool computeMinimalAvoidVector( const CollisionModel & model, GLVector3d & result );
00281 
00290         double computeMinimalAvoidDistance( const CollisionModel & model, GLVector3d & direction);
00291         
00297         void setTranslation( const GLVector3d &translation )
00298         {
00299                 mTranslation = translation;
00300         }
00301         
00308         void addTranslation( const GLVector3d &translation )
00309         {
00310                 mTranslation += translation;
00311         }
00312 
00318         void setRotation( const GLQuaterniond &rotation )
00319         {
00320                 mRotation = rotation;
00321         }
00322         
00328         void addRotation( const GLQuaterniond &rotation )
00329         {
00330                 mRotation *= rotation;
00331         }
00332 
00338         void finishTransformations()
00339         {
00340                 mTransBox = mBox;
00341                 mTransBox.rotate( mRotation );
00342                 mTransBox.translate( mTranslation );
00343                 mReseted = false;
00344         }
00345 
00349         void resetTransformations()
00350         {
00351                 mTranslation.set( 0, 0, 0 );
00352                 mRotation.set( 0, 0, 0, 0 );
00353                 mTransBox.zeroize();
00354                 mReseted = true;
00355         }
00356 
00360         bool isReseted() const
00361         {
00362                 return mReseted;
00363         }
00364 
00371         CDBox& getModel()
00372         {
00373                 return mBox;
00374         }
00375 
00380         CDBox& getTransModel()
00381         {
00382                 return mTransBox;
00383         }
00384 
00389         void setModel( const CDBox & model )
00390         {
00391                 mBox = model;
00392         }
00393 
00394 private:
00395 
00396         CDBox                   mBox;                   
00397 
00398         CDBox                   mTransBox;              
00399 
00400         bool                    mReseted;               
00401 
00402         GLVector3d              mTranslation;   
00403 
00404         GLQuaterniond   mRotation;              
00405 
00406         GLVector3d              mAvoidVector;   
00407 };
00408 
00410 #endif

Generated on Wed Apr 12 13:55:27 2006 for bjs by  doxygen 1.4.5