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 = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
00059         aabbMin = center - extent;
00060         aabbMax = center + extent;
00061 }
00062 
00063 void    btTriangleMeshShape::recalcLocalAabb()
00064 {
00065         for (int i=0;i<3;i++)
00066         {
00067                 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
00068                 vec[i] = btScalar(1.);
00069                 btVector3 tmp = localGetSupportingVertex(vec);
00070                 m_localAabbMax[i] = tmp[i]+m_collisionMargin;
00071                 vec[i] = btScalar(-1.);
00072                 tmp = localGetSupportingVertex(vec);
00073                 m_localAabbMin[i] = tmp[i]-m_collisionMargin;
00074         }
00075 }
00076 
00077 
00078 
00079 class SupportVertexCallback : public btTriangleCallback
00080 {
00081 
00082         btVector3 m_supportVertexLocal;
00083 public:
00084 
00085         btTransform     m_worldTrans;
00086         btScalar m_maxDot;
00087         btVector3 m_supportVecLocal;
00088 
00089         SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
00090                 : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT))
00091                 
00092         {
00093                 m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
00094         }
00095 
00096         virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
00097         {
00098                 (void)partId;
00099                 (void)triangleIndex;
00100                 for (int i=0;i<3;i++)
00101                 {
00102                         btScalar dot = m_supportVecLocal.dot(triangle[i]);
00103                         if (dot > m_maxDot)
00104                         {
00105                                 m_maxDot = dot;
00106                                 m_supportVertexLocal = triangle[i];
00107                         }
00108                 }
00109         }
00110 
00111         btVector3 GetSupportVertexWorldSpace()
00112         {
00113                 return m_worldTrans(m_supportVertexLocal);
00114         }
00115 
00116         btVector3       GetSupportVertexLocal()
00117         {
00118                 return m_supportVertexLocal;
00119         }
00120 
00121 };
00122 
00123         
00124 void btTriangleMeshShape::setLocalScaling(const btVector3& scaling)
00125 {
00126         m_meshInterface->setScaling(scaling);
00127         recalcLocalAabb();
00128 }
00129 
00130 const btVector3& btTriangleMeshShape::getLocalScaling() const
00131 {
00132         return m_meshInterface->getScaling();
00133 }
00134 
00135 
00136 
00137 
00138 
00139 
00140 //#define DEBUG_TRIANGLE_MESH
00141 
00142 
00143 
00144 void    btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00145 {
00146                 struct FilteredCallback : public btInternalTriangleIndexCallback
00147         {
00148                 btTriangleCallback* m_callback;
00149                 btVector3 m_aabbMin;
00150                 btVector3 m_aabbMax;
00151 
00152                 FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax)
00153                         :m_callback(callback),
00154                         m_aabbMin(aabbMin),
00155                         m_aabbMax(aabbMax)
00156                 {
00157                 }
00158 
00159                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
00160                 {
00161                         if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
00162                         {
00163                                 //check aabb in triangle-space, before doing this
00164                                 m_callback->processTriangle(triangle,partId,triangleIndex);
00165                         }
00166                         
00167                 }
00168 
00169         };
00170 
00171         FilteredCallback filterCallback(callback,aabbMin,aabbMax);
00172 
00173         m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
00174 }
00175 
00176 
00177 
00178 
00179 
00180 void    btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00181 {
00182         (void)mass;
00183         //moving concave objects not supported
00184         btAssert(0);
00185         inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
00186 }
00187 
00188 
00189 btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const
00190 {
00191         btVector3 supportVertex;
00192 
00193         btTransform ident;
00194         ident.setIdentity();
00195 
00196         SupportVertexCallback supportCallback(vec,ident);
00197 
00198         btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00199         
00200         processAllTriangles(&supportCallback,-aabbMax,aabbMax);
00201                 
00202         supportVertex = supportCallback.GetSupportVertexLocal();
00203 
00204         return supportVertex;
00205 }
00206 
00207