- •Введение
- •Глава 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
- •Предметный указатель
Созданиекукольнойанимации
if(vecSize->y < MINIMUM_BONE_SIZE) { vecSize->y = MINIMUM_BONE_SIZE; vecMax.y = MINIMUM_BONE_SIZE*0.5f;
}
ifvecSize->z < MINIMUM_BONE_SIZE) { vecSize->z = MINIMUM_BONE_SIZE; vecMax.z = MINIMUM_BONE_SIZE*0.5f;
}
//Установать смещение кости в центр, основываясь на половине
//размера ограничивающего параллелепипеда и максимальном
//положении
(*vecJointOffset) = ((*vecSize) * 0.5f) - vecMax;
}
В самом конце функции вы наконец то обнаружите вектор vecJointOffset о котором я говорил при создании функции GetBoundingBoxSize. Т. к. кость твердого тела может быть любого размера, а вы отслеживаете ее с помощью координат ее центра, необходимо создать дополнительную точку, которая бы представляла собой точку присоединения ограничивающего параллелепипеда к родителю. Это и есть вектор смещения соединения. Вы узнаете о нем больше при изучении усиления связей костей.
После того как вы вычислили размер ограничивающего параллелепипеда и установили разнообразные данные кости, вы можете прикладывать различные силы для нахождения движения костей.
Установка сил
Для любой прикладываемой силы (решайте сами, какие использовать) вы должны учитывать силу тяжести и амортизации. В классе cRagdoll я определил функцию, которая находит векторы силы и момента одной кости, после чего применяет к ней силы тяжести и амортизации.
void cRagdoll::SetForces(DWORD BoneNum, D3DXVECTOR3 *vecGravity,
float LinearDamping, float AngularDamping)
{
//Получить указатель на кость cRagdollBone *Bone = &m_Bones[BoneNum];
//Получить указатель на текущее состояние cRagdollBoneState *BCState = &Bone->m_State;
//Установить гравитацию и очистить момент
Bone->m_vecForce = ((*vecGravity) * Bone->m_Mass);
Bone->m_vecTorque = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
232
// Наложить амортизацию на силу и момент Bone->m_vecForce += (BCState->m_vecLinearVelocity * \
LinearDamping);
Bone->m_vecTorque += (BCState->m_vecAngularVelocity * \ AngularDamping);
}
Вы читали о силах тяжести и амортизации ранее в этой главе, поэтому мне не надо объяснять их опять. Вы заметите, что я масштабирую вектор силы тяжести на массу кости. Помните, что это необходимо для того, чтобы гравитация притягивала все объекты с одинаковой силой, когда вы потом масштабируете силы в соответствии с массой.
После того как вы установили силы, вы можете находить (интегрировать) движение заданной кости.
Объединение костей
После того как вы установили силу и момент кости, вы можете использовать эти векторы для нахождения движения твердого тела. Вы заметите, что на данный момент я работаю с одной костью. Достаточно двигать кости поочередно, в конце концов, объединив их перед визуализированием меша.
В разделе "Обработка движений твердого тела" вы видели, как прикладывать векторы силы и моменты к линейной скорости и угловому моменту для создания движения. В функции cRagdoll::Resolve я просто повторяю все прочитанное вами в том разделе.
Вы заметите, что значения положения, ориентации, скорости и момента хранятся в классе состояния кости cRagdollBoneState. Эти векторы используются при разрешении. Для вызова Integrate необходимо задать в качестве параметров обрабатываемую кость и время обработки (прошедшее время).
void cRagdoll::Integrate(DWORD BoneNum, float Elapsed)
{
//Получить указатель на кость cRagdollBone *Bone = &m_Bones[BoneNum];
//Получить указатели на состояния cRagdollBoneState *State = &Bone->m_State;
После того как вы получили указатель на класс кости (и указатель на объект состояния кости), вы вычисляете новое положение кости, основываясь на линейной скорости, изменение углового момента, основываясь на моменте, и изменение линейной скорости, основываясь на величине силы (масштабированной на массу объекта).
Созданиекукольнойанимации
// Сложить положения
State->m_vecPosition += (Elapsed*State->m_vecLinearVelocity);
// Сложить угловой момент
State->m_vecAngularMomentum += (Elapsed * Bone->m_vecTorque);
// Сложить линейную скорость
State->m_vecLinearVelocity += Elapsed * Bone->m_vecForce / \ Bone->m_Mass;
Теперь вычисляется новая ориентация (хранимая в кватернионе), используя угловую скорость, умноженную на прошедшее время.
// Сложить ориентацию кватернионов
D3DXVECTOR3 vecVelocity = Elapsed * State->m_vecAngularVelocity; State->m_quatOrientation.w -= 0.5f *
(State->m_quatOrientation.x * vecVelocity.x + State->m_quatOrientation.y * vecVelocity.y + State->m_quatOrientation.z * vecVelocity.z);
State->m_quatOrTentation.x += 0.5f *
(State->m_quatOrientation.w * vecVelocity.x - State->m_quatOrientation.z * vecVelocity.y + State->m_quatOrientation.y * vecVelocity.z);
State->m_quatOrientation.y += 0.5f * (State->m_quatOrientation.z * vecVelocity.x + State->m_quatOrientation.w * vecVelocity.y - State->m_quatOrientation.x * vecVelocity.z);
State->m_quatOrientation.z += 0.5f *
(State->m_quatOrientation.x * vecVelocity.y - State->m_quatOrientation.y * vecVelocity.x + State->m_quatOrientation.w * vecVelocity.z);
// Нормализовать кватернион (получая единичный кватернион) D3DXQuaternionNormalize(&State->m_quatOrientation,
&State->m_quatOrientation);
До этого момента я не рассказывал вам, как предотвратить неуправляемое искажение костей кукольного меша. Подумайте, т. к. кости являются твердыми телами, они могут вращаться в любом направлении на любой угол, так что, например, голова вашего персонажа может вращаться через грудь. Таким образом, я представляю вашему вниманию использование фактора разрешения вращения в объявлении каждого кукольного объекта.
После того как вы нашли новую ориентацию кости, вам необходимо медленно вернуть ее в начальное состояние. Вы можете выполнить это, предварительно вычислив разность ориентации кости и ее родителя. Используя эту предварительно вычисленную разность, вы рассчитываете ориентацию, которую должна принять кость.
234 |
Глава 7 |
Чем больший коэффициент разрешения вы установите, тем быстрее кость будет приобретать начальную ориентацию относительно родительской ориентации. Для переориентирования кости к начальному положению вы можете использовать сферическую интерполяцию от текущей ориентации кости к начальной ориентации относительно родительской ориентации. Величина интерполяции, вы угадали, определяется установленным коэффициентом разрешения. Большие значения заставляют не вращаться кости, в то время как маленькие значения заставляют кость постепенно (или никогда) возвращаться к начальной ориентации.
// Заставить разрешение вращения
if(BoneNum && Bone->m_ResolutionRate != 0.0f) {
// сферическая интерполяция от текущей ориентации к начальной D3DXQUATERNION quatOrientation = \
Bone->m_ParentBone->m_State.m_quatOrientation * \ Bone->m_quatOrientation;
D3DXQuaternionSlerp(&State->m_quatOrientation, \ &State->m_quatOrientation, \ &quatOrientation, \
Bone->m_ResolutionRate);
}
Двигаемся дальше. Оставшийся код функции Integrate создает матрицу преобразования, которая потом используется для преобразования точек костей твердого тела и создания угловой скорости. Т. к. мы работаем с левосторонней системой координат, после создания матрицы преобразования необходимо ее транспонировать при помощи функции D3DXMatrixRotationQuaternion. Этот шаг обсуждался ранее.
//Вычислить новую ориентацию при помощи матрицы преобразования
//полученной из только что посчитанного кватерниона D3DXMatrixRotationQuaternion(&State->m_matOrientation,
&State->m_quatOrientation); D3DXMatrixTranspose(&State->m_matOrientation,
&State->m_matOrientation);
// Вычислить суммарный тензор мировой инерции D3DXMATRIX matTransposedOrientation; D3DXMatrixTransposw(&matTransposedOrientation, &State- >m_matOrientation);
State->m_matInvWorldInertiaTensor = State->m_matOrientation * Bone->m_matInvInertiaTensor * matTransposedOrientation;