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