Example #1
0
    def __init__(self):
        """

        :return:
        :rtype:
        """
        super(SelectionScene, self).__init__()
        self.cullNode = RenderstateNode(CullFaceRenderNode)
        self.blendNode = RenderstateNode(_RenderstateAlphaBlendNode)
        self.groupNode = ChunkGroupNode()
        self.cullNode.addChild(self.blendNode)
        self.blendNode.addChild(self.groupNode)
        self.addChild(self.cullNode)
        self.loadTimer = QtCore.QTimer(timeout=self.loadMore)
        self.loadTimer.setInterval(0)
        self.loadTimer.start()
        self.renderSelection = None
Example #2
0
    def __init__(self):
        """

        :return:
        :rtype:
        """
        super(SelectionScene, self).__init__()
        self.cullNode = RenderstateNode(CullFaceRenderNode)
        self.blendNode = RenderstateNode(_RenderstateAlphaBlendNode)
        self.groupNode = ChunkGroupNode()
        self.cullNode.addChild(self.blendNode)
        self.blendNode.addChild(self.groupNode)
        self.addChild(self.cullNode)
        self.loadTimer = QtCore.QTimer(timeout=self.loadMore)
        self.loadTimer.setInterval(0)
        self.loadTimer.start()
        self.renderSelection = None
Example #3
0
class SelectionScene(scenegraph.Node):
    def __init__(self):
        """

        :return:
        :rtype:
        """
        super(SelectionScene, self).__init__()
        self.cullNode = RenderstateNode(CullFaceRenderNode)
        self.blendNode = RenderstateNode(_RenderstateAlphaBlendNode)
        self.groupNode = ChunkGroupNode()
        self.cullNode.addChild(self.blendNode)
        self.blendNode.addChild(self.groupNode)
        self.addChild(self.cullNode)
        self.loadTimer = QtCore.QTimer(timeout=self.loadMore)
        self.loadTimer.setInterval(0)
        self.loadTimer.start()
        self.renderSelection = None

    def __del__(self):
        self.loadTimer.stop()

    _selection = None
    @property
    def selection(self):
        return self._selection

    @selection.setter
    def selection(self, selection):
        if selection != self._selection:
            self._selection = selection
            self.updateSelection()

    _dimension = None
    @property
    def dimension(self):
        return self._dimension

    @dimension.setter
    def dimension(self, value):
        if value != self._dimension:
            self._dimension = value
            self.updateSelection()

    @property
    def filled(self):
        return self.cullNode.visible

    @filled.setter
    def filled(self, value):
        self.cullNode.visible = value

    def updateSelection(self):
        if self.dimension is None or self.selection is None:
            return

        selection = self.selection
        self.renderSelection = selection & NonAirMaskSelection(self.dimension, selection)
        self.groupNode.clear()
        self._loader = None
        if selection.chunkCount < 16:
            exhaust(self.loadSections())

            self.loadTimer.setInterval(333)

    _loader = None

    def loadMore(self):
        if self._loader is None:
            self._loader = self.loadSections()
        try:
            self._loader.next()
        except StopIteration:
            self._loader = None

    @profiler.iterator("SelectionScene")
    def loadSections(self):
        selection = self.renderSelection
        if selection is None:
            self.loadTimer.setInterval(333)
            return
        else:
            self.loadTimer.setInterval(0)

        for cx, cz in selection.chunkPositions():
            if self.groupNode.containsChunkNode((cx, cz)):
                continue

            vertexArrays = []
            for cy in selection.sectionPositions(cx, cz):
                box = SectionBox(cx, cy, cz).expand(1)
                mask = selection.box_mask(box)
                if mask is not None:
                    vertexArrays.extend(self.buildSection(mask, cy))
            if len(vertexArrays):
                chunkNode = ChunkNode((cx, cz))
                vertexNode = VertexNode(vertexArrays)
                chunkNode.addChild(vertexNode)
                self.groupNode.addChunkNode(chunkNode)
            yield
        self.loadTimer.setInterval(333)

    def discardChunk(self, cx, cz):
        self.groupNode.discardChunkNode(cx, cz)

    def exposedBlockMasks(self, mask):
        """
        Compare adjacent cells in the 3d mask along all three axes and return one mask for each cardinal direction.
        The returned masks contain the faces of each cell which are exposed in that direction and should be rendered.

        :param mask:
        :type mask: ndarray
        :return:
        :rtype: list[ndarray]
        """
        sy = sz = sx = 16
        exposedY = numpy.zeros((sy+1, sz, sx), dtype=bool)
        exposedZ = numpy.zeros((sy, sz+1, sx), dtype=bool)
        exposedX = numpy.zeros((sy, sz, sx+1), dtype=bool)

        exposedY[:] = mask[1:,   1:-1, 1:-1] != mask[ :-1, 1:-1, 1:-1]
        exposedZ[:] = mask[1:-1, 1:,   1:-1] != mask[1:-1,  :-1, 1:-1]
        exposedX[:] = mask[1:-1, 1:-1, 1:  ] != mask[1:-1, 1:-1,  :-1]

        exposedByFace = [
            exposedX[:, :, 1:],
            exposedX[:, :, :-1],
            exposedY[1:],
            exposedY[:-1],
            exposedZ[:, 1:],
            exposedZ[:, :-1],
        ]

        return exposedByFace

    def buildSection(self, sectionMask, cy):
        vertexArrays = []

        for (face, exposedFaceMask) in enumerate(self.exposedBlockMasks(sectionMask)):
            blockMask = sectionMask[1:-1, 1:-1, 1:-1] & exposedFaceMask

            vertexBuffer = QuadVertexArrayBuffer.fromBlockMask(face, blockMask, False, False)
            if not len(vertexBuffer.vertex):
                continue

            vertexBuffer.rgb[:] = faceShades[face]
            vertexBuffer.alpha[:] = 0x77
            vertexBuffer.vertex[..., 1] += cy << 4
            vertexArrays.append(vertexBuffer)

        return vertexArrays
