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

Созданиекукольнойанимации

Я вычисляю ориентацию, учитывая скорость, основанную на времени. Помните, что скорость была посчитана из момента, а он в свою очередь из вращательного момента. Вращательный момент содержал ось вращения, совсем как кватернион. Обычно вы просто перемножаете скорость и кватернион, после чего разделяете результат на такие части:

q1 = 1|2 vt q

Наконец, после приложения силы к твердому телу вы можете вычислить угол

иось вращения. Теперь вы знаете достаточно, чтобы двигать и вращать твердые тела! Хорошо, я признаю, что немного быстро и в вольном стиле излагал материал

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

ипо нему написано множество литературы. Я думаю, что немногие используют физику твердого тела из-за сложности ее математики. Я хочу, чтобы любой мог понять основы динамики твердого тела, не углубляясь в математику. По этой причине я пропустил большинство формул, которые могли бы пригодиться знающим читателям. Как я уже замечал, этот раздел существует долгое время, за которое было написано несколько замечательных книг и статей о нем. Особенно полезен набор статей Chris Hecker'a Behind the Screen series on physics. Вы можете найти эти статьи на домашней странице Chris'a, http://www.d6.com/users/checker.

Теперь идет самая забавная часть - создание набора сил, действующих на твердое тело и заставляющих его двигаться.

Использование сил для создания движения

Теперь вы имеете возможность следить за движением и вращением твердого тела. Они появляются, когда сторонние силы начинают действовать на тело. Для упрощения будем полагать, что возможны только такие силы: приложенная к телу, сопротивление воздуха, тяжести и пружина.

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

206

Глава 7

Как я замечал в последних двух разделах, для хранения сил используются векторы. Каждая сила определяется направлением приложения силы и величиной прилагаемой силы. Величина силы хранится в виде ускорения (в метрах в секунду3 для объекта массой 1). Для углового вращения это значение измеряется в радианах в секунду. Длина вектора силы определяет величину силы. Так, например, для силы тяжести, которая ускоряет объект приблизительно на 9.8 м/с2 в отрицательном направлении оси у (вниз), принимая во внимание массу, вы можете создать вектор:

D3DXVECTOR3 vecGravity = D3DXVECTOR3(0.0f, -9.8f, 0.0) * Mass;

Акак насчет приложенной силы, ускоряющей тело (массой 1) на 10 метров

всекунду в положительном направлении оси х?

D3DXVECTOR3 vecApplied = D3DXVECTOR3(10.0f, 0.0f, 0.0f);

А как же вычисляется сопротивление воздуха? Вы определяете сопротивление воздуха не как остальные силы; вместо этого, она создается из другой силы. Я имею ввиду, что сопротивление воздуха противодействующая сила, которая вычисляется умножением скорости тела на небольшое число (отрицательное число, если быть точным). Для моделирования сопротивления воздуха в вашей системе твердых тел вы можете создать два вектора, представляющие собой противодействующие силы. Эти силы используются для замедления движения, вызванного линейной скоростью и угловым моментом.

Положив, что скорость вашего твердого тела хранится в векторе vecVelocity, а угловой момент в vecMomentum, вы можете создать два вектора (силы и момента) для дальнейшего использования.

D3DXVECTOR3 vecLinearDamping = vecVelocity * LinearDamping; D3DXVECTOR3 vecAngularDamping = vecMomentum * AngularDamping;

Вещественные переменные LinearDamping и AngularDamping отрицательны. Чем больше значения этих переменных4, тем большее сопротивление воздуха действует на тело и тем больше оно замедляется. Обычно я использую значения -0.5 и -0.4 для LinearDamping и AngularDamping соответственно.

3. Автор подразумевает, но явно не показывает, что прикладываемая сила определяет ускорение в метрах

всекунду за секунду. - Примеч. науч. ред.

4. Очевидно — больше по модулю. - Примеч. науч. ред.

Созданиекукольнойанимации

