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