Exemplo n.º 1
0
    def updateTransformedScene(self):
        if self.pendingImport.transformedDim is not None:
            log.info("Showing transformed scene")
            self.rotateNode.visible = False
            self.worldSceneTranslateNode.visible = False
            self.transformedWorldTranslateNode.visible = True

            if self.transformedWorldScene:
                self.transformedWorldTranslateNode.removeChild(
                    self.transformedWorldScene)

            self.transformedWorldScene = WorldScene(
                self.pendingImport.transformedDim, self.textureAtlas)
            self.transformedWorldScene.depthOffsetNode.depthOffset = DepthOffset.PreviewRenderer
            self.transformedWorldTranslateNode.addChild(
                self.transformedWorldScene)

            self.updateTransformedSceneOffset()

            cPos = list(self.pendingImport.transformedDim.chunkPositions())
            self.loader = WorldLoader(self.transformedWorldScene, cPos)
            self.loader.startLoader()

        else:
            log.info("Hiding transformed scene")
            self.rotateNode.visible = True
            self.worldSceneTranslateNode.visible = True
            self.transformedWorldTranslateNode.visible = False
            if self.transformedWorldScene:
                self.transformedWorldTranslateNode.removeChild(
                    self.transformedWorldScene)
                self.transformedWorldScene = None
Exemplo n.º 2
0
    def updateTransformedScene(self):
        if self.pendingImport.transformedDim is not None:
            log.info("Showing transformed scene")
            self.rotateNode.visible = False
            self.worldSceneTranslateNode.visible = False
            self.transformedWorldTranslateNode.visible = True

            if self.transformedWorldScene:
                self.transformedWorldTranslateNode.removeChild(
                    self.transformedWorldScene)

            self.transformedWorldScene = WorldScene(
                self.pendingImport.transformedDim, self.textureAtlas)
            self.transformedWorldScene.depthOffsetNode.depthOffset = DepthOffset.PreviewRenderer
            self.transformedWorldTranslateNode.addChild(
                self.transformedWorldScene)

            self.updateTransformedSceneOffset()

            cPos = list(self.pendingImport.transformedDim.chunkPositions())
            self.loader = WorldLoader(self.transformedWorldScene, cPos)

            # ALERT!: self.hasHandle is overloaded with the meaning:
            #  "not the first clone in a repeated clone"
            self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        else:
            log.info("Hiding transformed scene")
            self.rotateNode.visible = True
            self.worldSceneTranslateNode.visible = True
            self.transformedWorldTranslateNode.visible = False
            if self.transformedWorldScene:
                self.transformedWorldTranslateNode.removeChild(
                    self.transformedWorldScene)
                self.transformedWorldScene = None
Exemplo n.º 3
0
    def displaySchematic(self, schematic, offset):
        if schematic is not None:
            dim = schematic.getDimension()

            if self.worldScene:
                self.sceneHolderNode.removeChild(self.worldScene)
                self.loader.timer.stop()
                self.loader = None

            atlas = self.editorSession.textureAtlas
            self.worldScene = WorldScene(dim, atlas)
            self.sceneHolderNode.translateOffset = offset
            self.sceneHolderNode.addChild(self.worldScene)

            self.loader = WorldLoader(self.worldScene)
            if dim.chunkCount() <= self.instantDisplayChunks:
                for _ in self.loader.work():
                    pass
            else:
                self.loader.timer.start()
        else:
            if self.worldScene:
                self.sceneHolderNode.removeChild(self.worldScene)
                self.worldScene = None
                self.loader.timer.stop()
                self.loader = None
