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