In third year we had an entire module dedicated to the different components that make up a complete game engine. The assessment for this module was based entirely around a solo project, where we had to choose one aspect of a game engine and develop it. I chose to develop a 2D physics engine, as I was interested in understanding how each step of the process worked, from the simulation of rigid bodies through to collision detection and resolution.
The engine was written by me, entirely from scratch, using the DirectX SDK in C++. I had to write it as if it was part of a complete engine, meaning it had to be totally modular and easily integrate into other systems. I implemented some debug-drawing style functions for rendering that feed directly into the DirectX pipeline. I used these to create a demo scene for the project’s assessment, and all the code I produced can be found on my GitHub.
The engine’s implementation should be familiar to anyone who has used a physics engine before, but the components are essentially:
- Shapes, these are the colliders that interact with one another in the scene. I implemented circles, boxes and planes (halfspaces), but the base class is easily extensible.
- Rigid body information, separate from the shape that the body is being represented by. This includes the body’s current velocity, angular velocity, its mass and inertia.
- Collision detection between shapes, including finding the point of penetration and calculating the collision normal, which is used to resolve the collision.
- Position resolution, separating the shapes when they collide. I completed linear resolution, which moves the objects apart in a straight line. I had started an implementation of non-linear projection to separate the entities, which uses rotation as well, which is still present in the code.
- Velocity resolution, for both linear and angular velocity. I completed the function for linear velocity resolution, but the algorithm for angular velocity resolution was not perfect by the time the module concluded.
As the focus of the module was on quality of code including incomplete features and understanding of the features implemented, I was under no pressure to rush to complete components as long as I had demonstrated a good understanding of them, which is why the engine ended in a partially implemented state. It would definitely be interesting to pick it up in the future to complete the non-linear algorithms and add in functions for body movement to see how the interactions all look in motion.
Nevertheless, I learnt a lot from the process of building the engine, both with regards to the workings of physics engines themselves and also in writing clear, concise, well-structured code, as this was a much larger project than those I had previously taken on by myself.