# Rigid body¶

Rigid bodies are the way to have dynamic interations with the fluid (other then changing the velocity field directly). Vortex2D only provides a way to get current forces applied to the rigidbodies, and applying velocities from the rigidbody to the fluid. Updating the rigidbody’s forces, velocities and position needs to be done by a seperate engine, such as Box2D.

Rigidbodies have three types:

• Static
• Weak
• Strong

## Static bodies¶

Static bodies act on the fluid, but the fluid doesn’t act on the fluid. They have a velocity that is imparted on the fluid. Think of motorized objects pushing through the fluid.

## Weak/Strong bodies¶

Weak rigidbodies are affected by the fluid. They can also in turn, affect the fluid, which is called a strong coupling with the fluid.

Mass and velocity is set using simple setter functions:

```Rigidbody rigidbody(device, size, drawable, type);
rigidbody.SetMassData(mass, inertia);
rigidbody.SetVelocities(velocity, angle);
```

Position and orientation is updated the same as with shapes:

```rigidbody.Position = {100.0f, 100.0f}
rigidbody.Rotation = 43.0f;
```

### Rigid body coupling¶

To have the fluid influence the rigid bodies and vice versa, two functions need to be implemented by deriving:

• `Vortex::Fluid::RigidBody::ApplyForces()`
• `Vortex::Fluid::RigidBody::ApplyVelocities()`

The first one has forces from the fluid applied to the rigidbody. The second has velocities from the rigidbody applied to the fluid.

An example implementation with Box2D is as follow:

```void Box2DRigidbody::ApplyForces()
{
if (GetType() & Vortex::Fluid::RigidBody::Type::eWeak)
{
auto force = GetForces();
b2Vec2 b2Force = {force.velocity.x, force.velocity.y};

mBody->ApplyForceToCenter(b2Force, true);
mBody->ApplyTorque(force.angular_velocity, true);
}
}

void Box2DRigidbody::ApplyVelocities()
{
auto pos = mBody->GetPosition();
Position = {pos.x, pos.y};
Rotation = glm::degrees(mBody->GetAngle());

if (GetType() & Vortex::Fluid::RigidBody::Type::eStatic)
{
glm::vec2 vel = {mBody->GetLinearVelocity().x, mBody->GetLinearVelocity().y};
float angularVelocity = mBody->GetAngularVelocity();
SetVelocities(vel, angularVelocity);
}
}
```

Note that any rigidbody physics can be used: chipmonk, bullet, etc.

Finally the rigidbody also needs to be updates, in lock-step with the fluid simulation.

Again, this is done by implementing `Vortex::Fluid::RigidBody::Step()`.

An example implementation with Box2D:

```   void Box2DSolver::Step(float delta)
{
const int velocityStep = 8;
const int positionStep = 3;
mWorld.Step(delta, velocityStep, positionStep);
}

The delta is the same used to create the world object.
```