Blender V2.61 - r43446

btBoxShape.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
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_MINKOWSKI_H
00017 #define OBB_BOX_MINKOWSKI_H
00018 
00019 #include "btPolyhedralConvexShape.h"
00020 #include "btCollisionMargin.h"
00021 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00022 #include "LinearMath/btVector3.h"
00023 #include "LinearMath/btMinMax.h"
00024 
00026 class btBoxShape: public btPolyhedralConvexShape
00027 {
00028 
00029     //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
00030 
00031 
00032 public:
00033 
00034     btVector3 getHalfExtentsWithMargin() const
00035     {
00036         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00037         btVector3 margin(getMargin(),getMargin(),getMargin());
00038         halfExtents += margin;
00039         return halfExtents;
00040     }
00041     
00042     const btVector3& getHalfExtentsWithoutMargin() const
00043     {
00044         return m_implicitShapeDimensions;//scaling is included, margin is not
00045     }
00046     
00047 
00048     virtual btVector3   localGetSupportingVertex(const btVector3& vec) const
00049     {
00050         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00051         btVector3 margin(getMargin(),getMargin(),getMargin());
00052         halfExtents += margin;
00053         
00054         return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00055             btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00056             btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
00057     }
00058 
00059     SIMD_FORCE_INLINE  btVector3    localGetSupportingVertexWithoutMargin(const btVector3& vec)const
00060     {
00061         const btVector3& halfExtents = getHalfExtentsWithoutMargin();
00062         
00063         return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00064             btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00065             btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
00066     }
00067 
00068     virtual void    batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
00069     {
00070         const btVector3& halfExtents = getHalfExtentsWithoutMargin();
00071     
00072         for (int i=0;i<numVectors;i++)
00073         {
00074             const btVector3& vec = vectors[i];
00075             supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
00076                 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
00077                 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
00078         }
00079 
00080     }
00081 
00082 
00083     btBoxShape( const btVector3& boxHalfExtents) 
00084         : btPolyhedralConvexShape()
00085     {
00086         m_shapeType = BOX_SHAPE_PROXYTYPE;
00087         btVector3 margin(getMargin(),getMargin(),getMargin());
00088         m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
00089     };
00090 
00091     virtual void setMargin(btScalar collisionMargin)
00092     {
00093         //correct the m_implicitShapeDimensions for the margin
00094         btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00095         btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00096         
00097         btConvexInternalShape::setMargin(collisionMargin);
00098         btVector3 newMargin(getMargin(),getMargin(),getMargin());
00099         m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
00100 
00101     }
00102     virtual void    setLocalScaling(const btVector3& scaling)
00103     {
00104         btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00105         btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00106         btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
00107 
00108         btConvexInternalShape::setLocalScaling(scaling);
00109 
00110         m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
00111 
00112     }
00113 
00114     virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
00115 
00116     
00117 
00118     virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
00119 
00120     virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
00121     {
00122         //this plane might not be aligned...
00123         btVector4 plane ;
00124         getPlaneEquation(plane,i);
00125         planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
00126         planeSupport = localGetSupportingVertex(-planeNormal);
00127     }
00128 
00129     
00130     virtual int getNumPlanes() const
00131     {
00132         return 6;
00133     }   
00134     
00135     virtual int getNumVertices() const 
00136     {
00137         return 8;
00138     }
00139 
00140     virtual int getNumEdges() const
00141     {
00142         return 12;
00143     }
00144 
00145 
00146     virtual void getVertex(int i,btVector3& vtx) const
00147     {
00148         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00149 
00150         vtx = btVector3(
00151                 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
00152                 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
00153                 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
00154     }
00155     
00156 
00157     virtual void    getPlaneEquation(btVector4& plane,int i) const
00158     {
00159         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00160 
00161         switch (i)
00162         {
00163         case 0:
00164             plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00165             break;
00166         case 1:
00167             plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00168             break;
00169         case 2:
00170             plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
00171             break;
00172         case 3:
00173             plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
00174             break;
00175         case 4:
00176             plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
00177             break;
00178         case 5:
00179             plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
00180             break;
00181         default:
00182             btAssert(0);
00183         }
00184     }
00185 
00186     
00187     virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
00188     //virtual void getEdge(int i,Edge& edge) const
00189     {
00190         int edgeVert0 = 0;
00191         int edgeVert1 = 0;
00192 
00193         switch (i)
00194         {
00195         case 0:
00196                 edgeVert0 = 0;
00197                 edgeVert1 = 1;
00198             break;
00199         case 1:
00200                 edgeVert0 = 0;
00201                 edgeVert1 = 2;
00202             break;
00203         case 2:
00204             edgeVert0 = 1;
00205             edgeVert1 = 3;
00206 
00207             break;
00208         case 3:
00209             edgeVert0 = 2;
00210             edgeVert1 = 3;
00211             break;
00212         case 4:
00213             edgeVert0 = 0;
00214             edgeVert1 = 4;
00215             break;
00216         case 5:
00217             edgeVert0 = 1;
00218             edgeVert1 = 5;
00219 
00220             break;
00221         case 6:
00222             edgeVert0 = 2;
00223             edgeVert1 = 6;
00224             break;
00225         case 7:
00226             edgeVert0 = 3;
00227             edgeVert1 = 7;
00228             break;
00229         case 8:
00230             edgeVert0 = 4;
00231             edgeVert1 = 5;
00232             break;
00233         case 9:
00234             edgeVert0 = 4;
00235             edgeVert1 = 6;
00236             break;
00237         case 10:
00238             edgeVert0 = 5;
00239             edgeVert1 = 7;
00240             break;
00241         case 11:
00242             edgeVert0 = 6;
00243             edgeVert1 = 7;
00244             break;
00245         default:
00246             btAssert(0);
00247 
00248         }
00249 
00250         getVertex(edgeVert0,pa );
00251         getVertex(edgeVert1,pb );
00252     }
00253 
00254 
00255 
00256 
00257     
00258     virtual bool isInside(const btVector3& pt,btScalar tolerance) const
00259     {
00260         btVector3 halfExtents = getHalfExtentsWithoutMargin();
00261 
00262         //btScalar minDist = 2*tolerance;
00263         
00264         bool result =   (pt.x() <= (halfExtents.x()+tolerance)) &&
00265                         (pt.x() >= (-halfExtents.x()-tolerance)) &&
00266                         (pt.y() <= (halfExtents.y()+tolerance)) &&
00267                         (pt.y() >= (-halfExtents.y()-tolerance)) &&
00268                         (pt.z() <= (halfExtents.z()+tolerance)) &&
00269                         (pt.z() >= (-halfExtents.z()-tolerance));
00270         
00271         return result;
00272     }
00273 
00274 
00275     //debugging
00276     virtual const char* getName()const
00277     {
00278         return "Box";
00279     }
00280 
00281     virtual int     getNumPreferredPenetrationDirections() const
00282     {
00283         return 6;
00284     }
00285     
00286     virtual void    getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
00287     {
00288         switch (index)
00289         {
00290         case 0:
00291             penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
00292             break;
00293         case 1:
00294             penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
00295             break;
00296         case 2:
00297             penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
00298             break;
00299         case 3:
00300             penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
00301             break;
00302         case 4:
00303             penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
00304             break;
00305         case 5:
00306             penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
00307             break;
00308         default:
00309             btAssert(0);
00310         }
00311     }
00312 
00313 };
00314 
00315 
00316 #endif //OBB_BOX_MINKOWSKI_H
00317 
00318