Source code for concepts.simulator.pymunk.collision
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File   : collision.py
# Author : Jiayuan Mao
# Email  : maojiayuan@gmail.com
# Date   : 07/01/2022
#
# This file is part of Project Concepts.
# Distributed under terms of the MIT license.
import pymunk
from typing import Optional, Tuple, List, Set, Dict
from .world import PymunkWorld
__all__ = ['SpacePositionRestorer', 'collision_test', 'collision_test_current']
[docs]
class SpacePositionRestorer(object):
[docs]
    def __init__(self, world: PymunkWorld):
        self.world = world
        self.positions = dict()
        for body in self.world.bodies:
            self.positions[body] = body.position 
[docs]
    def restore(self):
        for body, position in self.positions.items():
            body.position = position
        self.world.step(1e-9) 
    def __enter__(self):
        pass
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.restore() 
[docs]
def collision_test_current(world: PymunkWorld, bodies: Optional[List[pymunk.Body]] = None) -> Set[Tuple[str, str]]:
    ret = set()
    shape2body = dict()
    for body in world.bodies:
        for shape in body.shapes:
            shape2body[shape] = body
    if bodies is None:
        bodies = world.bodies
    for body in bodies:
        for shape in body.shapes:
            all_collisions = world.shape_query(shape)
            for other_shape, _ in all_collisions:
                if other_shape is not None and shape2body[other_shape] is not body:
                    ret.add((shape2body[shape].label, shape2body[other_shape].label))
    return ret 
[docs]
def collision_test(world: PymunkWorld, body_positions: Optional[Dict[str, Tuple[float, float]]] = None, bodies: Optional[List[pymunk.Body]] = None) -> Set[Tuple[str, str]]:
    if body_positions is None:
        body_positions = dict()
    with SpacePositionRestorer(world):
        for body, position in body_positions.items():
            body = world.get_body_by_label(body)
            body.position = position
        ret = collision_test_current(world, bodies)
    return ret