This question is a "follow-up" question from my previous one, regarding collision detection and resolution, which you can find here.
If you don't want to read the previous question, here's a brief description on how my physics engine works:
Every physical entity is stored in a class called SSSPBody.
Only AABBs are supported.
Every SSSPBody is stored in a class called SSSPWorld, which updates every body and handles gravity.
Every frame, SSSPWorld updates every body.
Every updated body looks for nearby bodies in a spatial hash, checks if they need to detect collisions with them. If yes, they invoke a "collision" event and check if they need to resolve collisions with them. If yes, they calculate the penetration vector and directional overlap, then change their position in order to resolve the penetration.
When a body collides with another, it transfers its velocity to the other one by simply setting the body's velocity to its own.
A body is velocity is set to 0 when it hasn't changed position from the last frame. If it also collides with a moving body (such as a lift or a moving platforms) it calculates the movement difference of the lift to see if the body hasn't moved from its last position.
Also, a body invokes a "crushed" event when all its AABB corners overlapped something in a frame.
This is the FULL source code of my game. It's divided in three projects. SFMLStart is a simple library handling input, drawing and updating of entities. SFMLStartPhysics is the most important one, where the SSSPBody and SSSPWorld classes are. PlatformerPhysicsTest is the game project, containing all the game logic.
And this is the "update" method in the SSSPBody class, commented and simplified. You can take a look only at this if you don't feel like looking at the whole SFMLStartSimplePhysics project. (And even if you do, you should still take a look at this since it's commented.)
The .gif shows two problems.
- If bodies are placed in a different order, different results happen. The crates on the left are identical to the crates on the right, only placed in the inverse order (in the editor).
- Both crates should be propelled towards the top of the screen. In the situation on the left, no crates are propelled. On the right, only one of them is. Both situations are unintended.
First problem: order of update
This is fairly simple to understand. In the situation on the left, the topmost crate is updated before the other one. Even if the crate on the bottom "transfers" velocity to the other one, it needs to wait the next frame to move. Since it didn't move, the bottom crate's velocity is set to 0.
I don't have any idea how to fix this. I'd prefer the solution to not be dependent on "sorting" the update list, because I feel I'm doing something wrong in the whole physics engine design.
How do the major physics engines (Box2D, Bullet, Chipmunk) handle the update order?
Second problem: only one crate is propelled towards the ceiling
I yet don't understand why this happens. What the "spring" entity does is set the body's velocity to -4000 and re-position it on top of the spring itself. Even if I disable the re-positioning code, the problem still occurs.
My idea is that when the bottom crate collides with the top crate, its velocity is set to 0. I'm not sure why this happens.
Despite the chance of looking like someone who gives up at the first problem, I posted the whole project source code above. I don't have anything to prove it, but believe me, I tried hard to fix this but I just couldn't find a solution and I don't have any previous experience with physics and collisions. I've been trying to solve these two problems for more than a week and now I'm desperate.
I don't think I can find a solution on my own without stripping many features out of the game (velocity transfer and springs, for example).
Thanks a lot for the time spent reading this question, and thanks even more if you even try coming up with a solution or a suggestion.