Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org 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_MINKOWSKI_H 00017 #define OBB_BOX_MINKOWSKI_H 00018 00019 #include "btPolyhedralConvexShape.h" 00020 #include "btCollisionMargin.h" 00021 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 00022 #include "LinearMath/btVector3.h" 00023 #include "LinearMath/btMinMax.h" 00024 00026 class btBoxShape: public btPolyhedralConvexShape 00027 { 00028 00029 //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead 00030 00031 00032 public: 00033 00034 btVector3 getHalfExtentsWithMargin() const 00035 { 00036 btVector3 halfExtents = getHalfExtentsWithoutMargin(); 00037 btVector3 margin(getMargin(),getMargin(),getMargin()); 00038 halfExtents += margin; 00039 return halfExtents; 00040 } 00041 00042 const btVector3& getHalfExtentsWithoutMargin() const 00043 { 00044 return m_implicitShapeDimensions;//scaling is included, margin is not 00045 } 00046 00047 00048 virtual btVector3 localGetSupportingVertex(const btVector3& vec) const 00049 { 00050 btVector3 halfExtents = getHalfExtentsWithoutMargin(); 00051 btVector3 margin(getMargin(),getMargin(),getMargin()); 00052 halfExtents += margin; 00053 00054 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), 00055 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), 00056 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 00057 } 00058 00059 SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const 00060 { 00061 const btVector3& halfExtents = getHalfExtentsWithoutMargin(); 00062 00063 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), 00064 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), 00065 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 00066 } 00067 00068 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const 00069 { 00070 const btVector3& halfExtents = getHalfExtentsWithoutMargin(); 00071 00072 for (int i=0;i<numVectors;i++) 00073 { 00074 const btVector3& vec = vectors[i]; 00075 supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), 00076 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), 00077 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 00078 } 00079 00080 } 00081 00082 00083 btBoxShape( const btVector3& boxHalfExtents) 00084 : btPolyhedralConvexShape() 00085 { 00086 m_shapeType = BOX_SHAPE_PROXYTYPE; 00087 btVector3 margin(getMargin(),getMargin(),getMargin()); 00088 m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin; 00089 }; 00090 00091 virtual void setMargin(btScalar collisionMargin) 00092 { 00093 //correct the m_implicitShapeDimensions for the margin 00094 btVector3 oldMargin(getMargin(),getMargin(),getMargin()); 00095 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; 00096 00097 btConvexInternalShape::setMargin(collisionMargin); 00098 btVector3 newMargin(getMargin(),getMargin(),getMargin()); 00099 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin; 00100 00101 } 00102 virtual void setLocalScaling(const btVector3& scaling) 00103 { 00104 btVector3 oldMargin(getMargin(),getMargin(),getMargin()); 00105 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; 00106 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling; 00107 00108 btConvexInternalShape::setLocalScaling(scaling); 00109 00110 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin; 00111 00112 } 00113 00114 virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; 00115 00116 00117 00118 virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; 00119 00120 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const 00121 { 00122 //this plane might not be aligned... 00123 btVector4 plane ; 00124 getPlaneEquation(plane,i); 00125 planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ()); 00126 planeSupport = localGetSupportingVertex(-planeNormal); 00127 } 00128 00129 00130 virtual int getNumPlanes() const 00131 { 00132 return 6; 00133 } 00134 00135 virtual int getNumVertices() const 00136 { 00137 return 8; 00138 } 00139 00140 virtual int getNumEdges() const 00141 { 00142 return 12; 00143 } 00144 00145 00146 virtual void getVertex(int i,btVector3& vtx) const 00147 { 00148 btVector3 halfExtents = getHalfExtentsWithoutMargin(); 00149 00150 vtx = btVector3( 00151 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1), 00152 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1), 00153 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); 00154 } 00155 00156 00157 virtual void getPlaneEquation(btVector4& plane,int i) const 00158 { 00159 btVector3 halfExtents = getHalfExtentsWithoutMargin(); 00160 00161 switch (i) 00162 { 00163 case 0: 00164 plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); 00165 break; 00166 case 1: 00167 plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); 00168 break; 00169 case 2: 00170 plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); 00171 break; 00172 case 3: 00173 plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); 00174 break; 00175 case 4: 00176 plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); 00177 break; 00178 case 5: 00179 plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); 00180 break; 00181 default: 00182 btAssert(0); 00183 } 00184 } 00185 00186 00187 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const 00188 //virtual void getEdge(int i,Edge& edge) const 00189 { 00190 int edgeVert0 = 0; 00191 int edgeVert1 = 0; 00192 00193 switch (i) 00194 { 00195 case 0: 00196 edgeVert0 = 0; 00197 edgeVert1 = 1; 00198 break; 00199 case 1: 00200 edgeVert0 = 0; 00201 edgeVert1 = 2; 00202 break; 00203 case 2: 00204 edgeVert0 = 1; 00205 edgeVert1 = 3; 00206 00207 break; 00208 case 3: 00209 edgeVert0 = 2; 00210 edgeVert1 = 3; 00211 break; 00212 case 4: 00213 edgeVert0 = 0; 00214 edgeVert1 = 4; 00215 break; 00216 case 5: 00217 edgeVert0 = 1; 00218 edgeVert1 = 5; 00219 00220 break; 00221 case 6: 00222 edgeVert0 = 2; 00223 edgeVert1 = 6; 00224 break; 00225 case 7: 00226 edgeVert0 = 3; 00227 edgeVert1 = 7; 00228 break; 00229 case 8: 00230 edgeVert0 = 4; 00231 edgeVert1 = 5; 00232 break; 00233 case 9: 00234 edgeVert0 = 4; 00235 edgeVert1 = 6; 00236 break; 00237 case 10: 00238 edgeVert0 = 5; 00239 edgeVert1 = 7; 00240 break; 00241 case 11: 00242 edgeVert0 = 6; 00243 edgeVert1 = 7; 00244 break; 00245 default: 00246 btAssert(0); 00247 00248 } 00249 00250 getVertex(edgeVert0,pa ); 00251 getVertex(edgeVert1,pb ); 00252 } 00253 00254 00255 00256 00257 00258 virtual bool isInside(const btVector3& pt,btScalar tolerance) const 00259 { 00260 btVector3 halfExtents = getHalfExtentsWithoutMargin(); 00261 00262 //btScalar minDist = 2*tolerance; 00263 00264 bool result = (pt.x() <= (halfExtents.x()+tolerance)) && 00265 (pt.x() >= (-halfExtents.x()-tolerance)) && 00266 (pt.y() <= (halfExtents.y()+tolerance)) && 00267 (pt.y() >= (-halfExtents.y()-tolerance)) && 00268 (pt.z() <= (halfExtents.z()+tolerance)) && 00269 (pt.z() >= (-halfExtents.z()-tolerance)); 00270 00271 return result; 00272 } 00273 00274 00275 //debugging 00276 virtual const char* getName()const 00277 { 00278 return "Box"; 00279 } 00280 00281 virtual int getNumPreferredPenetrationDirections() const 00282 { 00283 return 6; 00284 } 00285 00286 virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const 00287 { 00288 switch (index) 00289 { 00290 case 0: 00291 penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); 00292 break; 00293 case 1: 00294 penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); 00295 break; 00296 case 2: 00297 penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); 00298 break; 00299 case 3: 00300 penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); 00301 break; 00302 case 4: 00303 penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); 00304 break; 00305 case 5: 00306 penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); 00307 break; 00308 default: 00309 btAssert(0); 00310 } 00311 } 00312 00313 }; 00314 00315 00316 #endif //OBB_BOX_MINKOWSKI_H 00317 00318