Системы скелетной анимации требуют иерархии фреймов (которые представлены структурой костей) для ориентации каждой кости при визуализации. Формат файла .X определяет шаблон данных ссылочных фреймов, который вы можете использовать для задания иерархии костей. Этот шаблон, Frame, просто ответственный за типы. Он позволяет встраивать объекты любого типа, так что вы можете ссылаться на ссылочный объект Frame, присваивая ему имя и позволяя адресовать все содержащиеся объекты.
Построение иерархии фреймов включает в себя анализ .X файла, в котором вы связываете каждый объект Frame между собой. Взаимоотношения очень важны -объект Frame может быть как родственником, так и потомком другого объекта Frame и может иметь неограниченное количество родственников и/или потомков, привязанных к нему.
В DirectX 9 вы можете получить доступ к специальной структуре DirectX, называемой D3DXFRAME, предназначенной для хранения каждого кадра в иерархии. Я говорил об этой структуре в главе 1. В этом разделе я использовал D3DXFRAME для хранения иерархии фреймов.
Каким образом вы будете анализировать и создавать объекты Frame, зависит от вас. Вы можете использовать библиотеку D3DX или анализировать/строить иерархию сами, используя специализированные анализаторы .X. Что лучше для вас? Принимая во внимание, что замечательно использовать библиотеку D3DX, я обнаружил, что методы использования библиотеки при загрузке иерархии фреймов сложны, необходимо создавать не менее двух используемых интерфейсов и самостоятельно написанный класс операций с памятью. Зачем волноваться, когда вы можете загружать иерархию, используя один маленький созданный вами класс анализирования .X?
Вместо этого возьмите проверенный анализатор .X (разработанный ранее в этой главе в разделе "Создание класса анализатора .X") и унаследуйте от него версию, которая ищет объекты Frame. Я начну, показав наследуемый класс, который можно использовать.
class cXFrameParser : public cXParser {
public:
// объявить расширенную версию D3DXFRAME
// которая содержит конструктор и деструктор
struct D3DXFRAME_EX : public D3DXFRAME {
D3DXFRAME_EX()
{
Name = NULL;
pFrameSibling = NULL; pFrameFirstChild = NULL;
}
~D3DXFRAME_EX()
{
delete [] Name;
delete pFrameFirstChild;
delete pFrameSibling;
}
} D3DXFRAME_EX;
// создать корневой фрейм иерархии D3DXFRAME_EX *m_RootFrame;
public:
cXFrameParser() { m_RootFrame = NULL; } ~cXFrameParser() { delete m_RootFrame; }
BOOL BeginParse(void **Data) {
// очистить иерархию
delete m_RootFrame; m_RootFrame = NULL;
}
BOOL ParseObject(IDirectXFileData *pDataObj, \ IDirectXFileData *pParentDataObj, \ DWORD Depth, \
void **Data, BOOL Reference)
{
// пропустить ссылочные фреймы if(Reference == TRUE) return TRUE;
// убедиться, что анализируемый шаблон - Frame if(*GetObjectGUID(pDataObj) == TID_D3DRMFrame) {
// Создать структуру фрейма
D3DXFRAME_EX *Frame = new D3DXFRAME_EX();
// Получить имя фрейма (назначить новое, если не было найдено) if((Frame->Name = GetObjectName(pDataObj)) == NULL) Frame->Name = strdup("No Name") ;
// связать структуру фрейма в список
if(Data == NULL) {
// связать как родственник корневого Frame->pFrameSibling = m_RootFrame; m_RootFrame = Frame; Data = (void**)&m_RootFrame; } else {
// связать как потомка текущего фрейма
D3DXFRAME_EX *FramePtr = (D3DXFAME_EX*)*Data;
Frame->pFrameSibling = FramePtr->pFrameFirstChild; FramePtr->pFrameFirstChild = Frame; Data = (void**)&Frame;
}
}
return ParseChildObjects(pDataObj,Depth,Data,Reference);
};
cXFrameParser Parser; Parser.Parse("frames.x");
// Parser.m_RootFrame теперь указывает на корневой фрейм иерархии
Вот и все. После завершения функции cXFrameParser::Parse у вас будет хранящаяся самостоятельно иерархия фреймов, готовая к использованию в ваших проектах. Чтобы лучше понять, как использовать этот класс, посмотрите демонстрационную программу ParseFrame компакт-диска книги (смотрите конец главы для дополнительной информации). Демонстрационная программа ParseFrame загружает выбранный вами.Х файл и отображает иерархию объектов в окне списка.
В оставшейся части книги вы увидите, как использовать иерархию фреймов для создания анимации.
⇐Загрузка скелетных мешей || Оглавление || Загрузка анимации из .X⇒