Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

physics/OBBCollisionModel

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)1996 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: OBBCollisionModel 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.4 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
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   // OSGVisual
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   // helper classes
00059   
00060   // Moment
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   // Oriented Bounding Box
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);    // specialized for leaf nodes
00111     
00112     
00113     base::Matrix3 pR;   // placement in parent's space
00114     base::Vector3 pT;
00115     
00116     OBB* P;
00117     OBB* N;
00118     gfx::Triangle3 tr;      // valid if leaf
00119     base::Vector3 d;    // this is "radius", that is, 
00120     // half the measure of a side length
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   // methods
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   // variables
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 } // physics
00146 
00147 #endif

Generated on Thu Jul 29 15:56:24 2004 for OpenSim by doxygen 1.3.6