Ejemplo n.º 1
0
def rayHit(pfrom, pto, geom):
    """
    NOTE: this function is quite slow
    find the nearest collision point between vec(pto-pfrom) and the mesh of nodepath

    :param pfrom: starting point of the ray, Point3
    :param pto: ending point of the ray, Point3
    :param geom: meshmodel, a panda3d datatype
    :return: None or Point3

    author: weiwei
    date: 20161201
    """

    bulletworld = BulletWorld()
    facetmesh = BulletTriangleMesh()
    facetmesh.addGeom(geom)
    facetmeshnode = BulletRigidBodyNode('facet')
    bullettmshape = BulletTriangleMeshShape(facetmesh, dynamic=True)
    bullettmshape.setMargin(0)
    facetmeshnode.addShape(bullettmshape)
    bulletworld.attachRigidBody(facetmeshnode)
    result = bulletworld.rayTestClosest(pfrom, pto)

    if result.hasHit():
        return result.getHitPos()
    else:
        return None
Ejemplo n.º 2
0
def genBulletCDMeshMultiNp(nodepath, basenodepath=None, name='autogen'):
    """
    generate the BulletCD mesh of a nodepath using nodepath
    this function suppose the nodepath has multiple models with many geomnodes

    use genBulletCDMeshMultiNp instead of genBulletCDMeshNp for generality

    :param nodepath: the panda3d nodepath of the object
    :param basenodepath: the nodepath to compute relative transform, identity if none
    :param name: the name of the rigidbody
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    gndcollection = nodepath.findAllMatches("**/+GeomNode")
    geombullnode = BulletRigidBodyNode(name)
    for gnd in gndcollection:
        geom = gnd.node().getGeom(0)
        geomtf = gnd.getTransform(base.render)
        if basenodepath is not None:
            geomtf = gnd.getTransform(basenodepath)
        geombullmesh = BulletTriangleMesh()
        geombullmesh.addGeom(geom)
        bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
        bullettmshape.setMargin(0)
        geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 3
0
    def isRayHitMeshAll(self, pfrom, pto, objcm):
        """

        :param pfrom:
        :param pto:
        :param objcm:
        :return:

        author: weiwei
        date: 20190805
        """

        geom = base.pg.packpandageom_fn(objcm.trimesh.vertices,
                                        objcm.trimesh.face_normals,
                                        objcm.trimesh.faces)
        targetobjmesh = BulletTriangleMesh()
        targetobjmesh.addGeom(geom)
        bullettmshape = BulletTriangleMeshShape(targetobjmesh, dynamic=True)
        bullettmshape.setMargin(1e-6)
        targetobjmeshnode = BulletRigidBodyNode('facet')
        targetobjmeshnode.addShape(bullettmshape)
        self.world.attach(targetobjmeshnode)
        result = self.world.rayTestAll(base.pg.npToV3(pfrom),
                                       base.pg.npToV3(pto))
        self.world.removeRigidBody(targetobjmeshnode)
        if result.hasHits():
            allhits = []
            for hit in result.getHits():
                allhits.append([hit.getHitPos(), -hit.getHitNormal()])
            return allhits
        else:
            return []
Ejemplo n.º 4
0
def genCollisionMeshNp(nodepath, basenodepath=None, name='autogen'):
    """
    generate the collision mesh of a nodepath using nodepath
    this function suppose the nodepath is a single model with one geomnode

    :param nodepath: the panda3d nodepath of the object
    :param basenodepath: the nodepath to compute relative transform, identity if none
    :param name: the name of the rigidbody
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    geomnodepath = nodepath.find("**/+GeomNode")
    geombullnode = BulletRigidBodyNode(name)
    geom = geomnodepath.node().getGeom(0)
    geomtf = nodepath.getTransform(base.render)
    if basenodepath is not None:
        geomtf = nodepath.getTransform(basenodepath)
    geombullmesh = BulletTriangleMesh()
    geombullmesh.addGeom(geom)
    bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
    bullettmshape.setMargin(0)
    geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 5
