- •Введение
- •Глава 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
- •Предметный указатель
Созданиекукольнойанимации
// Вычислить новую угловую скорость State->m_vecAngularVelocity = Transform(&State- >m_vecAngularMomentum,
&State->m_matInvWorldInertiaTensor);
}
На данный момент мы рассчитали движение твердого тела, а теперь пришло время обрабатывать столкновения.
Обработка столкновений
Как вы помните из предыдущего материала этой главы, столкновения обрабатываются проверкой точек каждого твердого тела на попадание в объекты списка столкновений. Если точка находится внутри пространства сталкиваемого объекта, то тогда она выталкивается из него, а вектор импульса усредняется между всеми объектами таким образом, что тело отскакивает реалистично. Этой цели служит функция ProcessCollisions.
Яне буду приводить здесь полный код функции ProcessCollisions; вместо этого
япокажу отдельные фрагменты. Функция ProcessCollisions начинается с прототипа, который принимает в качестве параметров номер проверяемой кости и указатель на корневой объект столкновений.
BOOL cRagdoll::ProcessCollisions(DWORD BoneNum, \ cCollision *pCollision)
{
// Проверка на ошибки
if(!pCollision || !pCollision->m_NumObjects || \
!pCollision->m_Objects) return TRUE;
//Получить указатель на кость cRagdollBone *Bone = &m_Bones[BoneNum];
//Получить указатель на состояние cRagdollBoneState *State = &Bone->m_State;
//Сохранять количество столкновений
DWORD CollisionCount = 0;
// Сохранять количество сил столкновений
D3DXVECTOR3 vecLinearVelocity = D3DXVECTOR3(0.0f,0.0f,0.0f) ; D3DXVECTOR3 vecAngularMomentum = D3DXVECTOR3(0.0f,0.0f,0.0f);
236
Итак, функция ProcessCollisions начинает свою работу с получения указателя на объект кости и объект состояния кости. После этого вам необходимо следить за количеством обнаруженных столкновений (для последующего усреднения движений) и определить два вектора, определяющих встроенные импульсы, двигающие и вращающие кости в соответствии со столкновениями.
Двигаясь дальше в коде, вы начинаете просматривать восемь точек костей объекта твердого тела. Для каждой точки вы просматриваете все объекты столкновений. Прежде чем проверять столкновение точки и объекта, необходимо установить флаг, который отвечал бы за три вещи: столкнулась ли точка с объектом, нормаль объекта и расстояние, на которое точка проникает в объект.
// Просмотреть все вершины кости в поисках столкновений for(DWORD i=0;i<8;i++) {
//Просмотреть все объекты столкновений cCollisionObject *pObj = pCollision->m_Objects; while(pObj) {
//Установить флаг, если обнаружено столкновение BOOL Collision = FALSE;
//Нормаль объекта столкновений D3DXVECTOR3 vecCollisionNormal;
//Расстояние, на которое необходимо вытолкнуть точку из объекта float CollisionDistance = 0.0f;
//Обработать сферический объект столкновения
if(pObj->m_Type == COLLISION_SPHERE) {
Я собираюсь вырезать кусочек кода, потому что вы уже видели, как определять столкновения, вычислять нормаль и расстояние, на которое точка проникает в объект. Если вы посмотрите полный исходный код, вы увидите, что я проверяю столкновение точки и сферы и точки и плоскости.
После того как вы выполнили обнаружение столкновений, флаг Collision должен быть установлен в TRUE, если столкновения были, или в FALSE, если их не было. Если флаг установлен в TRUE, тогда точка выталкивается из объекта, и вычисляются корректные векторы импульсов.
// Обработать столкновение, если обнаружено if (Collision == TRUE) {
// Вытолкнуть объект на поверхность объекта столкновения State->m_vecPosition += (vecCollisionNormal * \
CollisionDistance);
Созданиекукольнойанимации
// Получить положение и скорость точки D3DXVECTOR3 vecPtoP = State->m_vecPosition - \
State->m_vecPoints[i]; D3DXVECTOR3 vecPtoPVelocity = \
State->m_vecLinearVelocity + \ CrossProduct(&State->m_vecAngularVelocity, \
&vecPtoP); \
// Получить скорость точки относительно поверхности float PointSpeed = D3DXVec3Dot(&vecCollisionNormal, \
&vecPtoPVelocity);
//Увеличить количество столкновений CollisionCount++;
//Вычислить силу импульса, основываясь на коэффициенте
//restitution, скорости точки и нормали сталкиваемого объекта float ImpulseForce = PointSpeed * \
(-(1.0f + Bone->m_Coefficient));
float ImpulseDamping = (1.0f / Bone->m_Mass) + \ D3DXVec3Dot(&CrossProduct( \ &Transform(&CrossProduct(&vecPtoP, \
&vecCollisionNormal), \ &State->m_matInvWorldInertiaTensor), \
&vecPtoP), &vecCollisionNormal); D3DXVECTOR3 vecImpulse = vecCollisionNormal * \
(ImpulseForce/ImpulseDamping);
// Добавить силы vecLinearVelocity += vecImpulse;
vecAngularMomentum += CrossProduct(&vecPtoP, &vecImpulse);
}
После последнего кусочка кода проверяются остальные объекты столкновений и обрабатываются оставшиеся точки. В конце, если были обнаружены столкновения, функция ProcessCollisions усредняет векторы импульсов и применяет их к линейной скорости и угловому моменту.
// Были ли столкновения if(CollisionCount) {
//Добавить усредненные силы к интегрированному состоянию State->m_vecLinearVelocity += ((vecLinearVelocity / \
Bone->m_Mass) / (float)CollisionCount); State->m_vecAngularMomentum += (vecAngularMomentum / \
(float)CollisionCount);
//Вычислить угловую скорость
State->m_vecAngularVelocity = Transform( \ &State->m_vecAngularMomentum, \
&State->m_matInvWorldInertiaTensor);
}
238 |
Глава 7 |
Следующая функция, которую я хочу вам показать, поможет восстановить соединения костей для сохранения формы вашего кукольного персонажа.
Восстановление соединений костей
После того, как вы нашли все силы и обработали столкновения, осталось выполнить последний шаг перед обновлением иерархии фреймов и визуализацией меша кукольного персонажа. Вы должны решить соединения костей.
Вспомните, в разделе "Соединение твердых тел с помощью пружин" вы научились создавать пружины между костями и использовать их для вычисления вектора силы, который немедленно перемещает и вращает тело в корректное положение. Это как раз и выполняет функция ProcessConnections - использует координаты преобразованной точки, представляющей смещение соединения (смещение от центра кости до точки ее присоединения к родителю) и координаты присоединения к родителю (хранящиеся в другой точке) для создания пружины.
void cRagdoll::ProcessConnections(DWORD BoneNum)
{
//Получить указатель на кость и родительскую кость cRagdollBone *Bone = &m_Bones[BoneNum]; cRagdollBone *ParentBone = Bone->m_ParentBone;
//Если родительской кости нет, то не продолжать if(!ParentBone)
return;
//Получить указатель на состояние кости cRagdollBoneState *BState = &Bone->m_State;
//Получить указатель на родительское состояние cRagdollBoneState *PState = &ParentBone->m_State;
//Получить положение соединения и вектор к центру D3DXVECTOR3 vecBonePos = BState->m_vecPoints[8]; D3DXVECTOR3 vecBtoC = BState->m_vecPosition - vecBonePos;
//Получить координаты присоединения к родителю D3DXVECTOR3 vecParentPos = BState->m_vecPoints[9];
//Вычислить вектор пружины из точки к родительской точке D3DXVECTOR3 vecSpring = vecBonePos - vecParentPos;
//Переместить точку в соответствии с родительской и
//скорректировать угловую скорость и момент
BState->m_vecPosition -= vecSpring; BState->m_vecAngularMomentum -= CrossProduct(&vecBtoC, \
&vecSpring); BState->m_vecAngularVelocity = Transform( \