Blender V2.61 - r43446
|
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 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 //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 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;//changed in Bullet 2.63: assume the scaling and margin are included 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 //correct the m_implicitShapeDimensions for the margin 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 //this plane might not be aligned... 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 //virtual void getEdge(int i,Edge& edge) const 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 //btScalar minDist = 2*tolerance; 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 //debugging 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