Exemplo n.º 4
0
    def __init__(self, pendingImport, textureAtlas):
        super(PendingImportNode, self).__init__()
        self.pendingImport = pendingImport
        self.pos = pendingImport.pos

        dim = pendingImport.schematic.getDimension()

        self.worldScene = WorldScene(dim, textureAtlas)
        self.worldScene.depthOffsetNode.depthOffset = DepthOffset.PreviewRenderer
        self.addChild(self.worldScene)

        self.outlineNode = SelectionBoxNode()
        self.outlineNode.filled = False
        self.outlineNode.selectionBox = dim.bounds
        self.addChild(self.outlineNode)

        self.faceHoverNode = SelectionFaceNode()
        self.faceHoverNode.selectionBox = dim.bounds
        self.addChild(self.faceHoverNode)

        self.loader = WorldLoader(self.worldScene)
        self.loader.timer.start()
Exemplo n.º 5
0
 def buildMeshes():
     o.worldScene = WorldScene(dim, o.textureAtlas)
     worker = o.worldScene.workOnChunk(dim.getChunk(*positions[0]))
     for i in worker:
         pass
Exemplo n.º 6
0
    def __init__(self, pendingImport, textureAtlas):
        """
        A scenegraph node displaying an object that will be imported later, including
        live and deferred views of the object with transformed items, and a BoxHandle
        for moving the item.

        Parameters
        ----------

        pendingImport: PendingImport
            The object to be imported. The PendingImportNode responds to changes in this
            object's position, rotation, and scale.
        textureAtlas: TextureAtlas
            The textures and block models used to render the preview of the object.

        Attributes
        ----------

        basePosition: Vector
            The pre-transform position of the pending import. This is equal to
            `self.pendingImport.basePosition` except when the node is currently being
            dragged.
        transformedPosition: Vector
            The post-transform position of the pending import. This is equal to
            `self.pendingImport.importPos` except when the node is currently being
            dragged, scaled, or rotated.
        """
        super(PendingImportNode, self).__init__()

        self.textureAtlas = textureAtlas
        self.pendingImport = pendingImport
        dim = pendingImport.sourceDim

        # positionTranslateNode contains the non-transformed preview of the imported
        # object, including its world scene. This preview will be rotated model-wise
        # while the user is dragging the rotate controls.

        self.positionTranslateNode = TranslateNode()
        self.rotateNode = Rotate3DNode()
        self.addChild(self.positionTranslateNode)
        self.positionTranslateNode.addChild(self.rotateNode)

        self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)

        # worldSceneTranslateNode is contained by positionTranslateNode, and
        # serves to translate the world scene back to 0, 0, 0 so the positionTranslateNode
        # can translate by the current position.

        self.worldSceneTranslateNode = TranslateNode()
        self.worldScene = WorldScene(dim,
                                     textureAtlas,
                                     bounds=pendingImport.selection)
        self.worldScene.depthOffsetNode.depthOffset = DepthOffset.PreviewRenderer

        # transformedWorldTranslateNode contains the transformed preview of the imported
        # object, including a world scene that displays the object wrapped by a
        # DimensionTransform.

        self.transformedWorldTranslateNode = TranslateNode()
        self.transformedWorldScene = None
        self.addChild(self.transformedWorldTranslateNode)

        self.worldSceneTranslateNode.translateOffset = -self.pendingImport.selection.origin
        self.worldSceneTranslateNode.addChild(self.worldScene)
        self.rotateNode.addChild(self.worldSceneTranslateNode)

        # handleNode displays a bounding box that can be moved around, and responds
        # to mouse events.

        box = BoundingBox(pendingImport.importPos,
                          pendingImport.importBounds.size)

        self.handleNode = BoxHandle()
        self.handleNode.bounds = box
        self.handleNode.resizable = False

        self.updateTransformedScene()
        self.basePosition = pendingImport.basePosition

        self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
        self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)

        self.addChild(self.handleNode)

        # loads the non-transformed world scene asynchronously.
        self.loader = WorldLoader(
            self.worldScene, list(pendingImport.selection.chunkPositions()))
        self.loader.startLoader()

        self.pendingImport.positionChanged.connect(self.setPosition)
        self.pendingImport.rotationChanged.connect(self.setRotation)