После вычисления векторов, которые представляют силы, противодействующие линейному и вращательному движению, вы можете применять их, как делали это ранее. На самом деле вы можете просто добавить векторы vecLinearDamping и vecAngularDamping к результирующей силе и суммарному моменту.

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

Соединение твердых тел с помощью пружин

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

Возвратимся к теме. Эти соединенные между собой твердые тела представляют собой кукольный персонаж. Вы знаете, как все устроено - кости кисти присоединены к руке, кость руки присоединена к .... Ну, вы поняли идею. Твердые тела соединяются между собой так же, как и кости в скелетном меше присоединяются к родительским костям (конечно, за исключением корневой кости).

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

Как вы можете видеть на рис. 7.9, пружины создаются для каждой точки соединения костей в исходной скелетной структуре.

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

208

Глава7

Рис. 7.9. Пружины соединяют твердые тела в точках сочленения костей

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

Помните, ранее в этой главе, вы определили восемь векторов, представляющих собой углы твердого тела? Было два набора по восемь вершин, один для определения локальных координат, а другой для определения этих же самых точек в мировых координатах. Теперь вам необходимо добавить еще две точки в список.

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

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

Созданиекукольнойанимации

209

Точка присоединения кости к родителю

Рис. 7.10. Каждая кость определяется размерами ограничивающего параллелепипеда и точкой соединения с родительской костью.

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

D3DXVECTOR3 vecLocalPoints[9];

D3DXVECTOR3 vecWorldPoints[10] ;

Вы уже видели, как сохранять координаты угловых точек с помощью векторов, так что я пропущу эту часть и покажу вам, как сохранять значения смещения соединения и родительского смещения. Восьмая точка будет представлять координаты смещения соединения, а точка девять — родительского смещения.

Вектор смещения соединения хранится в объекте D3DXVECTOR3, имеющем название vecJointOffset, в то время как вектор родительского смещения хранится в vecParentOffset. Первое, что необходимо сделать, это сохранить вектор смещения соединения в соответствующем векторе локального пространства.

vecLocalPoints[8] = vecJointOffset;

Теперь вы можете преобразовывать девять точек из локального пространства

вмировое, как вы делали это ранее. После чего, точка 8 будет содержать координаты

вмировом пространстве точки присоединения кости к родителю.

210

Глава7

Что же касается вектора родительского смещения, вам необходимо поместить его в один из векторов vecWorldPoints. Чтобы сделать это, используйте преобразования родительской кости. Если ориентация родителя кости хранится в виде матрицы преобразования matParentOrientation, а положение в векторе vecParentPosition, вы можете вычислить координаты преобразованной точки так:

D3DXVec3TransformCoord(&vecWorldPoints[9], \ &vecParentOffset, \ &matParentOrientation);

vecWorldPoints[9] += vecParentPosition;

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

Рис. 7.11. Вы создаете вектор пружины, соединяя точки смещения соединения и родительского смещения. Обе точки задаются в мировых координатах

//vecPosition = положение тела

//Получить положение смещения соединения в мировых координатах D3DXVECTOR3 vecBonePos = vecWorldPoints[8];

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

Создание кукольной анимации

211

//Он используется для вычисления момента D3DXVECTOR3 vecPtoC = vecPosition - vecBonePos;

//Получить положение родительского смещения в мировых координатах D3DXVECTOR3 vecParentPos = vecWorldPoints[9];

//Вычислить вектор пружины из точек соединения и родительской D3DXVECTOR3 vecSpring = vecBonePos - vecParentPos;

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

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

vecPosition += vecSpring; D3DXVECTOR3 vecCross;

D3DXVec3Cross(&vecCross, &vecBtoC, &vecSpring); vecAngularMoment += vecCross;

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

D3DXVECTOR3 vec D3DXVec3TransformCoord(&vecAngularVelocity, \

&vecAngularMomentum, \ &matInvWorldInertiaTensor);

Со всеми этими разговорами о векторах смещения, соединения и родительского смещения я забыл упомянуть, откуда получать их значения. При вычислении размера ограничивающего параллелепипеда вам необходимо принимать во внимание координаты кости и ее родителя в мировом пространстве.

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