Пример #1
0
class DynamicNp(DynamicObject):
	def __init__(self, name, model, game, pos):
		self.name = name
		self.game = game
		
		self.model = model
		self.geomNode = self.model.node()
		self.geom = self.geomNode.getGeom(0)
		
		# with triangle mesh it crashes
		#mesh = BulletTriangleMesh()
		#mesh.addGeom(self.geom)
		#self.shape = BulletTriangleMeshShape(mesh, dynamic=True)
		
		# with convex hull
		self.shape = BulletConvexHullShape()
		self.shape.addGeom(self.geom)
		
		self.node = BulletRigidBodyNode(self.name)
		self.node.setMass(10.0)
		self.node.addShape(self.shape)
		
		self.np = self.game.render.attachNewNode(self.node)
		self.np.setPos(pos)
		self.game.world.attachRigidBody(self.node)
		
		self.model.reparentTo(self.np)
		
		self.node.setCcdMotionThreshold(1e-7)
		self.node.setCcdSweptSphereRadius(0.5)
		self.slice_able = True
Пример #2
0
 def add_solid(self, node):
     mesh = BulletConvexHullShape()
     mesh.add_geom(
         GeomBuilder().add_wedge(self.color, self.base, self.top, self.width, LRotationf(*self.hpr)).get_geom()
     )
     node.add_shape(mesh)
     return node
Пример #3
0
class DynamicModel(DynamicObject):
    def __init__(self, name, modelPath, game, pos):
        self.name = name
        self.modelPath = modelPath
        self.game = game

        self.model = self.game.loader.loadModel(self.modelPath)
        geomNodes = self.model.findAllMatches('**/+GeomNode')
        self.geomNode = geomNodes.getPath(0).node()
        self.geom = self.geomNode.getGeom(0)
        self.shape = BulletConvexHullShape()
        self.shape.addGeom(self.geom)

        self.node = BulletRigidBodyNode(self.name)
        self.node.setMass(10.0)
        self.node.addShape(self.shape)

        self.np = self.game.render.attachNewNode(self.node)
        self.np.setPos(pos)
        self.game.world.attachRigidBody(self.node)

        self.model.reparentTo(self.np)

        self.node.setCcdMotionThreshold(1e-7)
        self.node.setCcdSweptSphereRadius(0.5)
        self.slice_able = True
Пример #4
0
class DynamicModel(DynamicObject):
	def __init__(self, name, modelPath, game, pos):
		self.name = name
		self.modelPath = modelPath
		self.game = game
		
		self.model = self.game.loader.loadModel(self.modelPath)
		geomNodes = self.model.findAllMatches('**/+GeomNode')
		self.geomNode = geomNodes.getPath(0).node()
		self.geom = self.geomNode.getGeom(0)
		self.shape = BulletConvexHullShape()
		self.shape.addGeom(self.geom)
		
		self.node = BulletRigidBodyNode(self.name)
		self.node.setMass(10.0)
		self.node.addShape(self.shape)
		
		self.np = self.game.render.attachNewNode(self.node)
		self.np.setPos(pos)
		self.game.world.attachRigidBody(self.node)
		
		self.model.reparentTo(self.np)
		
		self.node.setCcdMotionThreshold(1e-7)
		self.node.setCcdSweptSphereRadius(0.5)
		self.slice_able = True
Пример #5
0
 def add_solid(self, node):
     mesh = BulletConvexHullShape()
     mesh.add_geom(GeomBuilder().add_dome(self.color, self.center,
                                          self.radius,
                                          self.samples, self.planes,
                                          LRotationf(*self.hpr)).get_geom())
     node.add_shape(mesh)
     return node
Пример #6
0
 def add_solid(self, node):
     mesh = BulletConvexHullShape()
     mesh.add_geom(
         GeomBuilder().add_wedge(self.color,
                                 self.base, self.top, self.width,
                                 LRotationf(*self.hpr)).get_geom())
     node.add_shape(mesh)
     return node
Пример #7
0
 def add_solid(self, node):
     mesh = BulletConvexHullShape()
     mesh.add_geom(
         GeomBuilder()
         .add_dome(self.color, self.center, self.radius, self.samples, self.planes, LRotationf(*self.hpr))
         .get_geom()
     )
     node.add_shape(mesh)
     return node
Пример #8
0
def makeBulletConvexHullFromCollisionSolids(cnode):
    from panda3d.core import CollisionPolygon
    from panda3d.bullet import BulletConvexHullShape
    shape = BulletConvexHullShape()
    for solid in cnode.getSolids():
        if isinstance(solid, CollisionPolygon):
            for point in solid.getPoints():
                shape.addPoint(point)
    return shape
Пример #9
0
 def __set_collision_mesh(self):
     fpath = self.props.coll_path % self.mdt.name
     self.coll_mesh = loader.loadModel(fpath)
     chassis_shape = BulletConvexHullShape()
     for geom in PhysMgr().find_geoms(self.coll_mesh, self.props.coll_name):
         chassis_shape.addGeom(geom.node().getGeom(0), geom.getTransform())
     self.mdt.gfx.nodepath.node().addShape(chassis_shape)
     self.mdt.gfx.nodepath.setCollideMask(
         BitMask32.bit(1)
         | BitMask32.bit(2 + self.props.cars.index(self.mdt.name)))
Пример #10
0
    def __init__(
        self, world:BulletWorld, entity:Entity,
        mass=0, rotation=[None, None, None]
        ):

        geomNodes = entity.model.findAllMatches('**/+GeomNode')
        geomNode = geomNodes.getPath(0).node()
        geom = geomNode.getGeom(0)
        shape = BulletConvexHullShape()
        shape.addGeom(geom)

        super().__init__(world, entity, shape, 'convex_hull', rotation)
Пример #11
0
def modelToConvex(model):
    """

    :type model: panda3d.core.NodePath
    :return: tuple(panda3d.bullet.BulletConvexHull,transform)
    """
    geomnodes = model.findAllMatches('**/+GeomNode')
    transform = model.getTransform()
    gn = geomnodes.getPath(0).node()
    geom = gn.getGeom(0)
    shape = BulletConvexHullShape()
    shape.addGeom(geom)
    return shape, transform
Пример #12
0
    def setup_shape(self, gnodepath, bone, pname):
        shape = BulletConvexHullShape()

        gnode = gnodepath.node()
        geom = gnode.get_geom(0)
        shape.add_geom(geom)

        node = BulletRigidBodyNode(self.name + pname)
        np = self.actor.attach_new_node(node)
        np.node().add_shape(shape)
        np.node().set_kinematic(True)
        np.wrt_reparent_to(bone)
        self.world.physics.attach_rigid_body(node)
        return np
Пример #13
0
    def addMeshConvexRB(self,vertices, faces,ghost=False,**kw):
        #step 1) create GeomVertexData and add vertex information
        format=GeomVertexFormat.getV3()
        vdata=GeomVertexData("vertices", format, Geom.UHStatic)
        
        vertexWriter=GeomVertexWriter(vdata, "vertex")
        [vertexWriter.addData3f(v[0],v[1],v[2]) for v in vertices]
        
        #step 2) make primitives and assign vertices to them
        tris=GeomTriangles(Geom.UHStatic)
        [self.setGeomFaces(tris,face) for face in faces]
        
        #step 3) make a Geom object to hold the primitives
        geom=Geom(vdata)
        geom.addPrimitive(tris)
        
        #step 4) create the bullet mesh and node
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)

        shape = BulletConvexHullShape(mesh, dynamic=not ghost)#
        if ghost :
            inodenp = self.worldNP.attachNewNode(BulletGhostNode('Mesh'))
        else :
            inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        inodenp.node().addShape(shape)
