示例#1
0
    def _projectEdgeVertices(self, mvp, vertexIndex0, vertexIndex1):
        v0 = cgmath.Vec4(self._vertex_data[vertexIndex0 * 3], self._vertex_data[vertexIndex0 * 3 + 1],
                         self._vertex_data[vertexIndex0 * 3 + 2], 1.0)
        v1 = cgmath.Vec4(self._vertex_data[vertexIndex1 * 3 ], self._vertex_data[vertexIndex1 * 3 + 1],
                         self._vertex_data[vertexIndex1 * 3 + 2], 1.0)

        v0 = v0 * mvp
        v1 = v1 * mvp
        v0x = v0[0] / v0[3]
        v0y = v0[1] / v0[3]
        v1x = v1[0] / v1[3]
        v1y = v1[1] / v1[3]

        return mathutil.Vec2(v0x, v0y), mathutil.Vec2(v1x, v1y)
示例#2
0
    def mousePressEvent(self, mouseEvent):
        super(ModelerViewport, self).mousePressEvent(mouseEvent)

        if self._adjustingCamera:
            return

        modifiers = QApplication.keyboardModifiers()

        # Pan/Rotate/Zoom?
        if modifiers == Qt.AltModifier:
            self._adjustingCamera = True
            self._adjustCameraStartMousePos = mathutil.Vec2(mouseEvent.localPos().x(), mouseEvent.localPos().y())
            self._adjustCameraStartCamera = self._cameraTransform
            self._adjustCameraPivot = self._cameraPivot

            # Panning?
            if mouseEvent.buttons() & Qt.MiddleButton:
                self._adjustCameraMode = 0
            # Rotating?
            elif mouseEvent.buttons() & Qt.LeftButton:
                self._adjustCameraMode = 1
            # Zooming?
            elif mouseEvent.buttons() & Qt.RightButton:
                self._adjustCameraMode = 2

        # Simple click?
        else:
            clickHandled = False

            # Did we click on the modifier, if its visible?
            if self._modifierMode != ModifierMode.SELECT and self._isModifierVisible():
                axis = self._getMouseOnModifierAxis(mouseEvent.localPos().x(), mouseEvent.localPos().y())

                if axis != ModifierAxis.NONE:
                    node = self._getCurrentMainModelNode()
                    clickHandled = True
                    self._modifierAxis = axis
                    self._modifyStartMouseScreenPos = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y())

                    self._modifyStartModelTranslation = {}
                    self._modifyStartModelRotationMatrix = {}
                    self._modifyStartModelSize = {}

                    for node in self._currentModelNodes:
                        self._modifyStartModelTranslation[node] = node.translation
                        self._modifyStartModelRotationMatrix[node] = \
                            cgmath.Mat44.rotateZ(node.rotation[2]) * \
                            cgmath.Mat44.rotateY(node.rotation[1]) * \
                            cgmath.Mat44.rotateX(node.rotation[0])
                        self._modifyStartModelSize[node] = node.size

                    self.update()

            # Otherwise update our selection
            if self._currentModel is not None and not clickHandled:
                clickHandled = True
                self._selecting = True
                self._selectStartMouseScreenPos = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y())
                self._selectCurrentMouseScreenPos = cgmath.Vec4(self._selectStartMouseScreenPos)
示例#3
0
    def _edgeIntersectsRect2D(self, mvp, rectP0, rectP1, vertexIndex0, vertexIndex1):
        v0, v1 = self._projectEdgeVertices(mvp, vertexIndex0, vertexIndex1)
        dx = v1.x - v0.x
        dy = v1.y - v0.y

        # Single point, inside?
        if abs(dx) < 0.000001 and abs(dy) < 0.000001 and \
            v0.x >= rectP0.x and v0.x <= rectP1.x and v0.y >= rectP0.y and v0.y <= rectP1.y:
            return True

        c = mathutil.Vec2(0.0, 1.0)
        return self._edgeClip2D(rectP0.x - v0.x, dx, c) and self._edgeClip2D(v0.x - rectP1.x, -dx, c) and \
               self._edgeClip2D(rectP0.y - v0.y, dy, c) and self._edgeClip2D(v0.y - rectP1.y, -dy, c)
