- •Введение
- •Глава 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
- •Предметный указатель
324
Вот и все с классом cXPhonemeParser! Чтобы его использовать, вам просто необходимо создать его экземпляр и вызвать Parse, используя .X файл, содержащий данные последовательности фонем.
cXPhonemeParser PhonemeParser;
PhonemeParser.Parse("Phoneme.x");
Для каждого кадра анимации вызывайте функцию GetAnimData для определения мешей и значений комбинирования, используемых для визуализации лицевого меша. Вам необходимо вычислить время в анимации, вызвав такую функцию, как например timeGetTime, и ограничив результат продолжительностью анимации, как я сделал тут:
// Получить время анимации
DWORD Time = (DWORD)timeGetTime(); Time %= PhonemeParser.m_Length;
// Получить номера мешей и значения комбинирования DWORD Mesh1, Mesh2;
float Time1, Time2; PhonemeParser.GetAnimData(Time,&Mesh1,&Time1,&Mesh2,&Time2);
Ядумаю, вы уже знаете, что будет дальше. Используя значения, полученные
спомощью вызова функции GetAnimData, вы теперь можете визуализировать комбинированный меш. Для получения деталей о рисовании комбинированных мешей обратитесь к главе 8 или к демонстрационной программе лицевой анимации, находящейся на компакт-диске в качестве работающего примера. Посмотрите конец этой главы для получения дополнительной информации о демонстрационной программе лицевой анимации.
Поздравляю! Вы успешно загрузили и проиграли последовательность анимации фонем! Что идет далее в списке? Вы можете комбинировать большее количество мешей для повышения реалистичности анимации, добавив моргание глаз или возможность изменять выражения лица. После того как вы изучили основы, все это легко реализуется.
Проигрывание лицевых последовательностей со звуком
После того как вы записали и воспроизвели последовательности лицевой анимации, пришло время сделать еще один шаг и начать синхронизировать эти анимации со звуком. Если вы используете лицевую анимацию для синхронизации губ со звуком, то это настолько же просто, как проигрывание звукового файла и анимации одновременно.
Имея столько возможностей загрузки и воспроизведения звуковых файлов, что такой программист DirectX как вы, намерен делать? Исключив множество доступных медиа библиотек, я хочу обратиться к лучшей на сегодняшний день - DirectShow
Морфируемая лицевая анимация
корпорации Microsoft! При ближайшем рассмотрении DirectShow является очень мощной медиа системой. К счастью для нас, она проста в использовании.
Если все, что вам нужно, это проигрывать медиа файлы (аудио медиа файлы, в данном случае), то тогда вам везет, потому что это очень просто выполняется при использовании DirectShow. В данном разделе я устрою вам головокружительный тур проигрывания аудио файлов при помощи DirectShow, таких как .WAV, .MP3, .WMA или любого другого звукового файла, имеющего зарегистрированный в Windows кодек. Конечно же, эти аудио файлы будут содержать записанные диалоги, которые вы хотите синхронизировать с лицевой анимацией.
Для получения детальной информации о DirectShow и используемых объектах проконсультируйтесь с главой 14 "Использование анимированных текстур". Как я уже сказал, это головокружительный тур, так что все будет происходить быстро!
Использование DirectShow для звука
DirectShow является набором интерфейсов и объектов, которые работают с видео и аудио медиа. Я говорю о записи и воспроизведении медиа из любого источника, включая живое видео, потоковое содержимое веб, DVD и предварительно записанные файлы. И как будто этого было недостаточно, DirectShow даже позволяет вам создавать собственные декодеры и кодеры медиа, делающие ее единственной системой, которую выбирают.
Для того чтобы добавить DirectShow в проект, необходимо включить заголовочный файл dshow.h в исходный код.
#include "dshow.h"
Также убедитесь, что добавили файл strmiids.lib к списку файлов, связываемых в проекте. Он расположен в той же директории, что и остальные библиотеки DirectX (обычно \dxsdk\lib). После того как вы подключили и привязали соответствующие файлы, вы можете создать экземпляры следующих четырех интерфейсов DirectShow для использования в вашем коде:
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
IMediaPosition *pPosition = NULL;
Первый интерфейс IGraphBuilder, является основным. Он ответственен за загрузку и декодирование медиа файлов. Второй интерфейс, ImediaControl, управляет воспроизведением аудио файлов. Третий интерфейс, ImediaEvent, получает события,
326
такие как завершение воспроизведения. Последний интерфейс, ImediaPosition, устанавливает и получает положение, в которое происходит воспроизведение. (Например, вы можете проиграть пять секунд аудио файла или можете начать воспроизведение с 20 секунд от начала звука.)
Замечание. Т. к. используется система COМ, необходимо вызвать функцию CoInitialize внутри кода инициализации. После завершения программы вы должны вызвать CoUninitialize, чтобыдеинициализировать системуCOМ.
Для создания объекта IgraphBuilder (из которого получаются три остальных интерфейса) используйте функцию CoCreateInstance, как я сделал тут:
//Инициализировать систему COМ CoInitialize(NULL);
//Создать объект IGraphBuilder CoCreateInstance(CLSID_FilterGraph,NULL,\
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, \
(void**)&pGraph);
После создания объекта IGraphBuilder вы можете вызвать IGraphBuilding::RenderFile, чтобы сразу начать использовать его для загрузки аудио файла. (Это называется рендеринг.) По мере того как файл рендерится, DirectShow загружает все необходимые кодеки для декодирования данных.
Функция RenderFile принимает в качестве параметра имя проигрываемого медиа файла в виде широкосимвольной строки, которую можно создать с помощью макроса L. Например, для загрузки файла MeTalking.mp3 необходимо использовать следующий код. (Заметьте, что второй параметр RenderFile всегда устанавливается в NULL.)
pGraph->RenderFile(L"MeTalking.mp3", NULL);
После того как вы загрузили медиа файл, вы можете получить оставшиеся три интерфейса из объекта IGraphBuilder, как я сделал здесь:
pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); pGraph->QueryInterface(IID_IMediaEvent, (void**)&pEvent); pGraph->QueryInterface(IID_IMediaPosition,(void**)&pPosition);
Уже почти все! Начать проигрывать звук можно простым вызовом IMediaControl::Run.
pControl->Run();
Вот и все. Если все прошло, как было запланировано, вы должны услышать проигрываемый звук! Теперь необходимо просто синхронизировать лицевую анимацию с проигрываемым звуком.
Морфируемаялицеваяанимация
Синхронизация анимации со звуком
После того как вы загрузили и воспроизвели звук, пришло время синхронизировать его с анимацией. Т. к. анимация проигрывается в соответствии со временем (миллисекундами в данном случае), вы можете получить с помощью DirectSound точное время проигрываемого звука. Используя это значение времени, вы можете обновлять синхронизированную анимацию губ каждый кадр, делая ее таким образом великолепно синхронизированной со звуком.
Замечание.Автоматическиеособенности,такиекакморганиеглазмеша,должнывыполняться в соответствии свнешнимсчетчиком, аневременемпроигрыванияDirectSound. Для получения значения внешнего счетчика (в миллисекундах) вы можете использовать функцию timeGetTime, которая возвращает значение DWORD, содержащее количество миллисекунд,прошедшихсмоментазапускаWindows.
Для получения времени проигрываемого звука используйте интерфейс IMediaPosition, созданный в предыдущем разделе. Функция, которую мы ищем, называется IMediaPosition::get_CurrentPosition и имеет только один параметруказатель на REFTIME (вещественный тип данных), как вы можете видеть здесь:
REFTIME SndTime; // REFTIME = float pPosition->get_CurrentPosition(&SndTime);
Для получения текущего времени воспроизведения просто умножьте значение REFTIME, полученное с помощью get_CurrentPosition на 1000.0 и преобразуйте результирующее число в переменную DWORD. Это преобразованное значение будет содержать время, используемое для обновления синхронизированной лицевой анимации губ. Следующий кусочек кода демонстрирует преобразования времени, полученного с помощью get_CurrentPosition в миллисекунды.
DWORD MillisecondTime = (DWORD)(SndTime * 1000.0f);
Вы используете значение времени (MillisecondTime) для нахождения соответствующей последовательности лицевых мешей фонем, которые применяются для морфирования данных анимации, загруженной с помощью анализатора .X файлов. Немного позднее вы увидите демонстрационные программы этой главы, в которых показано, как использовать эти значения времени в анимациях. (Смотрите конец главы для получения дополнительной информации о демонстрационной программе.)
Если вы забежали вперед и пробовали воспроизвести синхронизированные звук и анимацию, вы могли заметить, что что-то не так. В реальном мире, прежде чем произнести звук, человек двигает ртом. В текущем состоянии метод син-