#        inodenp.setPos(0, 0, 0.1)
        self.setRB(inodenp,**kw)
        inodenp.setCollideMask(BitMask32.allOn())
   
        self.world.attachRigidBody(inodenp.node())
        return inodenp
Пример #14
0
def getCollisionShapeFromModel(model, mode='box', defaultCentered=False):

    #NOTE: make sure the position is relative to the center of the object
    minBounds, maxBounds = model.getTightBounds()
    offset = minBounds + (maxBounds - minBounds) / 2.0

    transform = TransformState.makeIdentity()
    if mode == 'mesh':
        # Use exact triangle mesh approximation
        mesh = BulletTriangleMesh()
        geomNodes = model.findAllMatches('**/+GeomNode')
        for nodePath in geomNodes:
            geomNode = nodePath.node()
            for n in range(geomNode.getNumGeoms()):
                geom = geomNode.getGeom(n)
                mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)
        transform = model.getTransform()

    elif mode == "sphere":
        minBounds, maxBounds = model.getTightBounds()
        dims = maxBounds - minBounds
        radius = np.sqrt(np.square(dims[0]) + np.square(dims[1])) / 2.0
        height = dims[2]
        shape = BulletCapsuleShape(radius, 2 * radius)
        if not defaultCentered:
            transform = TransformState.makePos(offset)

    elif mode == "hull":
        shape = BulletConvexHullShape()
        geomNodes = model.findAllMatches('**/+GeomNode')
        for nodePath in geomNodes:
            geomNode = nodePath.node()
            for n in range(geomNode.getNumGeoms()):
                geom = geomNode.getGeom(n)
                shape.addGeom(geom)

    elif mode == 'box':
        # Bounding box approximation
        minBounds, maxBounds = model.getTightBounds()
        dims = maxBounds - minBounds
        shape = BulletBoxShape(Vec3(dims.x / 2, dims.y / 2, dims.z / 2))
        if not defaultCentered:
            transform = TransformState.makePos(offset)

    elif mode == 'capsule':
        minBounds, maxBounds = model.getTightBounds()
        dims = maxBounds - minBounds
        radius = np.sqrt(np.square(dims[0]) + np.square(dims[1])) / 2.0
        height = dims[2]
        shape = BulletCapsuleShape(radius, height - 2 * radius)
        if not defaultCentered:
            transform = TransformState.makePos(offset)

    else:
        raise Exception(
            'Unknown mode type for physic object collision shape: %s' % (mode))

    return shape, transform
Пример #15
0
    def __addConvexHull(self, body, model, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ):        
        
        def one():
            geom = model.node().getGeom(0)          
            shape = BulletConvexHullShape()
            shape.addGeom(geom)
            body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) )
            return []

        children =  model.findAllMatches('**/+GeomNode') or one()

        model.flattenLight()

        for piece in children:
            shape = BulletConvexHullShape()
            geom = piece.node().getGeom(0)
            shape.addGeom(geom)
            body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) )
Пример #16
0
def addBox():
    # Box
    #shape = BulletCylinderShape(0.5, 3, 2)

    geomNodes = loader.loadModel('cilindroB').findAllMatches('**/+GeomNode')
    geomNode = geomNodes.getPath(0).node()
    geom = geomNode.getGeom(0)

    shape = BulletConvexHullShape()
    shape.addGeom(geom)
    node = BulletRigidBodyNode('Cylinder')
    node.setMass(random.randint(1, 10))
    node.addShape(shape)
    np = render.attachNewNode(node)
    np.setPos(0, 0, 10)
    world.attachRigidBody(node)
    #model = loader.loadModel('cilindroR')
    model.flattenLight()
    model.reparentTo(np)
Пример #17
0
 def create_solid(self):
     node = BulletRigidBodyNode(self.name)
     mesh = BulletConvexHullShape()
     mesh.add_geom(self.geom.get_geom(0))
     node.add_shape(mesh)
     return node
Пример #18
0
    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()
        self.debugNP.node().showWireframe(True)
        self.debugNP.node().showConstraints(True)
        self.debugNP.node().showBoundingBoxes(False)
        self.debugNP.node().showNormals(False)

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Ground
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        body = BulletRigidBodyNode('Ground')
        bodyNP = self.worldNP.attachNewNode(body)
        bodyNP.node().addShape(shape)
        bodyNP.setPos(0, 0, 0)
        bodyNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(bodyNP.node())

        # Bowl
        visNP = loader.loadModel('models/bowl.egg')

        geom = visNP.findAllMatches('**/+GeomNode').getPath(0).node().getGeom(
            0)
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=True)

        body = BulletRigidBodyNode('Bowl')
        bodyNP = self.worldNP.attachNewNode(body)
        bodyNP.node().addShape(shape)
        bodyNP.node().setMass(10.0)
        bodyNP.setPos(0, 0, 0)
        bodyNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(bodyNP.node())

        visNP.reparentTo(bodyNP)

        self.bowlNP = bodyNP
        self.bowlNP.setScale(2)

        # Eggs
        self.eggNPs = []
        for i in range(5):
            x = random.gauss(0, 0.1)
            y = random.gauss(0, 0.1)
            z = random.gauss(0, 0.1) + 1
            h = random.random() * 360
            p = random.random() * 360
            r = random.random() * 360

            visNP = loader.loadModel('models/egg.egg')

            geom = visNP.findAllMatches('**/+GeomNode').getPath(
                0).node().getGeom(0)
            shape = BulletConvexHullShape()
            shape.addGeom(geom)

            body = BulletRigidBodyNode('Egg-%i' % i)
            bodyNP = self.worldNP.attachNewNode(body)
            bodyNP.node().setMass(1.0)
            bodyNP.node().addShape(shape)
            bodyNP.node().setDeactivationEnabled(False)
            bodyNP.setCollideMask(BitMask32.allOn())
            bodyNP.setPosHpr(x, y, z, h, p, r)
            #bodyNP.setScale(1.5)
            self.world.attachRigidBody(bodyNP.node())

            visNP.reparentTo(bodyNP)

            self.eggNPs.append(bodyNP)
 def __addConvexHull(self, body, geom, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1) ):
     shape = BulletConvexHullShape()
     shape.addGeom(geom)
     body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) )
