class BonusPhys(PhysColleague): def __init__(self, mediator, pos): self.pos = pos self.ghost = None PhysColleague.__init__(self, mediator) self.ghost = BulletGhostNode('Bonus') self.ghost.add_shape(BulletBoxShape((1, 1, 2.5))) ghost_np = self.eng.attach_node(self.ghost) pos = self.pos pos = Vec(pos.x, pos.y, pos.z) ghost_np.set_pos(pos) ghost_np.set_collide_mask(BitMask32.bit(BitMasks.ghost)) self.eng.phys_mgr.attach_ghost(self.ghost) def destroy(self): self.ghost = self.eng.phys_mgr.remove_ghost(self.ghost) PhysColleague.destroy(self)
def enable(self, static_model_path, scale, gap='normal', shape=COLLIDER_SHAPE_CYLINDER): """ :param static_model_path: 用于预览的模型 :param radius: 用于进行碰撞检测的Cylinder半径 :return: Nothing """ if self._model: return # assert not self._model, "cannot call enable() twice before having called disable()" if gap == 'normal': self._gap = 0.25 self._gap_base = 0 elif gap == 'cell': self._gap = 2 self._gap_base = 1.0 elif gap == 'half_cell': self._gpa = 1 self._gap_base = 0.5 else: assert False, 'unknown gap: %s, expect [normal|cell|half_cell]' % gap self._model = G.res_mgr.get_static_model(static_model_path) log.debug("placement model: %s", self._model) self._model.set_shader(self._shader) assert self._model, static_model_path if shape == self.COLLIDER_SHAPE_BOX: shape, _ = G.physics_world.get_box_shape(self._model, scale) else: shape, _ = G.physics_world.get_cylinder_shape(self._model, scale) ghost = BulletGhostNode('placement') ghost.add_shape(shape, TransformState.makePos(Vec3(0, 0, .5))) ghost.set_into_collide_mask(config.BIT_MASK_PLACEMENT) ghost.set_static(False) ghost.set_deactivation_enabled(False) ghost.set_debug_enabled(True) G.physics_world.get_world().attach_ghost(ghost) self._ghost_np = G.render.attach_new_node(ghost) assert self._ghost_np self._model.reparent_to(self._ghost_np) self._model.set_shader_input('collider_color', self._green_color) self._model.set_transparency(1)
def do_explosion(self, node, radius, force): center = node.get_pos(self.scene) expl_body = BulletGhostNode("expl") expl_shape = BulletSphereShape(radius) expl_body.add_shape(expl_shape) expl_bodyNP = self.scene.attach_new_node(expl_body) expl_bodyNP.set_pos(center) self.physics.attach_ghost(expl_body) result = self.physics.contact_test(expl_body) for contact in result.getContacts(): n0_name = contact.getNode0().get_name() n1_name = contact.getNode1().get_name() obj = None try: obj = self.objects[n1_name] except: break if n0_name == "expl" and n1_name not in EXPLOSIONS_DONT_PUSH and not n1_name.startswith( 'Walker'): # repeat contact test with just this pair of objects # otherwise all manifold point values will be the same # for all objects in original result real_c = self.physics.contact_test_pair(expl_body, obj.solid) mpoint = real_c.getContacts()[0].getManifoldPoint() distance = mpoint.getDistance() if distance < 0: if hasattr(obj, 'decompose'): obj.decompose() else: expl_vec = Vec3(mpoint.getPositionWorldOnA() - mpoint.getPositionWorldOnB()) expl_vec.normalize() magnitude = force * 1.0 / math.sqrt( abs(radius - abs(distance))) obj.solid.set_active(True) obj.solid.apply_impulse(expl_vec * magnitude, mpoint.getLocalPointB()) if hasattr(obj, 'damage'): obj.damage(magnitude / 5) self.physics.remove_ghost(expl_body) expl_bodyNP.detach_node() del (expl_body, expl_bodyNP)
def do_explosion(self, node, radius, force): center = node.get_pos(self.scene); expl_body = BulletGhostNode("expl") expl_shape = BulletSphereShape(radius) expl_body.add_shape(expl_shape) expl_bodyNP = self.scene.attach_new_node(expl_body) expl_bodyNP.set_pos(center) self.physics.attach_ghost(expl_body) result = self.physics.contact_test(expl_body) for contact in result.getContacts(): n0_name = contact.getNode0().get_name() n1_name = contact.getNode1().get_name() obj = None try: obj = self.objects[n1_name] except: break if n0_name == "expl" and n1_name not in EXPLOSIONS_DONT_PUSH and not n1_name.startswith('Walker'): # repeat contact test with just this pair of objects # otherwise all manifold point values will be the same # for all objects in original result real_c = self.physics.contact_test_pair(expl_body, obj.solid) mpoint = real_c.getContacts()[0].getManifoldPoint() distance = mpoint.getDistance() if distance < 0: if hasattr(obj, 'decompose'): obj.decompose() else: expl_vec = Vec3(mpoint.getPositionWorldOnA() - mpoint.getPositionWorldOnB()) expl_vec.normalize() magnitude = force * 1.0/math.sqrt(abs(radius - abs(distance))) obj.solid.set_active(True) obj.solid.apply_impulse(expl_vec*magnitude, mpoint.getLocalPointB()) if hasattr(obj, 'damage'): obj.damage(magnitude/5) self.physics.remove_ghost(expl_body) expl_bodyNP.detach_node() del(expl_body, expl_bodyNP)
def create_solid(self): node = BulletGhostNode(self.name) node_shape = BulletSphereShape(.5) node.add_shape(node_shape) node.set_kinematic(True) return node
def create_solid(self): node = BulletGhostNode(self.name) node_shape = BulletSphereShape(.05) node.add_shape(node_shape) node.set_kinematic(True) return node