Collision & Physics¶
SimVX provides broadphase (AABB) + narrowphase (GJK) collision detection and raycasting.
Collision Shapes¶
Three built-in shape types:
from simvx.core import SphereShape, BoxShape, ConvexShape
sphere = SphereShape(radius=1.0)
box = BoxShape(half_extents=(0.5, 0.5, 0.5))
hull = ConvexShape(vertices=my_vertex_array) # numpy Nx3
Each shape implements get_aabb() for broadphase and support() for GJK narrowphase.
Collision World¶
Register bodies and query overlaps:
from simvx.core import CollisionWorld, SphereShape
import numpy as np
world = CollisionWorld()
# Register bodies with shapes and positions
world.add_body(player, SphereShape(1.0), position=np.array([0, 0, 0]))
world.add_body(enemy, SphereShape(1.5), position=np.array([3, 0, 0]))
# Update positions each frame
world.update_position(player, new_pos)
# Query overlaps
hits = world.query_overlaps(player) # returns list of overlapping bodies
# Test specific pair
if world.test_overlap(player, enemy):
print("Collision!")
Collision Layers¶
Filter collisions with layer/mask bitmasks:
world.add_body(bullet, SphereShape(0.1), position=pos, layer=2, mask=4)
world.add_body(enemy, SphereShape(1.0), position=pos, layer=4, mask=2)
Raycasting¶
Cast rays through the collision world:
hits = world.raycast(
origin=np.array([0, 1, 0]),
direction=np.array([0, 0, -1]),
max_dist=100.0,
layer_mask=0xFFFFFFFF,
)
for hit in hits:
print(f"Hit {hit.body} at distance {hit.distance}")
print(f"Point: {hit.point}")
Node-Based Collision¶
For simpler cases, use CharacterBody3D with CollisionShape3D:
from simvx.core import CharacterBody3D
class Bullet(CharacterBody3D):
def __init__(self):
super().__init__(collision=0.5) # sphere radius
self.velocity = Vec3(0, 0, -20)
def physics_process(self, dt):
self.move_and_slide(dt)
for enemy in self.get_overlapping(group="enemies"):
enemy.destroy()
API Reference¶
See simvx.core.collision for the complete collision API.