Пример #20
0
    def __init__(self, app, model_name):
        model_file_name = 'assets/cars/{}/{}.bam'.format(
            model_name, model_name)
        self.app = app

        def animation_path(model, animation):
            base_path = 'assets/cars/animations/{}/{}-{}.bam'
            return base_path.format(model, model, animation)

        self.model = Actor(
            model_file_name,
            {
                #    AIRBRAKE: 'assets/cars/animations/{}-{}.bam'.format(model_name, AIRBRAKE),
                #    AIRBRAKE: animation_path(model_name, AIRBRAKE),
                #    STABILIZER_FINS: animation_path(model_name, STABILIZER_FINS),
            })
        self.model.enableBlend()
        self.model.setControlEffect(AIRBRAKE, 1)
        self.model.setControlEffect(STABILIZER_FINS, 1)
        # FIXME: This code fails due to a bug in Actor
        # airbrake_joints = [joint.name
        #                    for joint in self.model.getJoints()
        #                    if joint.name.startswith(AIRBRAKE)
        # ]
        # self.model.makeSubpart(AIRBRAKE, airbrake_joints)
        # stabilizer_joints = [joint.name
        #                      for joint in self.model.getJoints()
        #                      if joint.name.startswith(STABILIZER_FINS)
        # ]
        # self.model.makeSubpart(STABILIZER_FINS, stabilizer_joints)

        puppet = self.app.loader.load_model(model_file_name)
        puppet.find("**/armature").hide()
        puppet.reparentTo(self.model)

        # Get the vehicle data
        self.vehicle_data = VehicleData(puppet, model_name, 'cars')

        # Configure the physics node
        self.physics_node = BulletRigidBodyNode('vehicle')
        self.physics_node.set_friction(self.vehicle_data.friction)
        self.physics_node.set_linear_sleep_threshold(0)
        self.physics_node.set_angular_sleep_threshold(0)
        self.physics_node.setCcdMotionThreshold(1e-7)
        self.physics_node.setCcdSweptSphereRadius(0.5)
        self.physics_node.setMass(self.vehicle_data.mass)
        shape = BulletConvexHullShape()
        for geom_node in self.model.find_all_matches("**/+GeomNode"):
            for geom in geom_node.node().get_geoms():
                vertices = GeomVertexReader(geom.get_vertex_data(), 'vertex')
                while not vertices.is_at_end():
                    v_geom = vertices.getData3f()
                    v_model = self.model.get_relative_point(geom_node, v_geom)
                    shape.add_point(v_model)
        self.physics_node.add_shape(shape)
        self.vehicle = NodePath(self.physics_node)
        self.vehicle.set_collide_mask(CM_VEHICLE | CM_COLLIDE)
        self.model.reparent_to(self.vehicle)

        # Navigational aids
        self.target_node = self.app.loader.load_model('models/zup-axis')
        self.target_node.reparent_to(self.model)
        self.target_node.set_scale(1)
        self.target_node.set_render_mode_wireframe()
        self.target_node.hide()

        self.delta_node = self.app.loader.load_model('models/smiley')
        self.delta_node.set_pos(1, 10, 1)
        self.delta_node.reparent_to(base.cam)
        self.delta_node.hide()

        self.airbrake_state = 0.0
        self.airbrake_factor = 0.5
        self.airbrake_speed = 1 / self.vehicle_data.airbrake_duration
        self.stabilizer_fins_state = 0.0
        self.stabilizer_fins_speed = 1 / self.vehicle_data.stabilizer_fins_duration

        self.centroid = base.loader.load_model('models/smiley')
        self.centroid.reparent_to(self.vehicle)
        self.centroid.hide()

        # Gyro sound
        sound_file = 'assets/cars/{}/{}.wav'.format(
            model_name,
            GYROSCOPE_SOUND,
        )
        sound = base.audio3d.load_sfx(sound_file)
        self.model.set_python_tag(GYROSCOPE_SOUND, sound)
        base.audio3d.attach_sound_to_object(sound, self.model)
        sound.set_volume(0)
        sound.set_play_rate(0)
        sound.set_loop(True)
        sound.play()

        # Thruster limiting
        self.thruster_state = 0.0
        self.thruster_heat = 0.0

        for repulsor in self.vehicle_data.repulsor_nodes:
            self.add_repulsor(repulsor, model_name)
        for thruster in self.vehicle_data.thruster_nodes:
            self.add_thruster(thruster, model_name)

        # ECU data storage from frame to frame
        self.last_flight_height = None

        # FIXME: Move into a default controller
        self.inputs = {
            # Repulsors
            REPULSOR_ACTIVATION: 0.0,
            ACCELERATE: 0.0,
            TURN: 0.0,
            STRAFE: 0.0,
            HOVER: 0.0,
            FULL_REPULSORS: False,
            # Gyro
            ACTIVE_STABILIZATION_ON_GROUND: PASSIVE,
            ACTIVE_STABILIZATION_CUTOFF_ANGLE: PASSIVE,
            ACTIVE_STABILIZATION_IN_AIR: PASSIVE,
            TARGET_ORIENTATION: Vec3(0, 0, 0),
            # Thrust
            THRUST: 0.0,
            # Air foils
            AIRBRAKE: 0.0,
            STABILIZER_FINS: 0.0,
        }
        self.sensors = {}
        self.commands = {}
Пример #21
0
    def setup(self):
        self.worldNP = render.attachNewNode('World')

        # World
        self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()
        self.debugNP.node().showWireframe(True)
        self.debugNP.node().showConstraints(True)
        self.debugNP.node().showBoundingBoxes(False)
        self.debugNP.node().showNormals(True)

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))
        self.world.setDebugNode(self.debugNP.node())

        # Plane (static)
        shape = BulletPlaneShape(Vec3(0, 0, 1), 0)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground'))
        np.node().addShape(shape)
        np.setPos(0, 0, -1)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Box (dynamic)
        shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Box'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(0, 0, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        self.boxNP = np  # For applying force & torque

        #np.node().notifyCollisions(True)
        #self.accept('bullet-contact-added', self.doAdded)
        #self.accept('bullet-contact-destroyed', self.doRemoved)

        # Sphere (dynamic)
        shape = BulletSphereShape(0.6)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Sphere'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(-4, 0, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Cone (dynamic)
        shape = BulletConeShape(0.6, 1.2, ZUp)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Cone'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(4, 0, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Capsule (dynamic)
        shape = BulletCapsuleShape(0.5, 1.0, ZUp)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Capsule'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(0, 4, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Cyliner (dynamic)
        shape = BulletCylinderShape(0.7, 1.5, ZUp)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Cylinder'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(4, 4, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Convex (dynamic)
        shape = BulletConvexHullShape()
        shape.addPoint(Point3(1, 1, 2))
        shape.addPoint(Point3(0, 0, 0))
        shape.addPoint(Point3(2, 0, 0))
        shape.addPoint(Point3(0, 2, 0))
        shape.addPoint(Point3(2, 2, 0))

        # Another way to create the convex hull shape:
        #shape = BulletConvexHullShape()
        #shape.addArray([
        #  Point3(1, 1, 2),
        #  Point3(0, 0, 0),
        #  Point3(2, 0, 0),
        #  Point3(0, 2, 0),
        #  Point3(2, 2, 0),
        #])

        # Yet another way to create the convex hull shape:
        #geom = loader.loadModel('models/box.egg')\
        #         .findAllMatches('**/+GeomNode')\
        #         .getPath(0)\
        #         .node()\
        #         .getGeom(0)
        #shape = BulletConvexHullShape()
        #shape.addGeom(geom)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Convex'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(-4, 4, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # Mesh (static)
        p0 = Point3(-10, -10, 0)
        p1 = Point3(-10, 10, 0)
        p2 = Point3(10, -10, 0)
        p3 = Point3(10, 10, 0)
        mesh = BulletTriangleMesh()
        mesh.addTriangle(p0, p1, p2)
        mesh.addTriangle(p1, p2, p3)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        # Another way to create the triangle mesh shape:
        #geom = loader.loadModel('models/box.egg')\
        #         .findAllMatches('**/+GeomNode')\
        #         .getPath(0)\
        #         .node()\
        #         .getGeom(0)
        #mesh = BulletTriangleMesh()
        #mesh.addGeom(geom)
        #shape = BulletTriangleMeshShape(mesh, dynamic=False)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh'))
        np.node().addShape(shape)
        np.setPos(0, 0, 0.1)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())

        # MutiSphere
        points = [Point3(-1, 0, 0), Point3(0, 0, 0), Point3(1, 0, 0)]
        radii = [.4, .8, .6]
        shape = BulletMultiSphereShape(points, radii)

        np = self.worldNP.attachNewNode(BulletRigidBodyNode('MultiSphere'))
        np.node().setMass(1.0)
        np.node().addShape(shape)
        np.setPos(8, 0, 4)
        np.setCollideMask(BitMask32.allOn())

        self.world.attachRigidBody(np.node())
