# Debug visualization debug_node = BulletDebugNode('Debug') debug_node.showWireframe(True) debug_node.showConstraints(True) debug_node.showBoundingBoxes(False) debug_node.showNormals(False) debug_np = s.render.attach_new_node(debug_node) bullet_world.set_debug_node(debug_node) debug_np.show() # The object in question mass = BulletRigidBodyNode() mass.set_mass(1) mass.setLinearSleepThreshold(0) mass.setAngularSleepThreshold(0) shape = BulletSphereShape(1) mass.add_shape(shape) mass_node = s.render.attach_new_node(mass) mass_node.set_hpr(1, 1, 1) bullet_world.attach_rigid_body(mass) model = s.loader.load_model('models/smiley') model.reparent_to(mass_node) model_axis = loader.load_model('models/zup-axis') model_axis.reparent_to(model) model_axis.set_pos(0, 0, 0) model_axis.set_scale(0.2) # The orientation to reach target_node = s.loader.load_model('models/smiley')
class Chunk(Entity): chunkmass = 5.0 def __init__(self, world, blocks, pos, hpr=Point3(0,0,0), diff = Vec3(0,0,0), angVel = Vec3(0,0,0), linVel = Vec3(0,0,0)): super(Chunk, self).__init__() self.mass = len(blocks)*Chunk.chunkmass self.world = world self.blocks = blocks self.bnode = BulletRigidBodyNode() self.bnode.setMass(self.mass) self.bnode.setAngularFactor(Vec3(0,1,0)) self.bnode.setLinearSleepThreshold(20) self.bnode.setAngularSleepThreshold(20) self.bnode.setAngularVelocity(angVel) self.bnode.setLinearVelocity(linVel) self.np = utilities.app.render.attachNewNode(self.bnode) self.np.setPos(pos.x,20,pos.y) self.np.setHpr(hpr) self.np.setPos(self.np, diff) self.bnode.setPythonTag("entity", self) self.inScope = False # culling not done yet # centre the blocks around the np and add their shapes in. self.minMax() cog = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) for block in blocks: block.rebuild(self, cog) world.bw.attachRigidBody(self.bnode) self.hitlist = dict() def update(self, timer): for index in self.hitlist: # returns true if the wall is destroyed by the hit if self.blocks[index].hitby(self.hitlist[index]): self.blocks[index].destroy() self.rebuild(index) self.hitlist.clear() if self.playerDistance() > 40.0: self.bnode.setAngularSleepThreshold(1) self.bnode.setLinearSleepThreshold(1) else: self.bnode.setAngularSleepThreshold(0) self.bnode.setLinearSleepThreshold(0) def playerDistance(self): sp = self.np.getPos() pp = self.world.player.node.getPos() distance = hypot(sp.x - pp.x, sp.z - pp.z) return distance # remove an element and rebuild # TODO add another method for removing multiple # blocks in a single go def rebuild(self, index): deadblock = self.blocks[index] out = list() for block in self.blocks: for edge in block.edges: if edge == deadblock: block.edges.remove(edge) for block in deadblock.edges: chunk = list() self.searchBlock(block, chunk, deadblock) out.append(chunk) #out is a list of lists of populated blocks #remove duplicate chunks results = list() for chunk in out: chunk.sort(compareBlock) if not chunk in results and len(chunk) > 0: results.append(chunk) for result in results: self.minMax(result) #diff = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) diff = Vec3((self.minX+self.maxX) / 2.0, 0, (self.minY+self.maxY) / 2.0) p = self.np.getPos() pos = Point2(p.x, p.z) h = self.np.getHpr() self.world.entities.append(Chunk(self.world, result, pos, h, diff, self.bnode.getAngularVelocity(), self.bnode.getLinearVelocity())) self.destroyNow() self.remove = True def searchBlock(self, block, lst, deleted): if block in lst: return else: lst.append(block) for newblock in block.edges: self.searchBlock(newblock, lst, deleted) def minMax(self, blocks=None): if blocks == None: blocks = self.blocks self.minX = blocks[0].pos.x self.minY = blocks[0].pos.y self.maxX = blocks[0].pos.x self.maxY = blocks[0].pos.y for point in blocks: self.minX = min(point.pos.x, self.minX) self.minY = min(point.pos.y, self.minY) self.maxX = max(point.pos.x, self.maxX) self.maxY = max(point.pos.y, self.maxY) # Need to clear the bulletrigidbody immediately # so that the phys object isn't present during next sim phase # which occurs before cleanup normally. Otherwise shit will # fly everywhere since two things are inside each other def destroyNow(self): self.world.bw.removeRigidBody(self.bnode) return # since this is handled earlier nothing happens def destroy(self): return def hitby(self, projectile, index): self.hitlist[index] = projectile
# Debug visualization debug_node = BulletDebugNode('Debug') debug_node.showWireframe(True) debug_node.showConstraints(True) debug_node.showBoundingBoxes(False) debug_node.showNormals(False) debug_np = s.render.attach_new_node(debug_node) bullet_world.set_debug_node(debug_node) debug_np.show() # The object in question mass = BulletRigidBodyNode() mass.set_mass(1) mass.setLinearSleepThreshold(0) mass.setAngularSleepThreshold(0) shape = BulletSphereShape(1) mass.add_shape(shape) mass_node = s.render.attach_new_node(mass) mass_node.set_hpr(1, 1, 1) bullet_world.attach_rigid_body(mass) model = s.loader.load_model('models/smiley') model.reparent_to(mass_node) model_axis = loader.load_model('models/zup-axis') model_axis.reparent_to(model) model_axis.set_pos(0, 0, 0) model_axis.set_scale(0.2) # The orientation to reach target_node = s.loader.load_model('models/smiley') target_node.reparent_to(s.render)
class Chunk(Entity): chunkmass = 5.0 def __init__(self, world, blocks, pos, hpr=Point3(0, 0, 0), diff=Vec3(0, 0, 0), angVel=Vec3(0, 0, 0), linVel=Vec3(0, 0, 0)): super(Chunk, self).__init__() self.mass = len(blocks) * Chunk.chunkmass self.world = world self.blocks = blocks self.bnode = BulletRigidBodyNode() self.bnode.setMass(self.mass) self.bnode.setAngularFactor(Vec3(0, 1, 0)) self.bnode.setLinearSleepThreshold(20) self.bnode.setAngularSleepThreshold(20) self.bnode.setAngularVelocity(angVel) self.bnode.setLinearVelocity(linVel) self.np = utilities.app.render.attachNewNode(self.bnode) self.np.setPos(pos.x, 20, pos.y) self.np.setHpr(hpr) self.np.setPos(self.np, diff) self.bnode.setPythonTag("entity", self) self.inScope = False # culling not done yet # centre the blocks around the np and add their shapes in. self.minMax() cog = Point2((self.minX + self.maxX) / 2.0, (self.minY + self.maxY) / 2.0) for block in blocks: block.rebuild(self, cog) world.bw.attachRigidBody(self.bnode) self.hitlist = dict() def update(self, timer): for index in self.hitlist: # returns true if the wall is destroyed by the hit if self.blocks[index].hitby(self.hitlist[index]): self.blocks[index].destroy() self.rebuild(index) self.hitlist.clear() if self.playerDistance() > 40.0: self.bnode.setAngularSleepThreshold(1) self.bnode.setLinearSleepThreshold(1) else: self.bnode.setAngularSleepThreshold(0) self.bnode.setLinearSleepThreshold(0) def playerDistance(self): sp = self.np.getPos() pp = self.world.player.node.getPos() distance = hypot(sp.x - pp.x, sp.z - pp.z) return distance # remove an element and rebuild # TODO add another method for removing multiple # blocks in a single go def rebuild(self, index): deadblock = self.blocks[index] out = list() for block in self.blocks: for edge in block.edges: if edge == deadblock: block.edges.remove(edge) for block in deadblock.edges: chunk = list() self.searchBlock(block, chunk, deadblock) out.append(chunk) #out is a list of lists of populated blocks #remove duplicate chunks results = list() for chunk in out: chunk.sort(compareBlock) if not chunk in results and len(chunk) > 0: results.append(chunk) for result in results: self.minMax(result) #diff = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) diff = Vec3((self.minX + self.maxX) / 2.0, 0, (self.minY + self.maxY) / 2.0) p = self.np.getPos() pos = Point2(p.x, p.z) h = self.np.getHpr() self.world.entities.append( Chunk(self.world, result, pos, h, diff, self.bnode.getAngularVelocity(), self.bnode.getLinearVelocity())) self.destroyNow() self.remove = True def searchBlock(self, block, lst, deleted): if block in lst: return else: lst.append(block) for newblock in block.edges: self.searchBlock(newblock, lst, deleted) def minMax(self, blocks=None): if blocks == None: blocks = self.blocks self.minX = blocks[0].pos.x self.minY = blocks[0].pos.y self.maxX = blocks[0].pos.x self.maxY = blocks[0].pos.y for point in blocks: self.minX = min(point.pos.x, self.minX) self.minY = min(point.pos.y, self.minY) self.maxX = max(point.pos.x, self.maxX) self.maxY = max(point.pos.y, self.maxY) # Need to clear the bulletrigidbody immediately # so that the phys object isn't present during next sim phase # which occurs before cleanup normally. Otherwise shit will # fly everywhere since two things are inside each other def destroyNow(self): self.world.bw.removeRigidBody(self.bnode) return # since this is handled earlier nothing happens def destroy(self): return def hitby(self, projectile, index): self.hitlist[index] = projectile