00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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 class btBox2dShape: public btPolyhedralConvexShape
00027 {
00028
00029
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;
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
00087 btBox2dShape( const btVector3& boxHalfExtents)
00088 : btPolyhedralConvexShape(),
00089 m_centroid(0,0,0)
00090 {
00091 m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
00092 m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
00093 m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
00094 m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
00095
00096 m_normals[0].setValue(0,-1,0);
00097 m_normals[1].setValue(1,0,0);
00098 m_normals[2].setValue(0,1,0);
00099 m_normals[3].setValue(-1,0,0);
00100
00101 btScalar minDimension = boxHalfExtents.getX();
00102 if (minDimension>boxHalfExtents.getY())
00103 minDimension = boxHalfExtents.getY();
00104 setSafeMargin(minDimension);
00105
00106 m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
00107 btVector3 margin(getMargin(),getMargin(),getMargin());
00108 m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
00109 };
00110
00111 virtual void setMargin(btScalar collisionMargin)
00112 {
00113
00114 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00115 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00116
00117 btConvexInternalShape::setMargin(collisionMargin);
00118 btVector3 newMargin(getMargin(),getMargin(),getMargin());
00119 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
00120
00121 }
00122 virtual void setLocalScaling(const btVector3& scaling)
00123 {
00124 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
00125 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
00126 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
00127
00128 btConvexInternalShape::setLocalScaling(scaling);
00129
00130 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
00131
00132 }
00133
00134 virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
00135
00136
00137
00138 virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
00139
00140
00141
00142
00143
00144 int getVertexCount() const
00145 {
00146 return 4;
00147 }
00148
00149 virtual int getNumVertices()const
00150 {
00151 return 4;
00152 }
00153
00154 const btVector3* getVertices() const
00155 {
00156 return &m_vertices[0];
00157 }
00158
00159 const btVector3* getNormals() const
00160 {
00161 return &m_normals[0];
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
00171 {
00172
00173 btVector4 plane ;
00174 getPlaneEquation(plane,i);
00175 planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
00176 planeSupport = localGetSupportingVertex(-planeNormal);
00177 }
00178
00179
00180 const btVector3& getCentroid() const
00181 {
00182 return m_centroid;
00183 }
00184
00185 virtual int getNumPlanes() const
00186 {
00187 return 6;
00188 }
00189
00190
00191
00192 virtual int getNumEdges() const
00193 {
00194 return 12;
00195 }
00196
00197
00198 virtual void getVertex(int i,btVector3& vtx) const
00199 {
00200 btVector3 halfExtents = getHalfExtentsWithoutMargin();
00201
00202 vtx = btVector3(
00203 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
00204 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
00205 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
00206 }
00207
00208
00209 virtual void getPlaneEquation(btVector4& plane,int i) const
00210 {
00211 btVector3 halfExtents = getHalfExtentsWithoutMargin();
00212
00213 switch (i)
00214 {
00215 case 0:
00216 plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00217 break;
00218 case 1:
00219 plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
00220 break;
00221 case 2:
00222 plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
00223 break;
00224 case 3:
00225 plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
00226 break;
00227 case 4:
00228 plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
00229 break;
00230 case 5:
00231 plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
00232 break;
00233 default:
00234 btAssert(0);
00235 }
00236 }
00237
00238
00239 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
00240
00241 {
00242 int edgeVert0 = 0;
00243 int edgeVert1 = 0;
00244
00245 switch (i)
00246 {
00247 case 0:
00248 edgeVert0 = 0;
00249 edgeVert1 = 1;
00250 break;
00251 case 1:
00252 edgeVert0 = 0;
00253 edgeVert1 = 2;
00254 break;
00255 case 2:
00256 edgeVert0 = 1;
00257 edgeVert1 = 3;
00258
00259 break;
00260 case 3:
00261 edgeVert0 = 2;
00262 edgeVert1 = 3;
00263 break;
00264 case 4:
00265 edgeVert0 = 0;
00266 edgeVert1 = 4;
00267 break;
00268 case 5:
00269 edgeVert0 = 1;
00270 edgeVert1 = 5;
00271
00272 break;
00273 case 6:
00274 edgeVert0 = 2;
00275 edgeVert1 = 6;
00276 break;
00277 case 7:
00278 edgeVert0 = 3;
00279 edgeVert1 = 7;
00280 break;
00281 case 8:
00282 edgeVert0 = 4;
00283 edgeVert1 = 5;
00284 break;
00285 case 9:
00286 edgeVert0 = 4;
00287 edgeVert1 = 6;
00288 break;
00289 case 10:
00290 edgeVert0 = 5;
00291 edgeVert1 = 7;
00292 break;
00293 case 11:
00294 edgeVert0 = 6;
00295 edgeVert1 = 7;
00296 break;
00297 default:
00298 btAssert(0);
00299
00300 }
00301
00302 getVertex(edgeVert0,pa );
00303 getVertex(edgeVert1,pb );
00304 }
00305
00306
00307
00308
00309
00310 virtual bool isInside(const btVector3& pt,btScalar tolerance) const
00311 {
00312 btVector3 halfExtents = getHalfExtentsWithoutMargin();
00313
00314
00315
00316 bool result = (pt.x() <= (halfExtents.x()+tolerance)) &&
00317 (pt.x() >= (-halfExtents.x()-tolerance)) &&
00318 (pt.y() <= (halfExtents.y()+tolerance)) &&
00319 (pt.y() >= (-halfExtents.y()-tolerance)) &&
00320 (pt.z() <= (halfExtents.z()+tolerance)) &&
00321 (pt.z() >= (-halfExtents.z()-tolerance));
00322
00323 return result;
00324 }
00325
00326
00327
00328 virtual const char* getName()const
00329 {
00330 return "Box2d";
00331 }
00332
00333 virtual int getNumPreferredPenetrationDirections() const
00334 {
00335 return 6;
00336 }
00337
00338 virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
00339 {
00340 switch (index)
00341 {
00342 case 0:
00343 penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
00344 break;
00345 case 1:
00346 penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
00347 break;
00348 case 2:
00349 penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
00350 break;
00351 case 3:
00352 penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
00353 break;
00354 case 4:
00355 penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
00356 break;
00357 case 5:
00358 penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
00359 break;
00360 default:
00361 btAssert(0);
00362 }
00363 }
00364
00365 };
00366
00367 #endif //BT_OBB_BOX_2D_SHAPE_H
00368
00369