После загрузки данных анимации вам необходимо прикрепить классы анимации к соответствующим им костям в иерархии костей. Сопоставление иерархий имеет большое значение, т. к. как только анимация обновляется, вам необходимо быстро получить доступ к преобразованиям костей. Сопоставив, вы можете получить простой метод доступа к костям.
В данном примере иерархия костей будет представлена иерархией 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 файлов || Оглавление || Обновление анимации⇒