Пример #22
0
 def create_solid(self):
     node = BulletRigidBodyNode(self.name)
     mesh = BulletConvexHullShape()
     mesh.add_geom(self.geom.get_geom(0))
     node.add_shape(mesh)
     return node
Пример #23
0
 def __init__(self, objinit, cdtype="triangle", mass=.3, restitution=0, allowdeactivation=False, allowccd=True,
              friction=.2, dynamic=True, name="rbd"):
     """
     :param objinit: could be itself (copy), or an instance of collision model
     :param type: triangle or convex
     :param mass:
     :param restitution: bounce parameter
     :param friction:
     :param dynamic: only applicable to triangle type, if an object does not move with force, it is not dynamic
     :param name:
     author: weiwei
     date: 20190626, 20201119
     """
     super().__init__(name)
     if isinstance(objinit, gm.GeometricModel):
         if objinit._objtrm is None:
             raise ValueError("Only applicable to models with a trimesh!")
         self.com = objinit.objtrm.center_mass
         self.setMass(mass)
         self.setRestitution(restitution)
         self.setFriction(friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allowdeactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(0.001)
             self.setAngularSleepThreshold(0.001)
         else:
             self.setDeactivationEnabled(False)
         if allowccd:  # continuous collision detection
             self.setCcdMotionThreshold(1e-6)
             self.setCcdSweptSphereRadius(0.0005)
         gnd = objinit.objpdnp.getChild(0).find("+GeomNode")
         geom = copy.deepcopy(gnd.node().getGeom(0))
         vdata = geom.modifyVertexData()
         vertrewritter = GeomVertexRewriter(vdata, 'vertex')
         while not vertrewritter.isAtEnd():  # shift local coordinate to geom to correctly update dynamic changes
             v = vertrewritter.getData3f()
             vertrewritter.setData3f(v[0] - self.com[0], v[1] - self.com[1], v[2] - self.com[2])
         geomtf = gnd.getTransform()
         if cdtype is "triangle":
             geombmesh = BulletTriangleMesh()
             geombmesh.addGeom(geom)
             bulletshape = BulletTriangleMeshShape(geombmesh, dynamic=dynamic)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         elif cdtype is "convex":
             bulletshape = BulletConvexHullShape()  # TODO: compute a convex hull?
             bulletshape.addGeom(geom, geomtf)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         else:
             raise NotImplementedError
         pdmat4 = geomtf.getMat()
         pdv3 = pdmat4.xformPoint(Vec3(self.com[0], self.com[1], self.com[2]))
         homomat = dh.pdmat4_to_npmat4(pdmat4)
         pos = dh.pdv3_to_npv3(pdv3)
         homomat[:3, 3] = pos  # update center to com
         self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(homomat)))
     elif isinstance(objinit, BDBody):
         self.com = objinit.com.copy()
         self.setMass(objinit.getMass())
         self.setRestitution(objinit.restitution)
         self.setFriction(objinit.friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allowdeactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(0.001)
             self.setAngularSleepThreshold(0.001)
         else:
             self.setDeactivationEnabled(False)
         if allowccd:
             self.setCcdMotionThreshold(1e-6)
             self.setCcdSweptSphereRadius(0.0005)
         self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(objinit.gethomomat())))
         self.addShape(objinit.getShape(0), objinit.getShapeTransform(0))
    def setup(self):
        self.worldNP = render.attach_new_node('World')

        # World
        self.debugNP = self.worldNP.attach_new_node(BulletDebugNode('Debug'))
        self.debugNP.show()
        self.debugNP.node().show_wireframe(True)
        self.debugNP.node().show_constraints(True)
        self.debugNP.node().show_bounding_boxes(False)
        self.debugNP.node().show_normals(False)

        self.world = BulletWorld()
        self.world.set_gravity(LVector3(0, 0, -9.81))
        self.world.set_debug_node(self.debugNP.node())

        # Ground
        shape = BulletPlaneShape(LVector3(0, 0, 1), 0)

        body = BulletRigidBodyNode('Ground')
        bodyNP = self.worldNP.attach_new_node(body)
        bodyNP.node().add_shape(shape)
        bodyNP.set_pos(0, 0, 0)
        bodyNP.set_collide_mask(BitMask32.all_on())
        self.world.attach(bodyNP.node())

        # Bowl
        visNP = loader.load_model('models/bowl.egg')

        geom = (visNP.findAllMatches('**/+GeomNode').get_path(
            0).node().get_geom(0))
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=True)

        body = BulletRigidBodyNode('Bowl')
        bodyNP = self.worldNP.attach_new_node(body)
        bodyNP.node().add_shape(shape)
        bodyNP.node().set_mass(10.0)
        bodyNP.set_pos(0, 0, 0)
        bodyNP.set_collide_mask(BitMask32.all_on())
        self.world.attach(bodyNP.node())

        visNP.reparent_to(bodyNP)

        self.bowlNP = bodyNP
        self.bowlNP.set_scale(2)

        # Eggs
        self.eggNPs = []
        for i in range(5):
            x = random.gauss(0, 0.1)
            y = random.gauss(0, 0.1)
            z = random.gauss(0, 0.1) + 1
            h = random.random() * 360
            p = random.random() * 360
            r = random.random() * 360

            visNP = loader.load_model('models/egg.egg')

            geom = (visNP.find_all_matches('**/+GeomNode').get_path(
                0).node().get_geom(0))
            shape = BulletConvexHullShape()
            shape.addGeom(geom)

            body = BulletRigidBodyNode('Egg-%i' % i)
            bodyNP = self.worldNP.attach_new_node(body)
            bodyNP.node().set_mass(1.0)
            bodyNP.node().add_shape(shape)
            bodyNP.node().set_deactivation_enabled(False)
            bodyNP.set_collide_mask(BitMask32.all_on())
            bodyNP.set_pos_hpr(x, y, z, h, p, r)
            #bodyNP.set_scale(1.5)
            self.world.attach(bodyNP.node())

            visNP.reparent_to(bodyNP)

            self.eggNPs.append(bodyNP)
