So the mess in the picture above actually marks some pretty sterling progress on my 3D platformer. You are looking at a cubic tile-based map along with a bunch of moving blocks and a controllable player that can run and jump.
All of the moving items in the world can have other items resting on top of them that are then moved with them, as in moving platforms. But the system works recursively so if you stand on a block that is on another block that is on a platform, everything moves as you would expect. This is tricky to get right so wanted to make sure it was working nice and early.
I had to give up on my dumb-arse method of doing collision and physics and have gone back to a more traditional approach where a sort of specialised SAT provides a minimum separation vector to move boxes apart. This presents some interesting problems when using a tile-based system as objects can easily become stuck on the seams between tiles.
The solution, it turns out, is to maintain a list of contact normals for each object and null out any velocity in a direction opposite to a current contact normal. So, for example, gravity cannot constantly pull an object downwards, it has to only operate on the object when there is nothing beneath it.
My solution, since I'm only dealing with AABBs, is to run a contact sweep on each object at the start of each update, checking for intersections with the objects bounding box but grown by an epsilon value along one of the axes. I do this for all three axes to build a contact list then modify the velocity vector to remove any velocity in the direction of an existing contact.
This solves the problem of edge-catching and allows for a level to be built from solid cubes but allows for a character to slide against surfaces perfectly.
Each object also maintains a pointer to the object it is on top of, plus a list of objects that are currently on top of it. This is updated after the main update, based on the current contact set. When an object moves, it recursively calls the move methods of its child objects.
So far everything seems pretty stable, even in a stress-test like above so I'm pretty happy.