A shape added with HC:add*() would be reintroduced to the spatial hash
after HC:remove() when any of shape:move(), shape:rotate() or
shape:scale() was called after the removal.
* intersectionsRay() -> intersectionsWithRay()
* intersectsRay() uses results from intersectionsWithRay()
(Exception: PointShape does it the other way around)
Sometimes the expanding polytype algorithm takes a long time to
terminate, e.g. in situations like this:
.-.
: +-:-+
'-' |
| |
+---+
The issue here is that the EPA adds vertices very close to each other,
which makes the separation distance change very slowly. If this is the
case, consider the current separation distance as approximately correct
and continue.
support(A,B, 1,0) returns 0,0 when A and B are touching in a vertex of
both A and B AND this vertex is on the right of A's center (in direction
(1,0)), e.g. this situation:
.---.
.-.| B |
: A x---'
'-'
Then: support(A,B, 1,0) = A:support(1,0) - B:support(-1,0) = x - x = 0
Since CircleShape:support(dx,dy) normalizes dx,dy this will result in a
division by 0 error in the subsequent execution of the GJK algorithm.
An early out with result 'not colliding' (in accordance to the other
edge cases) prevents this error.
Collecting collisions and then reporting leads to confusing behavior
when a previous collision callback resolved the collision, e.g.
platforms in jump in runs pushing the player upwards when standing on
two platforms at the same time.
Shape must have at least two functions:
- shape:bbox()
must return an axis aligned bounding box of the shape
- shape:collidesWith(other)
must return false, ... if the two shapes do not collide
must return true, sx, sy if the two shapes collide, where sx,sy is the
separation vector from from shape to other.
Convex shapes can use the supplied GJK algorithm. In that case the shape
must implement shape:support(dx,dy) which returns the point of the shape
that lies furthest in the direction of dx,dy.