btSoftRigidDynamicsWorld.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
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 
00017 #include "btSoftRigidDynamicsWorld.h"
00018 #include "LinearMath/btQuickprof.h"
00019 
00020 //softbody & helpers
00021 #include "btSoftBody.h"
00022 #include "btSoftBodyHelpers.h"
00023 
00024 
00025 
00026 
00027 
00028 btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
00029 :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
00030 {
00031         m_drawFlags                     =       fDrawFlags::Std;
00032         m_drawNodeTree          =       true;
00033         m_drawFaceTree          =       false;
00034         m_drawClusterTree       =       false;
00035         m_sbi.m_broadphase = pairCache;
00036         m_sbi.m_dispatcher = dispatcher;
00037         m_sbi.m_sparsesdf.Initialize();
00038         m_sbi.m_sparsesdf.Reset();
00039 
00040 }
00041 
00042 btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
00043 {
00044 
00045 }
00046 
00047 void    btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
00048 {
00049         btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep);
00050 
00051         for ( int i=0;i<m_softBodies.size();++i)
00052         {
00053                 btSoftBody*     psb= m_softBodies[i];
00054 
00055                 psb->predictMotion(timeStep);           
00056         }
00057 }
00058 
00059 void    btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
00060 {
00061         btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
00062 
00064         solveSoftBodiesConstraints();
00065 
00066         //self collisions
00067         for ( int i=0;i<m_softBodies.size();i++)
00068         {
00069                 btSoftBody*     psb=(btSoftBody*)m_softBodies[i];
00070                 psb->defaultCollisionHandler(psb);
00071         }
00072 
00074         updateSoftBodies();
00075 
00076 }
00077 
00078 void    btSoftRigidDynamicsWorld::updateSoftBodies()
00079 {
00080         BT_PROFILE("updateSoftBodies");
00081 
00082         for ( int i=0;i<m_softBodies.size();i++)
00083         {
00084                 btSoftBody*     psb=(btSoftBody*)m_softBodies[i];
00085                 psb->integrateMotion(); 
00086         }
00087 }
00088 
00089 void    btSoftRigidDynamicsWorld::solveSoftBodiesConstraints()
00090 {
00091         BT_PROFILE("solveSoftConstraints");
00092 
00093         if(m_softBodies.size())
00094         {
00095                 btSoftBody::solveClusters(m_softBodies);
00096         }
00097 
00098         for(int i=0;i<m_softBodies.size();++i)
00099         {
00100                 btSoftBody*     psb=(btSoftBody*)m_softBodies[i];
00101                 psb->solveConstraints();
00102         }       
00103 }
00104 
00105 void    btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body,short int collisionFilterGroup,short int collisionFilterMask)
00106 {
00107         m_softBodies.push_back(body);
00108 
00109         btCollisionWorld::addCollisionObject(body,
00110                 collisionFilterGroup,
00111                 collisionFilterMask);
00112 
00113 }
00114 
00115 void    btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body)
00116 {
00117         m_softBodies.remove(body);
00118 
00119         btCollisionWorld::removeCollisionObject(body);
00120 }
00121 
00122 void    btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
00123 {
00124         btSoftBody* body = btSoftBody::upcast(collisionObject);
00125         if (body)
00126                 removeSoftBody(body);
00127         else
00128                 btDiscreteDynamicsWorld::removeCollisionObject(collisionObject);
00129 }
00130 
00131 void    btSoftRigidDynamicsWorld::debugDrawWorld()
00132 {
00133         btDiscreteDynamicsWorld::debugDrawWorld();
00134 
00135         if (getDebugDrawer())
00136         {
00137                 int i;
00138                 for (  i=0;i<this->m_softBodies.size();i++)
00139                 {
00140                         btSoftBody*     psb=(btSoftBody*)this->m_softBodies[i];
00141                         btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
00142                         btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags);
00143                         if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
00144                         {
00145                                 if(m_drawNodeTree)              btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
00146                                 if(m_drawFaceTree)              btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer);
00147                                 if(m_drawClusterTree)   btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer);
00148                         }
00149                 }               
00150         }       
00151 }
00152 
00153 
00154 
00155 
00156 struct btSoftSingleRayCallback : public btBroadphaseRayCallback
00157 {
00158         btVector3       m_rayFromWorld;
00159         btVector3       m_rayToWorld;
00160         btTransform     m_rayFromTrans;
00161         btTransform     m_rayToTrans;
00162         btVector3       m_hitNormal;
00163 
00164         const btSoftRigidDynamicsWorld* m_world;
00165         btCollisionWorld::RayResultCallback&    m_resultCallback;
00166 
00167         btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
00168         :m_rayFromWorld(rayFromWorld),
00169         m_rayToWorld(rayToWorld),
00170         m_world(world),
00171         m_resultCallback(resultCallback)
00172         {
00173                 m_rayFromTrans.setIdentity();
00174                 m_rayFromTrans.setOrigin(m_rayFromWorld);
00175                 m_rayToTrans.setIdentity();
00176                 m_rayToTrans.setOrigin(m_rayToWorld);
00177 
00178                 btVector3 rayDir = (rayToWorld-rayFromWorld);
00179 
00180                 rayDir.normalize ();
00182                 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
00183                 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
00184                 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
00185                 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
00186                 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
00187                 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
00188 
00189                 m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
00190 
00191         }
00192 
00193         
00194 
00195         virtual bool    process(const btBroadphaseProxy* proxy)
00196         {
00198                 if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
00199                         return false;
00200 
00201                 btCollisionObject*      collisionObject = (btCollisionObject*)proxy->m_clientObject;
00202 
00203                 //only perform raycast if filterMask matches
00204                 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
00205                 {
00206                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
00207                         //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00208 #if 0
00209 #ifdef RECALCULATE_AABB
00210                         btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
00211                         collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
00212 #else
00213                         //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
00214                         const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
00215                         const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
00216 #endif
00217 #endif
00218                         //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
00219                         //culling already done by broadphase
00220                         //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
00221                         {
00222                                 m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
00223                                         collisionObject,
00224                                                 collisionObject->getCollisionShape(),
00225                                                 collisionObject->getWorldTransform(),
00226                                                 m_resultCallback);
00227                         }
00228                 }
00229                 return true;
00230         }
00231 };
00232 
00233 void    btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
00234 {
00235         BT_PROFILE("rayTest");
00238         btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
00239 
00240 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
00241         m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
00242 #else
00243         for (int i=0;i<this->getNumCollisionObjects();i++)
00244         {
00245                 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
00246         }       
00247 #endif //USE_BRUTEFORCE_RAYBROADPHASE
00248 
00249 }
00250 
00251 
00252 void    btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
00253                                           btCollisionObject* collisionObject,
00254                                           const btCollisionShape* collisionShape,
00255                                           const btTransform& colObjWorldTransform,
00256                                           RayResultCallback& resultCallback)
00257 {
00258         if (collisionShape->isSoftBody()) {
00259                 btSoftBody* softBody = btSoftBody::upcast(collisionObject);
00260                 if (softBody) {
00261                         btSoftBody::sRayCast softResult;
00262                         if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) 
00263                         {
00264                                 
00265                                 if (softResult.fraction<= resultCallback.m_closestHitFraction)
00266                                 {
00267 
00268                                         btCollisionWorld::LocalShapeInfo shapeInfo;
00269                                         shapeInfo.m_shapePart = 0;
00270                                         shapeInfo.m_triangleIndex = softResult.index;
00271                                         // get the normal
00272                                         btVector3 normal = softBody->m_faces[softResult.index].m_normal;
00273                                         btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
00274                                         if (normal.dot(rayDir) > 0) {
00275                                                 // normal always point toward origin of the ray
00276                                                 normal = -normal;
00277                                         }
00278                                         btCollisionWorld::LocalRayResult rayResult
00279                                                 (collisionObject,
00280                                                  &shapeInfo,
00281                                                  normal,
00282                                                  softResult.fraction);
00283                                         bool    normalInWorldSpace = true;
00284                                         resultCallback.addSingleResult(rayResult,normalInWorldSpace);
00285                                 }
00286                         }
00287                 }
00288         } 
00289         else {
00290                 btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
00291         }
00292 }

Generated on Mon Feb 15 22:17:06 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1