From 34699f6de63f57e02f37f322da9d99fa8616b919 Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Fri, 14 Aug 2009 21:36:51 +0000 Subject: [PATCH] + add option to set pre-tick callback, called at the beginning of each internal simulation step + use real-time for soft body demo (using this pre-tick callback) + optimize the generation of bending constraints for the special case where the distance is 2 --- Demos/SoftDemo/SoftDemo.cpp | 74 ++++++++++------- .../Dynamics/btContinuousDynamicsWorld.cpp | 4 + .../Dynamics/btDiscreteDynamicsWorld.cpp | 4 + src/BulletDynamics/Dynamics/btDynamicsWorld.h | 13 ++- src/BulletSoftBody/btSoftBody.cpp | 80 +++++++++++++++++-- 5 files changed, 135 insertions(+), 40 deletions(-) diff --git a/Demos/SoftDemo/SoftDemo.cpp b/Demos/SoftDemo/SoftDemo.cpp index f015d487e..fa34796f6 100644 --- a/Demos/SoftDemo/SoftDemo.cpp +++ b/Demos/SoftDemo/SoftDemo.cpp @@ -98,6 +98,41 @@ void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int extern int gNumManifold; extern int gOverlappingPairs; +///for mouse picking +void pickingPreTickCallback (btDynamicsWorld *world, btScalar timeStep) +{ + SoftDemo* softDemo = (SoftDemo*)world->getWorldUserInfo(); + + if(softDemo->m_drag) + { + const int x=softDemo->m_lastmousepos[0]; + const int y=softDemo->m_lastmousepos[1]; + const btVector3 rayFrom=softDemo->getCameraPosition(); + const btVector3 rayTo=softDemo->getRayTo(x,y); + const btVector3 rayDir=(rayTo-rayFrom).normalized(); + const btVector3 N=(softDemo->getCameraTargetPosition()-softDemo->getCameraPosition()).normalized(); + const btScalar O=btDot(softDemo->m_impact,N); + const btScalar den=btDot(N,rayDir); + if((den*den)>0) + { + const btScalar num=O-btDot(N,rayFrom); + const btScalar hit=num/den; + if((hit>0)&&(hit<1500)) + { + softDemo->m_goal=rayFrom+rayDir*hit; + } + } + btVector3 delta=softDemo->m_goal-softDemo->m_node->m_x; + static const btScalar maxdrag=10; + if(delta.length2()>(maxdrag*maxdrag)) + { + delta=delta.normalized()*maxdrag; + } + softDemo->m_node->m_v+=delta/timeStep; + } + +} + void SoftDemo::clientMoveAndDisplay() { @@ -106,39 +141,17 @@ void SoftDemo::clientMoveAndDisplay() - float dt = 1.0/60.; + float ms = getDeltaTimeMicroseconds(); + float dt = ms / 1000000.f;//1.0/60.; + + if (m_dynamicsWorld) { - if(m_drag) - { - const int x=m_lastmousepos[0]; - const int y=m_lastmousepos[1]; - const btVector3 rayFrom=m_cameraPosition; - const btVector3 rayTo=getRayTo(x,y); - const btVector3 rayDir=(rayTo-rayFrom).normalized(); - const btVector3 N=(m_cameraTargetPosition-m_cameraPosition).normalized(); - const btScalar O=btDot(m_impact,N); - const btScalar den=btDot(N,rayDir); - if((den*den)>0) - { - const btScalar num=O-btDot(N,rayFrom); - const btScalar hit=num/den; - if((hit>0)&&(hit<1500)) - { - m_goal=rayFrom+rayDir*hit; - } - } - btVector3 delta=m_goal-m_node->m_x; - static const btScalar maxdrag=10; - if(delta.length2()>(maxdrag*maxdrag)) - { - delta=delta.normalized()*maxdrag; - } - m_node->m_v+=delta/dt; - } + + -#define FIXED_STEP +//#define FIXED_STEP #ifdef FIXED_STEP m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0); @@ -1246,7 +1259,7 @@ static void Init_ClusterStackMixed(SoftDemo* pdemo) } } -unsigned current_demo=18; +unsigned current_demo=19; void SoftDemo::clientResetScene() { @@ -1711,6 +1724,7 @@ void SoftDemo::initPhysics() btDiscreteDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld = world; + m_dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true); m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; diff --git a/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp index fa0d63d74..23501c443 100644 --- a/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp @@ -48,6 +48,10 @@ void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) startProfiling(timeStep); + if(0 != m_internalPreTickCallback) { + (*m_internalPreTickCallback)(this, timeStep); + } + ///update aabbs information updateAabbs(); diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index cd6d9ed8e..9dd731d1a 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -362,6 +362,10 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) BT_PROFILE("internalSingleStepSimulation"); + if(0 != m_internalPreTickCallback) { + (*m_internalPreTickCallback)(this, timeStep); + } + ///apply gravity, predict motion predictUnconstraintMotion(timeStep); diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index ecf7a2f0c..a7b85afbe 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -41,6 +41,7 @@ class btDynamicsWorld : public btCollisionWorld protected: btInternalTickCallback m_internalTickCallback; + btInternalTickCallback m_internalPreTickCallback; void* m_worldUserInfo; btContactSolverInfo m_solverInfo; @@ -49,7 +50,7 @@ public: btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration) - :btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0), m_worldUserInfo(0) + :btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0),m_internalPreTickCallback(0), m_worldUserInfo(0) { } @@ -102,9 +103,15 @@ public: virtual void clearForces() = 0; /// Set the callback for when an internal tick (simulation substep) happens, optional user info - void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0) + void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0,bool isPreTick=false) { - m_internalTickCallback = cb; + if (isPreTick) + { + m_internalPreTickCallback = cb; + } else + { + m_internalTickCallback = cb; + } m_worldUserInfo = worldUserInfo; } diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index f6dcb0589..57c761306 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -704,6 +704,9 @@ void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse) cluster->m_ndimpulses++; } + + + // int btSoftBody::generateBendingConstraints(int distance,Material* mat) { @@ -715,14 +718,21 @@ int btSoftBody::generateBendingConstraints(int distance,Material* mat) const int n=m_nodes.size(); const unsigned inf=(~(unsigned)0)>>1; unsigned* adj=new unsigned[n*n]; + + #define IDX(_x_,_y_) ((_y_)*n+(_x_)) for(j=0;j m_links; + }; + + btAlignedObjectArray nodeLinks; + + + /* Build node links */ + nodeLinks.resize(m_nodes.size()); + + for( i=0;isum) + int k = nodeLinks[ii].m_links[jj]; + for (int kk=0;kksum) + { + adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + } + } + + } + } + } + } else + { + ///generic Floyd's algorithm + for(int k=0;ksum) + { + adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + } } } } } + + /* Build links */ int nlinks=0; for(j=0;j