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 _collisionmodel_h_
00027 #define _collisionmodel_h_
00028
00029 #include <list>
00030 #include <vector>
00031
00032 #include "matvec3D.h"
00033 #include "bBox.h"
00034 #include "triangle.h"
00035
00046 class BoundingBox;
00047
00048 namespace Collision{
00049
00050 class Branch;
00051 class CollisionModel;
00053
00057 class Node {
00058 protected:
00059 BoundingBox mBbox;
00060 public:
00062 Node() {}
00063 virtual ~Node(){}
00064 virtual bool isLeaf() const = 0;
00065 virtual Branch* split(){return NULL;}
00066 virtual void getBVRecurse(int currentDepth, int desiredDepth, std::vector<BoundingBox> *bvs);
00067 virtual int countRecurse(){return 1;}
00068 const BoundingBox& getBox() const {return mBbox;}
00069 double getBoxVolume() const {return mBbox.halfSize.x() *
00070 mBbox.halfSize.y() * mBbox.halfSize.z();}
00071
00072 virtual void markRecurse(bool m) const {mBbox.mMark = m;}
00073 virtual void mark(bool m) const {mBbox.mMark = m;}
00074 };
00075
00077
00081 class Leaf : public Node {
00082 private:
00084 static const double TOLERANCE;
00086 static const int MAX_LEAF_TRIANGLES;
00087
00088 std::list<Triangle> mTriangles;
00089 void computeBboxAA();
00090 void computeBboxOO();
00091 position getMeanVertex();
00093 double getMedianProjection(const vec3 &axis);
00094 void fitBox(const mat3 &R, vec3 ¢er, vec3 &halfSize);
00096 void balancedSplit(vec3 axis, double sepPoint, Leaf *child1, Leaf *child2);
00098 void randomSplit(Leaf *child1, Leaf *child2);
00100 void optimalSplit(const vec3 &x, const vec3 &y, const vec3 &z, Leaf *child1, Leaf *child2);
00102 void areaWeightedCovarianceMatrix(double covMat[3][3]);
00103 public:
00105 Leaf() : Node() {}
00106 bool isLeaf() const {return true;}
00108 Branch* split();
00109 void addTriangle(Triangle t){mTriangles.push_back(t);}
00110 void computeBbox(){computeBboxOO();}
00111 int getNumTriangles() const {return mTriangles.size();}
00112 void clearTriangles() {mTriangles.clear();}
00113 const std::list<Triangle>* getTriangles() const {return &mTriangles;}
00114 };
00115
00117
00119 class Branch : public Node {
00120 private:
00121 Node *mChild1, *mChild2;
00122 Branch(Leaf *c1, Leaf *c2, const BoundingBox &box) : Node(), mChild1(c1), mChild2(c2) {
00123 mBbox.setTran( box.getTran() );
00124 mBbox.halfSize = box.halfSize;
00125 }
00126 friend Branch* Leaf::split();
00127 public:
00128 ~Branch() {if(mChild1) delete mChild1; if (mChild2) delete mChild2;}
00129 bool isLeaf() const {return false;}
00135 void splitRecurse(int currentDepth, int desiredDepth) {
00136 if (desiredDepth >= 0 && currentDepth >= desiredDepth) return;
00137 Branch *tmp = mChild1->split();
00138 if (tmp) {
00139 delete mChild1;
00140 mChild1 = tmp;
00141 tmp->splitRecurse(currentDepth+1, desiredDepth);
00142 }
00143 tmp = mChild2->split();
00144 if (tmp) {
00145 delete mChild2;
00146 mChild2 = tmp;
00147 tmp->splitRecurse(currentDepth+1, desiredDepth);
00148 }
00149 }
00150 const Node* child1() const {return mChild1;}
00151 const Node* child2() const {return mChild2;}
00152 virtual void getBVRecurse(int currentDepth, int desiredDepth, std::vector<BoundingBox> *bvs);
00153 virtual int countRecurse(){return 1 + mChild1->countRecurse() + mChild2->countRecurse();}
00154 virtual void markRecurse(bool m) const {
00155 Node::markRecurse(m);
00156
00157 if (!m) {
00158 mChild1->markRecurse(m);
00159 mChild2->markRecurse(m);
00160 }
00161 }
00162 };
00163
00169 class CollisionModel {
00170 private:
00171 Node *mRoot;
00172 bool mActive;
00173 transf mTran;
00175 bool mClone;
00177
00179 int mThreadId;
00180 public:
00182 CollisionModel(int threadId) {
00183 mRoot = new Leaf();
00184 mActive = true;
00185 mClone = false;
00186 mThreadId = threadId;
00187 }
00189 ~CollisionModel(){if(!mClone) delete mRoot;}
00191 void cloneModel(CollisionModel *original);
00193 void addTriangle(Triangle t);
00194 const Node* getRoot() const {return mRoot;}
00196 void reset();
00198 void build();
00199 void getBoundingVolumes(int depth, std::vector<BoundingBox> *bvs);
00200 void setTran(const transf &t){mTran = t;}
00201 const transf& getTran() const {return mTran;}
00202 bool isActive() const {return mActive;}
00203 void setActive(bool act){mActive = act;}
00204 int getThreadId() const {return mThreadId;}
00205 };
00206
00207 }
00208
00209 #endif