Пример #25
0
    def __init__(self, mainReference, name, position, regionID):
        
        super(Enemy, self).__init__(mainReference)
        
        # unique enemy name
        self.name = name
        
        # If enemy is alive
        self.alive = True
        
        # enemy's pursue speed P-units/s
        self.speed = 2.9
        
        # enemy's rotation speed angles/s
        self.rotSpeed = 10
        
        # enemy's current convex region; for pursue purposes
        self.currentRegionID = regionID
        
        # Hit Points of each part of zombie
        self.hitPoints = {'leg_lr':2, 'leg_ll':2, 'arm_lr':2, 'arm_ll':2}
        self.lifePoints = 100
        
        # enemy NodePath
        self.enemyNP = self.mainRef.render.attachNewNode(self.name)
        self.enemyNP.setPos(position)
        
        # the name of the task the zombie is currently performing
        self.enemyActiveState = ""
        
        self.isEnemyAttacking = False
        
        # the cross point of the portal that the zombie is trying to cross
        self.currentCrossPointGoal = None
        
        # the time that the enemy will spend confused
        self.lostTargetTotalTime = 1.0
        self.lostTargetTimer = self.lostTargetTotalTime
        
        # load our zombie
        self.enemyModel = Actor("../../models/model_zombie/zombie",{
                                'walk':'../../models/model_zombie/zombie-walk',
                                'attack':'../../models/model_zombie/zombie-attack',
})
        # ****SCALE****
        self.enemyModel.setScale(0.55)
        # ****SCALE****
        
        #enemy's character controller
        self.enemyBody = CharacterBody(self.mainRef, self.enemyNP.getPos(), 0.38, 0.5 )
        self.enemyBody.charBodyNP.reparentTo(self.enemyNP)
        
        # load the zombie's bounding boxes
        self.enemyBB = loader.loadModel("../../models/model_zombie/zombieBB")
        
        global bodyParts      
        bodyParts = ['head', 'leg_ur', 'leg_ul', 'leg_lr', 'leg_ll', 'torso', 'arm_ur', 'arm_ul', 'arm_lr', 'arm_ll']
        
        # List of the bullet nodes for this enemy, to be removed later
        self.bulletNodes = {}
        self.partNodes = {}
        # Get Joints
        self.joints = {}
        
        #for bodyPart in ['leg_lr', 'leg_ll', 'arm_lr', 'arm_ll']:
        #    # Get joint control structure
        #    self.joints[bodyPart] = self.enemyModel.controlJoint(None, 'modelRoot', bodyPart)
        
        # getting 1 by 1 and attaching them to their corresponding bones     
        for bodyPart in bodyParts:
            
            self.bodyPartShape = BulletConvexHullShape()
            self.bodyPartShape.addGeom(self.enemyBB.getChild(0).find(bodyPart).node().getGeom(0))
            
            self.bulletbodyPartNode = BulletRigidBodyNode(bodyPart+"_"+name)
            self.bulletbodyPartNode.addShape(self.bodyPartShape)
            self.bodyPartNode = self.mainRef.render.attachNewNode(self.bulletbodyPartNode)
            # ****SCALE****
            self.bodyPartNode.setScale(0.55)
            # ****SCALE****
            
            self.mainRef.world.attachRigidBody(self.bulletbodyPartNode)
            self.bodyPartNode.setCollideMask( BitMask32.bit( 2 ) )
       
            self.bodyPartNode.wrtReparentTo(self.enemyModel.exposeJoint(None,"modelRoot",bodyPart))
            
            self.bulletNodes[bodyPart] = self.bulletbodyPartNode
            self.partNodes[bodyPart] = self.bodyPartNode
            # uncomment to use triangleMesh instead of convexHull
#            mesh = BulletTriangleMesh()
#            mesh.addGeom(self.enemyBB.getChild(0).find(bodyPart).node().getGeom(0))
#            self.bodyPartShape = BulletTriangleMeshShape(mesh, dynamic=True)
#            
#            self.bulletbodyPartNode = BulletRigidBodyNode(bodyPart)
#            self.bulletbodyPartNode.addShape(self.bodyPartShape)
#            
#            self.bodyPartNode = self.mainRef.render.attachNewNode(self.bulletbodyPartNode)
#            self.mainRef.world.attachRigidBody(self.bulletbodyPartNode)
#       
#            self.bodyPartNode.wrtReparentTo(self.enemyModel.exposeJoint(None,"modelRoot",bodyPart))

        # initial path must be calculated
        self.updatePath()
        
        # adding a task to check if the enemy is leaving their region
        self.checkIfChangedRegionName = self.name + "cicr"
        self.oldPosition = self.enemyNP.getPos()
        taskMgr.add(self.checkIfChangedRegion, self.checkIfChangedRegionName)
        
        # walk loop
#        self.enemyModel.loop("walk")
        self.enemyModel.loop("walk")
        
        # attaching to render
        self.enemyModel.reparentTo(self.enemyNP)
        self.enemyModel.setPos(0,0,-0.51)
        
        # loading enemy roar sound
        zombieRoar = [None,None,None,None]
        for i in range( len(zombieRoar) ):
            zombieRoar[i] = self.mainRef.audio3d.loadSfx('../../sounds/zombie_roar_' + str(i+1) + '.mp3')
        # initialize first zombie roar
        self.zombieRoarFX = zombieRoar[0] 
        self.mainRef.audio3d.attachSoundToObject(self.zombieRoarFX, self.enemyNP)
        self.zombieRoarFX.play()
        # random zombie roar
        def roarSort(task):
            if(self.zombieRoarFX.status() != self.zombieRoarFX.PLAYING):
                random.seed()
                value = random.choice(range(3))
                self.zombieRoarFX = zombieRoar[value]
                self.mainRef.audio3d.attachSoundToObject(self.zombieRoarFX, self.enemyNP)
                self.zombieRoarFX.play()
            return task.again
        self.mainRef.taskMgr.doMethodLater(2, roarSort,self.name+'roar sort')
Пример #26
0
class Enemy(Creature):
    
    def __init__(self, mainReference, name, position, regionID):
        
        super(Enemy, self).__init__(mainReference)
        
        # unique enemy name
        self.name = name
        
        # If enemy is alive
        self.alive = True
        
        # enemy's pursue speed P-units/s
        self.speed = 2.9
        
        # enemy's rotation speed angles/s
        self.rotSpeed = 10
        
        # enemy's current convex region; for pursue purposes
        self.currentRegionID = regionID
        
        # Hit Points of each part of zombie
        self.hitPoints = {'leg_lr':2, 'leg_ll':2, 'arm_lr':2, 'arm_ll':2}
        self.lifePoints = 100
        
        # enemy NodePath
        self.enemyNP = self.mainRef.render.attachNewNode(self.name)
        self.enemyNP.setPos(position)
        
        # the name of the task the zombie is currently performing
        self.enemyActiveState = ""
        
        self.isEnemyAttacking = False
        
        # the cross point of the portal that the zombie is trying to cross
        self.currentCrossPointGoal = None
        
        # the time that the enemy will spend confused
        self.lostTargetTotalTime = 1.0
        self.lostTargetTimer = self.lostTargetTotalTime
        
        # load our zombie
        self.enemyModel = Actor("../../models/model_zombie/zombie",{
                                'walk':'../../models/model_zombie/zombie-walk',
                                'attack':'../../models/model_zombie/zombie-attack',
})
        # ****SCALE****
        self.enemyModel.setScale(0.55)
        # ****SCALE****
        
        #enemy's character controller
        self.enemyBody = CharacterBody(self.mainRef, self.enemyNP.getPos(), 0.38, 0.5 )
        self.enemyBody.charBodyNP.reparentTo(self.enemyNP)
        
        # load the zombie's bounding boxes
        self.enemyBB = loader.loadModel("../../models/model_zombie/zombieBB")
        
        global bodyParts      
        bodyParts = ['head', 'leg_ur', 'leg_ul', 'leg_lr', 'leg_ll', 'torso', 'arm_ur', 'arm_ul', 'arm_lr', 'arm_ll']
        
        # List of the bullet nodes for this enemy, to be removed later
        self.bulletNodes = {}
        self.partNodes = {}
        # Get Joints
        self.joints = {}
        
        #for bodyPart in ['leg_lr', 'leg_ll', 'arm_lr', 'arm_ll']:
        #    # Get joint control structure
        #    self.joints[bodyPart] = self.enemyModel.controlJoint(None, 'modelRoot', bodyPart)
        
        # getting 1 by 1 and attaching them to their corresponding bones     
        for bodyPart in bodyParts:
            
            self.bodyPartShape = BulletConvexHullShape()
            self.bodyPartShape.addGeom(self.enemyBB.getChild(0).find(bodyPart).node().getGeom(0))
            
            self.bulletbodyPartNode = BulletRigidBodyNode(bodyPart+"_"+name)
            self.bulletbodyPartNode.addShape(self.bodyPartShape)
            self.bodyPartNode = self.mainRef.render.attachNewNode(self.bulletbodyPartNode)
            # ****SCALE****
            self.bodyPartNode.setScale(0.55)
            # ****SCALE****
            
            self.mainRef.world.attachRigidBody(self.bulletbodyPartNode)
            self.bodyPartNode.setCollideMask( BitMask32.bit( 2 ) )
       
            self.bodyPartNode.wrtReparentTo(self.enemyModel.exposeJoint(None,"modelRoot",bodyPart))
            
            self.bulletNodes[bodyPart] = self.bulletbodyPartNode
            self.partNodes[bodyPart] = self.bodyPartNode
            # uncomment to use triangleMesh instead of convexHull
