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)
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)