예제 #1
0
    def loadLevelData(self, inputData):
        """
        processes the level asloaded from the file. it seperates the input data until the data for each tile is ready.
        """
        rigidNode = RigidBodyCombiner("LevelNode")
        levelNode = NodePath(rigidNode)

        #deleting whitespaces and seperating the content for each tile into a list.
        inputData = inputData.replace("\n", "").strip().replace(
            " ", "").lstrip("<").rstrip(">").split("><")

        for tileData in inputData:
            tile = self.loadTile(tileData)
            if tile != None:
                tile.reparentTo(levelNode)
                tile.setPos(self.getPosFromTile(tile))
                tile.setZ(
                    tile, 0.00000001
                )  # workaround for rigid body combiner so it does not assume the (0,0) tile as static
            else:
                print("ERROR, could not load tile with data: ", tileData)
        rigidNode.collect()
        inode = rigidNode.getInternalScene().node(
        )  # workaround for a boundingvolume issue with rigidbodycombiner
        inode.setBounds(OmniBoundingVolume())  # still workaround
        inode.setFinal(True)  # still workaround
        return levelNode
예제 #2
0
 def loadLevelData(self,inputData):
     """
     processes the level asloaded from the file. it seperates the input data until the data for each tile is ready.
     each tile data will be passed to loadTile().
     it returns a rigidNode optimized nodepath.
     """
     rigidNode = RigidBodyCombiner("LevelNode")
     levelNode = NodePath(rigidNode)
     #rigidNode.reparentTo(levelNode)
     #this looks heavy but all it does is deleting whitespaces and seperating the content for each tile into a list.
     inputData = inputData.replace("\n","").strip().replace(" ","").lstrip("<").rstrip(">").split("><")
     
     for tileData in inputData:
         tile = self.loadTile(tileData)
         if tile != None:
             tile.reparentTo(levelNode)
             tile.setPos( self.getPosFromTile(tile) )
             tile.setZ(tile,0.00000001) #workaround for rigid body combiner so it does not assume the (0,0) tile as static
         else:
             print("ERROR, could not load tile with data: ",tileData)
     rigidNode.collect()
     inode = rigidNode.getInternalScene().node() #workaround for a boundingvolume issue with rigidbodycombiner
     inode.setBounds(OmniBoundingVolume())  #still workaround
     inode.setFinal(True) #still workaround
     #levelNode.analyze()  
     return levelNode 
예제 #3
0
    def __init__(self):
        """Setup this world manager."""
        Logger.info("Initializing world manager...")

        self.terrain = None
        self.portals = []
        self.gates = []
        self.objects = []
        self.scenery = RigidBodyCombiner("scenery")
        self.scenery_np = render.attach_new_node(self.scenery)
        self.is_dirty = True

        base.task_mgr.add(self.run_logic)

        Logger.info("World manager initialized.")
예제 #4
0
    def _render_chunk(self, chunk: Chunk):
        # Create the chunk hierarchy in the scene graph.
        c_new_chunk = chunk.chunk_center
        chunk_path = self.path.attachNewNode(
            "chunk.%s.%s.%s" %
            (c_new_chunk[0], c_new_chunk[1], c_new_chunk[2]))
        chunk_model = chunk_path.attachNewNode('model')
        rbc = RigidBodyCombiner('chunk')
        rbcnp = NodePath(rbc)
        rbcnp.reparentTo(chunk_model)

        # Offset the matrix from the origin to the center of the new relative chunk.
        relative_spiral_matrix = np.array(self.cubic_spiral)
        spiral_matrix = relative_spiral_matrix + np.repeat(
            [c_new_chunk], repeats=relative_spiral_matrix.shape[0], axis=0)

        for ii, c_sp in enumerate(spiral_matrix):
            # TODO: remove the terrain generation and put in a generator class.

            center = (256, 256)
            o_x, o_y = cube_to_offset(c_sp)
            current_noise = self.terrain_noise[center[0] + o_x][center[1] +
                                                                o_y]
            # TODO: noise times maximum height. work this out with the noise generation to make the jumps not drastic
            elevation = current_noise * 20
            terrain = None
            if -1.0 <= current_noise <= -0.5:
                terrain = WaterTerrain(elevation=elevation)
            elif -0.9 <= current_noise <= 0.6:
                percent = (current_noise + 0.9) / 1.5
                modulated_color = 0, 1 * percent, 0
                terrain = GrassTerrain(elevation=elevation,
                                       color=modulated_color)
            else:
                # Cliff are steeper than most terrain.
                elevation = elevation * 1.5
                terrain = CliffTerrain(elevation=elevation)

            c_rsp = relative_spiral_matrix[ii]
            loc = self.data_model.at_chunked(chunk.chunk_id, c_rsp)
            loc.major_terrain = terrain

            hex_loc = HexLocationComponent(chunk_path, loc, c_sp,
                                           self._hex_model)
            hex_loc.render(rbcnp, chunk_model)

        rbc.collect()
        return chunk_path
