Home | History | Annotate | Download | only in CollisionShapes
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      6 In no event will the authors be held liable for any damages arising from the use of this software.
      7 Permission is granted to anyone to use this software for any purpose,
      8 including commercial applications, and to alter it and redistribute it freely,
      9 subject to the following restrictions:
     10 
     11 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.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 #include "btTriangleMeshShape.h"
     17 #include "LinearMath/btVector3.h"
     18 #include "LinearMath/btQuaternion.h"
     19 #include "btStridingMeshInterface.h"
     20 #include "LinearMath/btAabbUtil2.h"
     21 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
     22 
     23 
     24 btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface)
     25 : btConcaveShape (), m_meshInterface(meshInterface)
     26 {
     27 	m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
     28 	if(meshInterface->hasPremadeAabb())
     29 	{
     30 		meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax);
     31 	}
     32 	else
     33 	{
     34 		recalcLocalAabb();
     35 	}
     36 }
     37 
     38 
     39 btTriangleMeshShape::~btTriangleMeshShape()
     40 {
     41 
     42 }
     43 
     44 
     45 
     46 
     47 void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
     48 {
     49 
     50 	btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
     51 	localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
     52 	btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
     53 
     54 	btMatrix3x3 abs_b = trans.getBasis().absolute();
     55 
     56 	btVector3 center = trans(localCenter);
     57 
     58     btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
     59 	aabbMin = center - extent;
     60 	aabbMax = center + extent;
     61 }
     62 
     63 void	btTriangleMeshShape::recalcLocalAabb()
     64 {
     65 	for (int i=0;i<3;i++)
     66 	{
     67 		btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
     68 		vec[i] = btScalar(1.);
     69 		btVector3 tmp = localGetSupportingVertex(vec);
     70 		m_localAabbMax[i] = tmp[i]+m_collisionMargin;
     71 		vec[i] = btScalar(-1.);
     72 		tmp = localGetSupportingVertex(vec);
     73 		m_localAabbMin[i] = tmp[i]-m_collisionMargin;
     74 	}
     75 }
     76 
     77 
     78 
     79 class SupportVertexCallback : public btTriangleCallback
     80 {
     81 
     82 	btVector3 m_supportVertexLocal;
     83 public:
     84 
     85 	btTransform	m_worldTrans;
     86 	btScalar m_maxDot;
     87 	btVector3 m_supportVecLocal;
     88 
     89 	SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
     90 		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT))
     91 
     92 	{
     93 		m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
     94 	}
     95 
     96 	virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
     97 	{
     98 		(void)partId;
     99 		(void)triangleIndex;
    100 		for (int i=0;i<3;i++)
    101 		{
    102 			btScalar dot = m_supportVecLocal.dot(triangle[i]);
    103 			if (dot > m_maxDot)
    104 			{
    105 				m_maxDot = dot;
    106 				m_supportVertexLocal = triangle[i];
    107 			}
    108 		}
    109 	}
    110 
    111 	btVector3 GetSupportVertexWorldSpace()
    112 	{
    113 		return m_worldTrans(m_supportVertexLocal);
    114 	}
    115 
    116 	btVector3	GetSupportVertexLocal()
    117 	{
    118 		return m_supportVertexLocal;
    119 	}
    120 
    121 };
    122 
    123 
    124 void btTriangleMeshShape::setLocalScaling(const btVector3& scaling)
    125 {
    126 	m_meshInterface->setScaling(scaling);
    127 	recalcLocalAabb();
    128 }
    129 
    130 const btVector3& btTriangleMeshShape::getLocalScaling() const
    131 {
    132 	return m_meshInterface->getScaling();
    133 }
    134 
    135 
    136 
    137 
    138 
    139 
    140 //#define DEBUG_TRIANGLE_MESH
    141 
    142 
    143 
    144 void	btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
    145 {
    146 		struct FilteredCallback : public btInternalTriangleIndexCallback
    147 	{
    148 		btTriangleCallback* m_callback;
    149 		btVector3 m_aabbMin;
    150 		btVector3 m_aabbMax;
    151 
    152 		FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax)
    153 			:m_callback(callback),
    154 			m_aabbMin(aabbMin),
    155 			m_aabbMax(aabbMax)
    156 		{
    157 		}
    158 
    159 		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
    160 		{
    161 			if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
    162 			{
    163 				//check aabb in triangle-space, before doing this
    164 				m_callback->processTriangle(triangle,partId,triangleIndex);
    165 			}
    166 
    167 		}
    168 
    169 	};
    170 
    171 	FilteredCallback filterCallback(callback,aabbMin,aabbMax);
    172 
    173 	m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
    174 }
    175 
    176 
    177 
    178 
    179 
    180 void	btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
    181 {
    182 	(void)mass;
    183 	//moving concave objects not supported
    184 	btAssert(0);
    185 	inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
    186 }
    187 
    188 
    189 btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const
    190 {
    191 	btVector3 supportVertex;
    192 
    193 	btTransform ident;
    194 	ident.setIdentity();
    195 
    196 	SupportVertexCallback supportCallback(vec,ident);
    197 
    198 	btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
    199 
    200 	processAllTriangles(&supportCallback,-aabbMax,aabbMax);
    201 
    202 	supportVertex = supportCallback.GetSupportVertexLocal();
    203 
    204 	return supportVertex;
    205 }
    206 
    207 
    208