- •Введение
- •Глава 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
- •Предметный указатель
Имитирование одежды и анимация мешей мягких тел
пять функций, первые из которых конструктор и деструктор. Они используются для очистки данных класса и вызова функции Free соответственно.
Функция Free предназначена для удаления связанного списка объектов и обнуления количества загруженных в него объектов столкновений. Функции AddSphere и AddPlane используются для создания нового объекта столкновения и добавления его в связанный список, хранящийся в классе cCollision.
Чтобы добавить в связанный список сферу, вызовите AddSphere, задав в качестве параметров координаты центра сферы и ее радиус. Чтобы добавить плоскость, вызовите AddPlane и передайте в качестве параметра объект D3DXPLANE, который бы задавал нормаль плоскости и ее смещение от начала координат.
Чтобы использовать данные объекта столкновения, необходимо создать функцию, которая бы просматривала все точки одежды и для каждой точки проверяла бы, сталкивается ли точка с объектом столкновения. Это выполняется простой проверкой расстояния, как вы увидите далее.
Обнаружение и реакция на столкновения
Создаваемая функция проверки столкновений должна просмотреть все точки одежды и для каждой точки проверить, происходит ли ее столкновение с какимлибо объектом столкновений, содержащимся в связанном списке объектов. Вызовете функцию CheckCollision; в качестве параметров задайте указатель на объект cCollision для проверки столкновений точки и объекта и матрицу преобразования, которая используется для расположения и ориентирования объектов столкновений в трехмерном мире.
void CheckCollisions(cCollision *pCollision, \ D3DXMATRIX *matTransform)
{
//Просмотреть все точки for(DWORD i=0;i<NumPoints;i++) {
//Нe обрабатывать точки с нулевой массой if(ClothPoints[i].m_Mass != 0.0f) {
Впредыдущем кусочке кода вы начали просматривать все точки одежды. Я полагаю, что количество точек определяется переменной NumPoints, а данные самих точек определены в массиве ClothPoints. При просмотре необходимо сначала убедится, что точка имеет ненулевую массу, т. е. что она может перемещаться. Если точка может перемещаться, тогда необходимо просмотреть все объекты столкновений и определить, сталкивается ли точка с ними.
402 |
Глава13 |
//Просмотреть каждый объект столкновений cCollisionObject *pObject = pCollision->m_Objects; while(pObject) {
//Проверить, сталкивается ли точка с объектом сферой if(pObject->m_Type == COLLISION_SPHERE) {
Первыйтипобъекта, которыйпроверяетсянастолкновение, -этосфера. Помните, что сфера располагается при помощи трехмерного вектора, а ее радиус определяется вещественным значением, которое вы установили при вызове AddSphere. Как показано на рис. 13.7, точка сталкивается со сферой, если расстояние от центра сферы до просматриваемой точки меньше ее радиуса.
Рис. 13.7. Точка сталкивается со сферой, если расстояние от центра сферы до точки меньше, чем радиуссферы
Т. к. для расположения объекта столкновения используется преобразование, необходимо применить часть преобразования, ответственного за перемещение,
квектору положения сферы, прежде чем проверять столкновения.
//Сохранить координаты сферы в локальный вектор D3DXVECTOR3 vecSphere = pObject->m_vecPos;
//Переместить сферу, если необходимо if(matTransform) {
vecSphere.x += matTransform->_41; // Translate x
vecSphere.y += matTransform->_42; // Translate у vecSphere.z += matTransform->_43; // Translate z
}
Имитирование одежды и анимация мешей мягких тел
После того как вы получили вектор, представляющий положение сферы, вычислите вектор, который равняется длине от точки до центра сферы.
// Вычислить вектор расстояния
vecDist = vecSphere - ClothPoints[i].m_vecPos;
Теперь вы можете сравнить длину этого вектора с радиусом сферы. Чтобы избежать использования sqrt при вычислении расстояний, просто сравните квадраты значений.
// Получить квадрат расстояния разности float Length = vecDist.x * vecDist.x + \
vecDist.y * vecDist.y + \ vecDist.z * vecDist.z;
//Проверить, меньше ли длина разницы радиуса if(Length <= (pObject->m_Radius*pObject->m_Radius)) {
//Произошло столкновение!
После того как вы определили, что произошло столкновение (расстояние между точкой и сферой меньше или равно радиусу сферы), вы можете обрабатывать столкновение. Для упрощения, я собираюсь отбросить физику и просто вытолкнуть точку из сферы. Также полагаем, что такая мягкая вещь, как кусочек одежды, не отскочит определенным образом от объекта столкновения, поэтому я также пропущу все вычисления коэффициентов возврата.
Чтобы вытолкнуть точку из сферы, необходимо масштабировать нормализованный вектор расстояния (вектор, представляющий расстояние от точки до центра сферы) на разность расстояний между точкой и краем сферы, а потом вычесть этот вектор из положения точки (и скорости, чтобы замедлить точку).
//Нормализовать значение расстояние и вектор Length = (float)sqrt(Length);
vecDist /= Length;
//Вычислить разность расстояний точки и границы сферы float Diff = pObject->m_Radius - Length;
//масштабировать вектор на эту разность
vecDist *= Diff;
// Вытолкнуть точку и скорректировать скорость ClothPoints[i].m_Pos -= vecDist; ClothPoints[i].m_Velocity -= vecDist;
}
}
Вот и все, что касается проверки столкновений точки и сферы! Далее следует проверка столкновения точки и плоскости.
404 |
Глава 13 |
// Проверить, сталкивается ли точка с объектом плоскостью if(pObject->m_Type == COLLISION_PLANE) {
Чтобы проверить пересекается ли точка с плоскостью, необходимо сначала преобразовать плоскость, после чего взять скалярное произведение ее нормали и положения точки. Это скалярное произведение, скомбинированное с компонентой смещения плоскости, определяет, расположена ли точка перед плоскостью (столкновения нет) или за плоскостью (столкновение есть). Точки, находящиеся за плоскостью должны быть вытолкнуты из нее.
Чтобы преобразовать плоскость, необходимо сначала обратить и транспонировать матрицу преобразования. Это необходимо сделать только один раз в функции, потому что вы можете использовать эту матрицу для всех плоскостей. В демонстрационной программе этой главы показано, как создать преобразование только однажды. А пока, я буду вычислять его каждый раз. Используя обратную транспонированную матрицу, вы можете вызвать D3DXPlaneTransform для преобразования плоскости.
//Сохранить плоскость в локальной переменной D3DXPLANE Plane = pObject->m_Plane;
//Преобразовать плоскость, если необходимо if(matTransform) {
//Обратить и транспонировать матрицу преобразования D3DXMATRIX matITTransform; D3DXMatrixInverse(&matITTransform, NULL, matTransform); D3DXMatrixTranspose(&matITTransform, &matITTransform);
//Преобразовать плоскость
D3DXPlaneTransform(&Plane, &Plane, &matITTransform);
}
После того как вы преобразовали плоскость, необходимо взять ее нормаль и использовать ее для вычисления скалярного произведения с вектором положения точки.
// Получить вектор нормали
D3DXVECTOR3 vecNormal = D3DXVECTOR3(Plane.a, \ Plane.b, \
Plane.c);
//Посчитать скалярное произведение нормали плоскости и
//положения точки
float Dot = D3DXVec3Dot(&ClothPoints[i].m_vecPos, \ &vecNormal) + Plane.d;
Вы заметите, что я добавил компоненту смещения плоскости (d) к результату скалярного произведения. Это гарантирует корректное вычисление расстояния от точки до плоскости. Если результирующее значение векторного произведения
Имитирование одежды и анимация мешей мягких тел
меньше 0, то точка сталкивается с плоскостью и должна быть вытолкнута. Чтобы вычислить вектор, который необходимо прибавить к векторам положения и скорости точки, необходимо просто умножить нормаль плоскости на значение скалярного произведения и прибавить результат к векторам положения и скорости.
// Проверить, находится ли точка за плоскостью if(Dot < 0.0f) {
// Масштабировать нормаль плоскости на модуль скалярного произведения vecNormal *= (-Dot);
// Переместить точку и скорректировать скорость на вектор нормали ClothPoints[i].m_vecPos += vecNormal; ClothPoints[i].m_vecVelocity += vecNormal;
}
}
После этого вы можете переходить к обработке следующего объекта столкновения и закончить цикл, который бы просматривал все остальные точки одежды.
// Перейти к следующему объекту столкновения pObject = pObject->m_Next;
}
}
}
}
Чтобы использовать функцию CheckCollisions, загрузите меш одежды и начните имитацию. После того как вы обработали силы одежды и обновили ее точки, вызовите CheckCollisions. В качестве примера приведем небольшой кусочек кода:
//Создать экземпляры объекта столкновений и матрицы преобразования cCollision Collision;
D3DXMATRIX matCollision;
//Добавить в список столкновений сферу и установить матрицу в единичную
Collision.AddSphere(&D3DXVECTOR3(0.0f, 0.0f, 0.0f), 40.0f); D3DXMatrixIdentity(&matCollision);
//Обработать силы меша одежды и обновить ее точки
//Обработать столкновения
CheckCollisions(&Collision, &matCollision);
Хотя методы, которые я только что показал, и не являются самыми точными для определения столкновений объектов и реакции на них, они в целом должны подойти для использования в игровых проектах. Тем из вас, кому необходима абсолютная точность, как например, значение точного момента времени столкновения точки