Example #1
0
    def __init__(self, models):
        super(ModelerViewport, self).__init__()

        self.setLayout(vlayout())

        self._updateMinMouseClickDist()

        self._primitives = Primitives()

        self._models = models
        self._currentModel = None
        self._currentModelNodes = set()

        self._cameraTransform = cgmath.Mat44.translate(0, 0, -2)
        self._modelTransform =  cgmath.Mat44()
        self._viewTransform = cgmath.Mat44()

        self._cameraPivot = cgmath.Vec3(0.0,0.0,0.0)
        self._adjustingCamera = False
        self._adjustCameraMode = 0

        self._selecting = False

        self._modifierMode = ModifierMode.SELECT
        self._modifierAxis = ModifierAxis.NONE

        self.setFocusPolicy(Qt.StrongFocus)

        self.installEventFilter(self)
Example #2
0
    def loadState(self):
        # save user camera position per scene
        userFile = currentProjectFilePath().ensureExt('user')
        if not userFile.exists():
            return

        xUser = parseXMLWithIncludes(userFile)
        if xUser is None:
            return

        xMod = xUser.find('Modeler')
        if xMod is None:
            return

        if 'CurrentModel' in xMod.attrib:
            currentModelIndex = int(xMod.attrib['CurrentModel'])
        else:
            currentModelIndex = -1
        if currentModelIndex >= 0 and currentModelIndex < len(self._models.models):
            self.selectedModelNodesChanged.emit(self._models.models[currentModelIndex], None)
        else:
            self.selectedModelNodesChanged.emit(None, None)

        ct = list(map(float, xMod.attrib['CameraTransform'].split(',')))
        self._cameraTransform = cgmath.Mat44(ct[0],ct[1],ct[2],ct[3],ct[4],ct[5],ct[6],ct[7],ct[8],ct[9],ct[10],ct[11],ct[12],ct[13],ct[14],ct[15])

        ct = list(map(float, xMod.attrib['CameraPivot'].split(',')))
        self._cameraPivot = cgmath.Vec3(ct[0], ct[1], ct[2])

        self.update()
Example #3
0
    def _getModifierMVP(self):
        modelTransform = self._getCurrentMainModelNode().getModelTransform()
        modifierSize = 0.05 if self._modifierMode == ModifierMode.ROTATE else 0.10

        if self._modifierMode == ModifierMode.TRANSLATE:
            # Translation is in world space, simply emit world space axes
            nonScaledModelTransform = cgmath.Mat44.translate(modelTransform[12], modelTransform[13], modelTransform[14])
        else:
            # Orthonormalize modelTransform (remove scale)
            modelRight = cgmath.Vec3(modelTransform[0], modelTransform[1], modelTransform[2])
            modelUp = cgmath.Vec3(modelTransform[4], modelTransform[5], modelTransform[6])
            modelForward = cgmath.Vec3(modelTransform[8], modelTransform[9], modelTransform[10])
            modelRight.normalize()
            modelUp.normalize()
            modelForward.normalize()

            nonScaledModelTransform = cgmath.Mat44(modelRight[0], modelRight[1], modelRight[2], 0,
                                                   modelUp[0], modelUp[1], modelUp[2], 0,
                                                   modelForward[0], modelForward[1], modelForward[2], 0,
                                                   modelTransform[12], modelTransform[13], modelTransform[14], 1)

        mv = nonScaledModelTransform * self._viewTransform
        mvp = cgmath.Mat44.scale(modifierSize * mv[14], modifierSize * mv[14],
                                 modifierSize * mv[14]) * mv * self._projection

        return mvp
Example #4
0
 def setModelerCameraTransform(self, cameraTransform):
     self.__modelerCameraTransform = cameraTransform
     if self._cameraControlMode == CameraControlMode.MODELER:
         cameraTransformInv = cgmath.Mat44(cameraTransform)
         cameraTransformInv.inverse()
         angles = cameraTransformInv.eulerXYZ()
         self.__data = CameraTransform(cameraTransform[12],
                                       cameraTransform[13],
                                       cameraTransform[14], -angles[0],
                                       angles[1], -angles[2])
         self.cameraChanged.emit()
