Making a 2D Physics Engine: The Series
This is the second article in the Making a 2D Physics Engine Series. If you haven't already read all the articles in the series before this one, I strongly recommend that you take a detour and skim through them.
- Making a 2D Physics Engine: The Math
- Making a 2D Physics Engine: Spaces and Bodies
- Making a 2D Physics Engine: Shapes, Worlds and Integration
- Making a 2D Physics Engine: Mass, Inertia and Forces
Prerequisites
Basic knowledge of linear algebra including 2D vectors and 2x2 matrices as covered in the first article in the series.
Introduction
This article intends to introduce the concepts of Local space and World space and deal with transformations from Local to World space and vice versa. It also outlines the representation of a body or physical entity in the physics engine.
Spaces
Spaces are limitless extents relative to which an object's properties, i.e. rotation and position are defined.
World Space
All objects in a world have a definite position and rotation in space, which are measured relative to the world origin. World space is omnipresent; all entities in our world will be placed relative to it.
Local Space
Local space is relative to a single entity in the world. When measured in local space of an entity, the properties of other entities are measured relative to that entity.
Transformation
Let the given point be \(X\) in world space and \(X'\) in local space relative to an entity. If the position of that entity (origin of the local space) is \(P\) and the rotation matrix of the entity (rotation matrix of the local space) is \(U = \begin{bmatrix}\cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\) (where \(\theta\) is the world rotation of the entity), then the following transformations can take place.
Local Space to World Space (Transform)
\(X = P + UX'\)
The local space point is first rotated to bring it to world space rotation, and then translated to the world space position.
It is important to note that a change in the local space origin or rotation will not affect a local space position. The world space position, however, may change.
World Space to Local Space (Inverse Transform)
Solving the above equation for (X') will give us the required world space to local space transformation:
\(X' = U^{-1}(X - P)\)
This gives us a problem - how to find the inverse \(U^{-1}\) of the matrix? Turns out that our rotation matrix is orthongonal, so \(U^{-1} = U^T\), where \(U^T\) is the transpose of matrix which we already know how to compute. The equation can now be rewritten as
\(X' = U^T(X - P)\)
Space transformations will be used throughout the engine to simplify mathematical routines.
Bodies
Bodies or entities are are simply objects in a world. In our case, a body is an object that can physically interact with the environment (or not, depending on its configuration). Each body has a few defining characteristics or properties, like position, velocity, torque, its shape, and mass.
A body in a physics engine does not do much by itself. Generally, all it is responsible for is integrating and updating its forces, velocities, and positions. It is the physics engine - or other external code - that manages interactions like collisions. A body will typically be manipulated by applying forces on it. However, in rare cases (like impulse collision resolution, which we will cover later), the velocity will be modified directly by the physics engine.
Body-Physics Engine Interactions
Typical interactions of a physics engine with the bodies in a world include:
- Application of forces
- Collision detection and resolution
- Spatial queries (raycasts and shapecasts)
- Joints and constraints
A Body in Code
A Body
structure in Rust (taken from the engine I am building in Rust alongside this article series) looks like the following:
pub struct Body {
pub position: Vec2,
pub rotation: f32,
pub velocity: Vec2,
pub angular_vel: f32,
force: Vec2,
torque: f32,
pub mass: f32,
pub inertia: f32,
pub coeff_friction: f32,
pub coeff_restitution: f32,
pub shape: Shape,
}
This Body
definition, however, is not complete. As the physics engine grows, more properties will be added to it.
History
7 Nov 2017: Initial post