# 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')
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
# 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)
Ejemplo n.º 4
0
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