- stop threads when exiting demo that uses multi threading

- improved friction model for parallel solver (align the friction direction with projected velocity, unless the projection is close to zero (only then use 2 arbitrary axis orthogonal to contact normal)
This commit is contained in:
ejcoumans
2007-11-11 22:48:08 +00:00
parent 232f41353f
commit 56c69bc42e
6 changed files with 76 additions and 19 deletions

View File

@@ -1,6 +1,15 @@
Bullet Continuous Collision Detection and Physics Library Bullet Continuous Collision Detection and Physics Library
Primary author and maintainer: Erwin Coumans Primary author and maintainer: Erwin Coumans
2007 Nov 11
- Fixed parallel solver (BulletMultiThreaded) friction issue
- Terminate Win32 Threads when closing the CcdPhysicsDemo (when USE_PARALLEL_SOLVER/USE_PARALLEL_DISPATCHER is defined)
2007 Nov 6
- Added support for 16-bit indices for triangle meshes
- Added support for multiple mesh parts using btBvhTriangleMeshShape.
Thanks to Tim Johansson
2007 Oct 22 2007 Oct 22
- All memory allocations go through btAlignedAlloc/btAlignedFree. User can override this to verify memory leaks - All memory allocations go through btAlignedAlloc/btAlignedFree. User can override this to verify memory leaks
- added a few more demos to AllBulletDemos - added a few more demos to AllBulletDemos

View File

@@ -93,12 +93,12 @@ public:
btDemoEntry g_demoEntries[] = btDemoEntry g_demoEntries[] =
{ {
{"BasicDemo", BasicDemo::Create},
{"RagdollDemo",RagdollDemo::Create}, {"RagdollDemo",RagdollDemo::Create},
{"ConvexDecomposition",ConvexDecompositionDemo::Create},
{"CcdPhysicsDemo", CcdPhysicsDemo::Create}, {"CcdPhysicsDemo", CcdPhysicsDemo::Create},
{"BspDemo", BspDemo::Create},
{"ConcaveDemo",ConcaveDemo::Create}, {"ConcaveDemo",ConcaveDemo::Create},
{"ConvexDecomposition",ConvexDecompositionDemo::Create},
{"BasicDemo", BasicDemo::Create},
{"BspDemo", BspDemo::Create},
{"Gimpact Test", GimpactConcaveDemo::Create}, {"Gimpact Test", GimpactConcaveDemo::Create},
{"Raytracer Test",Raytracer::Create}, {"Raytracer Test",Raytracer::Create},
{"GjkConvexCast",LinearConvexCastDemo::Create}, {"GjkConvexCast",LinearConvexCastDemo::Create},

View File

@@ -322,6 +322,9 @@ float myFrictionModel( btRigidBody& body1, btRigidBody& body2, btManifoldPoint&
void CcdPhysicsDemo::initPhysics() void CcdPhysicsDemo::initPhysics()
{ {
m_threadSupportSolver = 0;
m_threadSupportCollision = 0;
//#define USE_GROUND_PLANE 1 //#define USE_GROUND_PLANE 1
#ifdef USE_GROUND_PLANE #ifdef USE_GROUND_PLANE
m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5)); m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5));
@@ -356,7 +359,7 @@ int maxNumOutstandingTasks = 4;
#ifdef USE_WIN32_THREADING #ifdef USE_WIN32_THREADING
Win32ThreadSupport* threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
"collision", "collision",
processCollisionTask, processCollisionTask,
createCollisionLocalStoreMemory, createCollisionLocalStoreMemory,
@@ -389,7 +392,7 @@ int maxNumOutstandingTasks = 4;
#endif #endif
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,maxNumOutstandingTasks,m_collisionConfiguration); m_dispatcher = new SpuGatheringCollisionDispatcher(m_threadSupportCollision,maxNumOutstandingTasks,m_collisionConfiguration);
// m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); // m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
#else #else
@@ -422,7 +425,7 @@ int maxNumOutstandingTasks = 4;
#ifdef USE_PARALLEL_SOLVER #ifdef USE_PARALLEL_SOLVER
Win32ThreadSupport* threadSupportSolver = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( m_threadSupportSolver = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
"solver", "solver",
processSolverTask, processSolverTask,
createSolverLocalStoreMemory, createSolverLocalStoreMemory,
@@ -648,12 +651,22 @@ void CcdPhysicsDemo::exitPhysics()
//delete solver //delete solver
delete m_solver; delete m_solver;
if (m_threadSupportSolver)
{
delete m_threadSupportSolver;
}
//delete broadphase //delete broadphase
delete m_broadphase; delete m_broadphase;
//delete dispatcher //delete dispatcher
delete m_dispatcher; delete m_dispatcher;
if (m_threadSupportCollision)
{
delete m_threadSupportCollision;
}
delete m_collisionConfiguration; delete m_collisionConfiguration;

View File

@@ -25,6 +25,7 @@ class btCollisionDispatcher;
class btConstraintSolver; class btConstraintSolver;
struct btCollisionAlgorithmCreateFunc; struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration; class btDefaultCollisionConfiguration;
class Win32ThreadSupport;
///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1') ///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1')
class CcdPhysicsDemo : public DemoApplication class CcdPhysicsDemo : public DemoApplication
@@ -37,6 +38,10 @@ class CcdPhysicsDemo : public DemoApplication
btCollisionDispatcher* m_dispatcher; btCollisionDispatcher* m_dispatcher;
Win32ThreadSupport* m_threadSupportCollision;
Win32ThreadSupport* m_threadSupportSolver;
btConstraintSolver* m_solver; btConstraintSolver* m_solver;
btCollisionAlgorithmCreateFunc* m_boxBoxCF; btCollisionAlgorithmCreateFunc* m_boxBoxCF;

View File

@@ -1026,6 +1026,9 @@ void processSolverTask(void* userPtr, void* lsMemory)
btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition();
btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition(); btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition();
btScalar rel_vel;
btVector3 vel;
// De-penetration // De-penetration
{ {
SpuSolverInternalConstraint& constraint = localMemory->m_tempInternalConstr[0]; SpuSolverInternalConstraint& constraint = localMemory->m_tempInternalConstr[0];
@@ -1034,7 +1037,6 @@ void processSolverTask(void* userPtr, void* lsMemory)
constraint.m_localOffsetBodyB = offsB; constraint.m_localOffsetBodyB = offsB;
constraint.m_normal = cp.m_normalWorldOnB; constraint.m_normal = cp.m_normalWorldOnB;
{ {
//can be optimized, the cross products are already calculated //can be optimized, the cross products are already calculated
constraint.m_jacDiagABInv = computeJacobianInverse (rb0, rb1, pos1, pos2, cp.m_normalWorldOnB); constraint.m_jacDiagABInv = computeJacobianInverse (rb0, rb1, pos1, pos2, cp.m_normalWorldOnB);
@@ -1046,11 +1048,9 @@ void processSolverTask(void* userPtr, void* lsMemory)
btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1); btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1);
btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2); btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2);
btVector3 vel = vel1 - vel2; vel = vel1 - vel2;
btScalar rel_vel;
rel_vel = cp.m_normalWorldOnB.dot(vel); rel_vel = cp.m_normalWorldOnB.dot(vel);
constraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations); constraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations);
constraint.m_friction = cp.m_combinedFriction; constraint.m_friction = cp.m_combinedFriction;
float rest = - rel_vel * cp.m_combinedRestitution; float rest = - rel_vel * cp.m_combinedRestitution;
@@ -1082,8 +1082,16 @@ void processSolverTask(void* userPtr, void* lsMemory)
btVector3 frictionTangential0a, frictionTangential1b; btVector3 frictionTangential0a, frictionTangential1b;
btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b); frictionTangential0a = vel - cp.m_normalWorldOnB * rel_vel;
btScalar lat_rel_vel = frictionTangential0a.length2();
if (lat_rel_vel > SIMD_EPSILON)//0.0f)
{
frictionTangential0a /= btSqrt(lat_rel_vel);
frictionTangential1b = frictionTangential0a.cross(cp.m_normalWorldOnB);
} else
{
btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b);
}
{ {
SpuSolverInternalConstraint& constraint = localMemory->m_tempInternalConstr[1]; SpuSolverInternalConstraint& constraint = localMemory->m_tempInternalConstr[1];

View File

@@ -52,23 +52,27 @@ DWORD WINAPI Thread_no_1( LPVOID lpParam )
while (1) while (1)
{ {
WaitForSingleObject(status->m_eventStartHandle,INFINITE); WaitForSingleObject(status->m_eventStartHandle,INFINITE);
btAssert(status->m_status);
void* userPtr = status->m_userPtr; void* userPtr = status->m_userPtr;
if (userPtr) if (userPtr)
{ {
btAssert(status->m_status);
status->m_userThreadFunc(userPtr,status->m_lsMemory); status->m_userThreadFunc(userPtr,status->m_lsMemory);
status->m_status = 2; status->m_status = 2;
SetEvent(status->m_eventCompletetHandle); SetEvent(status->m_eventCompletetHandle);
} else } else
{ {
//exit Thread //exit Thread
status->m_status = 3;
SetEvent(status->m_eventCompletetHandle);
printf("Thread with taskId %i with handle %i exiting\n",status->m_taskId, status->m_threadHandle);
break; break;
} }
} }
printf("Thread TERMINATED\n");
return 0; return 0;
} }
@@ -202,7 +206,7 @@ void Win32ThreadSupport::startThreads(Win32ThreadConstructionInfo& threadConstru
SetThreadPriority(handle,THREAD_PRIORITY_HIGHEST); SetThreadPriority(handle,THREAD_PRIORITY_HIGHEST);
//SetThreadPriority(handle,THREAD_PRIORITY_TIME_CRITICAL); //SetThreadPriority(handle,THREAD_PRIORITY_TIME_CRITICAL);
//SetThreadAffinityMask(handle, 1<<i); SetThreadAffinityMask(handle, 1<<i);
spuStatus.m_taskId = i; spuStatus.m_taskId = i;
spuStatus.m_commandId = 0; spuStatus.m_commandId = 0;
@@ -225,10 +229,28 @@ void Win32ThreadSupport::startSPU()
///tell the task scheduler we are done with the SPU tasks ///tell the task scheduler we are done with the SPU tasks
void Win32ThreadSupport::stopSPU() void Win32ThreadSupport::stopSPU()
{ {
// m_activeSpuStatus.pop_back(); int i;
// WaitForSingleObject(spuStatus.bla, INFINITE); for (i=0;i<m_activeSpuStatus.size();i++)
// CloseHandle(spuStatus.m_threadHandle); {
btSpuStatus& spuStatus = m_activeSpuStatus[i];
if (spuStatus.m_status>0)
{
WaitForSingleObject(spuStatus.m_eventCompletetHandle, INFINITE);
}
spuStatus.m_userPtr = 0;
SetEvent(spuStatus.m_eventStartHandle);
WaitForSingleObject(spuStatus.m_eventCompletetHandle, INFINITE);
CloseHandle(spuStatus.m_eventCompletetHandle);
CloseHandle(spuStatus.m_eventStartHandle);
CloseHandle(spuStatus.m_threadHandle);
}
m_activeSpuStatus.clear();
m_completeHandles.clear();
} }
#endif //USE_WIN32_THREADING #endif //USE_WIN32_THREADING