0
def genCollisionMeshMultiNp(nodepath, basenodepath=None, name='autogen'):
    """
    generate the collision mesh of a nodepath using nodepath
    this function suppose the nodepath has multiple models with many geomnodes

    use genCollisionMeshMultiNp instead of genCollisionMeshNp for generality

    :param nodepath: the panda3d nodepath of the object
    :param basenodepath: the nodepath to compute relative transform, identity if none
    :param name: the name of the rigidbody
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    gndcollection = nodepath.findAllMatches("**/+GeomNode")
    geombullnode = BulletRigidBodyNode(name)
    for gnd in gndcollection:
        geom = gnd.node().getGeom(0)
        geomtf = gnd.getTransform(base.render)
        if basenodepath is not None:
            geomtf = gnd.getTransform(basenodepath)
        geombullmesh = BulletTriangleMesh()
        geombullmesh.addGeom(geom)
        bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
        bullettmshape.setMargin(0)
        geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 6
0
def genBulletCDMeshList(objcmlist, basenodepath=None, name='autogen'):
    """
    generate the collision mesh of a nodepath using nodepathlist
    this function suppose the nodepathlist is a list of models with many geomnodes
    "Multi" means each nodepath in the nodepath list may have multiple nps (parent-child relations)

    use genCollisionMeshMultiNp instead if the meshes have parent-child relations

    :param nodepathlist: panda3d nodepathlist
    :param basenodepath: the nodepath to compute relative transform, identity if none
    :param name: the name of the rigidbody
    :return: bulletrigidbody

    author: weiwei
    date: 20190514
    """

    geombullnode = BulletRigidBodyNode(name)
    for objcm in objcmlist:
        gndcollection = objcm.objnp.findAllMatches("+GeomNode")
        for gnd in gndcollection:
            geom = copy.deepcopy(gnd.node().getGeom(0))
            geomtf = gnd.getTransform(base.render)
            if basenodepath is not None:
                geomtf = gnd.getTransform(basenodepath)
            geombullmesh = BulletTriangleMesh()
            geombullmesh.addGeom(geom)
            bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
            bullettmshape.setMargin(0)
            geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 7
0
def bulletRayHit(pfrom, pto, geom):
    """
    NOTE: this function is quite slow
    find the nearest collision point between vec(pto-pfrom) and the mesh of nodepath

    :param pfrom: starting point of the ray, Point3
    :param pto: ending point of the ray, Point3
    :param geom: meshmodel, a panda3d datatype
    :return: None or Point3

    author: weiwei
    date: 20161201
    """

    bulletworld = BulletWorld()
    facetmesh = BulletTriangleMesh()
    facetmesh.addGeom(geom)
    facetmeshnode = BulletRigidBodyNode('facet')
    bullettmshape = BulletTriangleMeshShape(facetmesh, dynamic=True)
    bullettmshape.setMargin(1e-6)
    facetmeshnode.addShape(bullettmshape)
    bulletworld.attach(facetmeshnode)
    result = bulletworld.rayTestClosest(pfrom, pto)

    if result.hasHit():
        return result.getHitPos()
    else:
        return None
Ejemplo n.º 8
0
def gen_cdmesh_vvnf(vertices, vertex_normals, faces, name='auto'):
    geom = da.pandageom_from_vvnf(vertices * SCALE_FOR_PRECISION, vertex_normals, faces)
    bullet_triangles_mesh = BulletTriangleMesh()
    bullet_triangles_mesh.addGeom(geom)
    bullet_triangles_shape = BulletTriangleMeshShape(bullet_triangles_mesh, dynamic=True)
    bullet_triangles_shape.setMargin(0)
    geombullnode = BulletRigidBodyNode(name=name)
    geombullnode.addShape(bullet_triangles_shape)
    return geombullnode
Ejemplo n.º 9
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
Ejemplo n.º 10
0
    def __init__(self, name, modelPath, displayModelPath, 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)

        mesh = BulletTriangleMesh()
        mesh.addGeom(self.geom)
        self.shape = BulletTriangleMeshShape(mesh, dynamic=False)

        self.node = BulletRigidBodyNode(self.name)
        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.displayModel = self.game.loader.loadModel(displayModelPath)
        self.displayModel.reparentTo(self.np)
        self.displayModel.setTwoSided(True)
        self.slice_able = False
Ejemplo n.º 11
0
    def __init__(self, track_data, world):
        super().__init__()

        self.track_data = track_data
        self.world = world

        self.snode = GeomNode('track')

        self.width = track_data["width"]

        self.cur_x1 = 0
        self.cur_y1 = 0
        self.cur_z1 = 0
        self.cur_x2 = self.width
        self.cur_y2 = 0
        self.cur_z2 = 0

        self.mesh = BulletTriangleMesh()

        self.surfaces = {}
        self.load_surfaces()

        self.segments = []
        self.gen_segments()
        shape = BulletTriangleMeshShape(self.mesh, dynamic=False)

        self.track = render.attachNewNode(BulletRigidBodyNode('Track'))
        self.track.node().addShape(shape)
        self.world.attachRigidBody(self.track.node())
        self.track.attachNewNode(self.snode)
        self.track.setTwoSided(True)
        self.track.setCollideMask(BitMask32.allOn())
Ejemplo n.º 12
0
    def loadModel(self):

        if (self.viewing_object):
            self.world.removeRigidBody(self.viewing_object.node())

        Tk().withdraw(
        )  # we don't want a full GUI, so keep the root window from appearing
        filename = askopenfilename(
        )  # show an "Open" dialog box and return the path to the selected file
        # filename = "models/new2.obj"
        pandafile = Filename.fromOsSpecific(filename)
        viewing_object_NP = loader.loadModel(pandafile)
        geom = viewing_object_NP.findAllMatches("**/+GeomNode").getPath(
            0).node().getGeom(0)
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=True)
        body = BulletRigidBodyNode("viewing_object")
        self.viewing_object = self.worldNP.attachNewNode(body)
        self.viewing_object.node().addShape(shape)
        self.viewing_object.setPos(0, 0, 0)
        self.viewing_object.setHpr(0, 90, 0)
        self.viewing_object.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(self.viewing_object.node())
        self.viewing_object.setScale(50)
Ejemplo n.º 13
0
    def createLetter(self, loadFile, name, x, y, z):
        self.name = name
        self.letter = loader.loadModel(loadFile)
        geomnodes = self.letter.findAllMatches('**/+GeomNode')
        gn = geomnodes.getPath(0).node()
        geom = gn.getGeom(0)
        mesh = BulletTriangleMesh()
        mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        self.letterNode = BulletRigidBodyNode('Letter')
        self.letterNode.setMass(0)
        self.letterNode.addShape(shape)

        self.letters.append(self.letterNode)
        letternn = render.attachNewNode(self.letterNode)
        letternn.setPos(x, y, z)
        letternn.setScale(1)
        letternn.setP(90)  # orients the mesh for the letters to be upright

        self.world.attachRigidBody(self.letterNode)
        self.letter.reparentTo(letternn)

        self.letter.setP(
            -90)  # orients the actual letter objects to be upright
Ejemplo n.º 14
0
    def __init__(self, bulletWorld):

        #model used as collision mesh VOLCANO
        collisionModel = loader.loadModel('models/VolcanoCollision2')

        tex = loader.loadTexture("models/mars_1k_tex.jpg")
        collisionModel.setTexture(tex)

        mesh = BulletTriangleMesh()
        for geomNP in collisionModel.findAllMatches('**/+GeomNode'):
            geomNode = geomNP.node()
            ts = geomNP.getTransform(collisionModel)
            for geom in geomNode.getGeoms():
                mesh.addGeom(geom, ts)

        shape = BulletTriangleMeshShape(mesh, dynamic=False)

        self.rigidNode = BulletRigidBodyNode('Heightfield')
        self.rigidNode.notifyCollisions(False)
        np = render.attachNewNode(self.rigidNode)
        np.node().addShape(shape)

        collisionModel.reparentTo(np)
        np.setScale(7)
        ###Ucomment next line for RAZOR map:
        #np.setHpr(0,90,0)
        np.setPos(0, 0, -2)
        np.setCollideMask(BitMask32.allOn())
        np.node().notifyCollisions(False)
        bulletWorld.attachRigidBody(np.node())

        self.hf = np.node()  # To enable/disable debug visualization
Ejemplo n.º 15
0
    def build_node_path(self, parent_node_path, bullet_world):
        land_geom = self.__build_land_mesh()
        ocean_geom = self.__build_ocean_mesh()
        land_mesh = BulletTriangleMesh()
        land_mesh.addGeom(land_geom)
        land_shape = BulletTriangleMeshShape(land_mesh, dynamic=False)
        ocean_shape = BulletSphereShape(self.__radius)

        land_bullet_node = BulletRigidBodyNode('land collider')
        land_bullet_node.addShape(land_shape)
        bullet_world.attachRigidBody(land_bullet_node)
        land_bullet_node_path = parent_node_path.attachNewNode(
            land_bullet_node)

        ocean_bullet_node = BulletGhostNode('ocean collider')
        ocean_bullet_node.addShape(ocean_shape)
        bullet_world.attachGhost(ocean_bullet_node)
        ocean_bullet_node_path = land_bullet_node_path.attachNewNode(
            ocean_bullet_node)

        land_node = GeomNode('land')
        land_node.addGeom(land_geom)
        land_node_path = land_bullet_node_path.attachNewNode(land_node)
        ocean_node = GeomNode('ocean')
        ocean_node.addGeom(ocean_geom)
        ocean_node_path = ocean_bullet_node_path.attachNewNode(ocean_node)
        ocean_node_path.setTransparency(TransparencyAttrib.MAlpha)

        self.__node_path = land_bullet_node_path
        land_bullet_node.setPythonTag('planet', self)
        return land_bullet_node_path
	def __init__(self, model, world, worldNP, pos, scale, hpr):
		self.worldNP = worldNP
		bulletWorld = world
		
		# Initialize the model.
		self.AIModel = loader.loadModel(model)
		self.AINode = BulletRigidBodyNode('AIChar')
		self.AIModel.setScale(scale)
		self.AIModel.flattenLight() # Combines all geom nodes into one geom node.

		# Build the triangle mesh shape and attach it with the transform.
		geom = self.AIModel.findAllMatches('**/+GeomNode').getPath(0).node().getGeom(0)
		mesh = BulletTriangleMesh()
		mesh.addGeom(geom)
		shape = BulletTriangleMeshShape(mesh, dynamic=False)
		self.AINode.addShape(shape, TransformState.makePosHprScale(Point3(0,0,0), hpr, scale))
		self.AINode.setMass(0)
		bulletWorld.attachRigidBody(self.AINode)
		
		# Apply the same transforms on the model being rendered.
		self.AIModel.reparentTo(render)
		self.AIModel.setH(hpr.getX())
		self.AIModel.setP(hpr.getY())
		self.AIModel.setR(hpr.getZ())
		self.AINode.setAngularFactor(Vec3(0,0,0))
		
		# Attach it to the world.
		self.AIChar = self.worldNP.attachNewNode(self.AINode)
		self.AIModel.reparentTo(self.AIChar)
		self.AIChar.setPos(pos)
Ejemplo n.º 17
0
        def make_collision_from_model(input_model, node_number, mass, world,
                                      target_pos, h_adj):
            # tristrip generation from static models
            # generic tri-strip collision generator begins
            geom_nodes = input_model.find_all_matches('**/+GeomNode')
            geom_nodes = geom_nodes.get_path(node_number).node()
            # print(geom_nodes)
            geom_target = geom_nodes.get_geom(0)
            # print(geom_target)
            output_bullet_mesh = BulletTriangleMesh()
            output_bullet_mesh.add_geom(geom_target)
            tri_shape = BulletTriangleMeshShape(output_bullet_mesh,
                                                dynamic=False)
            print(output_bullet_mesh)

            body = BulletRigidBodyNode('input_model_tri_mesh')
            np = self.render.attach_new_node(body)
            np.node().add_shape(tri_shape)
            np.node().set_mass(mass)
            np.node().set_friction(0.01)
            np.set_pos(target_pos)
            np.set_scale(1)
            np.set_h(h_adj)
            # np.set_p(180)
            # np.set_r(180)
            np.set_collide_mask(BitMask32.allOn())
            world.attach_rigid_body(np.node())
Ejemplo n.º 18
0
    def addMeshRB(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 = BulletTriangleMeshShape(mesh, dynamic=not ghost)#BulletConvexHullShape
        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
Ejemplo n.º 19
0
    def __init__(self):
        base.accept('f1', self.toggleDebug)

        self.debugNode = BulletDebugNode('Debug')
        self.debugNode.showWireframe(True)
        self.debugNode.showConstraints(True)
        self.debugNode.showBoundingBoxes(False)
        self.debugNode.showNormals(False)
        self.debugNP = base.render.attachNewNode(self.debugNode)
        # self.debugNP.show()

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

        # Terrain
        visNP = base.loader.loadModel('models/terrain.egg')

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

        body = BulletRigidBodyNode('Bowl')
        bodyNP = base.render.attachNewNode(body)
        bodyNP.node().addShape(shape)
        bodyNP.setPos(0, 0, 1)
        bodyNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(bodyNP.node())

        visNP.reparentTo(bodyNP)

        shapex = BulletBoxShape(5)
        bodyx = BulletRigidBodyNode('Egg')
        bodyNPx = base.render.attachNewNode(bodyx)
        bodyNPx.setPos(0, 0, 3)
        bodyNPx.node().setMass(100.0)
        bodyNPx.node().addShape(shapex)
        self.world.attachRigidBody(bodyNPx.node())
        # visNP.reparentTo(bodyNPx)

        # Player
        self.players = []
        self.myId = -1
        self.speed = Vec3(0, 0, 0)
        self.walk_speed = 2.5

        # Camera
        base.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        base.win.requestProperties(props)

        # SkySphere
        Sky()

        self.initCam()
Ejemplo n.º 20
0
def get_bullet_shape(geom_node):
    shape = BulletTriangleMesh()
    for i in range(geom_node.getNumGeoms()):
        geom = geom_node.getGeom(i)
        # state = geom_node.getGeomState(i)
        shape.addGeom(geom)
    shape = BulletTriangleMeshShape(shape, True)
    return shape
Ejemplo n.º 21
0
 def egg_to_BulletTriangleMeshShape(self, modelnp):
     mesh = BulletTriangleMesh()
     for collisionNP in modelnp.findAllMatches('**/+CollisionNode'):
         collisionNode = collisionNP.node()
         for collisionPolygon in collisionNode.getSolids():
             tri_points = collisionPolygon.getPoints()
             mesh.addTriangle(tri_points[0], tri_points[1], tri_points[2])
     shape = BulletTriangleMeshShape(mesh, dynamic=False)
     return shape
Ejemplo n.º 22
0
def genBulletCDMesh(objcm, basenodepath=None, name='autogen'):
    """
    generate the collision mesh of a nodepath using nodepath
    this function suppose the nodepath has multiple models with many geomnodes

    use genCollisionMeshMultiNp instead of genCollisionMeshNp for generality

    :param nodepath: the panda3d nodepath of the object
    :param basenodepath: the nodepath to compute relative transform, identity if none
    :param name: the name of the rigidbody
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    gndcollection = objcm.objnp.findAllMatches("+GeomNode")
    geombullnode = BulletRigidBodyNode(name)
    for gnd in gndcollection:
        geom = copy.deepcopy(gnd.node().getGeom(0))
        # vdata = geom.modifyVertexData()
        # vertrewritter = GeomVertexRewriter(vdata, 'vertex')
        # while not vertrewritter.isAtEnd():
        #     v = vertrewritter.getData3f()
        #     vertrewritter.setData3f(v[0]-objcm.com[0], v[1]-objcm.com[1], v[2]-objcm.com[2])
        geomtf = gnd.getTransform(base.render)
        if basenodepath is not None:
            geomtf = gnd.getTransform(basenodepath)
        geombullmesh = BulletTriangleMesh()
        geombullmesh.addGeom(geom)
        bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
        bullettmshape.setMargin(-2)
        geombullnode.addShape(bullettmshape, geomtf)
        # rotmatpd4 = objcm.getMat(base.render)
        # geombullnode.addShape(bullettmshape,
        #                      TransformState.makeMat(rotmatpd4).
        #                      setPos(rotmatpd4.xformPoint(Vec3(objcm.com[0], objcm.com[1], objcm.com[2]))))
        from panda3d.core import Mat3, Mat4
        # geombullnode.setTransform(TransformState.makeMat(Mat4(Mat3.identMat(), rotmatpd4.xformPoint(Vec3(objcm.com[0], objcm.com[1], objcm.com[2])))))
        # print(objcm.com)
        # print(geomtf.getMat())
        # geombullnode.setTransform(TransformState.makeMat(geomtf.getMat()).setPos(geomtf.getMat().xformPoint(Vec3(objcm.com[0], objcm.com[1], objcm.com[2]))))
    return geombullnode
