Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DirectX. Продвинутая Анимация (2004) [rus].pdf
Скачиваний:
335
Добавлен:
16.08.2013
Размер:
8.39 Mб
Скачать

Глава 10

Комбинирование морфированных анимаций

Удары, отклонения, толчки, ходьба и прыжки - вот множество анимаций, с которыми приходится работать. Вы можете себе представить, сколько вам потребуется времени для кропотливого объявления каждой из этих анимации, и все это, чтобы потом услышать, что вашему начальнику необходимо, чтобы персонаж прыгал и бил одновременно, или отклонялся и толкал, или выполнял любое другое количество комбинированных анимаций? Что вы будете делать?

Хорошо, если вы используете морфированные анимации, тогда все что вам остается сделать, это использовать свои программистские способности и разработать технологию комбинирования морфированных анимаций, в которой меши из ранее созданных анимаций могут быть соединены для образования новых уникальных анимаций в реальном времени. Цель данной главы - показать вам как это делать!

Вэтой главе вы научитесь:

Изменять технологию морфирования для реализации комбинирования;

Работать с базовым мешем в комбинированном морфировании;

Управлять буферами вершин меша для комбинирования;

Создавать вершинные шейдеры комбинированного морфирования.

Комбинирование морфированных анимаций

Давно, в главе 6, вы видели, как создавать новые динамические анимации, объединяя, или, скорее, комбинируя разнообразные движения меша, определенные множественными наборами анимаций. В то время как глава 6 была посвящена комбинированию наборов анимаций, основанных на скелетах, эта глава расскажет вам как достичь таких же эффектов комбинирования анимаций для морфируемых

278

Глава10

мешей. Все правильно, в этой главе вы увидите, как объединять разнообразные движения ваших морфируемых мешей, основанных на пикселях, для создания новых динамических анимаций в реальном времени!

Комбинирование анимаций морфируемых мешей немного сложнее в сравнении с комбинированием анимаций мешей, основанных на скелетах. Но не волнуйтесь. Оно не на много сложнее, а просто требует другого подхода. При комбинировании морфированной анимации необходимо обеспечить возможность объединения не5скольких морфируемых мешей в один.

Например, предположим, что имеем меш, представляющий собой лицо человека,

идве морфированные анимации: одна, открывающая и закрывающая рот меша,

ивторая, моргающая глазами меша. На рис. 10.1 показаны циклы каждой анимации.

Рис. 10.1. Используя один и тот же меш, вы двигаете (морфируете) разнообразные вершины для создания двух уникальных последовательностей анимаций

Теперь предположим, что вы хотите все перемешать, скомбинировав эти две анимации (как показано на рис. 10.2) так, чтобы меш мог одновременно открывать рот и моргать глазами, с разньми скоростями для каждой анимации. Звучит устрашающе, не правда ли? Ну, на самом деле это не так сложно, когда вы знаете секрет.

Комбинирование морфированныханимаций

Рис. 10.2. Вы можете объединить две анимации для создания одного комбинированного меша

Весь фокус комбинирования морфированной анимации заключается в изолировании тех вершин, которые фактически движутся в каждой последовательности анимации, и объединении движения каждой вершины в один меш, который и необходимо визуализировать. Определение того, какие вершины движутся при последовательности анимации, кажется сложной задачей, но с помощью дополнительного ссылочного меша (называемого базовым мешем) вы можете решить эту проблему со связанными за спиной руками!

Использование базового меша в комбинированных морфированных анимациях

Настоящим секретом использования комбинированных преобразований является объявление ссылочного меша в уравнении. Базовый меш определяет начальные координаты каждой вершины в меше до применения морфинга. Зачастую базовым мешем является исходный меш операции морфирования. В примере лица человека базовым мешем является лицо человека с закрытым ртом и открытыми глазами.

280

Глава 10

Когда вы комбинируете два морфированных меша (или любое количество мешей), вы определяете разность координат вершин каждого морфированного меша и базового меша. Вы объединяете эти разности координат в результирующем комбинированном морфируемом меше. Читайте далее, чтобы узнать как вычислять эти разности.

Вычисление разностей

