16 - Physics

Physics is a vast topic in computing and gaming and you can spend months and months writing a complex physics engine that will power you game and make it fully dynamic... Alternatively you could integrate an already existing physics engine middleware package into your game and get it hooked up in much less time.

I chose to write my own physics implementation for my voxel engine, as I seem to do for most sub systems. :\ But rather than spend months and months writing something really complex, I decided I would write a simple physics solution and see if it could give me the level of dynamic motion that I needed and also look good at the same time.

Below I will give a brief outline of how the physics engine functions in my voxel engine...

Introduction

The greatest surprise about writing physics is that it really is very simple once you understand the mechanics. Physics equations and differential calculus isn't a hard topic to understand, and isn't as scary as we once thought at school. One BIG problem I have noticed when seeing other people talk about physics engines and describe problems they have when implementing physics in their games isn't a problem with the underlying physics. It's more a problem to do with applying a set of physics rules and properties to a discrete simulation.

Timesteps

// TODO..

Basic Integration

Here is the code to demonstrate the update loop and integration of our physics properties.

void PhysicsObject::Update(float dt) {
  Vector3d acceleration = m_force + (m_gravityDirection * 9.81 f);
  m_velocity += acceleration * dt;
  m_position += m_velocity * dt;
  m_angularVelocity += m_angularAcceleration * dt;
  m_rotation += m_angularVelocity * dt; // Reset force variable every frame
  m_force = Vector3d(0.0 f, 0.0 f, 0.0 f);
}

As you can see, this code really is very simple! There isn't a lot to understand to get a physics based simulation up and running in about 10 minutes.

Now there are a few things to note about this code:

    • I don't care about mass in my physics simulation. This is generally bad, but I have no interest in representing mass in my voxel engine so I can avoid some headaches by removing mass. The consequence of this means that all objects in my world appear to have the same mass (weight).
    • I cheat with rotation. See below
    • External force vector is reset every frame, functions to apply external force on the object get called outside of the objects update simulation and the force vector is just accumulated every time an external force is applied.
    • (At the moment) I am not simulating any advanced physics properties such as friction, wind resistance, drag, etc... again, this isnt something I am interested in simulating in my voxel engine.

By taking all the shortcuts and simplifications that I have listed above, you can end up with a very simple integration equation that will allow you to apply forces to objects and also simulate gravity. This is perfect for getting a simple physics simulation up and running to test.

Rotation

As I said above, I cheat with rotation. For each of my objects that I want to rotate in the world I store a vector to represent rotation. (Euler angles)

When rendering an object I apply this rotation vector (as well as the translation vector) into the world matrix for the object, and this allows me to render a translated and rotated object.

void PhysicsObject::CalculateWorldTransformMatrix() {
  m_worldMatrix.LoadIdentity();
  m_worldMatrix.SetRotation(DegToRad(m_rotation.x), DegToRad(m_rotation.y), DegToRad(m_rotation.z));
  m_worldMatrix.SetTranslation(m_position);
}

Warning : This code above WILL produce Gimbal Lock. Depending on what you are simulation and how you are applying your rotations, this might be a bad thing for you. The way to solve this problem is to use Quaternions to represent your rotations.

External Forces & Impulses

One particular problem that many struggle with is to do with applying external forces to objects in their physics engines and getting the desired results. Should we be storing forces applied to an object or calculating impulses every frame?

Personally I like to take the approach that every object's forces are reset every frame and we add any and all external forces to the object every frame (This includes gravity) Doing it this way seems more natural to me that storing a force vector internally in the object and manipulating it that way. For example applying gravity to acceleration as a downward force of 9.81 every frame seems the correct way to approach this problem.

Collision Responses

Now we are getting onto a very advanced topic and one that rightfully should cause some headaches. Since our simulation is discrete and every frame we apply some force and motion to our objects, and then calculate new positions for our objects. This will put us into the situation where we have objects overlapping or intersecting (something which never happens in the real world).

There are a number of different ways to tackle this problem and correctly work out a correct collision response.

    • You can roll back the integration and sub-divide the timestep, then apply the smaller integration, and keep doing this recursively until you get the exact point of collision.
    • You could artificially separate the objects by pushing their positions away from each other, and then applying the collision response to each object. This unfortunately causes some side effects since you are moving the objects positions outside of the physics loop and this will cause an imbalance of force in your system.
    • You can rollback the integration, so that the original object isnt colliding with the 2nd object anymore and apply a reverse collision response, so it appears as though the object bounced back and the collision happened in the previous frame.

There are other solutions to solve this problem too and get ultra realistic collision responses. Also the correct solution to use is entirely dependent on the situation and the desired outcome. For example in my block particle effects, whenever I detect a collision with the world, I simply just roll back the integration and apply a backwards velocity response. This has the desired effect of making particles look like they are bouncing off the world, while at the same time being fast and efficient and no body will care if the particle effects are not behaving physically ultra realistic.

Video Demonstrations

Here are a few videos demonstrating physics in my voxel engine:

Hopefully this article will go some way to helping you understand a little bit more about physics simulation and also demonstrate how I achieved the physics simulation in my personal voxel engine.