Grease collision detection systems
Grease uses two-phase broad and narrow collision detection. Broad-phase collision systems are used to efficiently identify pairs that may be colliding without resorting to a brute-force check of all possible pairs. Narrow-phase collision systems use the pairs generated by the broad-phase and perform more precise collision tests to determine if a collision has actually occurred. The narrow-phase system also calculates more details about each collision, including collision point and normal vector for use in collision response.
A typical collision detection system consists of a narrow-phase system that contains a broad-phased system. The narrow-phase system is usually the only
one that the application directly interacts with, though the application is free to use the broad-phased system directly if desired. This could be useful in cases where speed, rather than precision is paramount.
The narrow-phase system can be assigned handler objects to run after collision detection. These can perform tasks like handling collision response or dispatching collision events to application handlers.
Note that broad-phase systems can return false positives, though they should never return false negatives. Do not assume that all pairs returned by a broad-phase system are actually in collision.
2D Broad-phase sweep and prune bounding box collision detector
This algorithm is efficient for collision detection between many moving bodies. It has linear algorithmic complexity and takes advantage of temporal coherence between frames. It also does not suffer from bad worst-case performance (like RDC can). Unlike spacial hashing, it does not need to be optimized for specific space and body sizes.
Other algorithms may be more efficient for collision detection with stationary bodies, bodies that are always evenly distributed, or ad-hoc queries.
Parameters: |
|
---|
Hit test at the point specified.
Parameters: |
|
---|---|
Returns: | A set of entities where the point is inside their bounding boxes as of the last time step. |
Name of world’s collision component used by this system
Basic narrow-phase collision detector which treats all entities as circles with their radius defined in the collision component.
Parameters: |
|
---|
Hit test at the point specified.
Parameters: |
|
---|---|
Returns: | A set of entities where the point is inside their collision radii as of the last time step. |
Broad phase collision system used as a source for collision pairs
Name of world’s collision component used by this system
A sequence of collision handler functions invoke after collision detection
Name of world’s position component used by this system
Flag to indicate whether the system updates the entities’ collision.aabb field before invoking the broad phase collision system
Pair of entities in collision. This is an ordered sequence of two entities, that compares and hashes unordered.
Also stores additional collision point and normal vectors for each entity.
Sets of Pair objects are exposed in the collision_pairs attribute of collision systems to indicate the entity pairs in collision.
Set the collision point and normal for both entities
A sequence of (entity, collision point, collision normal) for each entity in the pair
Collision handler that dispatches on_collide() events to entities marked for collision by the specified collision system. The on_collide() event handler methods are defined by the application on the desired entity classes. These methods should have the following signature:
def on_collide(self, other_entity, collision_point, collision_normal):
'''Handle A collision between this entity and `other_entity`
- other_entity (Entity): The other entity in collision with
`self`
- collision_point (Vec2d): The point on this entity (`self`)
where the collision occurred. Note this may be `None` for
some collision systems that do not report it.
- collision_normal (Vec2d): The normal vector at the point of
collision. As with `collision_point`, this may be None for
some collision systems.
'''
Note the arguments to on_collide() are always passed positionally, so you can use different argument names than above if desired.
If a pair of entities are in collision, then the event will be dispatched to both objects in arbitrary order if all of their collision masks align.