#            mesh = BulletTriangleMesh()
#            mesh.addGeom(self.enemyBB.getChild(0).find(bodyPart).node().getGeom(0))
#            self.bodyPartShape = BulletTriangleMeshShape(mesh, dynamic=True)
#            
#            self.bulletbodyPartNode = BulletRigidBodyNode(bodyPart)
#            self.bulletbodyPartNode.addShape(self.bodyPartShape)
#            
#            self.bodyPartNode = self.mainRef.render.attachNewNode(self.bulletbodyPartNode)
#            self.mainRef.world.attachRigidBody(self.bulletbodyPartNode)
#       
#            self.bodyPartNode.wrtReparentTo(self.enemyModel.exposeJoint(None,"modelRoot",bodyPart))

        # initial path must be calculated
        self.updatePath()
        
        # adding a task to check if the enemy is leaving their region
        self.checkIfChangedRegionName = self.name + "cicr"
        self.oldPosition = self.enemyNP.getPos()
        taskMgr.add(self.checkIfChangedRegion, self.checkIfChangedRegionName)
        
        # walk loop
#        self.enemyModel.loop("walk")
        self.enemyModel.loop("walk")
        
        # attaching to render
        self.enemyModel.reparentTo(self.enemyNP)
        self.enemyModel.setPos(0,0,-0.51)
        
        # loading enemy roar sound
        zombieRoar = [None,None,None,None]
        for i in range( len(zombieRoar) ):
            zombieRoar[i] = self.mainRef.audio3d.loadSfx('../../sounds/zombie_roar_' + str(i+1) + '.mp3')
        # initialize first zombie roar
        self.zombieRoarFX = zombieRoar[0] 
        self.mainRef.audio3d.attachSoundToObject(self.zombieRoarFX, self.enemyNP)
        self.zombieRoarFX.play()
        # random zombie roar
        def roarSort(task):
            if(self.zombieRoarFX.status() != self.zombieRoarFX.PLAYING):
                random.seed()
                value = random.choice(range(3))
                self.zombieRoarFX = zombieRoar[value]
                self.mainRef.audio3d.attachSoundToObject(self.zombieRoarFX, self.enemyNP)
                self.zombieRoarFX.play()
            return task.again
        self.mainRef.taskMgr.doMethodLater(2, roarSort,self.name+'roar sort')
        
    def hide(self):
        self.enemyModel.hide()
        
    def show(self):
        self.mainRef.world.attachRigidBody(self.enemyBulletNode)
        self.enemyModel.show()
        self.enemyModel.loop("walk")
        
    
    def setNewCourse(self):
        # Simply follow the player
        if (len(self.portalsPathList) == 0):
            taskMgr.remove( self.enemyActiveState )
            self.enemyActiveState = self.name + "pt"
            taskMgr.add(self.pursueTargetStep, self.enemyActiveState)

        
        # Go to the cross point that makes you closer to your target
        elif (self.portalsPathList[0].connectedRegionsIDs[0] == self.mainRef.player.currentRegionID or
              self.portalsPathList[0].connectedRegionsIDs[1] == self.mainRef.player.currentRegionID):
            
            self.setOptimalCrossPoint()
            
            taskMgr.remove( self.enemyActiveState )
            self.enemyActiveState = self.name + "htp"
            taskMgr.add(self.headToPortalStep, self.enemyActiveState)
        
        
        # Go to the middle cross point
        else:
            
            self.currentCrossPointGoal = self.portalsPathList[0].middleCrossPoint
            
            taskMgr.remove( self.enemyActiveState )
            self.enemyActiveState = self.name + "htp"
            taskMgr.add(self.headToPortalStep, self.enemyActiveState)
            
    #                 ======================================================================== 
    #                 ======================== STATE MACHINE METHODS ==========================        
    def pursueTargetStep(self, task):
        if (self.mainRef.player.currentRegionID == self.currentRegionID):
            
            if ( self.mainRef.player.playerNP.getPos(self.enemyNP).length() < 4.0):
                if (not self.isEnemyAttacking):
                    self.speed += 1.0
                    self.isEnemyAttacking = True
                    self.enemyModel.loop("attack")     
                                   
            elif (self.isEnemyAttacking):
                self.speed -= 1.0
                self.isEnemyAttacking = False
                self.enemyModel.loop("walk") 
            
            targetDirection = Vec2( self.mainRef.player.playerNP.getPos(self.enemyNP).getXy() )
            targetDirectionAngle = Vec2(-sin(radians(self.enemyModel.getH())), 
                                         cos(radians(self.enemyModel.getH())) ).signedAngleDeg(targetDirection)

            rotationAngle = targetDirectionAngle * self.rotSpeed * globalClock.getDt()
            self.enemyModel.setH(self.enemyModel.getH() + rotationAngle)

            targetDirection.normalize()
            playerMoveSpeedVec = targetDirection * self.speed * globalClock.getDt()
            self.enemyNP.setPos( self.enemyBody.move(Vec3(playerMoveSpeedVec.getX(), playerMoveSpeedVec.getY(), 0) ) )                
            
            if (abs(rotationAngle) > 120 * globalClock.getDt()):
                self.lostTargetTimer = self.lostTargetTotalTime
                self.enemyActiveState = self.name + "lt"
                taskMgr.add(self.lostTargetStep, self.enemyActiveState)
                return task.done
             
        return task.cont
    
    def lostTargetStep(self, task):
        self.enemyNP.setPos( self.enemyBody.move(Vec3(-sin(radians(self.enemyModel.getH())),
                                                       cos(radians(self.enemyModel.getH())),
                                                        0) * self.speed * globalClock.getDt() ) )
        self.lostTargetTimer -= globalClock.getDt()
        
        if (self.lostTargetTimer < 0):
            self.enemyActiveState = self.name + "rt"
            taskMgr.add(self.recoverTargetStep, self.enemyActiveState) 
            return task.done
        
        return task.cont
        
    def recoverTargetStep(self, task):
        targetDirection = Vec2( self.mainRef.player.playerNP.getPos(self.enemyNP).getXy() )
        targetDirectionAngle = Vec2(-sin(radians(self.enemyModel.getH())), 
                                     cos(radians(self.enemyModel.getH())) ).signedAngleDeg(targetDirection)

        rotationAngle = targetDirectionAngle * self.rotSpeed * globalClock.getDt()
        self.enemyModel.setH(self.enemyModel.getH() + rotationAngle)

        if (abs(targetDirectionAngle) < 5):
            self.enemyActiveState = self.name + "pt"
            taskMgr.add(self.pursueTargetStep, self.enemyActiveState) 
            return task.done
        
        return task.cont
    
    def headToPortalStep(self, task):
        directionVec = Vec3(self.currentCrossPointGoal.getX() - self.enemyNP.getX(),
                            self.currentCrossPointGoal.getY() - self.enemyNP.getY(), 0)
        directionVec.normalize()
        
        targetDirection = Vec2( self.currentCrossPointGoal - self.enemyNP.getPos().getXy() )
        targetDirectionAngle = Vec2(-sin(radians(self.enemyModel.getH())), 
                                     cos(radians(self.enemyModel.getH())) ).signedAngleDeg(targetDirection)

        rotationAngle = targetDirectionAngle * self.rotSpeed * globalClock.getDt()
        self.enemyModel.setH(self.enemyModel.getH() + rotationAngle)
        
        self.enemyNP.setPos( self.enemyBody.move( directionVec * self.speed * globalClock.getDt() ) )
        
        return task.cont    
    #              ====================== END OF STATE MACHINE METHODS ========================  
    #              ============================================================================
        
    def destroy(self):
        self.alive = False
        taskMgr.remove(self.name+'roar sort') # removing sound
        for node in self.bulletNodes.keys():
            self.mainRef.world.removeRigidBody(self.bulletNodes[node])
            self.partNodes[node].removeNode()
        taskMgr.remove( self.enemyActiveState ) # removing state machine task 
        self.enemyModel.cleanup()
        self.enemyBB.removeNode()
        self.enemyBody.destroy()

    def detachLimb(self,limb):
        # Detaches a limb from the enemy and makes it drop on the floor
        print "[Detach] Detach %s" % limb
        