Ejemplo n.º 23
0
def bullet_shape_from(source, dynamic=False):
    mesh = BulletTriangleMesh()

    for geom_node in source.findAllMatches('**/+GeomNode'):
        gn = geom_node.node()
        ts = gn.getTransform()
        for geom in gn.getGeoms():
            mesh.addGeom(geom, True, ts)

    return BulletTriangleMeshShape(mesh, dynamic=dynamic)
  def _createBulletShape_(self,np, apply_scale = True, apply_transform = True):
    """
    @brief Creates a BulletTriangleMeshShape from the geometries in the model node.  The passed
    node path must point to a GeomNode type.  The Geom objects are then added to a 
    BulletTriangleMesh object which is then used to initialize the Shape.  Optionally, 
    the node's transform and scaled can be baked into the Geometries (recommended 
    according to the Panda3D guide https://www.panda3d.org/manual/index.php/Bullet_FAQ).
    If you apply the scale and transform make sure not to apply them again to the shape or
    the bullet node that contains the shape as it'll compound the effect.
    @warning: If the underlying GeomNode contains multiple geometries each with a different
    transform and scale then it's best to set apply_scale and apply_transform to True.
    @param np: The nodepath containing the GeomNode
    @param apply_scale: Boolean that allows choosing whether or not to apply the nodepath's scale to the geometries
    @param apply_transform: Boolean that indicates whether or not to apply the nodepath's trasform to the geometries.
    @return:  A BulletTriangleMeshShape object containing the node's geometries
    """
    
    geom_node = np.node()
    if type(geom_node) is not GeomNode:
      logging.error("Node %s is not a GeomNode node type"%(np.getName()))
      return None
    
    bullet_mesh = BulletTriangleMesh()
        
    # Assembling transform
    tr = TransformState.makeIdentity()
    geom_scale = np.getScale()
    if apply_transform:
      tr = tr.setPos(np.getPos())
      tr = tr.setQuat(np.getQuat())
      sc = LPoint3(1)
      tr = tr.setScale(sc)
    if apply_scale: # baking scale into geometry data
      tr = tr.setScale(geom_scale)    

    for geom in geom_node.getGeoms():      
      bullet_mesh.addGeom(geom,True,tr)
    
    bullet_shape = BulletTriangleMeshShape(bullet_mesh,False,True,True)    
    bullet_shape.setMargin(GameObject.DEFAULT_COLLISION_MARGIN)
    
    return bullet_shape
