Bullet Collision Detection & Physics Library

btTriangleMeshShape.cpp

Go to the documentation of this file.
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 #include "btTriangleMeshShape.h"
00017 #include "LinearMath/btVector3.h"
00018 #include "LinearMath/btQuaternion.h"
00019 #include "btStridingMeshInterface.h"
00020 #include "LinearMath/btAabbUtil2.h"
00021 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
00022 
00023 
00024 btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface)
00025 : btConcaveShape (), m_meshInterface(meshInterface)
00026 {
00027         m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
00028         if(meshInterface->hasPremadeAabb())
00029         {
00030                 meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax);
00031         }
00032         else
00033         {
00034                 recalcLocalAabb();
00035         }
00036 }
00037 
00038 
00039 btTriangleMeshShape::~btTriangleMeshShape()
00040 {
00041                 
00042 }
00043 
00044 
00045 
00046 
00047 void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
00048 {
00049 
00050         btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
00051         localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
00052         btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
00053         
00054         btMatrix3x3 abs_b = trans.getBasis().absolute();  
00055 
00056         btVector3 center = trans(localCenter);
00057 
00058         btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
00059                    abs_b[1].dot(localHalfExtents),
00060                   abs_b[2].dot(localHalfExtents));
00061         aabbMin = center - extent;
00062         aabbMax = center + extent;
00063 
00064 
00065 }
00066 
00067 void    btTriangleMeshShape::recalcLocalAabb()
00068 {
00069         for (int i=0;i<3;i++)
00070         {
00071                 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
00072                 vec[i] = btScalar(1.);
00073                 btVector3 tmp = localGetSupportingVertex(vec);
00074                 m_localAabbMax[i] = tmp[i]+m_collisionMargin;
00075                 vec[i] = btScalar(-1.);
00076                 tmp = localGetSupportingVertex(vec);
00077                 m_localAabbMin[i] = tmp[i]-m_collisionMargin;
00078         }
00079 }
00080 
00081 
00082 
00083 class SupportVertexCallback : public btTriangleCallback
00084 {
00085 
00086         btVector3 m_supportVertexLocal;
00087 public:
00088 
00089         btTransform     m_worldTrans;
00090         btScalar m_maxDot;
00091         btVector3 m_supportVecLocal;
00092 
00093         SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
00094                 : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT))
00095                 
00096         {
00097                 m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
00098         }
00099 
00100         virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
00101         {
00102                 (void)partId;
00103                 (void)triangleIndex;
00104                 for (int i=0;i<3;i++)
00105                 {
00106                         btScalar dot = m_supportVecLocal.dot(triangle[i]);
00107                         if (dot > m_maxDot)
00108                         {
00109                                 m_maxDot = dot;
00110                                 m_supportVertexLocal = triangle[i];
00111                         }
00112                 }
00113         }
00114 
00115         btVector3 GetSupportVertexWorldSpace()
00116         {
00117                 return m_worldTrans(m_supportVertexLocal);
00118         }
00119 
00120         btVector3       GetSupportVertexLocal()
00121         {
00122                 return m_supportVertexLocal;
00123         }
00124 
00125 };
00126 
00127         
00128 void btTriangleMeshShape::setLocalScaling(const btVector3& scaling)
00129 {
00130         m_meshInterface->setScaling(scaling);
00131         recalcLocalAabb();
00132 }
00133 
00134 const btVector3& btTriangleMeshShape::getLocalScaling() const
00135 {
00136         return m_meshInterface->getScaling();
00137 }
00138 
00139 
00140 
00141 
00142 
00143 
00144 //#define DEBUG_TRIANGLE_MESH
00145 
00146 
00147 
00148 void    btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00149 {
00150                 struct FilteredCallback : public btInternalTriangleIndexCallback
00151         {
00152                 btTriangleCallback* m_callback;
00153                 btVector3 m_aabbMin;
00154                 btVector3 m_aabbMax;
00155 
00156                 FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax)
00157                         :m_callback(callback),
00158                         m_aabbMin(aabbMin),
00159                         m_aabbMax(aabbMax)
00160                 {
00161                 }
00162 
00163                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
00164                 {
00165                         if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
00166                         {
00167                                 //check aabb in triangle-space, before doing this
00168                                 m_callback->processTriangle(triangle,partId,triangleIndex);
00169                         }
00170                         
00171                 }
00172 
00173         };
00174 
00175         FilteredCallback filterCallback(callback,aabbMin,aabbMax);
00176 
00177         m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
00178 }
00179 
00180 
00181 
00182 
00183 
00184 void    btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00185 {
00186         (void)mass;
00187         //moving concave objects not supported
00188         btAssert(0);
00189         inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
00190 }
00191 
00192 
00193 btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const
00194 {
00195         btVector3 supportVertex;
00196 
00197         btTransform ident;
00198         ident.setIdentity();
00199 
00200         SupportVertexCallback supportCallback(vec,ident);
00201 
00202         btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00203         
00204         processAllTriangles(&supportCallback,-aabbMax,aabbMax);
00205                 
00206         supportVertex = supportCallback.GetSupportVertexLocal();
00207 
00208         return supportVertex;
00209 }
00210 
00211