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