Exemplo n.º 7
0
    def __init__(self, pendingImport, textureAtlas, hasHandle=True):
        """
        A scenegraph node displaying an object that will be imported later, including
        live and deferred views of the object with transformed items, and a BoxHandle
        for moving the item.

        Parameters
        ----------

        pendingImport: PendingImport
            The object to be imported. The PendingImportNode responds to changes in this
            object's position, rotation, and scale.
        textureAtlas: TextureAtlas
            The textures and block models used to render the preview of the object.
        hasHandle: bool
            True if this import node should have a user-interactive BoxHandle associated
            with it. This is False for the extra copies displayed by a repeated clone.

        Attributes
        ----------

        basePosition: Vector
            The pre-transform position of the pending import. This is equal to
            `self.pendingImport.basePosition` except when the node is currently being
            dragged.
        transformedPosition: Vector
            The post-transform position of the pending import. This is equal to
            `self.pendingImport.importPos` except when the node is currently being
            dragged, scaled, or rotated.
        """
        super(PendingImportNode, self).__init__()

        self.textureAtlas = textureAtlas
        self.pendingImport = pendingImport
        self.hasHandle = hasHandle

        dim = pendingImport.sourceDim

        self.transformedPosition = Vector(0, 0, 0)

        # worldScene is contained by rotateNode, and
        # translates the world scene back to 0, 0, 0 so the rotateNode can
        # rotate it around the anchor, and the plainSceneNode can translate
        # it to the current position.

        self.worldScene = WorldScene(dim, textureAtlas, bounds=pendingImport.selection)
        self.worldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer

        self.worldSceneTranslate = Translate(-self.pendingImport.selection.origin)
        self.worldScene.addState(self.worldSceneTranslate)

        # rotateNode is used to rotate the non-transformed preview during live rotation

        self.rotateNode = Rotate3DNode()
        self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.rotateNode.addChild(self.worldScene)

        self.scaleNode = Scale3DNode()
        self.scaleNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.scaleNode.addChild(self.rotateNode)

        # plainSceneNode contains the non-transformed preview of the imported
        # object, including its world scene. This preview will be rotated model-wise
        # while the user is dragging the rotate controls.

        self.plainSceneNode = Node("plainScene")
        self.positionTranslate = Translate()
        self.plainSceneNode.addState(self.positionTranslate)
        self.plainSceneNode.addChild(self.scaleNode)

        self.addChild(self.plainSceneNode)

        # transformedSceneNode contains the transformed preview of the imported
        # object, including a world scene that displays the object wrapped by a
        # DimensionTransform.

        self.transformedSceneNode = Node("transformedScene")
        self.transformedSceneTranslate = Translate()
        self.transformedSceneNode.addState(self.transformedSceneTranslate)

        self.transformedWorldScene = None
        self.addChild(self.transformedSceneNode)

        box = BoundingBox(pendingImport.importPos, pendingImport.importBounds.size)

        if hasHandle:
            # handleNode displays a bounding box that can be moved around, and responds
            # to mouse events.
            self.handleNode = BoxHandle()
            self.handleNode.bounds = box
            self.handleNode.resizable = False
            self.boxNode = None
        else:
            # boxNode displays a plain, non-movable bounding box
            self.boxNode = SelectionBoxNode()
            self.boxNode.wireColor = (1, 1, 1, .2)
            self.boxNode.filled = False
            self.handleNode = None
            self.addChild(self.boxNode)

        self.updateTransformedScene()
        self.basePosition = pendingImport.basePosition

        if hasHandle:
            self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
            self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)

            self.addChild(self.handleNode)

        # loads the non-transformed world scene asynchronously.
        self.loader = WorldLoader(self.worldScene,
                                  list(pendingImport.selection.chunkPositions()))
        self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        self.pendingImport.positionChanged.connect(self.setPosition)
        self.pendingImport.rotationChanged.connect(self.setRotation)
        self.pendingImport.scaleChanged.connect(self.setScale)
