To get to know more about this project, please check the Week 1 article where I introduce this project.
During Week 7, I started by doing more tests on my Broad Phase and the collision resolution, which led me to discover some bugs in my code.
First of all, I had a minor bug in my AABBOverlap method, which was considering the AABB structure differently than it actually is. What I mean by that is, the AABB that I’m using has the top right and the bottom left corners, the AABB that the method was considering has the top left and bottom right corners.
Secondly, I changed the collision detection to work with the next position rather than the current position, which gives a better presentation to the collisions.
After I added a test case where I have multiple objects in the same scene interacting with each other, and the result was not what I was expecting: some bodies didn’t collide and got stuck to each other, others just went inside of other bodies etc.
So I debugged my code and I discovered that the problem was mainly caused by the direction of the normal. The reason why I didn’t notice this problem in the last week is that I had the same orientation from one object to the other, for example, for the polygon vs circle collision, I had the circle at the bottom of the polygon. So what I had to do to fix that bug is to compare the direction of the vector from the center of one object to the other to the normal, if they’re not in the same direction, then I reverse the normal.
That mostly fixed the bug, but not entirely. The issue that I still had was that if I have a large object, the normal is still not correct. The reason behind that is the center is probably far from the collision point, which gives the illusion that the direction between the centers and the normal direction are different, and thus the normal gets reversed. So to fix that issue, I don’t resolve the collision if the impulse causes one object to get closer to the other rather than further, so that avoided me having the smaller object get stuck to the bigger object.
I also didn’t resolve the collision of two objects not moving in opposite directions. And that makes more sense for the user than seeing two objects basically moving in the same direction with the same speed colliding and going in the opposite direction.
Here is a simulation for what I had after:
Phew, now since that is out of the way, let’s talk about the new features. So I added the centroid computation for the polygon shapes, which is used in the collision resolution fixes that I mentioned earlier and is going to be used for Inertia.
And speaking of Inertia, I also calculated that since I’m going to need it when I’m going to add rotational movement support to the engine. So calculating the latter for a concave non-regular polygon wasn’t the easiest thing to figure out. I did the research on how to do it, and the most convenient way I found was described in this article.
The method that I used is basically a combination of Polygon Triangulation using the centroid that we just calculated and Parallel Axis Theorem. The concept is simple, I decompose the polygon into multiple triangles, where each triangle is composed of one of the edges and the center. The inertia of the polygon is the sum of the inertias of the all of the triangles it contains, and the reason behind doing this is that the computation of the inertia of a triangle is easier. This web page gives more info on how to compute a triangle inertia. The inertia I’m computing is the one around the Z axis.
I actually didn’t use exactly the formula mentioned there, but a derivation of it that uses the vertices coordinates, which bodes better for me. I found the formula in one of the comments in the article I mentioned earlier.
The code is not the prettiest but it does the job with the info that I have at my disposal, with the least overhead possible:
Moving on, I added support to static bodies. Static bodies are basically bodies that have infinite mass and zero velocity and are not affected by forces like gravity. The mass and InvMass are represented as zeros in the code so that the formulas would add up.
The static bodies support was actually a preparation step to the next step which is adding gravity to the engine. The reason behind that is having a static body that will prevent the other bodies from falling off the screen, which is handy for the simulation.
Adding gravity is simple, all I had to do is add gravity to the force applied on an object, which will later also contain other forces like friction, and then update the velocity accordingly, and finally update the position:
That did the job, however, I had a problem in the simulation after this; the bodies were sinking into the static body beneath them:
Thanks to this article, I found a solution for this. I’m doing a positional correction for each pair of bodies that just collided:
And that gave me these results:
You can always check the project on my GitHub.