#        self.partNodes[limb].wrtReparentTo(self.mainRef.render)
#
#        shape = BulletSphereShape(10.0)
#        node = BulletRigidBodyNode('Sphere')
#        node.setMass(1.0)
#        node.addShape(shape)
#        playerNP = self.mainRef.render.attachNewNode(node)
#        playerNP.setPos(self.enemyModel.exposeJoint(None,"modelRoot",limb).getPos())
#        playerNP.setPos(playerNP.getRelativePoint(self.partNodes[limb],self.partNodes[limb].getPos()))
#        playerNP.setPos(60,0,-60)
#        print playerNP.getRelativePoint(self.partNodes[limb],self.partNodes[limb].getPos())
#        print self.partNodes[limb].getPos()
#        self.mainRef.world.attachRigidBody(node)
#        
#        self.bulletNodes[limb].applyCentralForce(Vec3(0, 0, -5))
#        self.mainRef.world.removeRigidBody(self.bulletNodes[limb])

    def updatePath(self):
        
        convexRegionsList = self.mainRef.map.convexRegions      
        self.portalsPathList = []        # this is what we want for enemy's correct pursue path
        discoveredRegionsList = []     # part of the BFS algorithm
        visitedRegionsList = [False for item in range( len(convexRegionsList))]
        regionFatherList = [None for item in range( len(convexRegionsList))]       # this list keeps track of a region's father AND the portalEntrance connecting them
        
        # from now, we'll execute a BFS to find each region that enemy will cross to reach player's position
        discoveredRegionsList.append( convexRegionsList[self.currentRegionID] )
        visitedRegionsList[self.currentRegionID] = True
        regionFatherList[self.currentRegionID] = [-1, None]
        
        while(discoveredRegionsList):
            
            analisedRegion = discoveredRegionsList.pop(0)
            for portalEntrance in analisedRegion.portalEntrancesList:
                neighbourRegionID = portalEntrance.connectedRegionID
                
                if (not visitedRegionsList[neighbourRegionID]):
                    regionFatherList[neighbourRegionID] = [analisedRegion.regionID, portalEntrance.portal]
                    
                    if (neighbourRegionID == self.mainRef.player.currentRegionID):
                        discoveredRegionsList = [] # break while statement trick          
                        break
                    
                    visitedRegionsList[neighbourRegionID] = True
                    discoveredRegionsList.append( convexRegionsList[neighbourRegionID] )
        
        # now that we have all regions necessary , we'll just put all portals on the correct order
        lastRegionFatherID = self.mainRef.player.currentRegionID
        while (lastRegionFatherID != -1):
            lastRegionFather = regionFatherList[lastRegionFatherID]
            lastRegionFatherID = lastRegionFather[0]
            self.portalsPathList.append(lastRegionFather[1])
        
        # putting portals path on the right order for enemy pursuing algorithm
        self.portalsPathList.pop()  
        self.portalsPathList.reverse()
        
        # Debug
#        print "lista de portais:"
#        for portal in self.portalsPathList:
#            print portal.connectedRegionsIDs

        self.setNewCourse()

    def checkIfChangedRegion(self, task, lastRegion=0):
        
        for portalEntrance in self.mainRef.map.convexRegions[self.currentRegionID].portalEntrancesList:
            
            if ( self.intersect( self.oldPosition, self.enemyNP.getPos(), 
                                 portalEntrance.portal.frontiers[0], portalEntrance.portal.frontiers[1] )
                                 and portalEntrance.portal.connectedRegionsIDs[0] != lastRegion 
                                 and portalEntrance.portal.connectedRegionsIDs[1] != lastRegion ):
                
                oldRegion = self.mainRef.player.currentRegionID
                self.currentRegionID = portalEntrance.connectedRegionID

                
                # Debug
