Управление изображением с помощью мыши
Отпускание правой кнопки должно просто отмечать факт прекращения перемещения вдоль оси Z и отпускать сообщения мыши для того, чтобы они работали на другие окна, в том числе и на наше окно-рамку. Если этого не сделать, то станет невозможным использование меню главного окна. Проверьте, если хотите. Для этого достаточно закомментировать вызов функции ReleaseCapture в обеих функциях:
void COGView::OnRButtonUp(UINT nFlags, CPoint point) { //====== Правая кнопка отпущена m_bRightButton = false; //====== Снимаем флаг захвата мыши m_bCaptured = false; //====== Отпускаем сообщения мыши ReleaseCapture(); }
Теперь реализуем самую сложную часть алгоритма – реакцию на перемещение курсора. Здесь мы должны оценить желаемую скорость вращения. Она зависит от того, насколько резко пользователь подвинул объект, то есть оценить модуль разности двух последних позиций курсора, В этой же функции надо выделить случай одновременного нажатия служебной клавиши CTRL Если она нажата, то интерпретация движения мыши при нажатой левой кнопке изменяется. Теперь вместо вращения мы должны сдвигать объект, то есть пропорционально изменять переменные m_xTrans и m_yTrans, которые затем подаются на вход функции glTranslate.
Третья ветвь алгоритма обрабатывает движение указателя при нажатой правой кнопке. Здесь необходимо изменять значение переменной m_zTrans, обеспечивая сдвиг объекта вдоль оси Z. Числовые коэффициенты пропорциональности, которые вы видите в коде функции, влияют на чувствительность мыши и подбираются экспериментально. Вы можете изменить их на свой вкус так, чтобы добиться желаемой управляемости изображения:
void COGView::OnMouseMove(UINT nFlags, CPoint point) { if (m_bCaptured) // Если был захват, { // Вычисляем компоненты желаемой скорости вращения m_dy = float (point.у – m_pt.у) /40 .f; m_dx = float (point.x – m_pt.x) /40 .f; //====== Если одновременно была нажата CTRL, if (nFlags & MK_CONTROL) { //=== Изменяем коэффициенты сдвига изображения m_xTrans += m_dx; m_yTrans -= m_dy; } else { //====== Если была нажата правая кнопка if (m_bRightButton) //====== Усредняем величину сдвига m_zTrans += (m_dx + m_dy)/2.f; else { //====== Иначе, изменяем углы поворота m_AngleX += m_dy; m_AngleY += m_dx; } } //=== В любом случае запоминаем новое положение мыши m_pt = point; Invalidate (FALSE); } }
Запустите и проверьте управляемость объекта. Введите коррективы чувствительности на свой вкус. Попробуйте скорректировать эффект влияния поворота вокруг оси X на интерпретацию знака желаемого вращения вокруг оси Y. Здесь можно воспользоваться стеком матриц моделирования. Теперь добавим код в заготовку функции реакции на сообщения таймера с тем, чтобы ввести фиксацию состояния вращения.