ИГРОДЕЛ
Войдите на сайт или зарегистрируйтесь!!!

Учимся делать анимацию тела

Перейти вниз

Учимся делать анимацию тела

Сообщение автор Admin в Вс Фев 21, 2010 9:15 pm

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

Используйте мышь, чтобы поворачивать тело вокруг оси y. Хотя этот прототип написан на языке AS3, здесь отсутствует какой-либо материал, относящийся только к AS3. Основа также должна работать на языке AS2, но вам нужно будет переписать некоторые строчки кода, такие как листенеры событий и упорядочивание по глубине.

1) Как получить анимационный массив без написания импортера трехмерной анимации:
Я использовал две последовательности изображений шагающего 3d персонажа (достаточно только визуализации частей тела/костей), одна последовательность визуализирована спереди, а вторая сзади. Я использовал десять кадров, равномерно растянутых по времени (где 11-й будет такой как 1-й), открыл их в любой из программ обработки изображений, которая может показывать положение курсора, и записал значения следующих частей тела для каждого кадра:

0 = голова
1 = левое плечо
2 = левый локоть
3 = левая рука
4 = левое бедро
5 = левое колено
6 = левая пятка
7 = левый палец

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

Я использовал вид сбоку, чтобы получить y- (вертикальную) и z- (горизонтальную) позицию, и вид спереди, чтобы получить x- (горизонтальную) позицию каждой части тела в 3d пространстве. Я взял среднее из всех x значений головы во всех кадрах и вычел его из x значений всех позиций частей тела, чтобы центрировать персонаж в середине моей системы координат. То же самое для z-значений.

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

Точки хранятся в моем массиве подобным образом:

var walk:Array = [
[
[head_frame1_x,head_frame1_y,head_frame1_z],
[head_frame2_x,head_frame2_y,head_frame2_z],...,
[...,...,head_frame10_z]
],
[
[leftshoulder_frame1_x,...,...],...
],
[...],
[
[lefttoes_frame1_x,...,...],...
]
];

Пример того, как это читать:

walk[4] содержит массив всех координат левого бедра, walk[4][3] содержит 3d координату в кадре 3, а walk[4][3][2] содержит значение z этой координаты.

На данном шаге walk.length имеет значение 8, потому что мы записали восемь точек (0-7, смотрите выше), walk[n] имеет длину 10 (число ключевых кадров), а walk[n][m] имеет длину 3 (x,y,z).

Отражаем точки:

//mirror var len=walk.length; for(pts=0;pts < len;pts++){ n=walk.length; walk[n]=new Array(); //sizes[n]=sizes[pts]; for(frm in walk[pts]){ walk[n][frm]=new Array(); walk[n][frm][0]=-walk[pts][(frm+5)%10][0]; walk[n][frm][1]=walk[pts][(frm+5)%10][1]; walk[n][frm][2]=walk[pts][(frm+5)%10][2]; } } Эта часть кода просто отражает массив walk (и удваивает его до 16 точек вхождения), где (frm+5)%10 – значение сдвига. Измените его, если вы используете больше или меньше 10 ключевых кадров.



2) КАК СОЕДИНИТЬ ЧАСТИ ТЕЛА:
Для хранения информации о соединении я использовал другой массив:

var lines:Array=[ [1,2],[2,3],[4,5],[5,6],[6,7], [9,10],[10,11],[12,13],[13,14],[14,15], [16,17],[1,9],[1,4],[9,12],[4,12] ]; Как это читать: нарисовать линию из части тела 1 (левое плечо) к части тела 2 (левый локоть), другую от локтя к руке, и так далее.

3) КАК ВИЗУАЛИЗИРОВАТЬ ОДИНОЧНЫЙ КЛЮЧЕВОЙ КАДР:
Итак, многие числа очень отдалены, давайте посмотрим, как они выглядят. Чтобы визуализировать одиночный ключевой кадр, мы прочитаем строковый массив в цикле и используем начальную и конечную точки каждой пары для адресации массива walk данного кадра. Чтобы визуализировать вид спереди, используйте x/y и игнорируйте значения z; чтобы визуализировать вид сбоку, используйте z/y и игнорируйте x значения.

Псевдокод:

For(n in lines) Startpoint=lines[n][0] Endpoint=lines[n][1] StartpointCoordinatesArray=walk[Startpoint][myframe]; EndpointCoordinatesArray=walk[Endpoint][myframe]; //render front view draw a line from StartpointCoordinatesArray[0], StartpointCoordinatesArray[1]// to EndpointCoordinatesArray [0], EndpointCoordinatesArray [1] //render side view draw a line from StartpointCoordinatesArray[2], StartpointCoordinatesArray[1] // to EndpointCoordinatesArray [2], EndpointCoordinatesArray [1] На данном шаге я использовал цикл для прохождения через массив точек, а также для рисования круга в каждой координате части тела данного кадра. Голова не использовалась в строковом массиве, поэтому она не будет нарисована при визуализации одних линий.


4) КАК ПРОВОДИТЬ ИНТЕРПОЛЯЦИЮ МЕЖДУ КЛЮЧЕВЫМИ КАДРАМИ:
Для получения сглаженной анимации нужна интерполяция. Мы не хотим визуализировать 3-й кадр и 4-й кадр друг за другом, но хотим вычислить между ними кадры 3.1, 3.2, ...,3.9 – просто как твининг.

