Source code for yyagl.engine.phys

from yyagl.gameobject import Colleague
from yyagl.lib.bullet.bullet import (
    BulletPhysWorld, BulletTriangleMesh, BulletTriangleMeshShape,
    BulletRigidBodyNode, BulletGhostNode)


PhysWorld = BulletPhysWorld
TriangleMesh = BulletTriangleMesh
TriangleMeshShape = BulletTriangleMeshShape
RigidBodyNode = BulletRigidBodyNode
GhostNode = BulletGhostNode


[docs]class CollInfo(object): def __init__(self, node, time): self.node = node self.time = time
[docs]class PhysFacade:
[docs] def attach_rigid_body(self, rbnode): return self.root.attach_rigid_body(rbnode)
[docs] def remove_rigid_body(self, rbnode): return self.root.remove_rigid_body(rbnode)
[docs] def attach_ghost(self, gnode): return self.root.attach_ghost(gnode)
[docs] def remove_ghost(self, gnode): return self.root.remove_ghost(gnode)
[docs] def attach_vehicle(self, vehicle): return self.root.attach_vehicle(vehicle)
[docs] def remove_vehicle(self, vehicle): return self.root.remove_vehicle(vehicle)
[docs] def ray_test_all(self, from_pos, to_pos, mask=None): return self.root.ray_test_all(from_pos, to_pos, mask)
[docs] def ray_test_closest(self, from_pos, to_pos, mask=None): return self.root.ray_test_closest(from_pos, to_pos, mask)
[docs]class PhysMgr(Colleague, PhysFacade): def __init__(self, mediator): Colleague.__init__(self, mediator) self.collision_objs = [] # objects to be processed self.__obj2coll = {} # {obj: [(node, coll_time), ...], ...} self.root = None self.__debug_np = None PhysFacade.__init__(self)
[docs] def reset(self): self.collision_objs = [] self.__obj2coll = {} self.root = PhysWorld() self.root.set_gravity((0, 0, -8.5)) self.root.init_debug()
[docs] def start(self): self.eng.attach_obs(self.on_frame, 2)
[docs] def on_frame(self): self.root.do_phys(self.eng.lib.last_frame_dt, 10, 1/180.0) self.__do_collisions()
[docs] def ray_test_closest(self, top, bottom): return self.root.ray_test_closest(top, bottom)
[docs] def add_collision_obj(self, node): self.collision_objs += [node]
[docs] def remove_collision_obj(self, node): self.collision_objs.remove(node)
[docs] def stop(self): self.root.stop() self.root = None self.eng.detach_obs(self.on_frame)
def __do_collisions(self): to_clear = self.collision_objs[:] # identical collisions are ignored for .25 seconds for obj in self.collision_objs: if obj not in self.__obj2coll: self.__obj2coll[obj] = [] # for contact in self.root.get_contacts(obj): # this doesn't work in 1.9, the following works # odd, this doesn't work too # for contact in self.root.wld.contact_test(obj).get_contacts(): result = self.root._wld.contact_test(obj) for contact in result.get_contacts(): self.__process_contact(obj, contact.get_node0(), to_clear) self.__process_contact(obj, contact.get_node1(), to_clear) for obj in to_clear: if obj in self.__obj2coll: # it may be that it isn't here e.g. # when you fire a rocket while you're very close to the prev # car and the rocket is removed suddenly for coll in self.__obj2coll[obj]: if self.eng.curr_time - coll.time > .25: self.__obj2coll[obj].remove(coll) def __process_contact(self, obj, node, to_clear): if node == obj: return if obj in to_clear: to_clear.remove(obj) if node in [coll.node for coll in self.__obj2coll[obj]]: return self.__obj2coll[obj] += [CollInfo(node, self.eng.curr_time)] self.eng.event.notify('on_collision', obj, node)
[docs] def toggle_dbg(self): if self.root: self.root.toggle_dbg()