Continous collision for plane of triangles vs AABB
The fact that you have nothing that rotates or stretches in your problem simplifies things a lot, because you go from having to solve a cubic in the general case to knowing the normal in advance and just having to solve something linear, i.e. start + t (end - start) = fixed, where start end and fixed are all just nice one dimensional scalars in the normal direction.
The fact that you have nothing that rotates or stretches in your problem simplifies things a lot, because you go from having to solve a cubic in the general case to knowing the normal in advance and just having to solve something linear, i.e. start + t (end - start) = fixed, where start end and fixed are all just nice one dimensional scalars in the normal direction.
Thanks a lot for your help. I've actually got an implementation mostly working. I do have 2 follow up questions:
1. I don't foresee scaling being needed, but rotation might be added. Could you recommend an algorithm/technique for this?
2. I'm using a delta timer to keep execution consistent across frame rates. With that said, I am noticing issues with the collision detection failing due to precision when the frame rate runs uncapped and the delta is very small. Are precision issues common? How often do physics implementations use a fixed time step as opposed to running as fast as possible?
To be completely accurate in your resolution, for a rotating object you would need to use the full cubic solver described in my previous post for all of your triangle-particle, particle-triangle, and edge-edge collision pairs.I don't foresee scaling being needed, but rotation might be added. Could you recommend an algorithm/technique for this?
You can get approximate continuous collision with a rotating body by considering the features of one body from the point of view of the frame of the body that is rotating. With a point vs a rotating box, you can get where the point is relative to the frame of the box at the start of the frame, where it is in the frame of the box at the end of the frame, and then pretend that the particle has moved linearly in the space of the box and resolve in that space. This linearizes what would actually be a curved motion in that space, so there can be edge cases where a particle slips through the cracks between triangles. Giving the particle some radius can help to make this more robust.
Precision issues are definitely common, and 80% of the work to make a robust physics system is doing extensive testing to find edge cases that fail, making sure that you have consistent repro steps so you can step in the debugger and see exactly which numeric operation is incorrect and for what reason (parallel moving edges can be a nightmare). A way that I've found works well to keep things fairly consistent/jitter free at arbitrary dynamic framerates is to advance the physics at a fixed large timestep which you never run slower than (typically 30fps), and then rewind the final result back to however much time actually elapsed. Since particles move linearly, if the final state is valid for continuous collision then interpolating the system backward will always be a valid state as well.I'm using a delta timer to keep execution consistent across frame rates. With that said, I am noticing issues with the collision detection failing due to precision when the frame rate runs uncapped and the delta is very small. Are precision issues common? How often do physics implementations use a fixed time step as opposed to running as fast as possible?
As a side note, I tend to use positional dynamics for simulation, which means at the start of the physics step I integrate initial particle positions to obtain an initial set of predicted positions, and then have constraints work directly by moving those predicted particle positions around until constraints are satisfied. Final velocities are then computed by subtracting where each particle lands from where it started. This makes stepping through what collisions and other constraints are doing a lot easier than working in velocity space.
You build the swept AABB around the original AABB at its start and end position (e.g. SweptAabb = Aabb(t1) + Aabb(t2)). You find/query all triangles within that swept AABB usually utilizing some kind of broadphase. This is the set of potentially colliding triangles and you have to compute the TOI for each triangle in this set and keep track of the minimum TOI.
The broad phase makes it possible to build a list of every potentially colliding feature pair (face-particle or edge-edge) to test without having to go N^2 over the whole world. The individual feature pair tests still have to be run to see if there was a collision, and for those that collided you want to resolve the one colliding earliest in the frame.
That said, you can make a more optimized tighter fitting broad phase shape. A k-DOP, or Discrete Oriented Polytope, generalizes the idea of the bounding box. Instead of just keeping the min/max extents in the x direction, y direction, and z direction, you add in some diagonal directions as well - for instance, the x+y direction or the x-y+z direction. Just like with a bounding box, only if all corresponding ranges for the two objects contain some overlap are the objects considered to be potentially colliding. This will reduce the number of false positive candidates you generate, but it won't completely eliminate them.
The broad phase makes it possible to build a list of every potentially colliding feature pair (face-particle or edge-edge) to test without having to go N^2 over the whole world. The individual feature pair tests still have to be run to see if there was a collision, and for those that collided you want to resolve the one colliding earliest in the frame.
These tests can be done completely in 2D, since everything is coplanar at the time you are testing.
For face-particle this is a check that the particle is contained within the face in 2D (for convex faces this basically means verifying that if the particle forms a triangle with each edge in the polygon, the winding orders of all the triangles formed are the same, i.e. their normals point in the same direction). For edge-edge this is a test that the location where the lines formed by each edge cross each other is between the endpoints for both edges involved. These tests can be done completely in 2D, since everything is coplanar at the time you are testing.
Ah! Now that makes sense. You've been a tremendous help.