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 ATTRIBUTE_ALIGNED16(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 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;
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
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
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
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
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
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