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

Имитирование одежды и анимация мешей мягких тел

// Освободить предыдущие данные пружин

delete [] m_ClothSprings; m_ClothSprings = NULL;

//Получить новое количество пружин и вершин DWORD NumSprings = *DataPtr++;

DWORD NumVertices = *DataPtr++;

//Выделить память под пружины

m_ClothSprings = new cClothSpring[NumSprings];

// Загрузить данные каждой пружины for(DWORD i=0;i<NumSprings;i++) { m_ClothSprings[i].m_Point1 = *DataPtr++; m_ClothSprings[i].m_Point2 = *DataPtr++;

}

}

return ParseChildObjects(pDataObj, Depth, \ Data, Reference);

}

}

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

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

А пока, пришло время оживить имитацию, добавив обнаружение столкновений и реакцию на них.

Работа с обнаружением столкновений и реакцией на них

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

398

Глава 13

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

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

Рис. 13.6. Точка сталкивается со сферой, если она расположена ближе, чем радиус сферы, или если онарасположена за плоскостью

Итак, при обнаружении столкновений используются два простых объекта: сфера и плоскость. Необходимо создать класс, который бы отвечал за сталкиваемые объекты.

Определение объектов столкновений

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

// макрос, определяющий тип сталкиваемы объектов #define COLLISION_SPHERE 0

#define COLLISION_PLANE 1

Имитирование одежды и анимация мешей мягких тел

class cCollisionObject { public:

DWORD m_Type; // Тип объекта

D3DXVECTOR3 m_vecPos; // координаты сферы float m_Radius; // Радиус сферы

D3DXPLANE m_Plane; // Параметры плоскости

cCollisionObject *m_Next; // Следующий объект в связанном списке

public:

cCollisionObject() { m_Next = NULL; } ~cCollisionObject() { delete m_Next; m_Next = NULL; }

};

В классе cCollisionObject содержаться четыре основные переменные. Необходимо установить переменную т_Туре с помощью макроса, представляющего тип объекта, содержащегося в классе, - либо сфера (COLLISION_SPHERE), либо плоскость (COLLISION_PLANE).

Необходимо хранить координаты объекта столкновения сферы в m_vecPos. Эти координаты определяют положение в трехмерном пространстве, совсем как у трехмерных мешей. Также, если используется объект сфера, убедитесь, что вы установили ее радиус в переменной m_Radius.

Однако, если вы используете объект столкновения плоскость, вам только необходимо установить ее соответствующие параметры в объекте mPlane. Параметры mPlane.a, m_Plane.b и m_Plane.c являются нормализованными векторами направления плоскости, в то время как m_Plane.d является смещением по вектору направления, определяющему положение плоскости.

Далее в классе располагается указатель m_Next, который используется для хранения структуры связанного списка. Используя связанный список, вы можете создать полный набор объектов столкновений, используемых при моделировании одежды. Далее в этом разделе вы увидите, как его использовать.

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

Кроме класса cCollisionObject вы можете создать еще один класс, который бы содержал связанный список набора объектов. Я рекомендую использовать отдельный класс, позволяющий хранить множество списков объектов столкновений, например, один для статичной геометрии, а другой — для динамичной. Объект столкновения может перемещаться, взаимодействуя с объектом одежды и вынуждая ее развеваться.

400

Г

Второй класс, названный cCollision, определяется так:

class cCollision { public:

DWORD m_NumObjects; // # объектов cCollisionObject *m_Objects; // список объектов

public:

cCollision() { m_NumObjects = 0; m_Objects = NULL; } ~cCollision() { Free(); }

void Free()

{

// Удалить связанный список объектов delete m_Objects; m_Objects = NULL; m_NumObjects = 0 ;

}

void AddSphere(D3DXVECTOR3 *vecPos, float Radius)

{

// Создать новый объект

cCollisionObject *Sphere = new cCollisionObject ();

// Установить данные сферы Sphere->m_Type = COLLISION_SPHERE; Sphere->m_vecPos = (*vecPos); Sphere->m_Radius = Radius;

// Добавить сферу в связанный список и увеличить счетчик Sphere->m_Next = m_Objects;

m_Objects = Sphere; m_NumObjects++;

}

void AddPlane(D3DXPLANE *PlaneParam)

{

// Создать новый объект

cCollisionObject *Plane = new cCollisionObject();

//Установить параметры плоскости Plane->m_Type = COLLISION_PLANE; Plane->m_Plane = (*PlaneParam);

//Добавить плоскость в связанный список и увеличить счетчик Plane->m_Next = m_Objects;

m_Objects = Plane; m_NumObjects++;

}

};

Объявление класса cCollision включает две переменные (m_NumObjects

иm_Objects), которые содержат количество загруженных объектов столкновений

иих связанный список соответственно. Также в вашем распоряжении находятся

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