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