#                print self.name + " region changed: ", oldRegion, ">", self.currentRegionID
                
                # erase last item of portalsPathList (if it isn't empty)
                if (len(self.portalsPathList) != 0):
                    self.portalsPathList.pop(0)
                
                # new course must be calculated if the enemy changed it's region
                self.setNewCourse()
        
        self.oldPosition = self.enemyNP.getPos()
        
        return task.cont        

    def ccw(self, A,B,C):
        return (C.getY()-A.getY())*(B.getX()-A.getX()) > (B.getY()-A.getY())*(C.getX()-A.getX())
    
    def intersect(self, A,B,C,D):
        return self.ccw(A,C,D) != self.ccw(B,C,D) and self.ccw(A,B,C) != self.ccw(A,B,D)



    def setOptimalCrossPoint(self):
        
        deltaPositionVec = self.mainRef.player.playerNP.getPos() - self.enemyNP.getPos()
        positionPoint = self.enemyNP.getPos()
        
        deltaFrontiersVec = self.portalsPathList[0].frontiersVec
        frontierPoint = self.portalsPathList[0].frontiers[0]
        
        if (deltaPositionVec.getX() == 0):
            tang2 = deltaFrontiersVec.getY() / deltaFrontiersVec.getX()
            b2 = frontierPoint.getY() - tang2 * frontierPoint.getX()
            
            xRes = positionPoint.getX()
            yRes = tang2 * xRes + b2
            
            
        if (deltaFrontiersVec.getX() == 0):
            tang1 = deltaPositionVec.getY() / deltaPositionVec.getX()
            b1 = positionPoint.getY() - tang1 * positionPoint.getX()
            
            xRes = frontierPoint.getX()
            yRes = tang1 * xRes + b1
            
        
        else:
            tang1 = deltaPositionVec.getY() / deltaPositionVec.getX()
            tang2 = deltaFrontiersVec.getY() / deltaFrontiersVec.getX()
            
            b1 = positionPoint.getY() - tang1 * positionPoint.getX()
            b2 = frontierPoint.getY() - tang2 * frontierPoint.getX()
            
            xRes = (b1 - b2) / (tang1 - tang2)
            yRes = tang1 * xRes + b1
            
            
        if (deltaFrontiersVec.getX() == 0):
            if ( ( yRes > self.portalsPathList[0].crossPoints[0].getY() and yRes < self.portalsPathList[0].crossPoints[1].getY() ) or
                 ( yRes < self.portalsPathList[0].crossPoints[0].getY() and yRes > self.portalsPathList[0].crossPoints[1].getY() ) ) :
                self.currentCrossPointGoal = Vec2(xRes, yRes)
                
            elif (yRes > self.portalsPathList[0].crossPoints[0].getY() and
                  yRes > self.portalsPathList[0].crossPoints[1].getY() ):
                if ( self.portalsPathList[0].crossPoints[0].getY() > 
                     self.portalsPathList[0].crossPoints[1].getY()):
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[0]
                else:
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[1]
        
            else:
                if ( self.portalsPathList[0].crossPoints[0].getY() < 
                     self.portalsPathList[0].crossPoints[1].getY()):
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[0]
                else:
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[1]
         
         
        else:
            if ( ( xRes > self.portalsPathList[0].crossPoints[0].getX() and xRes < self.portalsPathList[0].crossPoints[1].getX() ) or
                 ( xRes < self.portalsPathList[0].crossPoints[0].getX() and xRes > self.portalsPathList[0].crossPoints[1].getX() ) ) :
                self.currentCrossPointGoal = Vec2(xRes, yRes)
                
            elif (xRes > self.portalsPathList[0].crossPoints[0].getX() and
                  xRes > self.portalsPathList[0].crossPoints[1].getX()):
                if ( self.portalsPathList[0].crossPoints[0].getX() > 
                     self.portalsPathList[0].crossPoints[1].getX()):
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[0]
                else:
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[1]
        
            else:
                if ( self.portalsPathList[0].crossPoints[0].getX() < 
                     self.portalsPathList[0].crossPoints[1].getX()):
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[0]
                else:
                    self.currentCrossPointGoal = self.portalsPathList[0].crossPoints[1]
Пример #27
0
 def __init__(self,
              initor,
              cdtype="triangles",
              mass=.3,
              restitution=0,
              allow_deactivation=False,
              allow_ccd=True,
              friction=.2,
              dynamic=True,
              name="rbd"):
     """
     TODO: triangles do not seem to work (very slow) in the github version (20210418)
     Use convex if possible
     :param initor: could be itself (copy), or an instance of collision model
     :param type: triangle or convex
     :param mass:
     :param restitution: bounce parameter
     :param friction:
     :param dynamic: only applicable to triangle type, if an object does not move with force, it is not dynamic
     :param name:
     author: weiwei
     date: 20190626, 20201119
     """
     super().__init__(name)
     if isinstance(initor, gm.GeometricModel):
         if initor._objtrm is None:
             raise ValueError("Only applicable to models with a trimesh!")
         self.com = initor.objtrm.center_mass * base.physics_scale
         self.setMass(mass)
         self.setRestitution(restitution)
         self.setFriction(friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allow_deactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(.01 * base.physics_scale)
             self.setAngularSleepThreshold(.01 * base.physics_scale)
         else:
             self.setDeactivationEnabled(False)
         if allow_ccd:  # continuous collision detection
             self.setCcdMotionThreshold(1e-7)
             self.setCcdSweptSphereRadius(0.0005 * base.physics_scale)
         geom_np = initor.objpdnp.getChild(0).find("+GeomNode")
         geom = copy.deepcopy(geom_np.node().getGeom(0))
         vdata = geom.modifyVertexData()
         vertices = copy.deepcopy(
             np.frombuffer(vdata.modifyArrayHandle(0).getData(),
                           dtype=np.float32))
         vertices.shape = (-1, 6)
         vertices[:, :3] = vertices[:, :3] * base.physics_scale - self.com
         vdata.modifyArrayHandle(0).setData(
             vertices.astype(np.float32).tobytes())
         geomtf = geom_np.getTransform()
         geomtf = geomtf.setPos(geomtf.getPos() * base.physics_scale)
         if cdtype == "triangles":
             geombmesh = BulletTriangleMesh()
             geombmesh.addGeom(geom)
             bulletshape = BulletTriangleMeshShape(geombmesh,
                                                   dynamic=dynamic)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         elif cdtype == "convex":
             bulletshape = BulletConvexHullShape(
             )  # TODO: compute a convex hull?
             bulletshape.addGeom(geom, geomtf)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         elif cdtype == 'box':
             minx = min(vertices[:, 0])
             miny = min(vertices[:, 1])
             minz = min(vertices[:, 2])
             maxx = max(vertices[:, 0])
             maxy = max(vertices[:, 1])
             maxz = max(vertices[:, 2])
             pcd_box = CollisionBox(Point3(minx, miny, minz),
                                    Point3(maxx, maxy, maxz))
             bulletshape = BulletBoxShape.makeFromSolid(pcd_box)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         else:
             raise NotImplementedError
         pd_homomat = geomtf.getMat()
         pd_com_pos = pd_homomat.xformPoint(
             Vec3(self.com[0], self.com[1], self.com[2]))
         np_homomat = dh.pdmat4_to_npmat4(pd_homomat)
         np_com_pos = dh.pdv3_to_npv3(pd_com_pos)
         np_homomat[:3, 3] = np_com_pos  # update center to com
         self.setTransform(
             TransformState.makeMat(dh.npmat4_to_pdmat4(np_homomat)))
     elif isinstance(initor, BDBody):
         self.com = initor.com.copy()
         self.setMass(initor.getMass())
         self.setRestitution(initor.restitution)
         self.setFriction(initor.friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allow_deactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(.01 * base.physics_scale)
             self.setAngularSleepThreshold(.01 * base.physics_scale)
         else:
             self.setDeactivationEnabled(False)
         if allow_ccd:
             self.setCcdMotionThreshold(1e-7)
             self.setCcdSweptSphereRadius(0.0005 * base.physics_scale)
         np_homomat = copy.deepcopy(initor.get_homomat())
         np_homomat[:3, 3] = np_homomat[:3, 3] * base.physics_scale
         self.setTransform(
             TransformState.makeMat(dh.npmat4_to_pdmat4(np_homomat)))
         self.addShape(initor.getShape(0), initor.getShapeTransform(0))
Пример #28
0
 def one():
     geom = model.node().getGeom(0)          
     shape = BulletConvexHullShape()
     shape.addGeom(geom)
     body.addShape( shape, TransformState.makePosHprScale(pos,hpr,scale) )
     return []