예제 #5
0
    def _create_in_world(self):
        """
        Create NodePath and Geom node to perform both collision detection and render
        """
        self.lane_line_node_path = NodePath(
            RigidBodyCombiner(self._block_name + "_lane_line"))
        self.sidewalk_node_path = NodePath(
            RigidBodyCombiner(self._block_name + "_sidewalk"))
        self.lane_node_path = NodePath(
            RigidBodyCombiner(self._block_name + "_lane"))
        self.lane_vis_node_path = NodePath(
            RigidBodyCombiner(self._block_name + "_lane_vis"))
        graph = self.block_network.graph
        for _from, to_dict in graph.items():
            for _to, lanes in to_dict.items():
                self._add_lane_surface(_from, _to, lanes)
                for _id, l in enumerate(lanes):
                    line_color = l.line_color
                    self._add_lane(l, _id, line_color)
        self.lane_line_node_path.flattenStrong()
        self.lane_line_node_path.node().collect()

        self.sidewalk_node_path.flattenStrong()
        self.sidewalk_node_path.node().collect()
        self.sidewalk_node_path.hide(CamMask.ScreenshotCam)

        # only bodies reparent to this node
        self.lane_node_path.flattenStrong()
        self.lane_node_path.node().collect()

        self.lane_vis_node_path.flattenStrong()
        self.lane_vis_node_path.node().collect()
        self.lane_vis_node_path.hide(CamMask.DepthCam | CamMask.ScreenshotCam)

        self.node_path = NodePath(self._block_name)
        self.node_path.hide(CamMask.Shadow)

        self.sidewalk_node_path.reparentTo(self.node_path)
        self.lane_line_node_path.reparentTo(self.node_path)
        self.lane_node_path.reparentTo(self.node_path)
        self.lane_vis_node_path.reparentTo(self.node_path)

        self.bounding_box = self.block_network.get_bounding_box()
 def __init__(self, world, spawnNP):
     self.running = False
     self.world = world
     rbc = RigidBodyCombiner("rbc")
     self.rbcnp = NodePath(rbc)
     self.rbcnp.reparentTo(render)
     self.NrObjectToDrop = 10
     self.spawnNP = spawnNP
     self.objects = []
     self.model = loader.loadModel('models/box.egg')
     self.model.flattenLight()
     self.shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
예제 #7
0
def setupPandaApp(mesh):
    scene_members = getSceneMembers(mesh)

    p3dApp = ShowBase()
    nodePath = getBaseNodePath(render)

    rotateNode = GeomNode("rotater")
    rotatePath = nodePath.attachNewNode(rotateNode)
    matrix = numpy.identity(4)
    if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
        r = collada.scene.RotateTransform(0, 1, 0, 90)
        matrix = r.matrix
    elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
        r = collada.scene.RotateTransform(1, 0, 0, 90)
        matrix = r.matrix
    rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))

    rbc = RigidBodyCombiner('combiner')
    rbcPath = rotatePath.attachNewNode(rbc)

    for geom, renderstate, mat4 in scene_members:
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        geomPath = rbcPath.attachNewNode(node)
        geomPath.setMat(mat4)

    rbc.collect()

    ensureCameraAt(nodePath, base.camera)
    base.disableMouse()
    attachLights(render)
    render.setShaderAuto()
    render.setTransparency(TransparencyAttrib.MDual, 1)

    return p3dApp
예제 #8
0
def setupPandaApp(mesh):
    scene_members = getSceneMembers(mesh)
    
    p3dApp = ShowBase()
    nodePath = getBaseNodePath(render)
    
    rotateNode = GeomNode("rotater")
    rotatePath = nodePath.attachNewNode(rotateNode)
    matrix = numpy.identity(4)
    if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
        r = collada.scene.RotateTransform(0,1,0,90)
        matrix = r.matrix
    elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
        r = collada.scene.RotateTransform(1,0,0,90)
        matrix = r.matrix
    rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))
    
    rbc = RigidBodyCombiner('combiner')
    rbcPath = rotatePath.attachNewNode(rbc)
    
    for geom, renderstate, mat4 in scene_members:
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        geomPath = rbcPath.attachNewNode(node)
        geomPath.setMat(mat4)
        
    rbc.collect()
    
    ensureCameraAt(nodePath, base.camera)
    base.disableMouse()
    attachLights(render)
    render.setShaderAuto()
    render.setTransparency(TransparencyAttrib.MDual, 1)

    return p3dApp
