Repositioning a Solid in Bullet Physics

I am writing a character animation animation engine that uses Bullet Physics as a physics modeling engine.

The sequence will start without a model on the screen, then the animation will be assigned to this model, the model will be transferred to frame 0 of the animation, and the engine will begin rendering the model with animation.

What is the correct way to rearrange rigid bodies in a character model when it is initialized in frame 0?

I am currently using this code, which is called right after the animation is assigned to the model, and the bones move to frame position 0:

_world->removeRigidBody(_body); bool k = (_type == Kinematics); _body->setCollisionFlags(_body->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE); btTransform tr = BulletPhysics::ConvertD3DXMatrix(&(_bone->getCombinedTrans())); tr *= _trans; _body->setCenterOfMassTransform(tr); _body->clearForces(); _body->setLinearVelocity(btVector3(0,0,0)); _body->setAngularVelocity(btVector3(0,0,0)); _world->addRigidBody(_body, _groupID, _groupMask); 

The problem is that sometimes it works, and sometimes not. For example, take a model skirt. Sometimes it appears in its natural position, sometimes it shifts slightly, and it falls into place, and in other cases it is completely cut out through the body, as if the collision is disconnected, and some force pushes it in this direction. This makes sense most of the time, because in the test animation I use the model's initial position in the center of the screen, but the animation starts on the left side of the screen. Does anyone know how to solve this?

I know that the bones on the skirt are not a problem, because I turned off the physics and forced it to manually update the position of the bones in each frame, and everything was in the right positions throughout the animation.

EDIT: I also have limitations, maybe this could be the reason for this?

+4
source share
3 answers

Here is my reposition method that does just that.

 void LimbBt::reposition(btVector3 position,btVector3 orientation) { btTransform initialTransform; initialTransform.setOrigin(position); initialTransform.setRotation(orientation); mBody->setWorldTransform(initialTransform); mMotionState->setWorldTransform(initialTransform); } 

The mMotionState motion state is the motion state that you created for btRigidBody at the beginning. Just add your clearForces () and speeds to it to stop the body from moving from a new position, as if it was passing through a portal. That should do it. This works well with me here.

Edit: The restrictions will be adapted if you correctly set all rigid bodies. For this purpose, it is easy to calculate the relative position and move the entire limited structure of the rigid body in accordance with this. If you do it wrong, you will get a strong jerk, as the constraints will try to adjust the numerical value, causing high forces if there are large spaces of limitation.

Edit2: Another problem is that if you need deterministic behavior (every time you reset your bodies, they must match exactly the same), then you have to kill your old world dynamics, recreate it and add all the bodies again, The world stores information about bodies that cannot yet be cleaned. This may change in the future as bullet4 will support deterministic discharges. But for now, if you are conducting experiments with deterministic discharges, you need to reset the world and recreate it.

source: discussion with Erwin Cuman, developer of Bullet Physics .

+2
source

I can’t tell you what causes an unusual outcome when moving solids, but I can definitely sympathize!

To solve this problem, you need to do three things:

  • Transform your rigid bodies into kinematic ones.
  • Adjust the world transformation of the state of motion of bodies and NOT a solid body.
  • Transform the kinematic body back to solid.
0
source

A briefly tested code fragment effectively teleports a solid body, updating its state of motion to its new position and orientation, and also nullifies all the speeds and forces acting on it.

  void teleport(btVector3 position, btQuaternion& orientation) const { btTransform transform; transform.setIdentity(); transform.setOrigin(position); transform.setRotation(orientation); m_rigidBodyVehicle->setWorldTransform(transform); m_rigidBodyVehicle->getMotionState()->setWorldTransform(transform); m_rigidBodyVehicle->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); m_rigidBodyVehicle->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f)); m_rigidBodyVehicle->clearForces(); } 
0
source

Source: https://habr.com/ru/post/1432117/


All Articles