Example #4
0
class SelectionScene(scenegraph.Node):
    def __init__(self):
        """

        :return:
        :rtype:
        """
        super(SelectionScene, self).__init__()
        self.cullNode = RenderstateNode(CullFaceRenderNode)
        self.blendNode = RenderstateNode(_RenderstateAlphaBlendNode)
        self.groupNode = ChunkGroupNode()
        self.cullNode.addChild(self.blendNode)
        self.blendNode.addChild(self.groupNode)
        self.addChild(self.cullNode)
        self.loadTimer = QtCore.QTimer(timeout=self.loadMore)
        self.loadTimer.setInterval(0)
        self.loadTimer.start()
        self.renderSelection = None

    def __del__(self):
        self.loadTimer.stop()

    _selection = None
    @property
    def selection(self):
        return self._selection

    @selection.setter
    def selection(self, selection):
        if selection != self._selection:
            self._selection = selection
            self.updateSelection()

    _dimension = None
    @property
    def dimension(self):
        return self._dimension

    @dimension.setter
    def dimension(self, value):
        if value != self._dimension:
            self._dimension = value
            self.updateSelection()

    @property
    def filled(self):
        return self.cullNode.visible

    @filled.setter
    def filled(self, value):
        self.cullNode.visible = value

    def updateSelection(self):
        if self.dimension is None or self.selection is None:
            return

        selection = self.selection
        self.renderSelection = selection & NonAirMaskSelection(self.dimension, selection)
        self.groupNode.clear()
        self._loader = None
        if selection.chunkCount < 16:
            for _ in self.loadSections():
                pass
            self.loadTimer.setInterval(333)


    _loader = None
    def loadMore(self):
        if self._loader is None:
            self._loader = self.loadSections()
        try:
            self._loader.next()
        except StopIteration:
            self._loader = None

    @profiler.iterator("SelectionScene")
    def loadSections(self):
        selection = self.renderSelection
        if selection is None:
            self.loadTimer.setInterval(333)
            return
        else:
            self.loadTimer.setInterval(0)

        for cx, cz in selection.chunkPositions():
            if self.groupNode.containsChunkNode((cx, cz)):
                continue

            vertexArrays = []
            for cy in selection.sectionPositions(cx, cz):
                box = SectionBox(cx, cy, cz).expand(1)
                mask = selection.box_mask(box)
                if mask is not None:
                    vertexArrays.extend(self.buildSection(mask, cy))
            if len(vertexArrays):
                chunkNode = ChunkNode((cx, cz))
                vertexNode = VertexNode(vertexArrays)
                chunkNode.addChild(vertexNode)
                self.groupNode.addChunkNode(chunkNode)
            yield
        self.loadTimer.setInterval(333)

    def exposedBlockMasks(self, mask):
        """
        Compare adjacent cells in the 3d mask along all three axes and return one mask for each cardinal direction.
        The returned masks contain the faces of each cell which are exposed in that direction and should be rendered.

        :param mask:
        :type mask: ndarray
        :return:
        :rtype: list[ndarray]
        """
        sy = sz = sx = 16
        exposedY = numpy.zeros((sy+1, sz, sx), dtype=bool)
        exposedZ = numpy.zeros((sy, sz+1, sx), dtype=bool)
        exposedX = numpy.zeros((sy, sz, sx+1), dtype=bool)

        exposedY[:] = mask[1:,   1:-1, 1:-1] != mask[ :-1, 1:-1, 1:-1]
        exposedZ[:] = mask[1:-1, 1:,   1:-1] != mask[1:-1,  :-1, 1:-1]
        exposedX[:] = mask[1:-1, 1:-1, 1:  ] != mask[1:-1, 1:-1,  :-1]

        exposedByFace = [
            exposedX[:, :, 1:],
            exposedX[:, :, :-1],
            exposedY[1:],
            exposedY[:-1],
            exposedZ[:, 1:],
            exposedZ[:, :-1],
        ]

        return exposedByFace

    def buildSection(self, sectionMask, cy):
        vertexArrays = []

        for (face, exposedFaceMask) in enumerate(self.exposedBlockMasks(sectionMask)):
            blockIndices = sectionMask[1:-1, 1:-1, 1:-1] & exposedFaceMask

            vertexBuffer = VertexArrayBuffer.fromIndices(face, blockIndices, False, False)
            if not len(vertexBuffer.vertex):
                continue

            vertexBuffer.rgb[:] = faceShades[face]
            vertexBuffer.alpha[:] = 0x77
            vertexBuffer.vertex[..., 1] += cy << 4
            vertexArrays.append(vertexBuffer)

        return vertexArrays