예제 #9
0
from direct.directbase.DirectStart import *
from panda3d.core import RigidBodyCombiner, NodePath, Vec3

import random

rbc = RigidBodyCombiner("rbc")
rbcnp = NodePath(rbc)
rbcnp.reparentTo(render)

for i in range(200):

    pos = Vec3(random.uniform(-100, 100),
               random.uniform(-100, 100),
               random.uniform(-100, 100))

    f = loader.loadModel("box.egg")
    f.setPos(pos)
    f.reparentTo(rbcnp)

rbc.collect()
run()
예제 #10
0
class WorldManager(object):
    """A world manager for heightmapped worlds stored as XML."""
    def __init__(self):
        """Setup this world manager."""
        Logger.info("Initializing world manager...")

        self.terrain = None
        self.portals = []
        self.gates = []
        self.objects = []
        self.scenery = RigidBodyCombiner("scenery")
        self.scenery_np = render.attach_new_node(self.scenery)
        self.is_dirty = True

        base.task_mgr.add(self.run_logic)

        Logger.info("World manager initialized.")

    def load_map(self, map):
        """Load a map."""
        #Unload the current map first
        self.unload_map()

        #Locate the XML file for the map
        Logger.info("Loading map '{}'...".format(map))
        map_file = os.path.join(map, os.path.basename(map) + ".xml")

        if not os.path.exists(map_file):
            Logger.error("Failed to load map file '{}'.".format(map_file))
            return False

        #Load the map XML file
        xml = etree.parse(map_file)
        root = xml.getroot()

        for child in root:
            #Terrain?
            if child.tag == "terrain":
                #Validate terrain
                if not ("size" in child.attrib and "spawnpos" in child.attrib
                        and "heightmap" in child.attrib):
                    Logger.error(
                        "Terrain section must define 'size', 'spawnpos', and 'heightmap'."
                    )
                    return False

                #Load terrain
                self.size = parse_vec(child.attrib["size"], 3)
                self.spawnpos = parse_vec(child.attrib["spawnpos"], 2)
                heightmap = os.path.join(map, child.attrib["heightmap"])

                self.terrain = GeoMipTerrain("Terrain")
                self.terrain.set_block_size(64)
                self.terrain.set_bruteforce(True)

                if not self.terrain.set_heightfield(heightmap):
                    Logger.error("Failed to load heightmap for terrain.")
                    self.terrain = None
                    return False

                self.terrain_np = self.terrain.get_root()
                self.terrain_np.set_scale(self.size[0] / 512,
                                          self.size[1] / 512, self.size[2])
                tex = loader.load_texture(
                    "./data/textures/terrain/grass_tex2.png")
                self.terrain_np.set_texture(tex)
                self.terrain_np.set_tex_scale(TextureStage.get_default(),
                                              self.size[0] / 512,
                                              self.size[1] / 512)
                tex.set_wrap_u(Texture.WM_repeat)
                tex.set_wrap_v(Texture.WM_repeat)
                self.terrain_np.reparent_to(render)
                self.terrain.generate()

                base.camera.set_pos(self.size[0] / 2, self.size[1] / 2,
                                    self.size[2])

            #Portal?
            elif child.tag == "portal":
                #Validate portal
                if not ("pos" in child.attrib and "destmap" in child.attrib):
                    Logger.warning("Portal must define 'pos' and 'destmap'.")
                    continue

                #Load portal
                pos = parse_vec(child.attrib["pos"], 3)
                radius = parse_float(
                    child.attrib["radius"]) if "radius" in child.attrib else 1
                destmap = child.attrib["destmap"]
                self.add_portal(pos, radius, destmap)

            #Gate?
            elif child.tag == "gate":
                #Validate gate
                if not ("pos" in child.attrib and "destmap" in child.attrib
                        and "destvec" in child.attrib):
                    Logger.warning(
                        "Gate must define 'pos', 'destmap', and 'destvec'.")
                    continue

                #Load gate
                pos = parse_vec(child.attrib["pos"], 3)
                destmap = child.attrib["destmap"]
                destvec = parse_vec(child.attrib["destvec"], 3)
                material = child.attrib[
                    "material"] if "material" in child.attrib else ""
                self.add_gate(pos, destmap, destvec, material)

            #Object?
            elif child.tag == "object":
                #Validate object
                if not ("mesh" in child.attrib and "pos" in child.attrib):
                    Logger.warning("Object must define 'mesh' and 'pos'.")
                    continue

                #Load object
                mesh = child.attrib["mesh"]
                pos = parse_vec(child.attrib["pos"], 3)
                rot = parse_vec(child.attrib["rot"],
                                3) if "rot" in child.attrib else [0, 0, 0]
                scale = parse_vec(child.attrib["scale"],
                                  3) if "scale" in child.attrib else [1, 1, 1]
                material = child.attrib[
                    "material"] if "material" in child.attrib else ""
                sound = child.attrib["sound"] if "sound" in child.attrib else ""
                self.add_object(mesh, pos, rot, scale, material, sound)

            #Object Group?
            elif child.tag == "objectgroup":
                #Validate object group
                if not ("mesh" in child.attrib):
                    Logger.warning("Object group must define 'mesh'.")
                    continue

                #Load object group
                mesh = child.attrib["mesh"]
                material = child.attrib[
                    "material"] if "material" in child.attrib else ""
                self.load_object_group(child, mesh, material)

            #Unknown?
            else:
                Logger.warning(
                    "Unknown tag '{}' encountered in map '{}'.".format(
                        child.tag, map))

        #Map loaded
        Logger.info("Map '{}' loaded.".format(map))
        return True

    def unload_map(self):
        """Unload the current map."""
        if self.terrain is not None:
            self.terrain.get_root().remove_node()

        self.terrain = None
        self.size = [0, 0]
        self.spawnpos = [0, 0, 0]

        while len(self.portals) > 0:
            self.del_portal(self.portals[-1])

        while len(self.gates) > 0:
            self.del_gate(self.gates[-1])

        while len(self.objects) > 0:
            self.del_object(self.objects[-1])

    def load_object_group(self, group, mesh, material):
        """Load a group of objects."""
        for object in group:
            #Validate object
            if not ("pos" in object.attrib):
                Logger.warning("Group object must define 'pos'.")
                continue

            #Load object
            pos = parse_vec(object.attrib["pos"], 2)
            rot = parse_vec(object.attrib["rot"],
                            1) if "rot" in object.attrib else [0, 0, 0]
            scale = parse_vec(object.attrib["scale"],
                              1) if "scale" in object.attrib else [1, 1, 1]
            self.add_object(mesh, pos, rot, scale, material, "")

    def add_portal(self, pos, radius, dest):
        """Add a portal to this world."""
        self.portals.append(Portal(pos, radius, dest))
        self.is_dirty = True
        Logger.info("Added portal: pos = {}, radius = {}, dest = '{}'".format(
            pos, radius, dest))

    def del_portal(self, portal):
        """Remove a portal from this world."""
        self.portals.remove(portal)
        self.is_dirty = True
        Logger.info("Removed portal {}".format(portal))

    def add_gate(self, pos, dest, destvec, material):
        """Add a gate to this world."""
        self.gates.append(Gate(pos, dest, destvec, material))
        self.is_dirty = True
        Logger.info(
            "Added gate: pos = {}, dest = '{}', destvec = {}, material = '{}'".
            format(pos, dest, destvec, material))

    def del_gate(self, gate):
        """Remove a gate from this world."""
        self.gates.remove(gate)
        self.is_dirty = True
        Logger.info("Removed gate {}".format(gate))

    def add_object(self, mesh, pos, rot, scale, material, sound):
        """Add an object to this world."""
        #Handle 2 coordinate position
        if len(pos) == 2:
            pos = [pos[0], pos[1], self.get_terrain_height(pos)]

        #Handle single coordinate rotation
        if len(rot) == 1:
            rot = [rot[0], 0, 0]

        #Handle single or double coordinate scale
        if len(scale) == 1:
            scale = [scale[0], scale[0], scale[0]]

        elif len(scale) == 2:
            scale = [scale[0], scale[1], 1]

        #Add the object
        self.objects.append(Object(mesh, pos, rot, scale, material, sound))
        self.is_dirty = True
        Logger.info(
            "Added object: mesh = '{}', pos = {}, rot = {}, scale = {}, material = '{}', sound = '{}'"
            .format(mesh, pos, rot, scale, material, sound))

    def del_object(self, object):
        """Delete an object from this world."""
        self.objects.remove(object)
        self.is_dirty = True
        Logger.info("Removed object {}".format(object))

    def get_terrain_height(self, pos):
        """Get the height of the terrain at the given point."""
        #Is the position a list of 2 elements?
        if isinstance(pos, list) and len(pos) == 2:
            return self.terrain.get_elevation(
                pos[0] / (self.size[0] / 512), pos[1] /
                (self.size[1] / 512)) * self.size[2]

        #Assume it is a point object
        else:
            return self.terrain.get_elevation(
                pos[0] / (self.size[0] / 512), pos[1] /
                (self.size[1] / 512)) * self.size[2]

    def run_logic(self, task):
        """Run the logic for this world manager."""
        #Optimize the scenery
        if self.is_dirty:
            self.scenery.collect()
            self.is_dirty = False
            Logger.info("Optimized the scenery.")

        return Task.cont