void arkOpenGLWidget::mouseMoveEvent(QMouseEvent* event) { QPoint currentMousePos(event->x(), event->y()); QPoint diff = currentMousePos - m_lastMousePos; if (event->modifiers() & Qt::ControlModifier) { m_mediator_shptr->translateCamera( diff.x(), diff.y(), 0 ); m_mediator_shptr->translateCamera(diff.x(), diff.y(), 0); } else if (event->modifiers() & Qt::ShiftModifier) { m_mediator_shptr->translateCamera(0, 0, -diff.y()); } else { m_mediator_shptr->rotateCamera(diff.x(), diff.y()); } m_lastMousePos = currentMousePos; }
void CrystalEditorFrame::OnMouseMove(wxMouseEvent& event) { if (!dragging) return; // Turn mouse movement to a movement of a virtual trackball (which is as big as the window). Vector3 currentMousePos(event.GetX(), event.GetY(), 0); int width, height; GetSize(&width, &height); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, width); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, height); double windowSize = std::min(width, height); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, windowSize); Vector3 center(0.5 * width, 0.5 * height, 0); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, center); Vector3 normPrevPos = (prevMousePos - center) / windowSize; log_var(CRYSTAL_EDITOR_MOUSE_MOVE, normPrevPos); Vector3 normPos = (currentMousePos - center) / windowSize; log_var(CRYSTAL_EDITOR_MOUSE_MOVE, normPos); // Invert vertical axis, because in camera space Y grow upward. normPrevPos.y = -normPrevPos.y; normPos.y = -normPos.y; // Calculate the Z position on the trackball normPrevPos.z = normPrevPos * normPrevPos <= 1 ? sqrt(1.0 - normPrevPos * normPrevPos) : 0; normPos.z = normPos * normPos <= 1 ? sqrt(1.0 - normPos * normPos) : 0; log_var(CRYSTAL_EDITOR_MOUSE_MOVE, normPrevPos); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, normPos); // Calculate the rotation axis Vector3 rotAxis = normPrevPos % normPos; double rotAxisLength = ~rotAxis; if (rotAxisLength == 0) { // No rotation. return; } rotAxis /= rotAxisLength; log_var(CRYSTAL_EDITOR_MOUSE_MOVE, rotAxis); // Calculate the real rotation axis and the angle. double rotAngle = acos((normPrevPos * normPos)/(~normPrevPos * ~normPos)); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, rotAngle); Vector3 realRotAxis = rotAxis.x * right + rotAxis.y * upward + rotAxis.z * backward; // Create the true rotation axis (in camera space). log_var(CRYSTAL_EDITOR_MOUSE_MOVE, realRotAxis); Matrix rotation = createRotationMatrix(realRotAxis, -rotAngle); // Negative as we rotate the view, not the object log_var(CRYSTAL_EDITOR_MOUSE_MOVE, rotation); backward = transformVector(rotation, backward); right = transformVector(rotation, right); upward = transformVector(rotation, upward); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, backward); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, right); log_var(CRYSTAL_EDITOR_MOUSE_MOVE, upward); fix3VectorSystem(right, upward, backward); prevMousePos.x = event.GetX(); prevMousePos.y = event.GetY(); prevMousePos.z = 0; // Calculate ray path updateRayPaths(); mainPanel->Refresh(); log_printf(CRYSTAL_EDITOR_MOUSE_MOVE, "========================\n"); }