Blender V2.61 - r43446

btBox2dShape.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef OBB_BOX_2D_SHAPE_H
00017 #define OBB_BOX_2D_SHAPE_H
00018 
00019 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
00020 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
00021 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00022 #include "LinearMath/btVector3.h"
00023 #include "LinearMath/btMinMax.h"
00024 
00026 class btBox2dShape: public btPolyhedralConvexShape
00027 {
00028 
00029     //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
00030 
00031     btVector3 m_centroid;
00032     btVector3 m_vertices[4];
00033     btVector3 m_normals[4];
00034 
00035 public:
00036 
00037     btVector3 getHalfExtentsWithMargin() const
00038     {
00039         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00040         btVector3 margin(getMargin(),getMargin(),getMargin());
00041         halfExtents += margin;
00042         return halfExtents;
00043     }
00044     
00045     const btVector3& getHalfExtentsWithoutMargin() const
00046     {
00047         return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
00048     }
00049     
00050 
00051     virtual btVector3   localGetSupportingVertex(const btVector3& vec) const
00052     {
00053         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00054         btVector3 margin(getMargin(),getMargin(),getMargin());
00055         halfExtents += margin;
00056         
00057         return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00058             btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00059             btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
00060     }
00061 
00062     SIMD_FORCE_INLINE  btVector3    localGetSupportingVertexWithoutMargin(const btVector3& vec)const
00063     {
00064         const btVector3& halfExtents = getHalfExtentsWithoutMargin();
00065         
00066         return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00067             btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00068             btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
00069     }
00070 
00071     virtual void    batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
00072     {
00073         const btVector3& halfExtents = getHalfExtentsWithoutMargin();
00074     
00075         for (int i=0;i<numVectors;i++)
00076         {
00077             const btVector3& vec = vectors[i];
00078             supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00079                 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00080                 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
00081         }
00082 
00083     }
00084 
00085 
00086     btBox2dShape( const btVector3& boxHalfExtents) 
00087         : btPolyhedralConvexShape(),
00088         m_centroid(0,0,0)
00089     {
00090         m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
00091         m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
00092         m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
00093         m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
00094 
00095         m_normals[0].setValue(0,-1,0);
00096         m_normals[1].setValue(1,0,0);
00097         m_normals[2].setValue(0,1,0);
00098         m_normals[3].setValue(-1,0,0);
00099 
00100         m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
00101         btVector3 margin(getMargin(),getMargin(),getMargin());
00102         m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
00103     };
00104 
00105     virtual void setMargin(btScalar collisionMargin)
00106     {
00107         //correct the m_implicitShapeDimensions for the margin
00108         btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00109         btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00110         
00111         btConvexInternalShape::setMargin(collisionMargin);
00112         btVector3 newMargin(getMargin(),getMargin(),getMargin());
00113         m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
00114 
00115     }
00116     virtual void    setLocalScaling(const btVector3& scaling)
00117     {
00118         btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00119         btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00120         btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
00121 
00122         btConvexInternalShape::setLocalScaling(scaling);
00123 
00124         m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
00125 
00126     }
00127 
00128     virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
00129 
00130     
00131 
00132     virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
00133 
00134 
00135 
00136 
00137 
00138     int getVertexCount() const
00139     {
00140         return 4;
00141     }
00142 
00143     virtual int getNumVertices()const
00144     {
00145         return 4;
00146     }
00147 
00148     const btVector3* getVertices() const
00149     {
00150         return &m_vertices[0];
00151     }
00152 
00153     const btVector3* getNormals() const
00154     {
00155         return &m_normals[0];
00156     }
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164     virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
00165     {
00166         //this plane might not be aligned...
00167         btVector4 plane ;
00168         getPlaneEquation(plane,i);
00169         planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
00170         planeSupport = localGetSupportingVertex(-planeNormal);
00171     }
00172 
00173 
00174     const btVector3& getCentroid() const
00175     {
00176         return m_centroid;
00177     }
00178     
00179     virtual int getNumPlanes() const
00180     {
00181         return 6;
00182     }   
00183     
00184     
00185 
00186     virtual int getNumEdges() const
00187     {
00188         return 12;
00189     }
00190 
00191 
00192     virtual void getVertex(int i,btVector3& vtx) const
00193     {
00194         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00195 
00196         vtx = btVector3(
00197                 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
00198                 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
00199                 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
00200     }
00201     
00202 
00203     virtual void    getPlaneEquation(btVector4& plane,int i) const
00204     {
00205         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00206 
00207         switch (i)
00208         {
00209         case 0:
00210             plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00211             break;
00212         case 1:
00213             plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00214             break;
00215         case 2:
00216             plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
00217             break;
00218         case 3:
00219             plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
00220             break;
00221         case 4:
00222             plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
00223             break;
00224         case 5:
00225             plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
00226             break;
00227         default:
00228             btAssert(0);
00229         }
00230     }
00231 
00232     
00233     virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
00234     //virtual void getEdge(int i,Edge& edge) const
00235     {
00236         int edgeVert0 = 0;
00237         int edgeVert1 = 0;
00238 
00239         switch (i)
00240         {
00241         case 0:
00242                 edgeVert0 = 0;
00243                 edgeVert1 = 1;
00244             break;
00245         case 1:
00246                 edgeVert0 = 0;
00247                 edgeVert1 = 2;
00248             break;
00249         case 2:
00250             edgeVert0 = 1;
00251             edgeVert1 = 3;
00252 
00253             break;
00254         case 3:
00255             edgeVert0 = 2;
00256             edgeVert1 = 3;
00257             break;
00258         case 4:
00259             edgeVert0 = 0;
00260             edgeVert1 = 4;
00261             break;
00262         case 5:
00263             edgeVert0 = 1;
00264             edgeVert1 = 5;
00265 
00266             break;
00267         case 6:
00268             edgeVert0 = 2;
00269             edgeVert1 = 6;
00270             break;
00271         case 7:
00272             edgeVert0 = 3;
00273             edgeVert1 = 7;
00274             break;
00275         case 8:
00276             edgeVert0 = 4;
00277             edgeVert1 = 5;
00278             break;
00279         case 9:
00280             edgeVert0 = 4;
00281             edgeVert1 = 6;
00282             break;
00283         case 10:
00284             edgeVert0 = 5;
00285             edgeVert1 = 7;
00286             break;
00287         case 11:
00288             edgeVert0 = 6;
00289             edgeVert1 = 7;
00290             break;
00291         default:
00292             btAssert(0);
00293 
00294         }
00295 
00296         getVertex(edgeVert0,pa );
00297         getVertex(edgeVert1,pb );
00298     }
00299 
00300 
00301 
00302 
00303     
00304     virtual bool isInside(const btVector3& pt,btScalar tolerance) const
00305     {
00306         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00307 
00308         //btScalar minDist = 2*tolerance;
00309         
00310         bool result =   (pt.x() <= (halfExtents.x()+tolerance)) &&
00311                         (pt.x() >= (-halfExtents.x()-tolerance)) &&
00312                         (pt.y() <= (halfExtents.y()+tolerance)) &&
00313                         (pt.y() >= (-halfExtents.y()-tolerance)) &&
00314                         (pt.z() <= (halfExtents.z()+tolerance)) &&
00315                         (pt.z() >= (-halfExtents.z()-tolerance));
00316         
00317         return result;
00318     }
00319 
00320 
00321     //debugging
00322     virtual const char* getName()const
00323     {
00324         return "Box2d";
00325     }
00326 
00327     virtual int     getNumPreferredPenetrationDirections() const
00328     {
00329         return 6;
00330     }
00331     
00332     virtual void    getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
00333     {
00334         switch (index)
00335         {
00336         case 0:
00337             penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
00338             break;
00339         case 1:
00340             penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
00341             break;
00342         case 2:
00343             penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
00344             break;
00345         case 3:
00346             penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
00347             break;
00348         case 4:
00349             penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
00350             break;
00351         case 5:
00352             penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
00353             break;
00354         default:
00355             btAssert(0);
00356         }
00357     }
00358 
00359 };
00360 
00361 #endif //OBB_BOX_2D_SHAPE_H
00362 
00363