00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _collisionalgorithms_h_
00027 #define _collisionalgorithms_h_
00028
00069 #include <vector>
00070
00071 #include "mytools.h"
00072 #include "collisionStructures.h"
00073
00074 namespace Collision {
00075
00076 class Node;
00077 class Leaf;
00078 class Branch;
00079 class CollisionModel;
00080
00081 class RecursionCallback
00082 {
00083 protected:
00084 const CollisionModel *mModel1;
00085 const CollisionModel *mModel2;
00087 transf mTran2To1;
00089 transf mTran1To2;
00090
00091 int mNumLeafTests, mNumTriangleTests, mNumQuickTests;
00092 public:
00093 RecursionCallback(const CollisionModel *m1, const CollisionModel *m2);
00094 virtual void reset() {
00095 mNumLeafTests = 0;
00096 mNumTriangleTests = 0;
00097 mNumQuickTests = 0;
00098 }
00099 virtual ~RecursionCallback(){}
00100 virtual void leafTest(const Leaf *l1, const Leaf *l2) = 0;
00101 virtual double quickTest(const Node *n1, const Node *n2) = 0;
00102 virtual bool distanceTest(double d) = 0;
00103 virtual void printStatistics();
00104 };
00105
00107 void startRecursion(const CollisionModel *model1, const CollisionModel *model2,
00108 RecursionCallback *rc);
00109
00119 class CollisionCallback : public RecursionCallback
00120 {
00121 private:
00122 bool mCollision;
00123 public:
00124 CollisionCallback(const CollisionModel *m1, const CollisionModel *m2) :
00125 RecursionCallback(m1,m2){reset();}
00126 void reset(){
00127 RecursionCallback::reset();
00128 mCollision = false;
00129 }
00130 bool isCollision() const {return mCollision;}
00131 virtual void leafTest(const Leaf *l1, const Leaf *l2);
00132 virtual double quickTest(const Node *n1, const Node *n2);
00135 virtual bool distanceTest(double d) {
00136 if (mCollision) return false;
00137 if (d<0) return true;
00138 return false;
00139 }
00140 void printStatistics();
00141 };
00142
00151 class ContactCallback : public RecursionCallback
00152 {
00153 private:
00154 double mThreshold;
00155 ContactReport mReport;
00156
00157 void insertContactNoDuplicates(const position &p1, const position &p2,
00158 const vec3 &n1, const vec3 &n2,
00159 double distSq, double thresh);
00160 public:
00161 ContactCallback(double threshold, const CollisionModel *m1, const CollisionModel *m2) :
00162 RecursionCallback(m1,m2), mThreshold(threshold) {reset();}
00163
00164 virtual void reset() {
00165 RecursionCallback::reset();
00166 mReport.clear();
00167 }
00168 virtual void leafTest(const Leaf *l1, const Leaf *l2);
00169 virtual double quickTest(const Node *n1, const Node *n2);
00170 virtual bool distanceTest(double dSq) {
00171 if (dSq <= mThreshold * mThreshold) return true;
00172 return false;
00173 }
00174 const ContactReport& getReport(){return mReport;}
00175 void printStatistics();
00176 };
00177
00187 class DistanceCallback : public RecursionCallback
00188 {
00189 private:
00190 double mMinDistSq;
00191 position mP1, mP2;
00192 public:
00193 DistanceCallback(const CollisionModel *m1, const CollisionModel *m2) :
00194 RecursionCallback(m1,m2) {reset();}
00195 virtual void reset() {
00196 RecursionCallback::reset();
00197 mMinDistSq = 1.0e10;
00198 mP1 = position(0,0,0); mP2 = position(0,0,0);
00199 }
00200 virtual void leafTest(const Leaf *l1, const Leaf *l2);
00201 virtual double quickTest(const Node *n1, const Node *n2);
00202 virtual bool distanceTest(double dSq) {
00203 if (mMinDistSq < 0.0) return false;
00204 if (dSq<0.0 || dSq <= mMinDistSq) return true;
00205 return false;
00206 }
00207 double getMin() const {if (mMinDistSq<0.0) return -1.0; return sqrt(mMinDistSq);}
00208 void getClosestPoints(position &p1, position &p2) const {p1 = mP1; p2 = mP2;}
00209 void printStatistics();
00210 };
00211
00220 class ClosestPtCallback : public RecursionCallback
00221 {
00222 private:
00223 double mMinDistSq;
00224 position mRefPosition, mClosestPt;
00225 public:
00226 ClosestPtCallback(const CollisionModel *m1, const position &p) :
00227 RecursionCallback(m1, NULL), mRefPosition(p) {reset();}
00228 virtual void reset() {
00229 RecursionCallback::reset();
00230 mMinDistSq = 1.0e10;
00231 }
00232 virtual void leafTest(const Leaf *l1, const Leaf *l2);
00233 virtual double quickTest(const Node *n1, const Node *n2);
00234 virtual bool distanceTest(double dSq) {
00235 if (mMinDistSq < 0.0) return false;
00236 if (dSq<0.0 || dSq <= mMinDistSq) return true;
00237 return false;
00238 }
00239 double getMin() {if (mMinDistSq<0.0) return -1.0; return sqrt(mMinDistSq);}
00240 position getClosestPt() {return mClosestPt;}
00241 void printStatistics();
00242 };
00243
00252 class RegionCallback : public RecursionCallback
00253 {
00254 private:
00255 Neighborhood mNeighborhood;
00256 position mRefPosition;
00257 vec3 mNormal;
00258 double mRadiusSq;
00259
00260 void insertPoint(const position &point);
00261 public:
00262 RegionCallback(const CollisionModel *m1, const position &p, const vec3 &n, double r) :
00263 RecursionCallback(m1, NULL), mRefPosition(p),
00264 mNormal(n), mRadiusSq(r * r) {reset();}
00265 virtual void reset() {
00266 RecursionCallback::reset();
00267 mNeighborhood.clear();
00268 }
00269 virtual void leafTest(const Leaf *l1, const Leaf *l2);
00270 virtual double quickTest(const Node *n1, const Node *n2);
00271 virtual bool distanceTest(double dSq) {
00272 if (dSq<0.0 || dSq <= mRadiusSq) return true;
00273 return false;
00274 }
00275 Neighborhood& getRegion() {return mNeighborhood;}
00276 void printStatistics();
00277 };
00278
00279 }
00280
00281 #endif