Для этого нам нужно вычислить:
a) каким двум кадрам необходимо визуализировать, к примеру, кадр 3.75, и
b) как “взвесить” координаты частей тела обоих ключевых кадров, чтобы получить координату промежуточного кадра.

a) f1: главный кадр; f2: следующий кадр (10 – это число ключевых кадров; арифметический оператор используется для прохождения цикла по всей анимации, поэтому кадр=16 будет визуализирован снова после кадра 6)

var f1=int(frame) % 10;
var f2=int(frame+1) % 10;
выдает f1=3 и f2=4 для нашего примера, где кадр=3.75

b) fac1: коэффициент для оценки координат следующих кадров; fac2: коэффициент для оценки координат главных кадров

var fac1=frame-int(frame);
var fac2=1-fac1;
выдает fac1=0.75 и fac2=0.25 для нашего примера.

Это означает, что мы должны считывать координаты частей тела кадра 3, умноженные на 0.25, и добавлять координаты частей тела кадра 4, умноженные на 0.75, чтобы получить интерполированный кадр на временном отрезке 3.75.

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

5) КАК ПОВОРАЧИВАТЬ ТЕЛО ВОКРУГ ОСИ Y:
Простая вещь, которую вы просто можете изучить в любом уроке по 3d.

Псевдокод:

si=sin(angle)
co=cos(angle)
renderX=pos3dX*co+pos3dZ*si
renderY=pos3dY
renderZ=pos3dZ*co-pos3dX*si

используйте renderX и renderY для визуализации частей тела/линий, renderZ для упорядочивания по глубине на шаге 6.

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

6) КАК ВИЗУАЛИЗИРОВАТЬ “ЦЕЛЬНУЮ” МОДЕЛЬ В КОМИЧЕСКОМ СТИЛЕ:
Итак, я допускаю, это немного ограничено в дизайне, но относительно быстро и просто при кодировании по сравнению с импортированием и визуализацией реальной анимированной 3d модели с помощью технологии cell shader во Flash.

Фокус вот в чем:
- Визуализировать заполненный круг в каждой части тела.
- Визуализировать подходящий прямоугольник (или трапецию, или любую нужную вам форму) вместо линии, так чтобы начало и конец прямоугольника точно совпадали с подлежащим кругом.
- Использовать вычисленное значение renderZ (смотрите выше) для упорядочивания по глубине всех форм.
- Наконец, использовать фильтр “glow”, как показано в замечательном уроке Даниэля Ханта о технологии cell shading.

Я собрал все кусочки в отдельном клипе, к которому применил фильтр glow. Все соединяющие формы, такие как руки или ноги, в основном нарисованы слева направо и имеют ширину равную 100. Они подогнаны таким образом, чтобы потом точно совпасть между двумя точками на экране.

Вот как надо использовать класс matrix, чтобы проделать эту работу:

- положите левый край MC в p1 (matrix.tx,matrix.ty),
- измените масштаб MC по оси х, так чтобы его ширина совпадала с расстоянием между p1 и p2, и позвольте оси x показаться по направлению к точке 2 (matrix.a, matrix.b),
- подгоните ось y перпендикулярно оси x (matrix.c, matrix.d),
- всегда выводите ось y вертикально (конструкция if)

function renderMC(MC,p1,p2){
mat=MC.transform.matrix;
mat.tx=p1[0]/2;
mat.ty=p1[1]/2;
dx=p2[0]-p1[0];
dy=p2[1]-p1[1];
d=Math.sqrt(dx*dx+dy*dy);
mat.a=dx/200;
mat.b=dy/200;
mat.c=-dy/d;
mat.d=dx/d;
if(mat.d < 0){
mat.c=-mat.c;
mat.d=-mat.d;
}
MC.transform.matrix=mat;
MC.z=(p1[2]+p2[2])/2;
}


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

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

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

7) ИДЕИ О ТОМ, В КАКОМ НАПРАВЛЕНИИ ДВИНУТЬСЯ ДАЛЬШЕ (ТЕПЕРЬ ВАША ОЧЕРЕДЬ!)
- используйте движение, основанное на времени, вместо основанного на кадрах;

- попробуйте визуализировать лицо, может быть путем добавления дополнительных частей, или (гораздо проще), используя клип из 360 кадров, где вы перейдете с помощью функции gotoAndStop() к кадру, расположенному следом за значением угла – посмотрите поворачивающееся лицо в уроке о технологии cell shading, чтобы увидеть, что я имею ввиду;

- то же самое для верхнего тела, может быть с логотипом на грудной клетке?

- запишите свои собственные наборы анимации наподобие “idle”, “jumping”, “running”, “climbing”,... (неподвижный, прыгающий, бегающий, карабкающийся, и т. д.) и введите промежуточные кадры между ними, чтобы получить сглаженные движения;

- добавьте поле зрения и тень, чтобы прогуливаться кругом в пре-визуализированных трехмерных сценах как в приключенческой игре;

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

- развлекайтесь и размещайте свои эксперименты на форумах.
avatar
Admin
Admin

Сообщения : 92
Очки : 280
Репутация : 36
Дата регистрации : 2010-02-20

Посмотреть профиль http://game-dll.mirbb.net

Вернуться к началу Перейти вниз

Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения