Fix friction and restitution in BulletMultiThreaded (collision detection and parallel solver)
Thanks to lsgmasa for reporting, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1758
This commit is contained in:
@@ -31,13 +31,38 @@ SpuContactResult::SpuContactResult()
|
|||||||
g_manifoldDmaExport.swapBuffers();
|
g_manifoldDmaExport.swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, bool isSwapped)
|
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
|
||||||
|
inline btScalar calculateCombinedFriction(btScalar friction0,btScalar friction1)
|
||||||
|
{
|
||||||
|
btScalar friction = friction0*friction1;
|
||||||
|
|
||||||
|
const btScalar MAX_FRICTION = btScalar(10.);
|
||||||
|
|
||||||
|
if (friction < -MAX_FRICTION)
|
||||||
|
friction = -MAX_FRICTION;
|
||||||
|
if (friction > MAX_FRICTION)
|
||||||
|
friction = MAX_FRICTION;
|
||||||
|
return friction;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline btScalar calculateCombinedRestitution(btScalar restitution0,btScalar restitution1)
|
||||||
|
{
|
||||||
|
return restitution0*restitution1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction1, bool isSwapped)
|
||||||
{
|
{
|
||||||
//spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress);
|
//spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress);
|
||||||
m_rootWorldTransform0 = worldTrans0;
|
m_rootWorldTransform0 = worldTrans0;
|
||||||
m_rootWorldTransform1 = worldTrans1;
|
m_rootWorldTransform1 = worldTrans1;
|
||||||
m_manifoldAddress = manifoldAddress;
|
m_manifoldAddress = manifoldAddress;
|
||||||
m_spuManifold = spuManifold;
|
m_spuManifold = spuManifold;
|
||||||
|
|
||||||
|
m_combinedFriction = calculateCombinedFriction(friction0,friction1);
|
||||||
|
m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1);
|
||||||
m_isSwapped = isSwapped;
|
m_isSwapped = isSwapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +80,8 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
|
|||||||
btPersistentManifold* manifoldPtr,
|
btPersistentManifold* manifoldPtr,
|
||||||
btTransform& transA,
|
btTransform& transA,
|
||||||
btTransform& transB,
|
btTransform& transB,
|
||||||
|
btScalar combinedFriction,
|
||||||
|
btScalar combinedRestitution,
|
||||||
bool isSwapped)
|
bool isSwapped)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -109,8 +136,8 @@ bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
|
|||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
||||||
newPt.m_combinedFriction = 0.25f;//calculateCombinedFriction(m_body0,m_body1);
|
newPt.m_combinedFriction = combinedFriction;
|
||||||
newPt.m_combinedRestitution = 0.0f;//calculateCombinedRestitution(m_body0,m_body1);
|
newPt.m_combinedRestitution = combinedRestitution;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//potential TODO: SPU callbacks, either immediate (local on the SPU), or deferred
|
//potential TODO: SPU callbacks, either immediate (local on the SPU), or deferred
|
||||||
@@ -165,6 +192,8 @@ void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const b
|
|||||||
localManifold,
|
localManifold,
|
||||||
m_rootWorldTransform0,
|
m_rootWorldTransform0,
|
||||||
m_rootWorldTransform1,
|
m_rootWorldTransform1,
|
||||||
|
m_combinedFriction,
|
||||||
|
m_combinedRestitution,
|
||||||
m_isSwapped);
|
m_isSwapped);
|
||||||
m_RequiresWriteBack = m_RequiresWriteBack || retVal;
|
m_RequiresWriteBack = m_RequiresWriteBack || retVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,9 @@ class SpuContactResult
|
|||||||
|
|
||||||
btPersistentManifold* m_spuManifold;
|
btPersistentManifold* m_spuManifold;
|
||||||
bool m_RequiresWriteBack;
|
bool m_RequiresWriteBack;
|
||||||
|
btScalar m_combinedFriction;
|
||||||
|
btScalar m_combinedRestitution;
|
||||||
|
|
||||||
bool m_isSwapped;
|
bool m_isSwapped;
|
||||||
|
|
||||||
DoubleBuffer<btPersistentManifold, 1> g_manifoldDmaExport;
|
DoubleBuffer<btPersistentManifold, 1> g_manifoldDmaExport;
|
||||||
@@ -96,7 +99,8 @@ class SpuContactResult
|
|||||||
|
|
||||||
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1);
|
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1);
|
||||||
|
|
||||||
void setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, bool isSwapped = false);
|
void setContactInfo(btPersistentManifold* spuManifold, uint64_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction01, bool isSwapped);
|
||||||
|
|
||||||
|
|
||||||
void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold);
|
void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold);
|
||||||
|
|
||||||
|
|||||||
@@ -932,7 +932,11 @@ void ProcessSpuConvexConvexCollision(SpuCollisionPairInput* wuInput, CollisionTa
|
|||||||
#endif
|
#endif
|
||||||
btPersistentManifold* spuManifold=&lsMemPtr->gPersistentManifold;
|
btPersistentManifold* spuManifold=&lsMemPtr->gPersistentManifold;
|
||||||
//spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
|
//spuContacts.setContactInfo(spuManifold,manifoldAddress,wuInput->m_worldTransform0,wuInput->m_worldTransform1,wuInput->m_isSwapped);
|
||||||
spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),lsMemPtr->getColObj1()->getWorldTransform(),wuInput->m_isSwapped);
|
spuContacts.setContactInfo(spuManifold,manifoldAddress,lsMemPtr->getColObj0()->getWorldTransform(),
|
||||||
|
lsMemPtr->getColObj1()->getWorldTransform(),
|
||||||
|
lsMemPtr->getColObj0()->getRestitution(),lsMemPtr->getColObj1()->getRestitution(),
|
||||||
|
lsMemPtr->getColObj0()->getFriction(),lsMemPtr->getColObj1()->getFriction(),
|
||||||
|
wuInput->m_isSwapped);
|
||||||
|
|
||||||
SpuGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&vsSolver,&penetrationSolver);
|
SpuGjkPairDetector gjk(shape0Ptr,shape1Ptr,shapeType0,shapeType1,marginA,marginB,&vsSolver,&penetrationSolver);
|
||||||
gjk.getClosestPoints(cpInput,spuContacts);//,debugDraw);
|
gjk.getClosestPoints(cpInput,spuContacts);//,debugDraw);
|
||||||
|
|||||||
@@ -1062,15 +1062,14 @@ void processSolverTask(void* userPtr, void* lsMemory)
|
|||||||
};
|
};
|
||||||
|
|
||||||
btScalar penVel = -constraint.m_penetration/taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_timeStep;
|
btScalar penVel = -constraint.m_penetration/taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_timeStep;
|
||||||
if (rest > penVel)
|
|
||||||
{
|
|
||||||
rest = btScalar(0.);
|
|
||||||
}
|
|
||||||
constraint.m_restitution = rest;
|
|
||||||
|
|
||||||
constraint.m_penetration *=
|
constraint.m_penetration *=
|
||||||
-(taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_erp/taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_timeStep);
|
-(taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_erp/taskDesc.m_commandData.m_manifoldSetup.m_solverInfo.m_timeStep);
|
||||||
|
|
||||||
|
if (rest > penVel)
|
||||||
|
{
|
||||||
|
constraint.m_penetration = btScalar(0.);
|
||||||
|
}
|
||||||
|
constraint.m_restitution = rest;
|
||||||
constraint.m_appliedImpulse = 0.f;
|
constraint.m_appliedImpulse = 0.f;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user