00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
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
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
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
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
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