示例#4
0
    def mouseReleaseEvent(self, mouseEvent):
        super(ModelerViewport, self).mouseReleaseEvent(mouseEvent)

        # Panning/Rotating/Zooming?
        if self._adjustingCamera:
            # Panning?
            if self._adjustCameraMode == 0:
                self._adjustingCamera = (mouseEvent.buttons() & Qt.MiddleButton)
            # Rotating?
            elif self._adjustCameraMode == 1:
                self._adjustingCamera = (mouseEvent.buttons() & Qt.LeftButton)
            # Zooming?
            elif self._adjustCameraMode == 2:
                self._adjustingCamera = (mouseEvent.buttons() & Qt.RightButton)

        # Adjusting modifier?
        elif self._modifierMode != ModifierMode.SELECT and self._modifierAxis != ModifierAxis.NONE:
            self._modifierAxis = ModifierAxis.NONE
            self.update()

        # Selecting?
        elif self._selecting:
            self._selecting = False

            # Create rect with P0 is min (bottom left) and P1 is max (top right)
            rectP0 = mathutil.Vec2(min(self._selectStartMouseScreenPos[0], self._selectCurrentMouseScreenPos[0]), min(self._selectStartMouseScreenPos[1], self._selectCurrentMouseScreenPos[1]))
            rectP1 = mathutil.Vec2(max(self._selectStartMouseScreenPos[0], self._selectCurrentMouseScreenPos[0]), max(self._selectStartMouseScreenPos[1], self._selectCurrentMouseScreenPos[1]))

            # Enforce minimum size of selection rect
            boxSelect = False
            minRectSize = 2.0*math.sqrt(self._minMouseClickDistSq)
            rectSize = rectP1 - rectP0
            if abs(rectSize[0]) < minRectSize:
                rectP0[0] -= 0.5*(minRectSize - rectSize[0])
                rectP1[0] += 0.5*(minRectSize - rectSize[0])
            else:
                boxSelect = True
            if abs(rectSize[1]) < minRectSize:
                rectP0[1] -= 0.5*(minRectSize - rectSize[1])
                rectP1[1] += 0.5*(minRectSize - rectSize[1])
            else:
                boxSelect = True

            newSelectedNodes = self._getModelNodesUnderScreenRect(rectP0, rectP1)

            modifiers = QApplication.keyboardModifiers()

            # By holding Shift, the selection is extended instead of replaced.
            # (And by holding shift and clicking on a single item, that item can be excluded as well)
            if modifiers == Qt.ShiftModifier:
                if boxSelect:
                    for node in self._currentModelNodes:
                        if node not in newSelectedNodes:
                            newSelectedNodes.append(node)
                else:
                    clickedNodes = newSelectedNodes
                    newSelectedNodes = list(self._currentModelNodes)
                    for clickedNode in clickedNodes:
                        if clickedNode in newSelectedNodes:
                            newSelectedNodes.remove(clickedNode)
                        else:
                            newSelectedNodes.append(clickedNode)

            self.selectedModelNodesChanged.emit(self._currentModel, newSelectedNodes)
            self.update()
