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

       

Функция FacePickWin::PickFace()


Функция PickFace() использует функцию Pick() интерфейса Direct3DRMViewport для выполнения операции выбора. Если в результате выполнения операции выбора был возвращен объект, функция вернет индекс грани этого объекта. Код функции PickFace() выглядит следующим образом:

int FacePickWin::PickFace(const CPoint& point) { HRESULT r; LPDIRECT3DRMPICKEDARRAY pickarray;

viewport->Pick(point.x, point.y, &pickarray);

int faceindex = -1; DWORD numpicks = pickarray->GetSize(); if (numpicks > 0) { LPDIRECT3DRMVISUAL visual; LPDIRECT3DRMFRAMEARRAY framearray; D3DRMPICKDESC pickdesc;

r = pickarray->GetPick(0, &visual, &framearray, &pickdesc); if (r == D3DRM_OK) { faceindex = pickdesc.ulFaceIdx; visual->Release(); framearray->Release(); } } pickarray->Release(); return faceindex; }

Сперва вызывается функция Pick() интерфейса Direct3DRMViewport. В первых двух аргументах этой функции передаются текущие координаты указателя мыши. Третий аргумент— это адрес указателя на интерфейс Direct3DRMPickedArray.

Затем вызывается функция GetSize(), чтобы определить, был ли выбран какой-либо объект. Если массив пуст, указатель pickarray освобождается и функция возвращает –1. Если в массиве есть элементы, первый из них извлекается с помощью функции GetPick(). Нам необходим только первый элемент, поскольку элементы массива отсортированы по значению координаты Z, а нас интересует самый близкий к зрителю объект.

Функция GetPick() инициализирует два указателя и структуру. Первый указатель указывает на видимый объект, который был выбран. В нашем случае указатель visual будет указывать на сетку, созданную в функции CreateScene() (поскольку эта сетка является единственным видимым объектом сцены). Однако указатель на видимый объект нас не интересует. Он мог бы потребоваться, если бы сцена содержала несколько сеток (как в приложении MeshPick). Второй указатель, инициализируемый функцией GetPick() — это указаетль на массив фреймов. Эти данные нас также не интересуют, по рассмотренным выше причинам.

Данные, в которых мы нуждаемся, — это индекс выбранной грани. Функция GetPick() сохраняет это значение в поле ulFaceIdx структуры D3DRMPICKDESC. Функция PickFace() сохраняет это значение и возвращает его после освобождения своих локальных указателей, завершая тем самым свою работу.

Между прочим, структура D3DRMPICKDESC содержит еще два поля, которые могут оказаться полезными:

  • lGroupIdx: Содержит индекс группы граней сетки. Интерфейс Direct3DRMMesh поддерживает работу с несколькими группами граней в сетке. Индекс группы идентифицирует группу, в которую входит выбранная грань.
  • vPosition: Ориентация грани. Этот вектор указывает лицевое направление выбранной грани.


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