I am making a python project with the 2D physics engine pymunk, but I am not familiar with pymunk or the base C library that it interatcs with, Chipmunk2D. I have quite a few different objects that I want to collide with others, but not collide with certain ones. There is a wall, an anchor point in the wall, a segment attached to the anchor point with a circle on the end, and a car. I want the car to ONLY collide with the wall and the segment, but the wall needs to also collide with the circle on the end of the segment. Other than that I want no collisions. I have tried using groups with the pymunk.ShapeFilter
object, but the specific collisions are too complex for only using groups. I searched for a while and found out about categories and masks, but after looking at it I didn't understand. The explanation didn't make much sense to me and it was using bitwise operators which I don't really understand that well. I have been looking for a while but could not find any good tutorial or explanation so I want to know if someone could explain to me how it works or cite some useful resources.
It can look a bit tricky at first, but is actually quite straight forward, at least as long as you dont have too complicated needs.
With ShapeFilter you set the category that the shape belongs to, and what categories it can collide with (the mask property).
Both categories and the mask are stored as 32 bit integers (for performance), but instead just think of it as a list of 0s and 1s (maximum 32 digits long), where 1 means that the position is taken by that category. The list is written in Python in binary notation (0bxxxxx
) where the x's is the list of 0s and 1s.
Lets say you have 3 categories of things. Cars, trees and clouds. Cars can collide with other cars and trees, trees can collide with cars, trees and clouds. And clouds can only collide with trees.
First I define the categories. In this example I only have three categories, so I only use 3 digits, but if I had more I could make it longer (up to 32 digits):
car = 0b100
tree = 0b010
cloud = 0b001
I want car to collide with itself. I also want it to collide with the tree. That means that the car mask should put 1s at the same positions as the of 1s of the car category and the tree category car_mask = 0b110
. The tree can collide with car, itself and cloud, so all 3 positions should be set: tree_mask = 0b111
. Finally, the Cloud can only collide with trees: cloud_mask = 0b010
.
Then you need to assign these Shape Filters to the shapes:
car_shape.filter = pymunk.ShapeFilter(category = car, mask=car_mask)
tree_shape.filter = pymunk.ShapeFilter(category = tree, mask=tree_mask)
cloud_shape.filter = pymunk.ShapeFilter(category = cloud, mask=cloud_mask)