- •Введение
- •Глава 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
- •Предметный указатель
270 |
Глава 9 |
Визуализации морфированного меша
После того как вы загрузили данные набора анимаций морфируемого меша, визуализировать его просто. Используя время из анимации, вы можете просмотреть массив ключей анимации и найти два из них, между которыми оно находится. Первый ключ содержит указатель на исходный меш, используемый при морфинге, а второй ключ содержит указатель на целевой меш.
Т. к. вы можете загружать неограниченное количество анимаций в объект коллекции, вам необходимо создать функцию, которая бы искала заданную именем анимацию, после чего просматривала бы эту анимацию на соответствующие значения ключей для визуализации. Это делает функция cMorphAnimationCollection::Update.
void cMorphAnimationCollection::Update( \ char *AnimationSetName, \
DWORD Time, BOOL Loop, \ D3DXMESHCONTAINER_EX **ppSource, \ D3DXMESHCONTAINER_EX **ppTarget, \ float *Scalar)
Хотя функция Update и кажется большой, на самом деле она очень проста в использовании. В качестве параметра AnimationSetName вам необходимо указать имя используемого набора анимации, в качестве параметра Time указать время анимации и повторять ли ее циклически или нет (установите Loop в TRUE или FALSE).
Также вам необходимо предоставить два указателя (ppSource и ppTarget) на объекты исходного и целевого мешей, используемые при морфируемой визуализации, и указатель на переменную, в которую будет помещено значение скаляра, используемого при морфинге.
Функция Update начинается с получения указателя на связанный список набора анимаций и очищения указателей, переданных функции.
{
cMorphAnimationSet *AnimSet = m_AnimationSets; // Очистить возвращаемые значения
*ppSource = NULL; *ppTarget = NULL; *Scalar = 0.0f;
Указатели очищаются на случай возникновения ошибки. Если возникает ошибка, вы можете проверить, установлены ли указатели в NULL. Если они имеют значение отличное от NULL, то это означает, что функция Update отработала корректно.
Использование морфирующей анимации, основаннойна ключевыхкадрах
Двигаясь дальше в функции, вы просматривает список наборов анимаций в поисках той, которая имеет такое же имя, как и заданное в параметре AnimationSetName. Вы можете вынудить функцию Update использовать первый набор анимации в связанном списке, установив AnimationSetName в NULL.
Название анимации должно совпадать с названием, хранимым в .X файле. Название из .X файла является именем экземпляра объекта набора анимации. Например, следующий объект набора анимации имеет имя экземпляра Walk:
MorphAnimationSet Walk
{
2;
0; "Figure1";, 500; "Figure2";;
}
Для того чтобы получить указатели на меши Figure1 и Figure2, вам необходимо задать Walk в качестве AnimationSetName. Я думаю вы поняли смысл, так что вот код, который просматривает список наборов анимации (прекращая работу функции, если не было найдено набора или если найденный набор не содержит ключей анимации).
// Искать заданное имя набора анимации, если используется if(AnimationSetName) {
// Найти заданное имя набора анимации while(AnimSet !=NULL) {
//Остановится, если совпадение найдено if(!stricmp(AnimSet->m_Name, AnimationSetName)) break;
//Перейти к следующему объекту набора анимации AnimSet = AnimSet->m_Next;
}
}
//Прекратить, если набор не был найден if(AnimSet == NULL)
return;
//Прекратить работу, если в наборе нет ключей if(!AnimSet->m_NumKeys)
return;
На данный момент вы имеете указатель на объект cMorphAnimationSet, который содержит данные ключей, используемые при морфированной анимации. Используя этот указатель (AnimSet), вы можете проверить, попадает ли время анимации, для которого вы получаете данные ключа, в фактическую продолжительность анимации (хранимой в переменной m_Length набора анимации).
272 Глава 9
// Сравнить время с продолжительностью анимации if(Time > AnimSet->m_Length)
Time = (Loop==TRUE)?Time%(AnimSet->m_Length+1):AnimSet->m_Length;
После этого вы можете просмотреть каждый ключ в наборе анимации и определить, какие использовать для получения указателей на исходный и целевой меши. Вы видели как просматривать ключи в главе 5, так что я пропущу объяснения и сразу перейду к коду.
// Просмотреть весь набор анимации и найти используемые ключи DWORD Key1 = AnimSet->m_NumKeys-1;
DWORD Key2 = AnimSet->m_NumKeys-1; for(DWORD i=0;i<AnimSet->m_NumKeys-1;i++) {
if(Time >= AnimSet->m_Keys[i].m_Time && \ Time < AnimSet->m_Keys[i+1].m_Time) (
// Нашли ключи, устанавливаем указатели и прерываем цикл Key1 = i;
Кеу2 = i+1; break;
}
}
Теперь, когда мы нашли ключи, используемые в морфированной анимации (хранящиеся как Key1 и Кеу2), можно вычислять значение скаляра морфирования на основе времени этих двух ключей.
// Вычислить используемое значение временного скаляра DWORD Key1Time = AnimSet->m_Keys[Key1].m_Time;
DWORD Key2Time = AnimSet->m_Keys[Key2].m_Time; float KeyTime = (float)(Time - Key1Time);
float MorphScale = 1.0f/(float)(Key2Time-Key1Time)*KeyTime;
Наконец вы можете установить указатели на целевой, исходный меши и скаляр (которые вы передавали в качестве параметров функции Update) в соответствующие значения.
// Установить указатели
*ppSource = AnimSet->m_Keys[Key1].m_MeshPtr; *ppTarget = AnimSet->m_Keys[Key2].m_MeshPtr; *Scalar = MorphScale;
}
Теперь, когда все классы и функции определены, можно возвращаться к работе! Посмотрите на пример использования только что созданных классов для загрузки и использования коллекции морфированных анимаций из файла MorphAnim.x. Сначала необходимо создать экземпляр объекта cAnimationCollection и загрузить последовательность наборов анимации.
Использование морфирующей анимации, основаннойна ключевыхкадрах
cMorphAnimationCollection MorphAnim;
MorphAnim.Load("MorphAnim.x");
Также необходимо загрузить меши. Вы можете использовать удобные вспомогательные функции, разработанные в главе 1, для загрузки набора мешей (из упомянутого ранее файла MorphAnim.x).
D3DXMESHCONTAINER_EX *Meshes;
LoadMesh(SMeshes, NULL, pDevice, "MorphAnim.x");
После того как меши и наборы анимации были загружены, вам необходимо сопоставить наборы анимации мешам при помощи функции cMorphAnimationCollection::Map.
MorphAnim.Map(MorphAnim);
После этого вы можете использовать функцию Update для получения исходного, целевого мешей и значения скаляра, необходимых для создания последовательной морфируемой анимации. Возвращаясь к тому разделу, где создавались шаблоны наборов морфированных анимаций, положим, что имеется два набора анимации - MyAnimation1 и MyAnimation2.
Мы будем использовать анимацию MyAnimation2, и необходимо определить, как обновить ее в момент времени 700 (задав бесконечное повторение). Следующий код определит используемые исходный, целевой меши и значение скаляра:
//pAnimCollection = заранее загруженный объект
//cMorphAnimationCollection
//Time = значение DWORD, содержащее используемое время
//анимации, в данном случае 700
//Указатели на исходный и целевой меши, используемые для
//визуализации
D3DXMESHCONTAINER_EX *pSource, *pTarget;
//Значения скаляра, используемое для морфирования float Scalar;
//Вызвать Update, указав морфируемый меш и данные скаляра MorphAnim.Update("MyAnimation2", Time, TRUE, \
&pSource, &pTarget, &Scalar);
Теперь указатели исходного и целевого меша содержат меши, используемые при визуализации морфированного меша, и Scalar, который содержит значение скаляра. Все начинает проясняться; все, что остается сделать, - это нарисовать морфируемый меш, используя технологии, рассмотренные в главе 8. Если хотите,