I tried in the last weeks to move an object with a mouse and interact with other bodies.
I have a compound object (2 walls) and it is kinematic, so I can move this body with the mouse.
After setting setCcdMotionThreshold, I am able to set a infinity force to a ball and this ball will bounce on a wall/kinematic object (even if the wall is really thin).
I can also move the walls and the balls are moved. But if I move the walls too fast, I can move the walls through the balls.
So my question is:
- what is the right way to move the walls, without this effect?
I tried to set a sliderconstraint, so I move the kinematic object and on the slider I attach a rigid body. It was better, but I don't know if this is the right way.
The wiki says it is a one way collision. So a solid body can collide with a kinematic object but a kinematic object hasn't a collision detection with the dynamic objects? I read a lot of threads and I always see that it is possible to move kinematic objects for a direct interaction with the world.
I can upload the exe file if this can help (it is a dx10/9 executable).
I don't know if this can help, but here the code for the creation of the objects (I use the btCollisionObject::CF_KINEMATIC_OBJECT flag):
Code: Select all
double dWallDim = 0.2;
double dWallH = 2.0;
btCollisionShape* colShape1 = new btBoxShape(btVector3(dWallDim, dWallH*0.5, 2.5)); // |
btCollisionShape* colShape2 = new btBoxShape(btVector3(dWallDim, dWallH*0.5, 2.5)); // |
btCompoundShape* colCompoundShape = new btCompoundShape();
btTransform localTrans1;
localTrans1.setIdentity();
localTrans1.setOrigin(btVector3(-0.85 - dWallDim, dWallH*0.5, 0.0));
btTransform localTrans2;
localTrans2.setIdentity();
localTrans2.setOrigin(btVector3(0.85 + dWallDim, dWallH*0.5, 0.0));
colCompoundShape->addChildShape(localTrans1, colShape1);
colCompoundShape->addChildShape(localTrans2, colShape2);
collisionShapes.push_back(colCompoundShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(0.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
colCompoundShape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(btVector3(0.0, -0.5, 0.0));
g_myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,g_myMotionState,colCompoundShape,localInertia);
g_slider = new btRigidBody(rbInfo);
g_slider->setCollisionFlags( g_slider->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
g_slider->setActivationState(DISABLE_DEACTIVATION);
g_slider->setContactProcessingThreshold(btScalar(0.02));
g_slider->setCcdMotionThreshold(btScalar(0.00001));
g_slider->setCcdSweptSphereRadius(btScalar(0.01));
g_pDynamicsWorld->addRigidBody(g_slider);
Code: Select all
btCollisionShape* colShape = new btSphereShape(btScalar(g_ballDim));
collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.7f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(btVector3(-7.5 + i * 2.5,5.0,0.0));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
g_ball[i] = new btRigidBody(rbInfo);
g_ball[i]->setFriction(btScalar(0.005));
g_ball[i]->setRestitution(btScalar(0.8));
g_ball[i]->setDamping(btScalar(0.0), btScalar(0.0));
g_ball[i]->setHitFraction(btScalar(2.0));
g_ball[i]->setRollingFriction(btScalar(0.001));
g_ball[i]->setContactProcessingThreshold(btScalar(0.04));
g_ball[i]->setCcdMotionThreshold(btScalar(0.0001));
g_ball[i]->setActivationState(DISABLE_DEACTIVATION);
g_pDynamicsWorld->addRigidBody(g_ball[i]);
Code: Select all
double dMove;
btTransform slTr;
slTr = g_slider->getWorldTransform();
dMove = iMoveTo * 0.015625 * 0.022 * (325.0/240.0); // convert mouse/joystick position to a position
dMove = (dMove - slTr.getOrigin().x());
slTr.setOrigin(slTr.getOrigin() + btVector3(dMove,0,0));
g_slider->setWorldTransform(slTr); // set slider (2 walls) position
//g_slider->setInterpolationWorldTransform(slTr);
//g_pDynamicsWorld->updateSingleAabb(g_slider);
g_myMotionState->getWorldTransform(slTr);
slTr.setOrigin(slTr.getOrigin() + btVector3(dMove,0,0));
g_myMotionState->setWorldTransform(slTr);
g_pDynamicsWorld->stepSimulation(fDelayInSeconds, 20);