on
An Impulse Engine in Rust and WebAssembly
This is a simple 2D physics engine that simulates rigid body dynamics using impulse-based methods. It is written in Rust and compiled to WebAssembly.
I wrote this project a long time ago. As a Rust newbie, I tried to implement everything from scratch for learning purposes. That means it doesn’t depend on any third-party collision detection library or linear algebra library.
If your browser supports WebAssembly, you should see an interactive canvas below. Try to click your mouse and stack objects! The source code can be found here.
You may notice that objects will jitter when stacking. Maybe someday I can find a solution.
Physics and Math Details #
Almost all the math details are illustrated in Erin Catto’s slides, except the formula of the moment of inertia of a triangle rotated about one corner. The derivation is as follows.
Click to expand the derivation
Let the two sides that cross the pivot be \(\vec{P_1}=(x_1,y_1)\) and \(\vec{P_2}=(x_2,y_2)\), the area density be \(\rho\), and the mass be \(M\), then the moment of inertia is:
\[ \begin{aligned} I&=\int r^2 \;\mathrm{d}m=\int r^2\rho \;\mathrm{d}S\\ &=\rho\iint (x^2+y^2) \;\mathrm{d}x\;\mathrm{d}y\\ \end{aligned} \]
\[ \text{Integration by substitution:}\left\{ \begin{aligned} x & = ux_1+vx_2 \\ y & = uy_1+vy_2 \\ \end{aligned} \right. \]
\[ \begin{aligned} I&=\rho\iint \left(u\vec{P_1}+v\vec{P_2}\right)^2 \left|\frac{\partial{(x,y)}}{\partial{(u,v)}}\right| \;\mathrm{d}u\;\mathrm{d}v\\ &=\rho \iint \left(u^2\vec{P_1}^2+v^2\vec{P_2}^2+2uv\vec{P_1}\cdot\vec{P_2}\right)\left|x_1y_2-x_2y_1\right|\;\mathrm{d}u\;\mathrm{d}v\\ &=\rho\left|\vec{P_1}\times\vec{P_2}\right|\iint \left(u^2\vec{P_1}^2+v^2\vec{P_2}^2+2uv\vec{P_1}\cdot\vec{P_2}\right)\;\mathrm{d}u\;\mathrm{d}v\\ &=2M\int_{0}^{1}\;\mathrm{d}v\int_{0}^{1-v}\left(u^2\vec{P_1}^2+v^2\vec{P_2}^2+2uv\vec{P_1}\cdot\vec{P_2}\right)\;\mathrm{d}u\\ &=\frac{M}{6}\left(\vec{P_1}^2+\vec{P_2}^2+\vec{P_1}\cdot\vec{P_2}\right) \end{aligned} \]
Reference #
- Separating Axis Theorem with Details
- Separating Axis Theorem with Interactive Examples
- Making a 2D Physics Engine Series
- Game Technologies Series
- Find Contact Points Using Clipping
- Collision Response
- How to Create a Custom 2D Physics Engine
- Game Physics Series
- Box2d-lite
- RandyGaul/ImpulseEngine