Программирование графики с использованием Direct3D

       

Функции класса FacePickWin для работы с мышью


В приложении FacePick мышь используется не только для выбора граней, но и для вращения сетки и изменения ее ориентации. Для отслеживания состояния левой кнопки мыши класс FacePickWin использует функции OnLButtonDown() и OnLButtonUp(). Код функции OnLButtonDown() выглядит следующим образом:

void FacePickWin::OnLButtonDown(UINT nFlags, CPoint point) { int faceindex = PickFace(point); if (faceindex != -1) { LPDIRECT3DRMFACEARRAY facearray; meshbuilder->GetFaces(&facearray);

LPDIRECT3DRMFACE face; facearray->GetElement(faceindex, &face); face->SetColor(pickcolor); face->Release(); facearray->Release(); } else if (!drag) { drag = TRUE; last_x = GetMouseX(); last_y = GetMouseY(); SetCapture(); ShowCursor(FALSE); } RMWin::OnLButtonDown(nFlags, point); }

Сперва функция OnLButtonDown() вызывает функцию PickFace(), которая и реализует операцию выбора. Функция PickFace() очень похожа на функцию PickMesh() из приложения MeshPick, за исключением того, что функция PickFace() возвращает индекс выбранной грани (или –1, если ни одна грань не была выбрана).

Если грань была выбрана, ее индекс используется для изменения цвета грани. Сначала для получения массива граней используется функция GetFaces() интерфейса Direct3DRMMeshBuilder. Полученный ранее индекс используется для извлечения указателя на выбранную грань. Затем для смены цвета грани вызывается функция SetColor() интерфейса Direct3DRMFace.

Если грань не выбрана, начинается операция перетаскивания. В приложении MeshPick операция перетаскивания использовалась для переперемещения выбранной сетки. В приложении FacePick операция перетаскивания применяется для вращения сетки. В данном случае при запуске операции перетаскивания текущие координаты указателя мыши сохраняются в переменных last_x и last_y, после чего вызываются функции SetCapture() и ShowCursor().

Теперь пришло время взглянуть на функцию OnLButtonUp():

void FacePickWin::OnLButtonUp(UINT nFlags, CPoint point) { if (drag) { end_drag = TRUE; ReleaseCapture(); ShowCursor(TRUE); } RMWin::OnLButtonUp(nFlags, point); }


Вы можете предположить, что функция OnLButtonUp() прекращает операцию перетаскивания (если она была начата). Однако, такое решение помешало бы реализации одной из возможностей приложения FacePick. Приложение FacePick позволяет пользователю вращать отображаемую сетку. Сетка может быть повернута в ходе операции перетаскивания, но, кроме того, может быть приведена в движение путем резкого перемещения мыши с одновременным отпусканием кнопки. Если поместить здесь код прекращения операции перетаскивания, эту возможность не удастся реализовать, поскольку код должен иметь возможность зафиксировать последние атрибуты вращения. Код установки атрибутов вращения находится в функции обратного вызова UpdateDrag(). Вместо того, чтобы дублировать этот код, мы устанавливаем флаг, сигнализирующий о завершении операции перетаскивания. Тем временем мы воосстанавливаем отображение указателя мыши и отменяем захват мыши программой, поскольку эти действия не влияют на код, связанный с атрибутами вращения.


Содержание раздела