Вычисление значений разностей является простой задачей. Каждая комбинируемая анимация содержит исходный меш (базовый) и целевой меш. Для первой анимации целевым мешем будет тот, у которого рот человека полностью открыт. Целевой меш второй анимации содержит лицо человека с закрытыми глазами. И, конечно же, помните, что базовым мешем является лицо человека с закрытым ртом и открытыми глазами.

Для данного примера этими мешами будут меши, изображенные на рис. 10.2. Я думаю у вас не возникнет проблем при загрузке каждого меша в следующие три объекта:

ID3DXMesh *pBaseMesh; //Содержит базовый меш

ID3DXMesh *pTargetMesh1; //Содержит целевой меш первого морфирования ID3DXMesh *pTargetMesh2; //Содержит целевой меш второго морфирования

Наряду с базовым и двумя целевыми мешами вам потребуется еще один для хранения результирующего комбинированного меша. Этот комбинированный меш имеет столько же вершин и граней, что и остальные меши, так что вы можете просто скопировать его из базового меша.

Для копирования базового меша (после его загрузки) в комбинированный меш (объект ID3DXMesh, названный pBlendedMesh) вы можете использовать следующий код:

ID3DXMesh *pBlendedMesh;

//Получить FVF базового меша и 3D устройство DWORD FVF =pBaseMesh->GetFVF(); IDirect3DDevice9 *pMeshDevice; pBaseMesh->GetDevice(&pMeshDevice);

//Скопировать меш

pBaseMesh->CloneMesnFVF(0,FVF,pMeshDevice,&pBlendedMesh);

Итак, вы будете работать с четырьмя объектами меша - базовым мешем, двумя целевыми и комбинированным. Для упрощения, я полагаю, что все меши используют одинаковую структуру вершин и FVF, использующий только положение,

Комбинированиеморфированныханимаций

нормаль и пару текстурных координат, как я определил тут. Если необходимо, просто скопируйте все меши, используя одинаковый FVF, как я делал раньше.

typedef struct {

D3DXVECTOR3 vecPos; //Координаты вершины D3DXVECTIR3 vecNormal; //Нормаль вершины float u,v; //Текстурные координаты

} sVertex;

#define VERTEXFVF (D3DFVF_XYZ |D3DFVF_NORMAL |D3DFVF_TEX1)

Когда все меши готовы, вы можете заблокировать их вершинные буферы для получения доступа к данным вершин.

// Заблокировать все меши и получить указатели sVertex *pBaseVertices,*pBlendedVertices; sVertex *pTarget1Vertices,*pTarget2Vertices;

pBaseMesh->LockVertexBuffer(D3DLOCK_READONLY, \ (void**)&pBaseVertices);

pTargetMesh1->LockVertexBuffer(D3DLOCK_READONLY, \ (void**)&pTarget1Vertices);

pTargetMesh2->LockVertexBuffer(D3DLOCK_READONLY, \ (void**)&pTarget2Vertices);

pBlendedMesh->LockVertexBuffer(0,(void**)&pBlendedVertices);

После того как вы получили указатели на буферы вершин всех мешей, вы можете начать перебирать вершины каждого целевого меша, вычитая координаты вершины (и нормали) из соответствующих вершин базового меша (при этом каждая разность храниться во временных регистрах, о которых вы узнаете позднее).

// Перебрать все вершины

for(DWORD i=0;i<pBaseMesh->GetNumVertices();i++){

// Получить разность координат вершин

D3DXVECTOR3 vecPosDiff1 =pTarget1Vertices->vecPos - \ pBaseVertices->vecPos;

D3DXVECTOR3 vecPosDiff1 =pTarget2Vertices->vecPos - \ pBaseVertices->vecPos;

// Получить разность нормалей

D3DXVECTOR3 vecNormalDiff1 =pTarget1Vertices->vecNormal - \ pBaseVertices->vecNormal;

D3DXVECTOR3 vecNormalDiff2 =pTarget2Vertices->vecNormal - \ pBaseVertices->vecNormal;

Вы уже на полпути, но здесь необходимо задержаться! Мы вычислили разности, так что теперь необходимо скомбинировать их.

Соседние файлы в предмете Программирование на C++