Kinematic objects colliding with dynamic objects very badly
-
- Posts: 43
- Joined: Wed Mar 04, 2015 6:16 pm
Kinematic objects colliding with dynamic objects very badly
Kinematic objects do not seem to interact very well with dynamic objects. When you call m_pRigidBody->getWorldTransform().setOrigin() it caterpults any dynamic objects in it's way with enormous force. Is this normal?
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Kinematic objects colliding with dynamic objects very badly
What you want to do is to also set the velocities of the kinematic object correctly. Setting the velocities doesn't help move it to new transoforms, but it does help the collision system impart correct velocity on the dynamic object, allowing it to be knocked out of the way instead of getting into a state of interpenetration and then being ejected by non-physical algorithms.
So, you need to measure the velocity and ideally this would be done once per substep, which means you would give your Kinematic object a custom KinematicMotionsState and put the velocity measuring logic inside KinematicMotionState::getWorldTransform() method. It might look something like this:
Note: that is written from scratch and I didn't bother to compile it, so it may have bugs and typos. Tune the constants to suit your application.
So, you need to measure the velocity and ideally this would be done once per substep, which means you would give your Kinematic object a custom KinematicMotionsState and put the velocity measuring logic inside KinematicMotionState::getWorldTransform() method. It might look something like this:
Code: Select all
///synchronizes world transform from user to physics
void KinematicMotionState::getWorldTransform(btTransform & newWorldTransform) const override {
// linear velocity
btVector3 old_position = m_body->getWorldTransform().getPosition();
btVector3 new_position = newWorldTransform.getOrigin();
btVector3 new_linear_velocity = (new_position - old_position) / SUBSTEP_DURATION;
constexpr btScalar MIN_LINEAR_SPEED_SQUARED = 0.0001; // 1 cm/sec
if (new_linear_velocity.length2() < MIN_LINEAR_SPEED_SQUARED) {
new_linear_velocity.setZero();
}
m_body->setLinearVelocity(new_linear_velocity);
// angular velocity
btQuaternion old_rotation = m_body->getWorldTransform().getRotation();
btQuaternion new_rotation = newWorldTransform.getRotation();
btQuaternion delta_rotation = m_body->getWorldTransform().getRotation().inverse() * newWorldTransform.getRotation();
btScalar delta_angle = delta_rotation.getAngle();
btVector3 new_angular_velocity(0.0, 0.0, 0.0);
constexpr btScalar MIN_ANGULAR_SPEED = 0.01; // radians/sec
if (angle > MIN_ANGULAR_SPEED) {
new_angular_velocity = (angle / SUBSTEP_DURATION) * delta_rotation.getAxis();
}
m_body->setAngularVelocity(new_angular_velocity);
// transform
m_body->setWorldTransform(newWorldTransform);
}
-
- Posts: 43
- Joined: Wed Mar 04, 2015 6:16 pm
Re: Kinematic objects colliding with dynamic objects very badly
Thanks for the reply. Unfortunately, it makes no difference. I think velocity is ignored for kinematic objects.
Edit:
I finally figured it out. I was directly updating the WorldTransform, without updating the MotionState. I changed this to update both and now it works great:
Edit:
I finally figured it out. I was directly updating the WorldTransform, without updating the MotionState. I changed this to update both and now it works great:
Code: Select all
btTransform& t = m_pRigidBody->getWorldTransform();
t.setOrigin(btVector3(m_x+m_xOffset, m_y+m_yOffset, m_z));
m_pRigidBody->getMotionState()->setWorldTransform(t); // adding this line fixed the problem