Сопоставление костей фреймам

Если вы просматривали .X файлы, вы могли заметить сходство объектов Frame и SkinWeights. Для каждой кости в вашей скелетной структуре есть соответствующий объект SkinWeights, встроенный в объект Mesh, который содержит имя объекта Frame (или ссылку Frame). Так и есть - каждая кость называется так же, как и соответствующий ей объект Frame!

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

Для этой книги я встроил данные сопоставления костей в структуру D3DXMESH-CONTAINER_EX, описанную в главе 1. Структура D3DXMESHCONTAINEREX (созданная специально для этой книги и описанная ниже) добавляет к структуре D3DX-MESHCONTAINER массив объектов текстур, контейнер вторичного меша и данные прикрепления костей.

struct D3DXMESHCONTAINER_EX : D3DXMESHCONTAINER {

IDirect3DTexture9 **pTextures;

ID3DXMesh *pSkinMesh;

D3DXMATRIX **ppFrameMatrices; D3DXMATRIX *pBoneMatrices;

// .. дополнительнные данные и функции

};

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

Структура D3DXMESHCONTAINER_EX предоставляет указатель для каждой матрицы преобразования костей, содержащейся в иерархии объектов D3DXFRAME_EX в массиве указателей (ppFrameMatrices). Используя эти указатели, вы можете поместить каждое преобразование в созданный в результате обновления скелетного меша массив pBoneMatrices.

Вы можете создать массивы указателей и матриц после загрузки иерархии костей, взяв количество костей в иерархии и создав указатели и объекты D3DXMATRIX:

// pSkinInfo = объект скелетного меша

// Получить количество костей в иерархии DWORD NumBones = pSkinInfo->GetNumBones();

// Создать массив указателей D3DXMATRIX

// для указания на каждое преобразование костей

D3DXMATRIX *ppFrameMatrices = new D3DXMATRIX*[NumBones];

// Создать массив объектов D3DXMATRIX для хранения фактических // преобразований, используемых при обновлении скелетного меша D3DXMATRIX *pBoneMatrices = new D3DXMATRIX[NumBones];

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

Сначала я вам покажу, как определять соответствие кости фрейму. Помните, ранее в этой главе я заметил, что кости имеют такие же имена, как и фреймы. Используя функцию ID3DXSkinInfo::GetBoneName вы можете получить имя кости для сравнения с фреймом.

// Просмотреть все кости и получить имя каждой for(DWORD i=0;i<pSkinInfo->GetNumBones();i++) (

// Получить имя кости

const char *BoneName = pSkinInfo->GetBoneName(i);

После того как вы получили имя кости, вы можете просмотреть список фреймов в иерархии для поиска совпадений. Чтобы сделать это, используйте рекурсивный вызов функции FindFrame, разработанной в разделе "Изменение положения костей" ранее в этой главе.

// pRootFrame = корневой объект фрейма D3DXFAME_EX

// Находит совпадающее имя в фреймах

D3DXFRAME_EX *pFrame = pRootFrame->Find(BoneName);

Если фрейм с заданной костью именем найден, вы можете привязать комбинированную матрицу преобразования фрейма. Если не найден, то ссылка устанавливается в NULL.

// Сравнить фрейм с костью if(pFrame)

pMesh->ppFrameMatrices[i] = &pFrame->matCombined; else

pMesh->ppFrameMatrices[i] = NULL;

}

На данный момент вам могут быть непонятны причины сопоставления костей фреймам, но вам станет все ясно, когда придет время управления скелетными мешами и восстановления меша для его визуализации.

Создание контейнера вторичного меша || Оглавление || Управление скелетными мешами