Box

Simple 3D Collision Detection with Python Scripting in Blender

by Paul Balzer on 8. Juni 2016

No Comments

If you are looking for a very simple way to check, if two objects touch each other in Blender, maybe this might be a solution. The field of collision detection is very popular in game development and these guys have a lot of special algorithms for fast and/or exact collision between circles & circles, rectangles & circles, triangles & circles and so on…

Most of these are based on the Seperating Axis Theorem, which is simply the mathematical solution of the question: Is it possible to look ‚between‘ the two objects from any direction? If so, they are not colliding. Things get much simpler, if you just check the bounding boxes of two objects. In case of a cube, the bounding box is exactly the object itself. To check if two cubes touch each other, you have to check a collision between two bounding boxes. To make it even easier, one of the boxes is axis aligned (not rotated). We are talking about AABB (axis aligned bounding box) 3D collision check in Python. For visualization, we are using Blender. In Blender, you can run Python scripts.

Collision Check in Blender

The setup is the following:

boxes

Python Script to Check Collision of 3D Bounding Boxes

Remember: One of them need to be axis aligned!

import bpy
from mathutils import Vector

def get_BoundBox(object_name):
    """
    returns the corners of the bounding box of an object in world coordinates
    #  ________ 
    # |\       |\
    # |_\______|_\
    # \ |      \ |
    #  \|_______\|
    # 
    """
    bpy.context.scene.update()
    ob = bpy.context.scene.objects[object_name]
    bbox_corners = [ob.matrix_world * Vector(corner) for corner in ob.bound_box]

    return bbox_corners



def check_Collision(box1, box2):
    """
    Check Collision of 2 Bounding Boxes
    box1 & box2 muss Liste mit Vector sein,
    welche die Eckpunkte der Bounding Box
    enthält
    #  ________ 
    # |\       |\
    # |_\______|_\
    # \ |      \ |
    #  \|_______\|
    # 
    #
    """
    print('\nKollisionscheck mit:')

    x_max = max([e[0] for e in box1])
    x_min = min([e[0] for e in box1])
    y_max = max([e[1] for e in box1])
    y_min = min([e[1] for e in box1])
    z_max = max([e[2] for e in box1])
    z_min = min([e[2] for e in box1])
    print('Box1 min %.2f, %.2f, %.2f' % (x_min, y_min, z_min))
    print('Box1 max %.2f, %.2f, %.2f' % (x_max, y_max, z_max))    
    
    x_max2 = max([e[0] for e in box2])
    x_min2 = min([e[0] for e in box2])
    y_max2 = max([e[1] for e in box2])
    y_min2 = min([e[1] for e in box2])
    z_max2 = max([e[2] for e in box2])
    z_min2 = min([e[2] for e in box2])
    print('Box2 min %.2f, %.2f, %.2f' % (x_min2, y_min2, z_min2))
    print('Box2 max %.2f, %.2f, %.2f' % (x_max2, y_max2, z_max2))        
    
    
    isColliding = ((x_max >= x_min2 and x_max <= x_max2) \
                    or (x_min <= x_max2 and x_min >= x_min2)) \
                    and ((y_max >= y_min2 and y_max <= y_max2) \
                    or (y_min <= y_max2 and y_min >= y_min2)) \
                    and ((z_max >= z_min2 and z_max <= z_max2) \
                    or (z_min <= z_max2 and z_min >= z_min2))

    if isColliding:
        print('Kollision!')
        
    return isColliding

# MAIN
# Check Collision of Objects named 'Cube1' and 'Cube2' in Scene
collision = check_Collision(get_BoundBox('Cube1'), get_BoundBox('Cube2'))

BoxCollision_Blender

Leave a Reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>