btGImpactShape.cpp

Go to the documentation of this file.
00001 /*
00002 This source file is part of GIMPACT Library.
00003 
00004 For the latest info, see http://gimpact.sourceforge.net/
00005 
00006 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
00007 email: projectileman@yahoo.com
00008 
00009 
00010 This software is provided 'as-is', without any express or implied warranty.
00011 In no event will the authors be held liable for any damages arising from the use of this software.
00012 Permission is granted to anyone to use this software for any purpose,
00013 including commercial applications, and to alter it and redistribute it freely,
00014 subject to the following restrictions:
00015 
00016 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.
00017 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00018 3. This notice may not be removed or altered from any source distribution.
00019 */
00020 
00021 
00022 #include "btGImpactShape.h"
00023 #include "btGImpactMassUtil.h"
00024 
00025 
00026 #define CALC_EXACT_INERTIA 1
00027 
00028 void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00029 {
00030         lockChildShapes();
00031 #ifdef CALC_EXACT_INERTIA
00032         inertia.setValue(0.f,0.f,0.f);
00033 
00034         int i = this->getNumChildShapes();
00035         btScalar shapemass = mass/btScalar(i);
00036 
00037         while(i--)
00038         {
00039                 btVector3 temp_inertia;
00040                 m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
00041                 if(childrenHasTransform())
00042                 {
00043                         inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
00044                 }
00045                 else
00046                 {
00047                         inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
00048                 }
00049 
00050         }
00051 
00052 #else
00053 
00054         // Calc box inertia
00055 
00056         btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
00057         btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
00058         btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
00059         const btScalar x2 = lx*lx;
00060         const btScalar y2 = ly*ly;
00061         const btScalar z2 = lz*lz;
00062         const btScalar scaledmass = mass * btScalar(0.08333333);
00063 
00064         inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
00065 
00066 #endif
00067         unlockChildShapes();
00068 }
00069 
00070 
00071 
00072 void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00073 {
00074         lockChildShapes();
00075 
00076 
00077 #ifdef CALC_EXACT_INERTIA
00078         inertia.setValue(0.f,0.f,0.f);
00079 
00080         int i = this->getVertexCount();
00081         btScalar pointmass = mass/btScalar(i);
00082 
00083         while(i--)
00084         {
00085                 btVector3 pointintertia;
00086                 this->getVertex(i,pointintertia);
00087                 pointintertia = gim_get_point_inertia(pointintertia,pointmass);
00088                 inertia+=pointintertia;
00089         }
00090 
00091 #else
00092 
00093         // Calc box inertia
00094 
00095         btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
00096         btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
00097         btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
00098         const btScalar x2 = lx*lx;
00099         const btScalar y2 = ly*ly;
00100         const btScalar z2 = lz*lz;
00101         const btScalar scaledmass = mass * btScalar(0.08333333);
00102 
00103         inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
00104 
00105 #endif
00106 
00107         unlockChildShapes();
00108 }
00109 
00110 void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00111 {
00112 
00113 #ifdef CALC_EXACT_INERTIA
00114         inertia.setValue(0.f,0.f,0.f);
00115 
00116         int i = this->getMeshPartCount();
00117         btScalar partmass = mass/btScalar(i);
00118 
00119         while(i--)
00120         {
00121                 btVector3 partinertia;
00122                 getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
00123                 inertia+=partinertia;
00124         }
00125 
00126 #else
00127 
00128         // Calc box inertia
00129 
00130         btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
00131         btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
00132         btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
00133         const btScalar x2 = lx*lx;
00134         const btScalar y2 = ly*ly;
00135         const btScalar z2 = lz*lz;
00136         const btScalar scaledmass = mass * btScalar(0.08333333);
00137 
00138         inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
00139 
00140 #endif
00141 }
00142 
00143 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
00144 {
00145 }
00146 
00147 
00148 void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00149 {
00150         lockChildShapes();
00151         btAABB box;
00152         box.m_min = aabbMin;
00153         box.m_max = aabbMax;
00154 
00155         btAlignedObjectArray<int> collided;
00156         m_box_set.boxQuery(box,collided);
00157 
00158         if(collided.size()==0)
00159         {
00160                 unlockChildShapes();
00161                 return;
00162         }
00163 
00164         int part = (int)getPart();
00165         btPrimitiveTriangle triangle;
00166         int i = collided.size();
00167         while(i--)
00168         {
00169                 this->getPrimitiveTriangle(collided[i],triangle);
00170                 callback->processTriangle(triangle.m_vertices,part,collided[i]);
00171         }
00172         unlockChildShapes();
00173 
00174 }
00175 
00176 void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00177 {
00178         int i = m_mesh_parts.size();
00179         while(i--)
00180         {
00181                 m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
00182         }
00183 }
00184 
00185 
00187 const char*     btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
00188 {
00189         btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer;
00190 
00191         btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
00192 
00193         m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
00194 
00195         trimeshData->m_collisionMargin = float(m_collisionMargin);
00196 
00197         localScaling.serializeFloat(trimeshData->m_localScaling);
00198 
00199         trimeshData->m_gimpactSubType = int(getGImpactShapeType());
00200 
00201         return "btGImpactMeshShapeData";
00202 }
00203