Basic physics

posted in ProjectW for project ProjectW
Published July 15, 2020
Advertisement

I decided to implement some basic physics to the game. I really like when players can mess around with furnitures in dungeons, so I wanted them to be able to push stuff around. It could also be fun to have big baddies destroying/pushing everything in their path. So I implemented some basic rigid bodies simulations. For the moment, I only do box and disks, without friction or other constraints. I plan to develop this further in the future (for example, to have doors with a fixed pivot axis).

Here is what it looks like for the moment:

I found a lot of references for aligned box to box collisions, but not so many for rotated boxes. I used Nilson Souto tutorial as a reference, and then cooked up the following solution:

→ When I update my nodes, if I have a collision constraint, I add it to the PhysicsEngine, which estimates how much space the body occupies in the x-coordinate. This allows me to insert them in a map indexed by their estimated left-most position.

→ After the node update loop step, I iterate over this map. For each element, I consider all the next elements in the map whose estimated left-most position is less or equal than my element right-most position. This allows me to already drop a lot of collisions tests because the bodies are too far appart, since their projections on the x-axis do not intersect.

→ For disk to disk collision, I simply compute the minimal translation vector directly (because it is easy and only require to compare the distance of the centers and the radii), and push my objects along it, depending on their mass using the simple formula (unless one of the masses is infinite):

 push_1 = MTV * mass_1 / (mass_1 + mass_2)
 push_2 = - MTV * mass_2 / (mass_1 + mass_2)

Because I don't want to have stuff bouncing, I do not modify the velocity of my objects, but I directly modify their position.

→ For box to box and box to disk, I put myself in the relative coordinate system of the box, and then compute the explicit Minkowski “difference” (actually the Minkowski sum of A and -B, not the true difference). Then, I verify if the origin is in the Minkowski “difference”, and I compute the minimal translation vector by computing the point on the boundary closest to the origin. Because I only have box to disk and box to box, it is easy to have an exact answer for these questions. Indeed, the Minkoswki “difference” looks like this:

Minkoswki difference of a box and a disk
Minkoswski difference of two boxes

Thus, I only need to check whether the origin is in a corner or not, and then it is easy to compute the closest point by projection (or consider I'm in a disk to disk case). Then, I can again push my bodies depending on their mass.

0 likes 2 comments

Comments

DavinCreed

I implemented the Minkowski Difference in most of the engines I built from scratch. It's a pretty fast way to check oriented boxes and convex polygons. I like it.

When I was first looking into it, I found it difficult to find much useful information and it took me a few weeks time to figure it out and get it working reliably.

July 15, 2020 04:38 PM
gregouar

@DavinCreed Yeah, I'm surprised there isn't more resources about it. Especially for rotated box to box collision.

I guess the hard part when doing arbritrary convex polygons is computing the Minkoswki difference (finding the closest point on the boundary is easy by walking around the boundary and projecting, computing the determinant also allows to easily determine whether there is a collision or not). It's probably something like you take you shape A and translate it over the boundary of shape B, but then you need to fing the “exterior” vertice. How do you do that efficiently ?

July 15, 2020 04:47 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement