126 lines
2.7 KiB
Python
Executable file
126 lines
2.7 KiB
Python
Executable file
from py3dutil import vect, quat
|
|
import gametimer
|
|
import math
|
|
|
|
floor = math.floor
|
|
|
|
class motion(object):
|
|
def __init__(self):
|
|
pass
|
|
|
|
def turn(self, dir):
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class physics_manager(object):
|
|
def __init__(self):
|
|
self.cellsize = 100.0
|
|
self.cells = {}
|
|
self.zones = {}
|
|
def getcell(self, pos, create=False):
|
|
x = int(floor(pos.x / self.cellsize))
|
|
y = int(floor(pos.y / self.cellsize))
|
|
z = int(floor(pos.z / self.cellsize))
|
|
k = (x, y, z)
|
|
if k in self.cells:
|
|
return self.cells[k]
|
|
if create:
|
|
self.cells[k] = collision_cell()
|
|
return self.cells[k]
|
|
else:
|
|
return None
|
|
|
|
def collide(self, obj, pos, newpos):
|
|
pass
|
|
|
|
def get_neighbors(self, cellkey, dist):
|
|
return []
|
|
|
|
def _postcollide_single(self, obj, cellkey, pairmap):
|
|
movement = obj._collide_end - obj._collide_start
|
|
cellmove = int(movement.mag() / self.cellsize) + 2
|
|
neighbors = self.get_neighbors(cellkey, cellmove)
|
|
for neighbor in neighbors:
|
|
for other in neighbor:
|
|
d = obj.pos.dist(other.pos)
|
|
thresh = movement.mag()
|
|
if obj.radius:
|
|
thresh += obj.radius
|
|
if other.radius:
|
|
thresh += other.radius
|
|
if d > thresh:
|
|
continue
|
|
|
|
pairkey = (obj, other)
|
|
if id(other) < id(obj):
|
|
pairkey = (other, obj)
|
|
pairmap[pairkey] = 1
|
|
|
|
def _postcollide_pair(self, pair):
|
|
obj, other = pair
|
|
moved1, moved2 = False, False
|
|
if not obj.massless:
|
|
moved1 = other.collide(obj)
|
|
if not other.massless:
|
|
moved2 = obj.collide(other)
|
|
|
|
print("Collision!")
|
|
assert False
|
|
return moved1 or moved2
|
|
|
|
def postcollide(self):
|
|
positions_adjusted = True
|
|
iter = 0
|
|
while positions_adjusted:
|
|
positions_adjusted = False
|
|
iter += 1
|
|
pairmap = {}
|
|
for key, cell in list(self.cells.items()):
|
|
for obj in cell:
|
|
self._postcollide_single(obj, key, pairmap)
|
|
|
|
for pair in pairmap:
|
|
rv = self._postcollide_pair(pair)
|
|
if rv:
|
|
positions_adjusted = True
|
|
|
|
def collide_failed(self):
|
|
pass
|
|
|
|
|
|
def move(self, obj, pos, newpos):
|
|
x = int(floor(pos.x / self.cellsize))
|
|
y = int(floor(pos.y / self.cellsize))
|
|
z = int(floor(pos.z / self.cellsize))
|
|
xn = int(floor(newpos.x / self.cellsize))
|
|
yn = int(floor(newpos.y / self.cellsize))
|
|
zn = int(floor(newpos.z / self.cellsize))
|
|
if x != xn or y != yn or z != zn:
|
|
cellold = self.getcell(pos)
|
|
cellnew = self.getcell(newpos, create=True)
|
|
if cellold:
|
|
cellold.remove(obj)
|
|
cellnew.add(obj)
|
|
|
|
class collision_cell(object):
|
|
def __init__(self):
|
|
self.objects = {}
|
|
def add(self, obj):
|
|
self.objects[obj] = 1
|
|
def remove(self, obj):
|
|
if obj in self.objects:
|
|
del self.objects[obj]
|
|
def __iter__(self):
|
|
return iter(self.objects)
|
|
class render_zone(object):
|
|
def __init__(self):
|
|
pass
|
|
|
|
def init():
|
|
global mgr
|
|
mgr = physics_manager()
|
|
|
|
mgr = None
|