ПРОГРАМИРУЕМ 3D ГРАФИКУ ИСПОЛЬЗУЯ DirectX



Проверка попадания - часть 9


Зная положение указателя мыши в окне, необходимо выяснить, какая грань объекта будет содержать проекцию точки. Более того, если под указателем мыши находится сразу несколько граней, необходимо выбрать ближнюю (с минимальным значением z).

Делается это следующим образом. Сначала мы получаем список всех граней объекта, а затем по очереди проектируем вершины каждой грани на плоскость вида и проверяем, лежит ли точка попадания внутри многоугольника, образованного проекциями вершин. Если будет найдена грань, содержащая точку попадания, необходимо выяснить, не находится ли она перед предыдущей найденной гранью. После проверки всех граней мы получим желаемый результат.

Единственное затруднение может возникнуть при проектировании вершин грани на плоскость вида; этот процесс состоит из трех шагов. Сначала необходимо преобразовать координаты каждой вершины из локальных координат фрейма в систему общих, «мировых» координат. Затем мировые координаты преобразуются в однородные координаты в плоскости вида. Наконец, вектор однородных координат преобразуется в точку окна.

Выделение отдельной грани 4¦^i 173

Рисунок. 7-3. Грань, спроектированная в трехмерное окно


Кроме того, необходимо как-то определить, находится ли точка внутри многоугольника вершин, спроектированных на плоскость вида. Вскоре мы увидим, как это делается, а пока давайте взглянем на функцию, в которой проверяются попадания в грань:

BOOL C3dShape::HitTest(CPoint pt,

C3dViewport* pViewport, int* piFace, D3DVECTOR* pvHit)

int iHitFace = -1;

double dHitZ = 0;

// Просмотреть список граней D3DVECTOR lv;

D3DVECTOR wv;

D3DRMVECTOR4D sv;

for (int i = 0; i « nFaces; i++) {

// Получить данные грани IDirect3DRMFace* piFace ° NULL;

m hr = pIFac@List-»GetElement (i, spIFace) ;

ASSERT;SUCCEEDED(m_hr)) ;

// Получить количество вершин и разместить массив // для хранения экранных координат int nVert = pIFace-»GetVertexCount () ;

ASSERT(nVert » 2) ;

/h2>

Глава 7. Проверка попадания

POINT* pScrnVert = new POINT [nVert];




Содержание  Назад  Вперед