astrid dot tech

Planet-Asteroid Collision

A GPU-accelerated simulation of a planet hitting an asteroid

October 2020 - November 2020

opengl glsl cpp simulation school:cal-poly=csc-572



Our project is a simulation of an asteroid impacting the Earth. We were inspired by this GitHub repo.


After the first collision, there are 552 particles being simulated at:

  • 60 FPS running on Ubuntu 20.04 (i5-8300H, GTX 1060M)
  • 20 FPS running on Windows 10 (i7-7820, GTX 1070)

Without GPU-accelerated computation, these would be running at 20 FPS and 1.5 FPS respectively.

How it works


At the beginning, there are two particles, an asteroid and a planet, on a collision course with each other. When they collide, they are deleted and replaced with 64 chunks and 488 chunks respectively.

Our chunks were made in Blender by slicing meshes and filling them in.


Physics Engine

Our physics engine runs in the following 4 steps:

1. GPU Phase

The GPU runs through the cartesian product of all particles, and calculates both gravitational force and intersections. Gravitational force is summed up per-particle, and intersections are recorded in a array list.

When the CPU receives the GPU’s output, the gravity is written to the particles and the intersecting ones are recorded in a contact index.

2. Intersection Bookkeeping

Contacts keep track of an internal state to improve the stability of low-relative velocity contacts. This phase performs the following tasks:

Creates new contacts that did not previously exist
Updates old contacts that still exist
Deletes old contacts that no longer exist

3. Contact Solving

I describe this step in detail in this blog post.

4. Integration

This phase performs a single Euler step of position and rotation.

Position is integrated with

sk+1=vΔt+sks_{k+1} = v \cdot \Delta t + s_k

where ss is position, vv is velocity, and Δt\Delta t is the time step.

Rotation is stored in a matrix Θ\Theta to avoid gimbal lock. Angular velocity is a vector ω\omega which is in the direction that the axis the object is rotating around using the right-hand rule, scaled to the speed in radians per second.

Suppose MM is the matrix representing a rotation of ωΔt|\omega|\cdot \Delta t around ω\omega . Thus, we integrate rotation with

Θk+1=MΘk\Theta_{k+1} = M \cdot \Theta_k