- •Введение
- •Глава 1. Подготовка к изучению книги
- •Установка DirectX SDK
- •Выбор отладочных или рабочих версий библиотек
- •Настройка вашего компилятора
- •Установка директорий DirectX SDK
- •Привязывание к библиотекам DirectX
- •Установка используемого по умолчанию состояния символа
- •Использование вспомогательного кода книги
- •Использование вспомогательных объектов
- •Проверка вспомогательных функций
- •Двигаясь дальше по книге
- •Глава 2. Синхронизация анимации и движения
- •Использование движения, синхронизированного по времени
- •Считывание времени в Windows
- •Анимирование с использованием временных меток
- •Перемещение, синхронизированное со временем
- •Движение вдоль траекторий
- •Создание анализатора маршрутов .X файла
- •Создание внутриигровых кинематографических последовательностей
- •Посмотрите демонстрационные программы
- •TimedAnim
- •TimedMovement
- •Route
- •Cinematic
- •Глава 3. Использование формата файла .X
- •Работа с .X шаблонами и объектами данных
- •Определение шаблонов
- •Работа со стандартными шаблонами DirectX
- •Открытие .X файла
- •Перечисление объектов данных
- •Получение данных объекта
- •Создание класса .X анализатора
- •Загрузка мешей с использованием D3DX
- •Загрузка мешей, используя анализатор .X
- •Загрузка скелетных мешей
- •Загрузка анимации из .X
- •Загрузка специализированных данных из .X
- •Посмотрите демонстрационные программы
- •ParseFrame
- •Глава 4. Работа со скелетной анимацией
- •Начало скелетной анимации
- •Использование структур скелетов и иерархий костей
- •Использование скелетной структуры и скелетного меша
- •Загрузка иерархий из .X
- •Изменение положения костей
- •Обновление иерархии
- •Работа со скелетными мешами
- •Загрузка скелетных мешей из .X
- •Создание контейнера вторичного меша
- •Сопоставление костей фреймам
- •Обновление скелетного меша
- •Визуализация скелетных мешей
- •Глава 5. Использование скелетной анимации, основанной на ключевых кадрах
- •Использование наборов скелетных анимаций, основанных на ключевых кадрах
- •Использование ключей при анимации
- •Работа с четырьмя типами ключей
- •Считывание данных анимации из .X файлов
- •Прикрепление анимации к костям
- •Обновление анимации
- •Посмотрите демонстрационные программы
- •Глава 6. Комбинирование скелетных анимаций
- •Комбинирование скелетных анимаций
- •Соединение преобразований
- •Улучшение объектов скелетной анимации
- •Посмотрите демонстрационные программы
- •Глава 7. Создание кукольной анимации
- •Работа с физикой твердого тела
- •Создание твердого тела
- •Расположение и ориентирование твердых тел
- •Обработка движения твердых тел
- •Использование сил для создания движения
- •Соединение твердых тел с помощью пружин
- •Обеспечение обнаружения столкновений и ответной реакции
- •Создание систем кукольной анимации
- •Определение состояния твердого тела
- •Хранение костей
- •Создание класса управления куклой
- •Создание данных костей
- •Вычисление ограничивающего параллелепипеда кости
- •Установка сил
- •Объединение костей
- •Обработка столкновений
- •Восстановление соединений костей
- •Перестроение иерархии
- •Посмотрите демонстрационные программы
- •Глава 8. Работа с морфирующей анимацией
- •Морфинг в действии
- •Определение исходного и целевого меша
- •Морфинг мешей
- •Создание морфированного меша при помощи обработки
- •Визуализация морфированных мешей
- •Расчленение наборов
- •Создание морфирующего вершинного шейдера
- •Посмотрите демонстрационные программы
- •Глава 9. Использование морфирующей анимации, основанной на ключевых кадрах
- •Использование наборов морфируемой анимации
- •Создание шаблонов .X для морфируемой анимации
- •Загрузка данных морфируемой анимации
- •Визуализации морфированного меша
- •Получение данных морфируемого меша из альтернативных источников
- •Посмотрите демонстрационные программы
- •Глава 10. Комбинирование морфированных анимаций
- •Комбинирование морфированных анимаций
- •Использование базового меша в комбинированных морфированных анимациях
- •Вычисление разностей
- •Комбинирование разностей
- •Создание вершинных шейдеров комбинированного морфирования
- •Использование вершинного шейдера морфируемого комбинирования
- •Посмотрите демонстрационные программы
- •Глава 11. Морфируемая лицевая анимация
- •Основы лицевой анимации
- •Использование комбинированного морфирования
- •Использования фонем для речи
- •Создание лицевых мешей
- •Создание базового меша
- •Создание выражений лица
- •Создание мешей визем
- •Создание анимационных последовательностей
- •Создание последовательностей фонем
- •Использование анализатора файлов .X для последовательностей
- •Проигрывание лицевых последовательностей со звуком
- •Использование DirectShow для звука
- •Синхронизация анимации со звуком
- •Зацикливание воспроизведения звуков
- •Посмотрите демонстрационные программы
- •Глава 12. Использование частиц в анимации
- •Работа с частицами
- •Основы
- •Рисование частиц с помощью квадратных полигонов
- •Работа с точечными спрайтами
- •Улучшения визуализации частиц при помощи вершинных шейдеров
- •Оживление частиц
- •Передвижение частиц при помощи скорости
- •Использование интеллекта при обработке
- •Создание и уничтожение частиц
- •Управление частицами с помощью класса
- •Использование излучателей в проектах
- •Создание движков частиц в вершинных шейдерах
- •Посмотрите демонстрационные программы
- •Глава 13. Имитирование одежды и анимация мешей мягких тел
- •Имитация одежды в ваших проектах
- •Получение данных одежды из мешей
- •Приложение сил для создания движения
- •Воссоздание и визуализация меша одежды
- •Восстановление исходного меша
- •Добавление дополнительных пружин
- •Загрузка данных масс и пружин из .X файла
- •Создание анализатора .X данных одежды
- •Работа с обнаружением столкновений и реакцией на них
- •Определение объектов столкновений
- •Обнаружение и реакция на столкновения
- •Создание класса меша одежды
- •Использование мешей мягких тел
- •Восстановление мешей мягких тел
- •Посмотрите демонстрационные программы
- •Глава 14. Использование анимированных текстур
- •Использование анимации текстур в ваших проектах
- •Работа с преобразованиями текстур
- •Создание преобразования текстур
- •Установка матриц преобразования текстуры
- •Использование преобразования текстур в проектах
- •Использование файлов видео в качестве текстур
- •Импорт видео при помощи DirectShow
- •Создание специализированного фильтра
- •Работа со специализированным фильтром
- •Создание менеджера анимированных текстур
- •Окончание современной анимации
- •Веб-сайты
- •Рекомендуемые книги
- •DirectX 9.0 SDK
- •GoldWave Demo
- •Paint Shop Pro Trial Version
- •TrueSpace Demo
- •Microsoft Agent and LISET
- •Предметный указатель
164 |
Глава 5 |
Последним является код для считывания массива ключей преобразования.
case 4: // Матрица преобразования delete [] Anim->m_MatrixKeys; Anim->m_NumMatrixKeys= NumKeys;
Anim->m_MatrixKeys= new cAnimationMatrixKey[NumKeys]; for(i=0;i<NumKeys;i++) {
// Получить время Anim->m_MatrixKeys[i].m_Time=*DataPtr++; if(Anim->m_MatrixKeys[i].m_Time> \
m_AnimationSets->m_Length) m_AnimationSets->m_Length = \
Anim->m_MatrixKeys[i].m_Time;
//Пропустить количество далее следующих ключей (должно быть 16) DataPtr++;
//Получить значения матриц
D3DXMATRIX *mPtr = (D3DXMATRIX *)DataPtr; Anim->m_MatrixKeys[i].m_matKey = *mPtr; DataPtr += 16;
}
break;
}
}
Хорошо, передохните немного и давайте посмотрим, чего мы достигли. Пока что мы обработали каждый объект AnimationSet, Animation и AnimationKey (не беря во внимание ссылочный объект Frame, который содержит названия костей) и загрузили объекты ключей, содержащие данные анимации. Вы почти готовы начать анимирование!
Почти является правильным словом; остался один небольшой шаг - прикрепление объектов анимации к соответствующим им объектам костей.
Прикрепление анимации к костям
После загрузки данных анимации вам необходимо прикрепить классы анимации к соответствующим им костям в иерархии костей. Сопоставление иерархий имеет большое значение, т. к. как только анимация обновляется, вам необходимо быстро получить доступ к преобразованиям костей. Сопоставив, вы можете получить простой метод доступа к костям.
В данном примере иерархия костей будет представлена иерархией 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.
166
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;
}
Можете расслабиться. Данные анимации были загружены, и вы прикрепили объекты анимации к иерархии костей. Осталось только обновить анимацию и установить матрицы преобразования для костей.
Обновление анимации
После прикрепления классов анимации к иерархии костей вы можете начать анимировать меши! Все, что необходимо сделать, - это просмотреть ключи анимации для каждой кости, накладывая интерполированные преобразования на преобразования костей перед визуализацией. Это можно сделать простым перебором каждого класса анимации и его ключей для нахождения используемых значений ключа.
Вернувшись к классу cAnimationCollection, вы можете увидеть, что всего одна функция выполнит все это за вас. Предоставив функции cAnimationCollection::Update в качестве параметра название используемого набора анимаций и время в анимации, все матрицы преобразования во всей иерархии прикрепленных костей будут установлены и готовы к визуализации.
Посмотрите на функцию Update, чтобы иметь представление о том, как обновлять данные анимации.
Использование скелетнойанимации, основанной на ключевыхкадрах
void cAnimationCollection::Update(char *AnimationSetName, \ DWORD Time)
{
cAnimationSet *AnimSet = m_AnimationSets; DWORD i, Key, Key2;
// Искать совпадающее название набора анимации, если установлено if(AnimationSetName) {
// Искать совпадающее название набора анимации while(AnimSet != NULL) {
//Прекратить, если совпадение найдено if(!stricmp(AnimSet->m_Name, AnimationSetName)) break;
//Перейти к следующему объекту набора анимаций AnimSet = AnimSet->m_Next;
}
}
// Вернуть, если набор не был найден if(AnimSet == NULL)
return;
Функция Update начинает работу с просмотра наборов анимаций, загруженных в связанный список. Если вы установите значение NULL в качестве AnimationSetName, Update просто будет использовать первый набор анимаций в списке (который обычно является последним загруженным). Если при использовании заданного названия не было найдено совпадений, функция без промедления прекращает работу.
Однако, как только найден соответствующий набор анимаций, функция продолжает работу, просматривая каждый объект cAnimation в нем. Для каждого объекта анимации ищется ключ (перемещения, масштабирования, вращения и преобразования), который необходимо использовать для заданного значения времени.
После того как подходящий ключ обнаружен, значения (вращения, масштабирования, перемещения или преобразования) интерполируются и вычисляется матрица результирующего преобразования. Далее эта матрица хранится в прикрепленной кости (на которую указывает указатель m_Bone).
Вы уже видели, как просматривать список ключей для поиска тех, между которыми находится заданное время, так что я пропущу этот код. Смотрите его на компакт-диске книги; для получения дополнительной информации о демонстрационной программе BoneAnim читайте конец главы.
После вычисления преобразований, накладываемых на каждую кость из данных анимации, вы можете вернуться в игру и визуализировать меш, используя методы, изученные в главе 1. Помните, вы должны наложить матрицы преобразования на
168 |
Глава5 |
каждую кость соответствующей вершины, и лучшим способом сделать это является использование вершинных тейдеров. Если вам необходимо, вы можете обратиться к главе 1, чтобы вспомнить как визуализировать скелетные меши.
Получение скелетныхданных меша из альтернативных источников
Формат файла Microsoft .X является не единственным, используемым для хранения данных мешей и анимаций. Есть еще два формата, сравнимые с ним по простоте использования, которые являются замечательными для хранения данных мешей и анимаций, - форматы chUmbaLum sOft's Milkshape 3D .MS3D и id Software's Quake 2 .MD2.
Формат файла Milkshape .MS3D похож на двоичный .X, за исключением того, что файл .MD3D хранит только один меш и иерархию костей. На самом деле, формат .MS3D является очень простым, т. к. не использует шаблоны; вместо этого в файле хранится заранее определенная последовательность структур.
Формат файла Quake 2 .MD2 является простым набором мешей, помещенных в один файл. Каждый меш представляет собой один кадр анимации из последовательности ее наборов. В то время как файлы .MS3D содержат скелетные анимации, формат .MD2 содержит только наборы морфируемых анимаций.
Замечание. Морфированная анимация мешей является еще одной привлекательной темой, освещенной в книге, так что я просто указал на двойственность программы MeshConv.Пока что просто игнорируйте любыеупоминания морфированной анимации и вернитесь к теме: преобразование наборов скелетных анимаций, основанных на ключевых кадрах из .MS3D в .X.
Итак, для скелетных анимаций вы можете использовать файлы .MS3D, а для морфируемых анимаций .MD2. Как же конкретно их использовать? Существует множество информации об этих форматах. Посмотрите книжку Focus On 3D Models (Premier Press, 2002) или веб-сайты http://www.gamedev.net или http://nehe.gamedev.net.
Компакт-диск содержит программу MeshConv, которую вы можете использовать для преобразования файлов .MS3D и .MD2 в .X. После запуска программы вы увидите диалоговое окно MeshConv, показанное на рис. 5.2.
Не дайте неказистости кнопок в программе MeshConv напугать вас - она конвертирует все файлы .MS3D и .MD2 files в .X, используя шаблоны, виденные вами в этой главе. Файлы .MS3D сохраняются, используя иерархию фреймов и один объект AnimationSet, в то время как файлы .MD2 сохраняются, используя набор объектов Mesh и MorphAnimationSet, которые хранят названия мешей, используемых для морфированной анимации.
Использованиескелетнойанимации, основаннойнаключевыхкадрах
Рис. 5.2. Диалоговое окно MeshConv содержит две кнопки, щелкнув на которые вы можете преобразовать файлы .MS3D и .MD2 в .X
Замечание. На компакт-диске содержится полностью комментированный исходный код программы MeshConv. Читайте конец этой главы, чтобы подробнее узнать о программах и их местоположениях.
Для преобразования файла (.MS3D или .MD2) в .X файл щелкните по соответствующей кнопке в диалоговом окне MeshConv. Появится диалоговое окно "Open File". Это диалоговое окно позволяет вам перемещаться по директориям для указания расположения конвертируемого файла. Выберете необходимый для конвертации файл и нажмите "Open".
Появится диалоговое окно "Save .X File". Вы можете использовать его для указания имени и положения файла, в котором вы хотите сохранить данные мешей и анимации. Введите имя файла и нажмите "Save". Через некоторое время вы должны увидеть окно сообщений, говорящее о том, что преобразование было выполнено успешно.
Теперь вы готовы использовать .X файлы при помощи классов, разработанных ранее в этой главе, для загрузки наборов скелетной или морфируемой анимации. Набор скелетных анимаций использует один исходный меш, деформируемый (shaped) иерархией костей; для получения дополнительной информации об использовании скелетных мешей читайте эту главу и главу 2.
Для морфируемых анимаций (из .MD2) используется последовательность объектов Mesh, содержащих все цели морфирования меша из исходного файла. Всего один объект MorphAnimationSet поможет вам загрузить данные анимации в ваш проект, используя ранее изученные классы и технологии.
В качестве примера работы с конвертированным, при использовании программы MeshConv, .X файлом смотрите демонстрационные программы, включенные в эту главу. Вы правильно поняли - программы BoneAnim и MorphAnim используют конвертированные файлы .MS3D и .MD2 для иллюстрирования скелетной и морфируемой анимации. Посмотрите их и получайте удовольствие!