|
class Collider: |
|
def __init__(self, pos1 = (None,) * 3, pos2 = (None,) * 3): |
|
|
|
|
|
|
|
self.x1, self.y1, self.z1 = pos1 |
|
self.x2, self.y2, self.z2 = pos2 |
|
|
|
def __add__(self, pos): |
|
x, y, z = pos |
|
|
|
return Collider( |
|
(self.x1 + x, self.y1 + y, self.z1 + z), |
|
(self.x2 + x, self.y2 + y, self.z2 + z) |
|
) |
|
|
|
def __and__(self, collider): |
|
x = min(self.x2, collider.x2) - max(self.x1, collider.x1) |
|
y = min(self.y2, collider.y2) - max(self.y1, collider.y1) |
|
z = min(self.z2, collider.z2) - max(self.z1, collider.z1) |
|
|
|
return x > 0 and y > 0 and z > 0 |
|
|
|
def collide(self, collider, velocity): |
|
|
|
|
|
|
|
no_collision = 1, None |
|
|
|
|
|
|
|
vx, vy, vz = velocity |
|
|
|
time = lambda x, y: x / y if y else float('-' * (x > 0) + "inf") |
|
|
|
x_entry = time(collider.x1 - self.x2 if vx > 0 else collider.x2 - self.x1, vx) |
|
x_exit = time(collider.x2 - self.x1 if vx > 0 else collider.x1 - self.x2, vx) |
|
|
|
y_entry = time(collider.y1 - self.y2 if vy > 0 else collider.y2 - self.y1, vy) |
|
y_exit = time(collider.y2 - self.y1 if vy > 0 else collider.y1 - self.y2, vy) |
|
|
|
z_entry = time(collider.z1 - self.z2 if vz > 0 else collider.z2 - self.z1, vz) |
|
z_exit = time(collider.z2 - self.z1 if vz > 0 else collider.z1 - self.z2, vz) |
|
|
|
|
|
|
|
if x_entry < 0 and y_entry < 0 and z_entry < 0: |
|
return no_collision |
|
|
|
if x_entry > 1 or y_entry > 1 or z_entry > 1: |
|
return no_collision |
|
|
|
|
|
|
|
entry = max(x_entry, y_entry, z_entry) |
|
exit_ = min(x_exit, y_exit, z_exit ) |
|
|
|
if entry > exit_: |
|
return no_collision |
|
|
|
|
|
|
|
nx = (0, -1 if vx > 0 else 1)[entry == x_entry] |
|
ny = (0, -1 if vy > 0 else 1)[entry == y_entry] |
|
nz = (0, -1 if vz > 0 else 1)[entry == z_entry] |
|
|
|
return entry, (nx, ny, nz) |