Функция 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 содержит еще два поля, которые могут оказаться полезными: