I'm try to use contact callback and special friction mode, with a target velocity and direction to simulate a conveyor.
Like this topic about "How to simulate a conveyor?": viewtopic.php?f=9&t=6076
The following is my conveyor (Static RigidBody):
Code: Select all
btRigidBody* conveyor = createRigidBody(mass(0), transform, shape, color);
conveyor->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
conveyor->setUserIndex3(10086);
conveyor->setCollisionFlags(conveyor->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
conveyor->setFriction(0.5);
I judge the collision between box and conveyor by UserIndex3 in ContactAddedCallback or ContactProcessedCallback.
Here is myContactAddedCallback
Code: Select all
bool myContactAddedCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1)
{
//cp.m_contactPointFlags |= BT_CONTACT_FLAG_FRICTION_ANCHOR;
cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
if (colObj0Wrap->getCollisionObject()->getUserIndex3() == 10086
|| colObj1Wrap->getCollisionObject()->getUserIndex3() == 10086)
{
const btCollisionObjectWrapper* target = colObj0Wrap->getCollisionObject()->getUserIndex3() == 10086 ?
colObj0Wrap : colObj1Wrap;
btVector3 v(-1.f, 0, 0);
btTransform s = colObj0Wrap->getWorldTransform();
v = v.dot3(s.getBasis().getRow(0), s.getBasis().getRow(1), s.getBasis().getRow(2));
cp.m_lateralFrictionDir1 = v;
cp.m_contactMotion1 = 1;
}
return true;
}
1.
Code: Select all
conveyor->setFriction(0.5); & cp.m_contactMotion1 = 0.8;
2.
Code: Select all
conveyor->setFriction(0.2); & cp.m_contactMotion1 = 0.8;
That seems workable, but has some subtle problems: The box will come to rest after traveling a certain distance.
3. When cp.m_contactMotion1 is a little bit small and friction is greater than the horizontal component of gravity:
Code: Select all
conveyor->setFriction(0.5); & cp.m_contactMotion1 = 0.6;
4. When conveyor's friction is a little bit smaller (the horizontal component of gravity is greater than friction) :
Code: Select all
conveyor->setFriction(0.3); & cp.m_contactMotion1 = 0.6;
I think both of these cases are because myContactAddedCallback() is not called.
What causes it?
After the box stopped, the left mouse button click on the box, the box will move again and come to rest after traveling a certain distance.
Thanks!
See attached BasicExample.cpp