示例#1
0
    def workOnChunk(self, chunk, visibleSections=None):
        work = 0
        cPos = chunk.chunkPosition

        log.debug("Working on chunk %s sections %s", cPos, visibleSections)
        chunkInfo = self.worldScene.getChunkRenderInfo(cPos)

        chunkInfo.visibleSections = visibleSections  # currently unused

        try:
            chunkUpdate = chunkupdate.ChunkUpdate(self, chunkInfo, chunk)
            for _ in chunkUpdate:
                work += 1
                if (work % SceneUpdateTask.workFactor) == 0:
                    yield

            meshesByRS = collections.defaultdict(list)
            for mesh in chunkUpdate.blockMeshes:
                meshesByRS[mesh.renderstate].append(mesh)

            # Create one ChunkNode for each renderstate group, if needed
            for renderstate in renderstates.allRenderstates:
                groupNode = self.worldScene.getRenderstateGroup(renderstate)
                if groupNode.containsChunkNode(cPos):
                    chunkNode = groupNode.getChunkNode(cPos)
                else:
                    chunkNode = ChunkNode(cPos)
                    groupNode.addChunkNode(chunkNode)

                meshes = meshesByRS[renderstate]
                if len(meshes):
                    meshes = sorted(meshes, key=lambda m: m.layer)
                    log.debug("Updating chunk node for renderstate %s, mesh count %d", renderstate, len(meshes))
                    for layer, layerMeshes in itertools.groupby(meshes, lambda m: m.layer):
                        if layer not in self.worldScene.visibleLayers:
                            continue
                        layerMeshes = list(layerMeshes)

                        # Check if the mesh was re-rendered and remove the old mesh
                        meshTypes = set(type(m) for m in layerMeshes)
                        for arrayNode in list(chunkNode.children):
                            if arrayNode.meshType in meshTypes:
                                chunkNode.removeChild(arrayNode)

                        # Add the scene nodes created by each mesh builder
                        for mesh in layerMeshes:
                            if mesh.sceneNode:
                                mesh.sceneNode.layerName = layer
                                mesh.sceneNode.meshType = type(mesh)
                                chunkNode.addChild(mesh.sceneNode)

                        chunkInfo.renderedLayers.add(layer)

                if chunkNode.childCount() == 0:
                    groupNode.discardChunkNode(*cPos)

        except Exception as e:
            logging.exception(u"Rendering chunk %s failed: %r", cPos, e)
示例#2
0
    def workOnChunk(self, chunk, visibleSections=None):
        work = 0
        cPos = chunk.chunkPosition

        chunkInfo = self.worldScene.getChunkRenderInfo(cPos)

        chunkInfo.visibleSections = visibleSections
        try:
            chunkUpdate = chunkupdate.ChunkUpdate(self, chunkInfo, chunk)
            for _ in chunkUpdate:
                work += 1
                if (work % SceneUpdateTask.workFactor) == 0:
                    yield

            chunkInfo.invalidLayers = set()
            meshesByRS = collections.defaultdict(list)
            for mesh in chunkUpdate.blockMeshes:
                meshesByRS[mesh.renderstate].append(mesh)

            for renderstate in renderstates.allRenderstates:
                groupNode = self.worldScene.getRenderstateGroup(renderstate)
                meshes = meshesByRS[renderstate]
                if len(meshes):
                    arrays = sum([mesh.vertexArrays for mesh in meshes], [])
                    if len(arrays):
                        chunkNode = ChunkNode(cPos)
                        groupNode.addChunkNode(chunkNode)
                        node = scenegraph.VertexNode(arrays)
                        chunkNode.addChild(node)
                    else:
                        groupNode.discardChunkNode(*cPos)

                        # Need a way to signal WorldScene that this chunk didn't need updating in this renderstate,
                        # but it should keep the old vertex arrays for the state.
                        # Alternately, signal WorldScene that the chunk did update for the renderstate and no
                        # vertex arrays resulted. Return a mesh with zero length vertexArrays
                        #else:
                        #    groupNode.discardChunkNode(*cPos)

        except Exception as e:
            logging.exception(u"Rendering chunk %s failed: %r", cPos, e)