Вычисление значений разностей является простой задачей. Каждая комбинируемая анимация содержит исходный меш (базовый) и целевой меш. Для первой анимации целевым мешем будет тот, у которого рот человека полностью открыт. Целевой меш второй анимации содержит лицо человека с закрытыми глазами. И, конечно же, помните, что базовым мешем является лицо человека с закрытым ртом и открытыми глазами.
Для данного примера этими мешами будут меши, изображенные на рис. 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;
Вы уже на полпути, но здесь необходимо задержаться! Мы вычислили разности, так что теперь необходимо скомбинировать их.
⇐Использование базового меша в комбинированных морфированных анимациях || Оглавление || Комбинирование разностей⇒