Прикрепление анимации к костям

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

В данном примере иерархия костей будет представлена иерархией D3DXFRAME. Если вы используете DirectX 8, то могли заметить, что не можете использовать объект D3DXFRAME; его структура определена в DirectX 9. Не расстраивайтесь; вспомогательный код Direct3D, используемый во всех демонстрационных программах этой книги, компенсирует недостающую структуру наличием ложной версии D3DXFRAME,

которую вы можете использовать. Вы можете найти поддельную версию структуры D3DXFRAME в файле Direct3D.h, находящемся в директории этой главы компакт-диска.

Структура D3DXFRAME использует два связанных списка указателей, которые применяются для создания иерархии. Из корневой структуры D3DXFRAME вы можете получать доступ к дочерним объектам, используя указатель D3DXFRAME::pFrameFirstChild, и к родственным объектам, используя указатель D3DXFRAME::pFrameSibling.

Следующая функция в классе cAnimationCollection, на которую вам необходимо обратить внимание, - Map. Используйте функцию Map для прикрепления указателя m_Bone анимационной структуры к фрейму, имеющему в иерархии фреймов то же самое имя.

Функция Map просматривает все объекты cAnimationSet и находящиеся в них объекты cAnimation. Название каждого объекта cAnimation сравнивается с названием каждого фрейма; если найдено совпадение, в указатель cAnimation::m_Bone устанавливается адрес фрейма.

Функция Map имеет в качестве параметра корневой фрейм иерархии.

void cAnimationCollection::Map(D3DXFRAME *RootFrame) {

// Просмотреть все наборы анимаций cAnimationSet *AnimSet = m_AnimationSets; while(AnimSet != NULL) {

// Просмотреть все объекты анимаций cAnimation *Anim = AnimSet->m_Animations;

while(Anim != NULL) {

// Просмотреть все фреймы в поисках совпадения Anim->m_Bone = FindFrame(RootFrame, Anim->m_Name) ;

// Перейти к следующему объекту анимации Anim = Anim->m_Next;

}

// Перейти к следующему объекту набора анимаций AnimSet = AnimSet->m_Next;

}

}

В то время как функция Map только просматривает все объекты cAnimationSet и cAnimation, функция FindFrame рекурсивно обрабатывает иерархию фреймов в поисках соответствия заданному имени. Когда такое имя найдено, функция FindFrame возвращает указатель на найденный фрейм. Посмотрите на код FindFrame, от которого зависит функция Map.

D3DXFRAME *cAnimationCollection::FindFrame(D3DXFRAME *Frame, char

*Name)

{

D3DXFRAME *FramePtr;

// Если нет фрейма, вернуть NULL if(!Frame) return NULL;

// Вернуть текущий фрейм, если имя не задано if(!Name) return Frame;

// Обработать дочерние фреймы

if((FramePtr = FindFrame(Frame->pFrameFirstChild, Name))) return FramePtr;

// Обработать родственные фреймы

if((FramePtr = FindFrame(Frame->pFrameSibling, Name))) return FramePtr;

// Ничего не найдено return NULL;

}

Можете расслабиться. Данные анимации были загружены, и вы прикрепили объекты анимации к иерархии костей. Осталось только обновить анимацию и установить матрицы преобразования для костей.

Считывание данных анимации из .X файлов || Оглавление || Обновление анимации