Exemplo n.º 8
0
class PendingImportNode(Node, QtCore.QObject):
    __node_id_counter = 0

    def __init__(self, pendingImport, textureAtlas, hasHandle=True):
        """
        A scenegraph node displaying an object that will be imported later, including
        live and deferred views of the object with transformed items, and a BoxHandle
        for moving the item.

        Parameters
        ----------

        pendingImport: PendingImport
            The object to be imported. The PendingImportNode responds to changes in this
            object's position, rotation, and scale.
        textureAtlas: TextureAtlas
            The textures and block models used to render the preview of the object.
        hasHandle: bool
            True if this import node should have a user-interactive BoxHandle associated
            with it. This is False for the extra copies displayed by a repeated clone.

        Attributes
        ----------

        basePosition: Vector
            The pre-transform position of the pending import. This is equal to
            `self.pendingImport.basePosition` except when the node is currently being
            dragged.
        transformedPosition: Vector
            The post-transform position of the pending import. This is equal to
            `self.pendingImport.importPos` except when the node is currently being
            dragged, scaled, or rotated.
        """
        super(PendingImportNode, self).__init__()

        self.textureAtlas = textureAtlas
        self.pendingImport = pendingImport
        self.hasHandle = hasHandle

        dim = pendingImport.sourceDim

        self.transformedPosition = Vector(0, 0, 0)

        # worldScene is contained by rotateNode, and
        # translates the world scene back to 0, 0, 0 so the rotateNode can
        # rotate it around the anchor, and the plainSceneNode can translate
        # it to the current position.

        self.worldScene = WorldScene(dim, textureAtlas, bounds=pendingImport.selection)
        self.worldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer

        self.worldSceneTranslate = Translate(-self.pendingImport.selection.origin)
        self.worldScene.addState(self.worldSceneTranslate)

        # rotateNode is used to rotate the non-transformed preview during live rotation

        self.rotateNode = Rotate3DNode()
        self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.rotateNode.addChild(self.worldScene)

        self.scaleNode = Scale3DNode()
        self.scaleNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.scaleNode.addChild(self.rotateNode)

        # plainSceneNode contains the non-transformed preview of the imported
        # object, including its world scene. This preview will be rotated model-wise
        # while the user is dragging the rotate controls.

        self.plainSceneNode = Node("plainScene")
        self.positionTranslate = Translate()
        self.plainSceneNode.addState(self.positionTranslate)
        self.plainSceneNode.addChild(self.scaleNode)

        self.addChild(self.plainSceneNode)

        # transformedSceneNode contains the transformed preview of the imported
        # object, including a world scene that displays the object wrapped by a
        # DimensionTransform.

        self.transformedSceneNode = Node("transformedScene")
        self.transformedSceneTranslate = Translate()
        self.transformedSceneNode.addState(self.transformedSceneTranslate)

        self.transformedWorldScene = None
        self.addChild(self.transformedSceneNode)

        box = BoundingBox(pendingImport.importPos, pendingImport.importBounds.size)

        if hasHandle:
            # handleNode displays a bounding box that can be moved around, and responds
            # to mouse events.
            self.handleNode = BoxHandle()
            self.handleNode.bounds = box
            self.handleNode.resizable = False
            self.boxNode = None
        else:
            # boxNode displays a plain, non-movable bounding box
            self.boxNode = SelectionBoxNode()
            self.boxNode.wireColor = (1, 1, 1, .2)
            self.boxNode.filled = False
            self.handleNode = None
            self.addChild(self.boxNode)

        self.updateTransformedScene()
        self.basePosition = pendingImport.basePosition

        if hasHandle:
            self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
            self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)

            self.addChild(self.handleNode)

        # loads the non-transformed world scene asynchronously.
        self.loader = WorldLoader(self.worldScene,
                                  list(pendingImport.selection.chunkPositions()))
        self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        self.pendingImport.positionChanged.connect(self.setPosition)
        self.pendingImport.rotationChanged.connect(self.setRotation)
        self.pendingImport.scaleChanged.connect(self.setScale)

    # Emitted when the user finishes dragging the box handle and releases the mouse
    # button. Arguments are (newPosition, oldPosition).
    importMoved = QtCore.Signal(object, object)

    # Emitted while the user is dragging the box handle. Argument is the box origin.
    importIsMoving = QtCore.Signal(object)

    def handleBoundsChangedDone(self, bounds, oldBounds):
        point = self.getBaseFromTransformed(bounds.origin)
        oldPoint = self.getBaseFromTransformed(oldBounds.origin)
        if point != oldPoint:
            self.importMoved.emit(point, oldPoint)

    def handleBoundsChanged(self, bounds):
        log.info("handleBoundsChanged: %s", bounds)
        self.setPreviewBasePosition(bounds.origin)

    def setPreviewBasePosition(self, origin):
        point = self.getBaseFromTransformed(origin)
        if self.basePosition != point:
            self.basePosition = point
            self.importIsMoving.emit(point)

    def getBaseFromTransformed(self, point):
        return point - self.pendingImport.transformOffset

    def setPreviewRotation(self, rots):
        self.plainSceneNode.visible = True
        self.transformedSceneNode.visible = False
        self.rotateNode.setRotation(rots)

    def setRotation(self, rots):
        self.updateTransformedScene()
        self.updateBoxHandle()
        self.rotateNode.setRotation(rots)

    def setPreviewScale(self, scale):
        self.plainSceneNode.visible = True
        self.transformedSceneNode.visible = False
        self.scaleNode.setScale(scale)

    def setScale(self, scale):
        self.updateTransformedScene()
        self.updateBoxHandle()
        self.scaleNode.setScale(scale)

    def updateTransformedScene(self):
        if self.pendingImport.transformedDim is not None:
            log.info("Showing transformed scene")
            self.plainSceneNode.visible = False
            self.transformedSceneNode.visible = True

            if self.transformedWorldScene:
                self.transformedSceneNode.removeChild(self.transformedWorldScene)

            self.transformedWorldScene = WorldScene(self.pendingImport.transformedDim,
                                                    self.textureAtlas)
            self.transformedWorldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer
            self.transformedSceneNode.addChild(self.transformedWorldScene)

            self.updateTransformedPosition()

            cPos = list(self.pendingImport.transformedDim.chunkPositions())
            self.loader = WorldLoader(self.transformedWorldScene,
                                      cPos)

            # ALERT!: self.hasHandle is overloaded with the meaning:
            #  "not the first clone in a repeated clone"
            self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        else:
            log.info("Hiding transformed scene")
            self.plainSceneNode.visible = True
            self.transformedSceneNode.visible = False
            if self.transformedWorldScene:
                self.transformedSceneNode.removeChild(self.transformedWorldScene)
                self.transformedWorldScene = None

    def updateTransformedPosition(self):
        self.transformedPosition = self.basePosition + self.pendingImport.transformOffset
        self.transformedSceneTranslate.translateOffset = self.transformedPosition - self.pendingImport.importDim.bounds.origin

    def updateBoxHandle(self):
        if self.transformedWorldScene is None:
            bounds = BoundingBox(self.basePosition, self.pendingImport.bounds.size)
        else:
            origin = self.transformedPosition
            bounds = BoundingBox(origin, self.pendingImport.importBounds.size)
        #if self.handleNode.bounds.size != bounds.size:
        if self.hasHandle:
            self.handleNode.bounds = bounds
        else:
            self.boxNode.selectionBox = bounds

    @property
    def basePosition(self):
        return self.positionTranslate.translateOffset

    @basePosition.setter
    def basePosition(self, value):
        value = Vector(*value)
        if value == self.positionTranslate.translateOffset:
            return

        self.positionTranslate.translateOffset = value
        self.updateTransformedPosition()
        self.updateBoxHandle()

    def setPosition(self, pos):
        self.basePosition = pos

    # --- Mouse events ---

    # inherit from BoxHandle?
    def mouseMove(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mouseMove(event)

    def mousePress(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mousePress(event)

    def mouseRelease(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mouseRelease(event)
Exemplo n.º 9
0
class PendingImportNode(Node, QtCore.QObject):
    __node_id_counter = 0

    def __init__(self, pendingImport, textureAtlas, hasHandle=True):
        """
        A scenegraph node displaying an object that will be imported later, including
        live and deferred views of the object with transformed items, and a BoxHandle
        for moving the item.

        Parameters
        ----------

        pendingImport: PendingImport
            The object to be imported. The PendingImportNode responds to changes in this
            object's position, rotation, and scale.
        textureAtlas: TextureAtlas
            The textures and block models used to render the preview of the object.

        Attributes
        ----------

        basePosition: Vector
            The pre-transform position of the pending import. This is equal to
            `self.pendingImport.basePosition` except when the node is currently being
            dragged.
        transformedPosition: Vector
            The post-transform position of the pending import. This is equal to
            `self.pendingImport.importPos` except when the node is currently being
            dragged, scaled, or rotated.
        """
        super(PendingImportNode, self).__init__()

        self.textureAtlas = textureAtlas
        self.pendingImport = pendingImport
        self.hasHandle = hasHandle

        dim = pendingImport.sourceDim

        self.transformedPosition = Vector(0, 0, 0)

        # worldScene is contained by rotateNode, and
        # translates the world scene back to 0, 0, 0 so the rotateNode can
        # rotate it around the anchor, and the plainSceneNode can translate
        # it to the current position.

        self.worldScene = WorldScene(dim, textureAtlas, bounds=pendingImport.selection)
        self.worldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer

        self.worldSceneTranslate = Translate(-self.pendingImport.selection.origin)
        self.worldScene.addState(self.worldSceneTranslate)

        # rotateNode is used to rotate the non-transformed preview during live rotation

        self.rotateNode = Rotate3DNode()
        self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.rotateNode.addChild(self.worldScene)

        # plainSceneNode contains the non-transformed preview of the imported
        # object, including its world scene. This preview will be rotated model-wise
        # while the user is dragging the rotate controls.

        self.plainSceneNode = Node("plainScene")
        self.positionTranslate = Translate()
        self.plainSceneNode.addState(self.positionTranslate)
        self.plainSceneNode.addChild(self.rotateNode)

        self.addChild(self.plainSceneNode)

        # transformedSceneNode contains the transformed preview of the imported
        # object, including a world scene that displays the object wrapped by a
        # DimensionTransform.

        self.transformedSceneNode = Node("transformedScene")
        self.transformedSceneTranslate = Translate()
        self.transformedSceneNode.addState(self.transformedSceneTranslate)

        self.transformedWorldScene = None
        self.addChild(self.transformedSceneNode)

        box = BoundingBox(pendingImport.importPos, pendingImport.importBounds.size)

        if hasHandle:
            # handleNode displays a bounding box that can be moved around, and responds
            # to mouse events.
            self.handleNode = BoxHandle()
            self.handleNode.bounds = box
            self.handleNode.resizable = False
            self.boxNode = None
        else:
            # boxNode displays a plain, non-movable bounding box
            self.boxNode = SelectionBoxNode()
            self.boxNode.wireColor = (1, 1, 1, .2)
            self.boxNode.filled = False
            self.handleNode = None
            self.addChild(self.boxNode)

        self.updateTransformedScene()
        self.basePosition = pendingImport.basePosition

        if hasHandle:
            self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
            self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)

            self.addChild(self.handleNode)

        # loads the non-transformed world scene asynchronously.
        self.loader = WorldLoader(self.worldScene,
                                  list(pendingImport.selection.chunkPositions()))
        self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        self.pendingImport.positionChanged.connect(self.setPosition)
        self.pendingImport.rotationChanged.connect(self.setRotation)

    # Emitted when the user finishes dragging the box handle and releases the mouse
    # button. Arguments are (newPosition, oldPosition).
    importMoved = QtCore.Signal(object, object)

    # Emitted while the user is dragging the box handle. Argument is the box origin.
    importIsMoving = QtCore.Signal(object)

    def handleBoundsChangedDone(self, bounds, oldBounds):
        point = self.getBaseFromTransformed(bounds.origin)
        oldPoint = self.getBaseFromTransformed(oldBounds.origin)
        if point != oldPoint:
            self.importMoved.emit(point, oldPoint)

    def handleBoundsChanged(self, bounds):
        self.setPreviewBasePosition(bounds.origin)

    def setPreviewBasePosition(self, origin):
        point = self.getBaseFromTransformed(origin)
        if self.basePosition != point:
            self.basePosition = point
            self.importIsMoving.emit(point)

    def getBaseFromTransformed(self, point):
        return point - self.pendingImport.transformOffset

    def setPreviewRotation(self, rots):
        self.plainSceneNode.visible = True
        self.transformedSceneNode.visible = False
        self.rotateNode.setRotation(rots)

    def setRotation(self, rots):
        self.updateTransformedScene()
        self.updateBoxHandle()
        self.rotateNode.setRotation(rots)

    def updateTransformedScene(self):
        if self.pendingImport.transformedDim is not None:
            log.info("Showing transformed scene")
            self.plainSceneNode.visible = False
            self.transformedSceneNode.visible = True

            if self.transformedWorldScene:
                self.transformedSceneNode.removeChild(self.transformedWorldScene)

            self.transformedWorldScene = WorldScene(self.pendingImport.transformedDim,
                                                    self.textureAtlas)
            self.transformedWorldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer
            self.transformedSceneNode.addChild(self.transformedWorldScene)

            self.updateTransformedPosition()

            cPos = list(self.pendingImport.transformedDim.chunkPositions())
            self.loader = WorldLoader(self.transformedWorldScene,
                                      cPos)

            # ALERT!: self.hasHandle is overloaded with the meaning:
            #  "not the first clone in a repeated clone"
            self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        else:
            log.info("Hiding transformed scene")
            self.plainSceneNode.visible = True
            self.transformedSceneNode.visible = False
            if self.transformedWorldScene:
                self.transformedSceneNode.removeChild(self.transformedWorldScene)
                self.transformedWorldScene = None

    def updateTransformedPosition(self):
        self.transformedPosition = self.basePosition + self.pendingImport.transformOffset
        self.transformedSceneTranslate.translateOffset = self.transformedPosition - self.pendingImport.importDim.bounds.origin

    def updateBoxHandle(self):
        if self.transformedWorldScene is None:
            bounds = BoundingBox(self.basePosition, self.pendingImport.bounds.size)
        else:
            origin = self.transformedPosition
            bounds = BoundingBox(origin, self.pendingImport.importBounds.size)
        #if self.handleNode.bounds.size != bounds.size:
        if self.hasHandle:
            self.handleNode.bounds = bounds
        else:
            self.boxNode.selectionBox = bounds

    @property
    def basePosition(self):
        return self.positionTranslate.translateOffset

    @basePosition.setter
    def basePosition(self, value):
        value = Vector(*value)
        if value == self.positionTranslate.translateOffset:
            return

        self.positionTranslate.translateOffset = value
        self.updateTransformedPosition()
        self.updateBoxHandle()

    def setPosition(self, pos):
        self.basePosition = pos

    # --- Mouse events ---

    # inherit from BoxHandle?
    def mouseMove(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mouseMove(event)

    def mousePress(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mousePress(event)

    def mouseRelease(self, event):
        if not self.hasHandle:
            return
        self.handleNode.mouseRelease(event)
Exemplo n.º 10
0
    def __init__(self, pendingImport, textureAtlas, hasHandle=True):
        """
        A scenegraph node displaying an object that will be imported later, including
        live and deferred views of the object with transformed items, and a BoxHandle
        for moving the item.

        Parameters
        ----------

        pendingImport: PendingImport
            The object to be imported. The PendingImportNode responds to changes in this
            object's position, rotation, and scale.
        textureAtlas: TextureAtlas
            The textures and block models used to render the preview of the object.
        hasHandle: bool
            True if this import node should have a user-interactive BoxHandle associated
            with it. This is False for the extra copies displayed by a repeated clone.

        Attributes
        ----------

        basePosition: Vector
            The pre-transform position of the pending import. This is equal to
            `self.pendingImport.basePosition` except when the node is currently being
            dragged.
        transformedPosition: Vector
            The post-transform position of the pending import. This is equal to
            `self.pendingImport.importPos` except when the node is currently being
            dragged, scaled, or rotated.
        """
        super(PendingImportNode, self).__init__()

        self.textureAtlas = textureAtlas
        self.pendingImport = pendingImport
        self.hasHandle = hasHandle

        dim = pendingImport.sourceDim

        self.transformedPosition = Vector(0, 0, 0)

        # worldScene is contained by rotateNode, and
        # translates the world scene back to 0, 0, 0 so the rotateNode can
        # rotate it around the anchor, and the plainSceneNode can translate
        # it to the current position.

        self.worldScene = WorldScene(dim,
                                     textureAtlas,
                                     bounds=pendingImport.selection)
        self.worldScene.depthOffset.depthOffset = DepthOffsets.PreviewRenderer

        self.worldSceneTranslate = Translate(
            -self.pendingImport.selection.origin)
        self.worldScene.addState(self.worldSceneTranslate)

        # rotateNode is used to rotate the non-transformed preview during live rotation

        self.rotateNode = Rotate3DNode()
        self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.rotateNode.addChild(self.worldScene)

        self.scaleNode = Scale3DNode()
        self.scaleNode.setAnchor(self.pendingImport.selection.size * 0.5)
        self.scaleNode.addChild(self.rotateNode)

        # plainSceneNode contains the non-transformed preview of the imported
        # object, including its world scene. This preview will be rotated model-wise
        # while the user is dragging the rotate controls.

        self.plainSceneNode = Node("plainScene")
        self.positionTranslate = Translate()
        self.plainSceneNode.addState(self.positionTranslate)
        self.plainSceneNode.addChild(self.scaleNode)

        self.addChild(self.plainSceneNode)

        # transformedSceneNode contains the transformed preview of the imported
        # object, including a world scene that displays the object wrapped by a
        # DimensionTransform.

        self.transformedSceneNode = Node("transformedScene")
        self.transformedSceneTranslate = Translate()
        self.transformedSceneNode.addState(self.transformedSceneTranslate)

        self.transformedWorldScene = None
        self.addChild(self.transformedSceneNode)

        box = BoundingBox(pendingImport.importPos,
                          pendingImport.importBounds.size)

        if hasHandle:
            # handleNode displays a bounding box that can be moved around, and responds
            # to mouse events.
            self.handleNode = BoxHandle()
            self.handleNode.bounds = box
            self.handleNode.resizable = False
            self.boxNode = None
        else:
            # boxNode displays a plain, non-movable bounding box
            self.boxNode = SelectionBoxNode()
            self.boxNode.wireColor = (1, 1, 1, .2)
            self.boxNode.filled = False
            self.handleNode = None
            self.addChild(self.boxNode)

        self.updateTransformedScene()
        self.basePosition = pendingImport.basePosition

        if hasHandle:
            self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
            self.handleNode.boundsChangedDone.connect(
                self.handleBoundsChangedDone)

            self.addChild(self.handleNode)

        # loads the non-transformed world scene asynchronously.
        self.loader = WorldLoader(
            self.worldScene, list(pendingImport.selection.chunkPositions()))
        self.loader.startLoader(0.1 if self.hasHandle else 0.0)

        self.pendingImport.positionChanged.connect(self.setPosition)
        self.pendingImport.rotationChanged.connect(self.setRotation)
        self.pendingImport.scaleChanged.connect(self.setScale)