- •Введение
- •Глава 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
- •Предметный указатель
Работасоскелетнойанимацией
Вы заметите также, что функция ParseObject содержит код для загрузки матрицы преобразования (трансформации) фрейма (представленной шаблоном FrameTransformMatrix). Обычно объект FrameTransformMatrix встраивается в объект Frame. Объект FrameTransformMatrix определяет начальное положение загруженного фрейма.
Примененная к скелетной анимации, эта матрица преобразования фрейма определяет начальную позу вашей скелетной структуры. Например, стандартная скелетная структура может находится в позе, в которой тело расположено вертикально, а руки расставлены. Однако предположим, что все ваши анимации рассчитаны на персонаж, находящийся в другой позе, возможно с руками по швам и чуть согнутыми ногами. Вместо того чтобы менять положение всех вершин или костей, чтобы они соответствовали позе, перед сохранением .X файла в вашей программе трехмерного моделирования вы можете изменить преобразования фреймов. Таким образом, все движения костей будут происходить относительно этой позы. Это становится более понятным после того, как вы попробуете управлять положением костей при анимации, так что я пока пропущу эту тему. Просто запомните, что внутри каждой загружаемой структуры фрейма есть место для хранения начальной матрицы преобразования (в объекте D3DXFRAME::TransformationMatrix).
После выполнения всего сказанного иерархия фреймов будет загружена. Корневой фрейм хранится в mRootFrame связанного списка объектов D3DXFRAMEEX
вклассе загрузки фреймов. Вашей задачей является использование этого указателя
вваших программах. После этого вы можете начать разбираться с положением костей.
Изменение положения костей
После того как вы загрузили иерархию костей, вы можете управлять ими. Для изменения положения кости вам необходимо обнаружить соответствующую ей структуру фрейма, создав функцию, которая бы рекурсивно просматривала фрейм на совпадение с именем кости. Как только он будет найден, у вас будет указатель на него, который вы можете использовать для получения доступа к матрице преобразования. Функция рекурсивного поиска может иметь такой вид:
D3DXFRAME_EX *FindFrame(D3DXFRAME_EX *Frame, char *Name)
{
// Искать только не пустые имена if(Frame && Frame->Name && Name) {
// Вернуть указатель на фрейм, если имя совпадает if(!strcmp(Frame->Name, Name))
return Frame;
}
132
// попробовать найти заданное имя в родственных фреймах if(Frame && Frame->pFrameSibling) {
D3DXFRAME_EX *FramePtr = \ FindFrame((D3DXFRAME_EX*)Frame->pFrameSibling, \
Name);
if(FramePtr) return FramePtr;
}
// попытаться найти имя в дочерних фреймах if(Frame && Frame->pFrameFirstChild) { D3DXFRAME_EX *FramePtr = \
FindFrame((D3DXFRAME_EX*)Frame->pFrameFirstChild, \ Name);
if(FramePtr) return FramePtr;
}
// ничего не найдено, возвращаем NULL return NULL;
}
Замечание. Вы можете применять любые преобразования к кости в иерархии, но рекомендуется использовать только повороты. Почему только повороты? Подумайте об этом так: когда вы сгибаете локоть, он вращается. А что вы скажете, если вместо этого переместить локоть? Получится, что локоть отделится от вашей руки, чего бы вам определенно не хотелось!
Если вы хотите переместить весь меш, просто перемещайте корневую кость; это преобразование распространится на все остальные кости. А еще лучше использовать преобразование мира, чтобы двигать ваш меш-объект.
Предположим, вы хотите найти кость "Leg" используя функцию FindFrame. Вы просто указываете имя этой кости и указатель на корневой объект фрейм, как показано тут:
// pRootframe = указатель на корневой фрейм D3DXFRAME_EX D3DXFRAME_EX *Frame = FindFrame(pRootFrame, "Leg"); if(Frame) {
// Сделать что-нибудь с фреймом, как, например, заменить
// |
одну матрицу преобразования |
D3DXFRAME_EX::TransformationMa- |
trix |
// на другую. |
|
// Здесь давайте немного повернем кость D3DXМatrixRotationY(&Frame->TransformationМatrix, 1.57f);
}
Работасоскелетнойанимацией |
133 |
Обновление иерархии
После того как вы изменили матрицу преобразования костей, вам необходимо обновить всю иерархию, чтобы вы могли использовать ее для последующей визуализации. Даже если вы не изменяли матрицу преобразования костей, вам все равно необходимо обновить иерархию для установления некоторых переменных перед визуализацией.
Во время обновления иерархии вам необходимо комбинировать удачные трансформации вниз по иерархии. Начиная с корня, вы накладываете матрицу преобразования костей на комбинированную матрицу преобразования фреймов. Матрица преобразования костей накладывается также на все родственные фреймы корневого. После этого только что посчитанная матрица преобразования накладывается на все дочерние фреймы корневого. Этот процесс распространяется на всю иерархию.
Хотя это и трудно понять сразу, сделайте так: возьмите скелетную структуру, показанную на рис. 4.2, и, начиная с корня, умножайте ее на матрицу преобразования, которая размещает корень в мире.
Кость |
Преобразование |
Шея |
Шеи |
Плечо= |
Плеча х Шеи |
Локоть= |
Локтя х Плеча х Шеи |
Кисть= |
Кисти хЛоктях Плеча х Шеи |
Рис. 4.2. Простая скелетная структура слева использует преобразования костей справа для расположения фреймов
Как вы можете видеть на рис. 4.2, комбинированное преобразование корня применяется на все дочерние кости, которые в свою очередь тоже комбинированные. Результаты передаются дочерним костям тех костей. Однако расчет матриц преобразования показанным путем слишком труден, так что необходимы другие пути.
134 |
Глава 4 |
Самым простым способом обновления иерархии фреймов является создание рекурсивной функции, которая бы комбинировала матрицу преобразования фрейма с заданной матрицей преобразования. Далее матрица преобразования передается родственникам, а комбинированная матрица - потомкам. Посмотрите на такую функцию.
void UpdateHierarchy(D3DXFRAME_EX *Frame, \ D3DXMATRIX matTransformation = NULL)
{
D3DXFRAME_EX*pFramePtr; D3DXMATRIX matIdentity;
// Использовать единичную матрицу, если ничего не было передано if(!matTransformation) {
D3DXMatrixIdentity(&matIdentity); matTransformation = &matIdentity;
}
//Комбинировать матрицу преобразования с заданной matCombined = TransformationMatrix * (*matTransformation);
//Комбинировать с родственными фреймами
if((pFramePtr = (D3DXFRAME_EX*)pFrameSibling)) pFramePtr->UpdateHierarchy(matTransformation);
// Комбинировать с дочерними фреймами if((pFramePtr = (D3DXFRAME_EX*)pFrameFirstChild)) pFramePtr->UpdateHierarchy(&matCombined);
}
Как вы можете здесь видеть, функция UpdateHierarchy использует в качестве первого параметра объект D3DXFRAME_EX, который является текущим обрабатываемым фреймом. Вам необходимо вызвать функцию UpdateHierarchy только один раз, задав указатель на корневой фрейм; функция рекурсивно будет вызывать сама себя для каждого фрейма.
Второй параметр UpdateHierarchy - matTransformation. Параметр matTransformation является матрицей преобразования, накладываемой на преобразование фрейма. По умолчанию указатель matTransformation является NULL, означая, что будет использоваться единичная матрица при вызове UpdateHierarchy. После того как матрица фрейма комбинируется с заданным преобразованием, результирующее преобразование передается дочерним фреймам в качестве параметра matTransformation при следующих вызовах функции.
Замечание. Если вы уже читали главу 1 (наверное, читали), тогда должны были заметить, что функция UpdateHierarchy содержится в классе D3DXFRAME_EX, так что вместо вызова функции UpdateHierachy, используя в качестве параметра корневой фрейм, вы можете использовать функцию-член корневого фрейма ::UpdateHierarchy! Для получения дополнительной информации обэтой функции-члене читайте главу 1.