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 #ifndef _PHYSICS_OBBCOLLISIONMODEL_
00026 #define _PHYSICS_OBBCOLLISIONMODEL_
00027
00028 #include <physics/physics>
00029 #include <physics/CollisionModel>
00030
00031 #include <base/array>
00032 #include <gfx/TriangleContainer>
00033 #include <gfx/Triangle3>
00034
00035
00036
00037 namespace physics {
00038
00039
00040 class OBBCollisionModel : public CollisionModel
00041 {
00042 public:
00043 OBBCollisionModel(const gfx::TriangleContainer& triangles);
00044 OBBCollisionModel(const OBBCollisionModel& cm);
00045 virtual ~OBBCollisionModel();
00046
00047 virtual String className() const { return String("OBBCollisionModel"); }
00048 virtual Object& clone() const { return *NewNamedObj(className()) OBBCollisionModel(*this); }
00049
00050 virtual CollisionModelType getType() const { return OBBModel; }
00051
00052
00053 virtual bool visualTypeSupported(VisualType type) const { return (type==OSGVisual); }
00054 virtual osg::Node* createOSGVisual(Visual::Attributes visualAttributes=0) const;
00055
00056 protected:
00057
00058
00059
00060
00061 class Moment {
00062 public:
00063 Moment() { clear(); }
00064 ~Moment() {}
00065
00066 Real A;
00067 base::Vector3 m;
00068 base::Matrix3 s;
00069
00070 bool operator==(const Moment& moment) const
00071 {
00072 return ((A==moment.A) && (m==moment.m) && (s==moment.s));
00073 }
00074
00075 bool equals(const Moment& moment, Real epsilon = consts::epsilon) const throw()
00076 {
00077 return (base::equals(A,moment.A,epsilon) && m.equals(moment.m,epsilon)
00078 && s.equals(moment.s,epsilon));
00079 }
00080
00081 void clear();
00082 void accumulate(const Moment& b);
00083 base::Vector3 meanFromMoment() const { return m; }
00084 base::Vector3 meanFromAccum() const { return m/A; }
00085 base::Matrix3 covariance() const;
00086
00087 static void computeMoment(Moment& M, const gfx::Vector3& p,
00088 const base::Vector3& q, const base::Vector3& r);
00089 static void computeMoment(base::array<Moment>& M,
00090 base::array<gfx::Triangle3>& tris,
00091 Int firstTri, Int numTris);
00092
00093 };
00094
00095
00096
00097 class OBB {
00098 public:
00099 OBB() : P(0), N(0) {}
00100 ~OBB() {}
00101
00102 bool leaf() const { return ((P==0) && (N==0)); }
00103 Real size() const { return d.x; }
00104
00105 Int splitRecurse(base::array<gfx::Triangle3>& tri,
00106 base::array<Moment>& moment, base::array<OBB>& boxes,
00107 Int OBBsInited, Int t[], Int f, Int n);
00108 Int splitRecurse(base::array<gfx::Triangle3>& tri,
00109 base::array<Moment>& moment, base::array<OBB>& boxes,
00110 Int OBBsInited, Int t[], Int f);
00111
00112
00113 base::Matrix3 pR;
00114 base::Vector3 pT;
00115
00116 OBB* P;
00117 OBB* N;
00118 gfx::Triangle3 tr;
00119 base::Vector3 d;
00120
00121 protected:
00122 void reaccumMoments(Moment& A, base::array<Moment>& moment, Int t[], Int f, Int n);
00123 static void minmax(base::Vector3& min, base::Vector3& max, const base::Vector3& v);
00124
00125 };
00126
00127
00128
00129 void buildHierarchy();
00130 static Int eigenAndSort1(Matrix3& evecs, const Matrix3& cov, Int maxIterations=50);
00131 osg::Node* createOBBVisualRecurse(OBB& obb, Int level) const;
00132
00133
00134 base::array<OBB>& b;
00135 base::array<gfx::Triangle3>& tris;
00136
00137 static const Int maxLevels = 3;
00138 static const Int onlyLevel = 3;
00139 static const bool onlyOneLevel = false;
00140
00141 friend class OBBCollisionDetector;
00142 };
00143
00144
00145 }
00146
00147 #endif