Ejemplo n.º 25
0
def genBullectCDMeshFromGeom(geom, name='autogen'):
    """
    generate the collision mesh of a nodepath using geom

    :param geom: the panda3d geom of the object
    :param basenodepath: the nodepath to compute relative transform
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    geomtf = TransformState.makeIdentity()
    geombullmesh = BulletTriangleMesh()
    geombullmesh.addGeom(geom)
    geombullnode = BulletRigidBodyNode(name)
    bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
    bullettmshape.setMargin(0)
    geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 26
0
def genCollisionMeshGeom(geom, name='autogen'):
    """
    generate the collision mesh of a nodepath using geom

    :param geom: the panda3d geom of the object
    :param basenodepath: the nodepath to compute relative transform
    :return: bulletrigidbody

    author: weiwei
    date: 20161212, tsukuba
    """

    geomtf = TransformState.makeIdentity()
    geombullmesh = BulletTriangleMesh()
    geombullmesh.addGeom(geom)
    geombullnode = BulletRigidBodyNode(name)
    bullettmshape = BulletTriangleMeshShape(geombullmesh, dynamic=True)
    bullettmshape.setMargin(0)
    geombullnode.addShape(bullettmshape, geomtf)
    return geombullnode
Ejemplo n.º 27
0
def build_bullet_from_model(modelNP):
    body = BulletRigidBodyNode('...')
    for geomNP in modelNP.findAllMatches('**/+GeomNode'):
        geomNode = geomNP.node()
        ts = geomNode.getTransform()
        for geom in geomNode.getGeoms():
            mesh = BulletTriangleMesh()
            mesh.addGeom(geom)

            shape = BulletTriangleMeshShape(mesh, dynamic=False)
            body.addShape(shape, ts)
    return body
Ejemplo n.º 28
0
        def setup_world(self):
            self.world_node = self.render.attachNewNode('World')
            self.world.setGravity(Vec3(0, 0, -9.81))

            # Landscape
            model = self.loader.loadModel("mesh/models/landscape/landscape")
            model.reparentTo(self.render)
            model.setScale(100)
            model.flatten_light()
            geom_nodes = model.findAllMatches('**/+GeomNode')
            geom_node = geom_nodes.getPath(0).node()
            geom_mesh = geom_node.getGeom(0)
            mesh = BulletTriangleMesh()
            mesh.add_geom(geom_mesh)
            ground_shape = BulletTriangleMeshShape(mesh, dynamic=False)

            ground_node = self.world_node.attachNewNode(
                BulletRigidBodyNode('Ground'))
            ground_node.node().addShape(ground_shape)
            '''
            if self.debug_mode:
                debug_node_path = self.world_node.attachNewNode(BulletDebugNode('Debug'))
                debug_node_path.show()
                debug_node_path.node().showNormals(True)
                self.world.setDebugNode(debug_node_path.node())
            '''
            self.debug_node_path = self.world_node.attachNewNode(
                BulletDebugNode('Debug'))
            self.debug_node_path.hide()
            self.world.setDebugNode(self.debug_node_path.node())

            ground_node.setPos(0, 0, 0)
            ground_node.setCollideMask(BitMask32.allOn())

            self.world.attachRigidBody(ground_node.node())

            # Character
            player = Player()

            # Other models
            path = 'mesh/models/bullet/pyramid'
            self.add_model(path, pos_x=50, pos_y=15, pos_z=370, scale=5)
            self.add_model(path, pos_x=30, pos_y=15, pos_z=370, scale=5)
            self.add_model(path, pos_x=70, pos_y=15, pos_z=390, scale=5)
            self.add_model(path, pos_x=50, pos_y=40, pos_z=360, scale=5)

            path = 'mesh/models/bullet/ball'
            self.add_model(path, pos_x=0, pos_y=15, pos_z=400, scale=8)
            self.add_model(path, pos_x=30, pos_y=40, pos_z=450, scale=8)

            taskMgr.add(self.update, 'updateWorld')
Ejemplo n.º 29
0
    def __init__(
        self, world:BulletWorld, entity:Entity,
        dynamic=False, rotation=[None, None, None]
        ):

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

        shape = BulletTriangleMeshShape(mesh, dynamic=dynamic)

        super().__init__(world, entity, shape, 'mesh', rotation)
Ejemplo n.º 30
0
    def update_from_raycast(self, result, method):
        has_hit = result.hasHit()
        if has_hit:
            # if we hit, then first find out which chunk to change
            chunk = result.getNode()

            if 'bullet-(' in chunk.name:
                cell_location = tuple(
                    map(
                        int,
                        chunk.name.replace('bullet-(',
                                           '').rstrip(')').split(',')))
            else:
                return

            # remove block and update chunk data
            self.cells[cell_location]['chunk_data'].edit_block(
                result.getHitPos(), method=method)

            # detach and remove meshes
            self.app.bullet_world.remove(
                self.cells[cell_location]['bullet_mesh'].node())
            self.cells[cell_location]['bullet_mesh'].removeNode()

            for material_id in self.cells[cell_location]['node_path'].keys():
                self.cells[cell_location]['node_path'][material_id].removeNode(
                )

            self.cells[cell_location][
                'bullet_mesh'] = self.app.render.attachNewNode(
                    BulletRigidBodyNode('bullet-' + str(cell_location)))

            for material_id in self.cells[cell_location]['node_path'].keys():
                self.cells[cell_location]['node_path'][
                    material_id] = self.app.render.attachNewNode(
                        self.cells[cell_location]
                        ['chunk_data'].material_nodes[material_id])

            self.cells[cell_location]['node_path'][3].setTransparency(
                True)  # make water transparent

            # re-add the bullet mesh to the bullet node
            self.cells[cell_location]['bullet_mesh'].node().addShape(
                BulletTriangleMeshShape(
                    self.cells[cell_location]['chunk_data'].bullet_mesh,
                    dynamic=False))
            self.app.bullet_world.attach(
                self.cells[cell_location]['bullet_mesh'].node())

            self.texture_materials(cell_location)
Ejemplo n.º 31
0
def makeBulletCollFromPandaColl(rootNode, exclusions=[]):
    """
    Replaces all of the CollisionNodes underneath `rootNode` with static
    BulletRigidBodyNodes/GhostNodes which contain the shapes from the CollisionNodes.

    Applies the same transform as the node it is replacing, goes underneath same parent,
    has same name, has same collide mask.

    If the Panda CollisionNode is intangible, a BulletGhostNode is created.
    Else, a BulletRigidBodyNode is created.
    """

    # First combine any redundant CollisionNodes.
    optimizePhys(rootNode)

    for pCollNp in rootNode.findAllMatches("**"):
        if pCollNp.getName() in exclusions:
            continue
        if pCollNp.node().getType() != CollisionNode.getClassType():
            continue
        if pCollNp.node().getNumSolids() == 0:
            continue

        mask = pCollNp.node().getIntoCollideMask()
        group = CIGlobals.WallGroup
        if mask == CIGlobals.FloorBitmask:
            group = CIGlobals.FloorGroup
        elif mask == CIGlobals.EventBitmask:
            group = CIGlobals.LocalAvGroup
        elif mask == CIGlobals.CameraBitmask:
            group = CIGlobals.CameraGroup

        isGhost = not pCollNp.node().getSolid(0).isTangible()
        if isGhost:
            rbnode = BulletGhostNode(pCollNp.getName())
            group = CIGlobals.LocalAvGroup
        else:
            rbnode = BulletRigidBodyNode(pCollNp.getName())
        rbnode.addShapesFromCollisionSolids(pCollNp.node())
        for shape in rbnode.getShapes():
            if shape.isOfType(BulletTriangleMeshShape.getClassType()):
                shape.setMargin(0.1)
        rbnode.setKinematic(True)
        rbnodeNp = NodePath(rbnode)
        rbnodeNp.reparentTo(pCollNp.getParent())
        rbnodeNp.setTransform(pCollNp.getTransform())
        rbnodeNp.setCollideMask(group)
        # Now that we're using bullet collisions, we don't need the panda collisions anymore.
        pCollNp.removeNode()
Ejemplo n.º 32
0
def modelToShape2(model):
    """

    :type model: str
    :return: panda3d.bullet.BulletTriangleMeshShape
    """
    np = loader.loadModel(model)  #####componer luego
    mesh = BulletTriangleMesh()
    for geomNP in np.findAllMatches('**/+GeomNode'):
        geomNode = geomNP.node()
        ts = geomNP.getTransform(np)
        for geom in geomNode.getGeoms():
            mesh.addGeom(geom, ts)
    shape = BulletTriangleMeshShape(mesh, False)
    return shape
Ejemplo n.º 33
0
def modelToShape(model, dynamic=False):
    """

    :type model: panda3d.core.NodePath
    :type dynamic: bool
    :return: tuple(panda3d.bullet.BulletTriangleMeshShape, transform)
    """
    geomnodes = model.findAllMatches('**/+GeomNode')
    transform = model.getTransform()
    gn = geomnodes.getPath(0).node()
    geom = gn.getGeom(0)
    mesh = BulletTriangleMesh()
    mesh.addGeom(geom)
    shape = BulletTriangleMeshShape(mesh, dynamic)
    return shape, transform
Ejemplo n.º 34
0
    def createElement(self, name, type, start, end=None):
        if type == "cell":
            model_file = "sphere.dae"
        elif type == "bit":
            model_file = "box.dae"
        elif type == "segment" or type == "synapse":
            model_file = "cylinder.dae"

        # Create the rigid body
        body_node = BulletRigidBodyNode(name)
        body_node.setDeactivationEnabled(False)
        body_np = self.render.attachNewNode(body_node)
        body_np.setName(name)

        if type == "segment" or type == "synapse":
            # Calculate the linear distance between the start and the end position of the segment.
            length = (Point3(start) - Point3(end)).length()

            body_np.setPos(start)
            body_np.lookAt(end)
            body_np.setScale(1, length / 2, 1)
        else:
            body_np.setPos(start)

        # Load the 3d model file using the asset folder relative path and attach the geom node to rigid body
        object_np = self.loader.loadModel(
            Filename.from_os_specific(
                os.path.join(REPO_DIR, "models", model_file)))
        object_np.reparentTo(body_np)
        object_np.setPosHpr((0, 0, 0), (0, 0, 0))
        object_np.setName(name + "_geom")
        object_np.setTexGen(TextureStage.getDefault(),
                            TexGenAttrib.MWorldPosition)

        # Apply any transforms from modelling sotware to gain performance
        object_np.flattenStrong()

        # Create the shape used for collisions
        geom_nodes = object_np.findAllMatches("**/+GeomNode")
        mesh = BulletTriangleMesh()
        for geom in geom_nodes[0].node().getGeoms():
            mesh.addGeom(geom)
        shape = BulletTriangleMeshShape(mesh, dynamic=True)
        body_node.addShape(shape)

        self.physics_manager.attachRigidBody(body_node)
        return body_np