1. Зачем это надо?
Вполне логичный вопрос. Тем более что в 3dsMAX'е имеются уже для этих целей соответствующий объект, который так и называется Spring (англ. - пружина). Создать ее можно из меню Create > Dynamic s > Spring или выбрав на командной панели (Command Panel) закладку Create > кнопка Geometry > в выпадающем списке Dynamics Objects > Spring.
Этот стандартный объект имеет немало параметров, отвечающих за форму (длинна, ширина, количество витков, сечение) и за метод построения концов пружины (End Point Method). Все это благополучно анимируется, а при выборе End Point Method > Bound to Object Pivots концы пружины можно привязать к конкретным объектам в сцене, тогда анимировать придется только эти объекты (если они еще не были заанимированы), а пружина уже будет самостоятельно изменять свою длину и местоположение в сцене.
Но если пружина необходима абсолютно другого сечения, чем те, которыми располагает стандартный объект: круглое, прямоугольное и D-образное? Или уже есть готовая модель пружины со своим набором материалов, текстур, текстурных координат? Или же пружину эту надо отэкспортить вместе с анимациями в какой-либо движок (Engine), а он совсем не знает о существовании такого замечательного объекта как Spring, и понимает только Skin-анимацию? Короче говоря, существуют такие ситуации, когда вопрос «Зачем это надо?» не возникает.
2. Устройство пружины
В более общем случае пружину можно разделить на три части:
- красным цветом обозначен недеформируемый нижний конец пружины, т.е. все точки этой части не изменят своего положения относительно друг друга;
- желтым – деформируемая часть;
- зеленым – недеформируемый верхний конец.
3. Анимация деформируемой части
Для начала будет удобно скрыть недеформируемые части пружины(перейти в режим редактирования полигонов, выделить соответствующие недеформированным частям и скрыть Edit Geometry > Hide Selected):
Основная особенность анимации деформируемой части пружины состоит в том, что при изменении длинны пружины, меняется расстояния между витками, при этом форма сечения должна оставаться неизменной. Если применить простое масштабирование вдоль оси пружины, то при растяжении толщина сечения будет увеличиваться, а при сжатии – уменьшаться:
Для того чтоб избежать подобных неприятностей понадобится модификатор Skin и две кости(Bones). При чем, абсолютно не важно ни количество витков пружины, ни форма сечения, ни разность между углами относительно оси пружины, в которых начинается первый виток и заканчивается второй. Важно правильно расположить кости:
- они должны быть параллельны пружине;
- первая кость должна начинаться строго в нижней части сечения первого(нижнего) витка и заканчиваться в нижнейчасти последнего витка;
- вторая кость должна начинаться строго в верхней части сечения первого витка и заканчиваться в верхней части последнего витка.
Войти в режим создания костей можно из меню Create > Systems > Bones IK Chain или из командной панели(Command Panel) закладка Create > кнопка Systems > в выпадающем списке Standard > Bones:
При создании костей необходимо использовать привязки для правильного расположения. Создание первой кости:
И второй:
Для удобства кости можно отодвинуть от оси пружины, чтоб они не находили друг на друга; завершающие косточки – удалить(в них нет необходимости):
Первая кость будет называться bone_down, вторая – bone_ up. Модификатор Skin назначается на саму пружину, в его параметры(Parameters) добавить созданные кости Bones > Add:
Дальше необходимо настроить коэффициенты влияния костей на вершины сетки пружины по следующим правилам:
- на точки, расположенные в нижней части любого сечения пружины, будет влиять только первая кость bone_down;
- на точки, расположенные в верхней части любого сечения пружины, будет влиять только вторая кость bone_up;
- на промежуточные точки коэффициент влияния первой кости bone_down будет равен отношению удаленности точки от верхнегокрая сечения к толщине сечения, второй кости bone_up – отношению удаленности точки от нижнего края сечения к толщине.
Для данного примера:
- толщина сечения равна 5;
- желтые точки расположены в нижней части сечения: коэффициенты влияния bone_down = 1.0, bone_up = 0.0;
- красные точки расположены в верхней части сечения: bone_down = 0.0, bone_up = 1.0;
- синие точки удалены от нижнего края сечения на 1, от верхнего – на 4: bone_down = 1/5 = 0.2, bone_up = 4/5 = 0.8;
- зеленые точки удалены от нижнего края на 4, от верхнего – на 1: bone_down = 4/5 = 0.8, bone_up = 1/5 = 0.8.
Для назначения коэффициентов влияния костей на вершины в свитке параметров модификатора Skin нажать кнопку Edit Envelopes, в группе Select напротив Vertices поставить галочку и в группе Weight Properties нажать кнопку Weight Tool (на кнопке нарисован гаечный ключ), после чего появиться дополнительное окно с одноименным названием:
Материал предоставила группа модмейкеров FORS - fors.at.ua
Для удобства можно выделить все вершины и сбросить коэффициент влияния первой кости bone_ down в ноль. Коэффициенты влияния на вершины назначать лучше сразу на цепочки вершин, расположенных вдоль витков: выделить две соседние вершины и нажать кнопку Loop, выбрать кость в параметрах модификатора, затем нажать кнопку на которой изображен требуемый коэффициент(0, .1, .25, .5, .75, .9, 1) либо рядом с кнопкой Set Weight ввести требуемую величину и нажать ее:
После всех этих манипуляций должно получиться следующее:
Теперь если выделить кости bone_up и bone_down, войти в режим масштабирования, выбрать в качестве центра точки привязки объектов, то при масштабировании костей вдоль оси пружины сама пружина будет корректно сжиматься и разжиматься, при этом толщина сечения изменяться не будет:
4. Анимация не деформируемых частей пружины.
Теперь можно сделать видимыми скрытые полигоны отвечающие, за недеформируемые части. Для этого выбрать объект пружины, перейти на уровень редактирования полигонов и нажать кнопку Edit Geometry > Unhide all:
Для анимации недеформируемых частей понадобится еще две кости: первая кость располагается по оси пружины и ее начало и конец соответствуют началу и концу пружины, вторая – просто завершающая косточка:
Первая кость будет называться bone_start, а вторая – bone_end. В настройках иерархии вращение второй косточки должно быть заблокировано Command Panel > Hierarchy > Link Info > Locks > X, Y, Z:
Для настройки первой кости понадобиться утилита Bone Tools, которая находится в меню Animation > Bone Tools... .Кость должна иметь возможность изменять свою длину (убрать галочку с Freeze Length) и при этом сохранять неизменной свою матрицу трансформаций(Stretch > None):
Кости влияющие на деформируемую чать пружины bone_down и bone_up привязываются к кости bone_start инструментомSelect and Link:
В параметры(Parameters) модификатора Skin добавляются оставшиеся кости bone_start и bone_end. Для скрытых ранее недеформируемых частей пружины назначаются соответствующие коэффициенты влияния:
- для нижней части bone_start = 1.0, все остальные кости 0.0;
- для верхней части bone_end = 1.0, все остальные кости 0.0.
Теперь при изменении положения корневой кости bone_start за ней перемещаются вершины нижней недеформируемой части пружины(через модификатор Skin), кости bone_down и bone_end, которые изменяют положения вершин деформируемой части, и косточка bone_end, изменяющая положения вершин верхней недеформируемой части. При изменении положения косточки bone_end,за ней меняет свою ориентацию корневая кость bone_start и соответственно вся пружина, а также изменяют свое положение относительно продольной оси пружины вершины верхней недеформированой части. Осталось связать масштабирование вдоль оси пружины костей bone_down и bone_end с перемещением косточкиbone_end вдоль оси пружины.
Для начало необходимо получить зависимость коэффициента масштабирования костей деформируемой части от расстояния от косточки bone_end до начала кости bone_start:
Пояснения к рисунку:
- L – расстояние от косточки bone_end до начала кости bone_start (для начального положения L');
- c1, c2, c3, c4 – отступы от концов костей bone_down и bone_up до краев пружины, из-за присутствия недеформируемых частей эти величины неизменны при растяжении или сжатии пружины;
- ld и lu – длины костей bone_down и bone_up соответственно, нетрудно заметить, что они равны между собой, поэтому в дальнейшем будут обозначаться l (для начального положения l').
Необходимо найти соотношение l/l' = s, что и является коэффициентом масштабирования костей деформируемой части. Итак:
L = c1 + lu + c2 = c3 + ld + c4, c1 + c2 + l = c3 + c4 + l, следовательно c1 + c2 = c3 + c4 = C = L' - l',
L = C + l, l = L - C, l' = L' - C,
l / l' = (L - C) / (L' - C) = (L - (L' - l')) / (L' - (L' - l')) = (L - L' + l')/(L' - L' + l') = (L - L' + l') / l' = (L - L')/l' + 1.
Таким образом s = (L - L')/l' + 1, где L' и l' известные величины (их можно получить используя Command Panel > Utilities >Measure. В данном примере получилось L' = 147, l' = 132:
Следующие действия проделываются для каждой кости bone_up и bone_down:
- выделить кость отвечающую за деформируемую часть;
- перейти Command Panel >Motion > Parameters > Assign Controller;
- назначить Sceale контроллер ScaleXYZ;
- назначить X Scale контроллер Float Expression;
- появится окно настройки контроллера:
- тут в группе Create Variables создается новая векторная переменная end_pos и назначается ей контроллер$bone_end.transform.controller.Position, теперь эту переменную можно использовать в выражении Expression, куда и вписываеться полученная ранее формула (length(end_pos) - 147) / 132 + 1, где length(end_pos) и есть расстояние от косточки bone_end до начала кости bone_start, так как переменная end_pos содержит координаты косточкиbone_end относительно родительской кости bone_start.
Вот вроде и все. Теперь если выделить косточку bone_end и выбрать инструмент перемещение Move и подвигать ее должно получиться так:
5. Почему это работает.
Основная идея заключается в правильном расположении костей, отвечающих за деформируемую часть пружины: они смещены друг относительно друга на величину толщины сечения. Именно поэтому при одновременном масштабировании относительно своих точек привязки этих костей расстояния между врхними и нижними точками сечения пружины остаеться неизменным и равным смещению.
Конечно справедливости ради стоит добавить что при растяжении или сжатии пружины сечения должны не только перемещаться вдоль оси, а еще и "закручиваться". Но при небольших изменениях длинны пружины это в глаза не кидается, да и для не очень больших нужно присматриваться, чтоб заметить несоответствие с реальной жизнью. Но и это тоже можно решить, разместив косточки, отвечающие за деформируемую часть пружины, строго по оси пружины и повесив на них еще один контроллер, который будет их вращать вокруг оси пружины и изменять смещение относительно друг друга. Формулы там конечно будут пострашнее и оставляются для настоящих фанатов сделать все как в реальности. Целью было показать основной принцип костевой анимации пружин и вроде она была достигнута.
Файл сцены для 3ds MAX 2010.
|