Home | History | Annotate | Download | only in Gimpact
      1 /*
      2 This source file is part of GIMPACT Library.
      3 
      4 For the latest info, see http://gimpact.sourceforge.net/
      5 
      6 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
      7 email: projectileman (at) yahoo.com
      8 
      9 
     10 This software is provided 'as-is', without any express or implied warranty.
     11 In no event will the authors be held liable for any damages arising from the use of this software.
     12 Permission is granted to anyone to use this software for any purpose,
     13 including commercial applications, and to alter it and redistribute it freely,
     14 subject to the following restrictions:
     15 
     16 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.
     17 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     18 3. This notice may not be removed or altered from any source distribution.
     19 */
     20 
     21 
     22 #include "btGImpactShape.h"
     23 #include "btGImpactMassUtil.h"
     24 
     25 
     26 #define CALC_EXACT_INERTIA 1
     27 
     28 
     29 void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
     30 {
     31 	lockChildShapes();
     32 #ifdef CALC_EXACT_INERTIA
     33 	inertia.setValue(0.f,0.f,0.f);
     34 
     35 	int i = this->getNumChildShapes();
     36 	btScalar shapemass = mass/btScalar(i);
     37 
     38 	while(i--)
     39 	{
     40 		btVector3 temp_inertia;
     41 		m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
     42 		if(childrenHasTransform())
     43 		{
     44 			inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
     45 		}
     46 		else
     47 		{
     48 			inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
     49 		}
     50 
     51 	}
     52 
     53 #else
     54 
     55 	// Calc box inertia
     56 
     57 	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
     58 	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
     59 	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
     60 	const btScalar x2 = lx*lx;
     61 	const btScalar y2 = ly*ly;
     62 	const btScalar z2 = lz*lz;
     63 	const btScalar scaledmass = mass * btScalar(0.08333333);
     64 
     65 	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
     66 
     67 #endif
     68 	unlockChildShapes();
     69 }
     70 
     71 
     72 
     73 void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const
     74 {
     75 	lockChildShapes();
     76 
     77 
     78 #ifdef CALC_EXACT_INERTIA
     79 	inertia.setValue(0.f,0.f,0.f);
     80 
     81 	int i = this->getVertexCount();
     82 	btScalar pointmass = mass/btScalar(i);
     83 
     84 	while(i--)
     85 	{
     86 		btVector3 pointintertia;
     87 		this->getVertex(i,pointintertia);
     88 		pointintertia = gim_get_point_inertia(pointintertia,pointmass);
     89 		inertia+=pointintertia;
     90 	}
     91 
     92 #else
     93 
     94 	// Calc box inertia
     95 
     96 	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
     97 	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
     98 	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
     99 	const btScalar x2 = lx*lx;
    100 	const btScalar y2 = ly*ly;
    101 	const btScalar z2 = lz*lz;
    102 	const btScalar scaledmass = mass * btScalar(0.08333333);
    103 
    104 	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
    105 
    106 #endif
    107 
    108 	unlockChildShapes();
    109 }
    110 
    111 void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
    112 {
    113 
    114 #ifdef CALC_EXACT_INERTIA
    115 	inertia.setValue(0.f,0.f,0.f);
    116 
    117 	int i = this->getMeshPartCount();
    118 	btScalar partmass = mass/btScalar(i);
    119 
    120 	while(i--)
    121 	{
    122 		btVector3 partinertia;
    123 		getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
    124 		inertia+=partinertia;
    125 	}
    126 
    127 #else
    128 
    129 	// Calc box inertia
    130 
    131 	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
    132 	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
    133 	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
    134 	const btScalar x2 = lx*lx;
    135 	const btScalar y2 = ly*ly;
    136 	const btScalar z2 = lz*lz;
    137 	const btScalar scaledmass = mass * btScalar(0.08333333);
    138 
    139 	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
    140 
    141 #endif
    142 }
    143 
    144 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
    145 {
    146 }
    147 
    148 void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
    149 {
    150 	lockChildShapes();
    151 
    152 	btAlignedObjectArray<int> collided;
    153 	btVector3 rayDir(rayTo - rayFrom);
    154 	rayDir.normalize();
    155 	m_box_set.rayQuery(rayDir, rayFrom, collided);
    156 
    157 	if(collided.size()==0)
    158 	{
    159 		unlockChildShapes();
    160 		return;
    161 	}
    162 
    163 	int part = (int)getPart();
    164 	btPrimitiveTriangle triangle;
    165 	int i = collided.size();
    166 	while(i--)
    167 	{
    168 		getPrimitiveTriangle(collided[i],triangle);
    169 		callback->processTriangle(triangle.m_vertices,part,collided[i]);
    170 	}
    171 	unlockChildShapes();
    172 }
    173 
    174 void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
    175 {
    176 	lockChildShapes();
    177 	btAABB box;
    178 	box.m_min = aabbMin;
    179 	box.m_max = aabbMax;
    180 
    181 	btAlignedObjectArray<int> collided;
    182 	m_box_set.boxQuery(box,collided);
    183 
    184 	if(collided.size()==0)
    185 	{
    186 		unlockChildShapes();
    187 		return;
    188 	}
    189 
    190 	int part = (int)getPart();
    191 	btPrimitiveTriangle triangle;
    192 	int i = collided.size();
    193 	while(i--)
    194 	{
    195 		this->getPrimitiveTriangle(collided[i],triangle);
    196 		callback->processTriangle(triangle.m_vertices,part,collided[i]);
    197 	}
    198 	unlockChildShapes();
    199 
    200 }
    201 
    202 void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
    203 {
    204 	int i = m_mesh_parts.size();
    205 	while(i--)
    206 	{
    207 		m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
    208 	}
    209 }
    210 
    211 void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
    212 {
    213 	int i = m_mesh_parts.size();
    214 	while(i--)
    215 	{
    216 		m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
    217 	}
    218 }
    219 
    220 
    221 ///fills the dataBuffer and returns the struct name (and 0 on failure)
    222 const char*	btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
    223 {
    224 	btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer;
    225 
    226 	btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
    227 
    228 	m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
    229 
    230 	trimeshData->m_collisionMargin = float(m_collisionMargin);
    231 
    232 	localScaling.serializeFloat(trimeshData->m_localScaling);
    233 
    234 	trimeshData->m_gimpactSubType = int(getGImpactShapeType());
    235 
    236 	return "btGImpactMeshShapeData";
    237 }
    238 
    239