示例#5
0
    def mouseMoveEvent(self, mouseEvent):
        super(ModelerViewport, self).mouseMoveEvent(mouseEvent)

        # Panning/Rotating/Zooming?
        if self._adjustingCamera:
            # Panning?
            if self._adjustCameraMode == 0:
                panSpeed = 0.025
                deltaMouse = mathutil.Vec2(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._adjustCameraStartMousePos
                self._cameraTransform = cgmath.Mat44.translate(deltaMouse[0] * -panSpeed, deltaMouse[1] * panSpeed, 0.0) * self._adjustCameraStartCamera
                self._cameraPivot = self._adjustCameraPivot + cgmath.Vec3(self._cameraTransform[12] - self._adjustCameraStartCamera[12], self._cameraTransform[13] - self._adjustCameraStartCamera[13], self._cameraTransform[14] - self._adjustCameraStartCamera[14])

            # Rotating?
            elif self._adjustCameraMode == 1:
                rotateSpeed = 0.010
                deltaMouse = mathutil.Vec2(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._adjustCameraStartMousePos

                # Remove pivot
                self._cameraTransform = cgmath.Mat44(self._adjustCameraStartCamera) * cgmath.Mat44.translate(-self._adjustCameraPivot[0], -self._adjustCameraPivot[1], -self._adjustCameraPivot[2])

                # Rotate
                self._cameraTransform = self._cameraTransform * cgmath.Mat44.rotateY(deltaMouse[0] * rotateSpeed)
                self._cameraTransform = self._cameraTransform * self.axisAngle(cgmath.Vec3(1.0, 0.0, 0.0) * self._cameraTransform, deltaMouse[1] * -rotateSpeed)

                # Add pivot back
                self._cameraTransform = cgmath.Mat44(self._cameraTransform) * cgmath.Mat44.translate(self._adjustCameraPivot[0], self._adjustCameraPivot[1], self._adjustCameraPivot[2])

            # Zooming?
            elif self._adjustCameraMode == 2:
                zoomSpeed = 0.025
                deltaMouse = mathutil.Vec2(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._adjustCameraStartMousePos
                self._cameraTransform = cgmath.Mat44.translate(0.0, 0.0, deltaMouse[1] * zoomSpeed) * self._adjustCameraStartCamera

            self.cameraChanged.emit(self._cameraTransform)

        # Dragging a translation modifier axis?
        elif self._modifierMode == ModifierMode.TRANSLATE and self._modifierAxis != ModifierAxis.NONE:
            deltaMouse = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._modifyStartMouseScreenPos
            if self._modifierAxis == ModifierAxis.X:
                axisDir = cgmath.Vec3(1.0,0.0,0.0)
            elif self._modifierAxis == ModifierAxis.Y:
                axisDir = cgmath.Vec3(0.0,1.0,0.0)
            else:
                axisDir = cgmath.Vec3(0.0,0.0,1.0)

            screenDir = self._getModifierAxisScreenDir(axisDir)
            delta = screenDir[0]*deltaMouse[0] + screenDir[1]*deltaMouse[1]

            for node in self._currentModelNodes:
                node.translation = axisDir * delta + self._modifyStartModelTranslation[node]

        # Dragging a rotation modifier axis?
        elif self._modifierMode == ModifierMode.ROTATE and self._modifierAxis != ModifierAxis.NONE:
            deltaMouse = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._modifyStartMouseScreenPos
            amount = deltaMouse[0]

            if self._modifierAxis == ModifierAxis.X:
                rot = cgmath.Mat44.rotateX(amount)
            elif self._modifierAxis == ModifierAxis.Y:
                rot = cgmath.Mat44.rotateY(amount)
            else:
                rot = cgmath.Mat44.rotateZ(amount)

            for node in self._currentModelNodes:
                node.rotation = (rot * self._modifyStartModelRotationMatrix[node]).eulerXYZ()

        # Dragging a scale modifier axis?
        elif self._modifierMode == ModifierMode.SCALE_NONUNIFORM and self._modifierAxis != ModifierAxis.NONE:
            deltaMouse = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y()) - self._modifyStartMouseScreenPos
            if self._modifierAxis == ModifierAxis.X:
                axisDir = cgmath.Vec3(1.0,0.0,0.0)
            elif self._modifierAxis == ModifierAxis.Y:
                axisDir = cgmath.Vec3(0.0,1.0,0.0)
            else:
                axisDir = cgmath.Vec3(0.0,0.0,1.0)

            screenDir = self._getModifierAxisScreenDir(axisDir)
            delta = screenDir[0]*deltaMouse[0] + screenDir[1]*deltaMouse[1]

            for node in self._currentModelNodes:
                node.size = axisDir * delta * 0.5 + self._modifyStartModelSize[node]

        # Selecting nodes?
        elif self._selecting:
            self._selectCurrentMouseScreenPos = self._convertMousePosToScreenPos(mouseEvent.localPos().x(), mouseEvent.localPos().y())

        self.update()