Example #5
0
    def paintGL(self):
        # view = inverse of camera, which is:
        self._viewTransform = \
            cgmath.Mat44.translate(-self._cameraTransform[12], -self._cameraTransform[13], -self._cameraTransform[14]) * \
            cgmath.Mat44(self._cameraTransform[0], self._cameraTransform[4], self._cameraTransform[8], 0, self._cameraTransform[1], self._cameraTransform[5], self._cameraTransform[9], 0, self._cameraTransform[2], self._cameraTransform[6], self._cameraTransform[10], 0, 0, 0, 0, 1)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Draw grid
        mvp = self._viewTransform * self._projection
        glUniformMatrix4fv(self._uniform_mvp, 1, False, (ctypes.c_float * 16)(*mvp))
        glUniform4f(self._uniform_color, 0.5, 0.5, 0.5, 1.0)
        glLineWidth(1)
        self._primitives.draw(PrimitiveType.GRID)

        # Draw nodes
        if self._currentModel is not None:
            # glLineWidth(2)

            # Put current model node at the end of the list
            nodes = list(self._currentModel.nodes)
            if len(self._currentModelNodes) > 0:
                for node in self._currentModelNodes:
                    nodes.remove(node)
                for node in self._currentModelNodes:
                    nodes.append(node)

            # Draw all nodes
            for node in nodes:
                modelTransform = node.getModelTransform()
                mvp = (modelTransform * self._viewTransform) * self._projection
                glUniformMatrix4fv( self._uniform_mvp, 1, False, (ctypes.c_float * 16)(*mvp))
                if node in self._currentModelNodes:
                    glUniform4f(self._uniform_color, 1.0, 1.0, 0.0, 1.0)
                else:
                    glUniform4f(self._uniform_color, 0.0, 0.0, 0.5, 1.0)
                self._primitives.draw(PrimitiveType.CUBE)

            # Draw our modifier?
            if self._modifierMode != ModifierMode.SELECT and len(self._currentModelNodes) > 0:
                self._drawModifier()

        # Draw selection rect
        if self._selecting and (self._selectCurrentMouseScreenPos - self._selectStartMouseScreenPos).lengthSq > 0.0:
            self._drawSelectionRect()
Example #6
0
    def axisAngle(self, axis, angle):
        # https://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/
        c = math.cos(angle)
        s = math.sin(angle)
        t = 1 - c
        m00 = c + axis[0] * axis[0] * t
        m11 = c + axis[1] * axis[1] * t
        m22 = c + axis[2] * axis[2] * t

        tmp1 = axis[0] * axis[1] * t
        tmp2 = axis[2] * s
        m10 = tmp1 + tmp2
        m01 = tmp1 - tmp2
        tmp1 = axis[0] * axis[2] * t
        tmp2 = axis[1] * s
        m20 = tmp1 - tmp2
        m02 = tmp1 + tmp2
        tmp1 = axis[1] * axis[2] * t
        tmp2 = axis[0] * s
        m21 = tmp1 + tmp2
        m12 = tmp1 - tmp2

        return cgmath.Mat44(m00, m01, m02, 0, m10, m11, m12, 0, m20, m21, m22, 0, 0, 0, 0, 1)
Example #7
0
    def __init__(self, animator, animationEditor, timer):
        super(Camera, self).__init__()
        self.setLayout(hlayout())

        self._freeCameraControlButton = QPushButton(
            icons.get('icons8-video-camera-50'), '')
        self._freeCameraControlButton.clicked.connect(
            self._setFreeCameraControl)
        self._freeCameraControlButton.setCheckable(True)
        self._freeCameraControlButton.setIconSize(QSize(24, 24))
        self._freeCameraControlButton.setToolTip("Free")
        self._animationCameraControlButton = QPushButton(
            icons.get('icons8-line-chart-50'), '')
        self._animationCameraControlButton.clicked.connect(
            self._setAnimationCameraControl)
        self._animationCameraControlButton.setCheckable(True)
        self._animationCameraControlButton.setIconSize(QSize(24, 24))
        self._animationCameraControlButton.setToolTip("Animation curves")
        self._modelerCameraControlButton = QPushButton(
            icons.get('icons8-grid-50'), '')
        self._modelerCameraControlButton.clicked.connect(
            self._setModelerCameraControl)
        self._modelerCameraControlButton.setCheckable(True)
        self._modelerCameraControlButton.setIconSize(QSize(24, 24))
        self._modelerCameraControlButton.setToolTip("Modeler viewport")

        self.layout().addWidget(self._freeCameraControlButton)
        self.layout().addWidget(self._animationCameraControlButton)
        self.layout().addWidget(self._modelerCameraControlButton)
        self.layout().addSpacing(24)

        self._cameraControlMode = CameraControlMode.FREE
        self.toggleBetweenFreeAndAnimation()

        timer.timeChanged.connect(self.__copyAnim)
        copyAnim = QPushButton(QIcon(icons.get('Film-Refresh-48')), '')
        copyAnim.setToolTip('Copy anim')
        copyAnim.setStatusTip('Copy anim')
        self.__animator = animator
        self.__animationEditor = animationEditor
        self._timer = timer
        copyAnim.clicked.connect(self.copyAnim)
        self.layout().addWidget(copyAnim)
        copyAnim.setIconSize(QSize(24, 24))

        self.__keyStates = {Qt.Key_Shift: False, Qt.Key_Control: False}
        for key in Camera.MOVE_LUT:
            self.__keyStates[key] = False
        for key in Camera.TURN_LUT:
            self.__keyStates[key] = False
        self.__data = CameraTransform()
        self.__modelerCameraTransform = cgmath.Mat44()
        self.__inputs = []
        for i, value in enumerate(self.__data):
            s = DoubleSpinBox(value)
            s.setMinimumWidth(50)
            self.__inputs.append(s)
            if i in (3, 4, 5):
                s.setSingleStep(5)
            self.layout().addWidget(s)
            s.valueChanged.connect(functools.partial(self.__setData, i))
        self.__prevTime = None
        self.__appLoop = QTimer()
        self.__appLoop.timeout.connect(self.flyUpdate)
        self.__appLoop.start(1.0 / 15.0)
        self.__drag = None
        self.__dirty = False
Example #8
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()