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