Render.ru

Управдение частицами per particle при помощи joints.

Юрий.

Активный участник
Рейтинг
5
#1
Добрый день!
Очень прошу помочь новичку в Майа в вопросе, который связан с моделированием для научных целей (биология).
У меня есть skeleton. Скелет, который получился в результате импорта файла PDB (формат, описывающий координаты атомов макромолекул). Т.е. joints - это атомы, а bones - межатомные расстояния. Более того, считав весь PDB-файл (все структуры) и поместив все joints в каждой модели в keyframes, я получил анимированную модель макромолекулы. Далее идёт "химическая" кухня, задание ограничений для того, чтобы при движении молекула не занимала невозможных с точки зрения химии положений.
Ну и вот - теперь стала задача атомы представить шариками. А вот тут нас ждала маленькая засада. Атомов в сцене - десятки тысяч, доходит до 100 тысяч. Пробовали с NURBS, Poligons - ничего не вышло. Машина P-IV, 3,2 Ghz, памяти 2 Gb. Остановились на частицах.
А вот теперь вопрос - как в real time при помощи joints управлять положением per particles. Написался у меня следующий скрипт:
global proc contrpart()

global proc contrpart()
{
float $x;
float $y;
float $z;
string $pame;

$pame = ("_Pame_");
particle -n $pame ;
addAttr -ln "rgbPP" -dt vectorArray ($pame + "Shape") ;
addAttr -ln "rgbPP0" -dt vectorArray ($pame + "Shape");
addAttr -ln "radiusPP" -dt doubleArray ($pame + "Shape") ;
addAttr -ln "radiusPP0" -dt doubleArray ($pame + "Shape");
addAttr -ln Mult -at double -min 0 -max 10 -dv 1 $pame;
setAttr -e -keyable true ($pame+".Mult");
setAttr (($pame + "Shape") +".particleRenderType") 4;

global float $xtrans=-1;
global float $ytrans=3;
global float $ztrans=8;
global float $xmov;
global float $ymov;
global float $zmov;
global float $vect[];
global float $vect1[];
global int $i;
global string $am;
global int $i1;
global string $am1;

joint -a -p 0 0 0 -n "j1";
joint -a -p 2 3 0 -n "j2";
joint -a -p 1 6 8 -n "j3";
joint -a -p 3 1 2 -n "j4";
joint -a -p 5 2 -2 -n "j5";

setKeyframe -attribute "translateX" -time 1 -value -1 j3;
setKeyframe -attribute "translateY" -time 1 -value 3 j3;
setKeyframe -attribute "translateZ" -time 1 -value 8 j3;

emit -o $pame -pos 0 0 0 -at rgbPP -vv 0 0 1 -at radiusPP -fv 0.7;
emit -o $pame -pos 2 3 0 -at rgbPP -vv 0 0 1 -at radiusPP -fv 0.7;
emit -o $pame -pos 1 6 8 -at rgbPP -vv 0 0 1 -at radiusPP -fv 0.7;
emit -o $pame -pos 3 1 2 -at rgbPP -vv 0 0 1 -at radiusPP -fv 0.7;
emit -o $pame -pos 5 2 -2 -at rgbPP -vv 0 0 1 -at radiusPP -fv 0.7;

setKeyframe -attribute "translateX" -time 24 -value 10 j3;

$am1="j3";
expression -s "global float $vect[];\r\n$vect=`joint -q -a -p $am1`;" -o $am1 -ae 1 -uc all ;
$am="j4";
expression -s "global float $vect1[];\r\n$vect1=`joint -q -a -p $am`;" -o $am -ae 1 -uc all ;

$i1=2;
$i=3;
dynExpression -s "particle -e -or $i1 -at position -vv ($vect[0]) ($vect[1]) ($vect[2]) _Pame_Shape ;\r\nparticle -e -or $i -at position -vv ($vect1[0]) ($vect1[1]) ($vect1[2]) _Pame_Shape ;" -rad _Pame_Shape;
}

Как вы видите, частицы 2 и 3 движутся за joints 3 и 4. Проблема в строке "dynExpression.........", где пришлось явно прописывать частицы и ведущие "суставы". Но, как вы понимаете, программа пишется для того, чтобы унифицировать импорт макромолекул, а они, как известно, все разные.
Вот в этом и заключается вопрос: как модифицировать скрипт (или может как-то по другому связать частицы с ведущими joints) таким образом, чтобы при любом количестве joints и particles они привязывались автоматически и двигались вместе?

С уважением.
Юра.
 

Юрий.

Активный участник
Рейтинг
5
#3
В этом-то всё и дело :( Нет, зависит от импортируемого белка :((( Но, в принципе, если это поможет запрограммировать управление, я могу в диалоговом окне ввода (там у меня много разных настроек прописано - имя файла, тайминг, метод при получении структуры молекулы, углы и т.д.) прописать запрос на количество joints. Это мы знаем (количество атомов) для каждого импортируемого белка или ДНК.
 
Рейтинг
34
#4
Т.е. для каждой структуры после импорта количество джоинтов не меняется?
Тогда вам просто нужно на импорте эмиттить нужное кол-во частиц - в любом месте сцены, а потом сделать run-time expression для того чтобы в каждом кадре частицы следовали за джоинтами.

int $id = particleShape1.id;
getAttr joints[$id] someAttributes // на джоинты на импорте можно вешать нужные атрибуты - название или номер вещества и в зависимости от этого номера задавать нужные атрибуты частицам
particleShape1.wpos = getAttr joints[$id].translate;

По идее всё. Ессно то что я написал - это псевдокод, работать не будет. Но идея понятна, надеюсь.

Я не помню точно, но кажется для уже готового облака частиц, creation expression выполняется только на первом кадре, и для того чтобы это работало побыстрее, можно впихнуть назначение атрибутов - в creation, а изменение позиции - в run-time.

Более того, можно сделать quickSelectionSet, с только нужными джоинтами, и делать так:
string $joints[] = `sets -q jointSet`;
Но тогда вам придётся как-то хэндлить изменяемое кол-во джоинтов. Например в первом кадре(playbackOptions -q -min) убивать все частицы и эмиттить нужное количество.

В общем там вариантов тонна - зависит от того что вам нужно.
 

Юрий.

Активный участник
Рейтинг
5
#5
Большое спасибо, Решатель! На след неделе попробую так. Немного не понял, какие атрибуты добавать к джойнтам - они имеют названия по атомарной спецификации. wpos, как я понимаю, worldPosition. Я, кажется, понял, что Вы имеете в виду в команде particleShape1.wpos = getAttr joints[$id].translate; Это было бы всё хорошо, если бы не одно "но" - у нас одна частица занимает объём одного атома. Другая - другого. И т.д. А объект "Частицы" - один на одну полимолекулу. Поэтому, как мне кажется, такой сценарий (particleShape1.wpos = getAttr joints[$id].translate;) не сработает, поскольку не заданы id частиц.

С уважением и благодарностью.
Юра.
 
Рейтинг
34
#6
в run-time expressions .id - это текущий номер частицы. Эти экспрешны перебирают все частицы в цикле. Если бы это был другой экспрешн - не particle run-time, то он двигал бы всё облако. Но это именно run-time, и он будет перебирать каждую частицу, двигая её куда надо.

Собственно ваши названия джоинтов и есть та доп. информация, по которой можно задавать параметры - можно завести атрибуты, а можно действительно использовать и названия.
 

Юрий.

Активный участник
Рейтинг
5
#8
Попробовал сделать так

int $id = particleShape1.id;
getAttr joints[$id] someAttributes // на джоинты на импорте можно вешать нужные атрибуты - название или номер вещества и в зависимости от этого номера задавать нужные атрибуты частицам
particleShape1.wpos = getAttr joints[$id].translate;

Что-то не работает. Может, чего не так я написал?
 
Рейтинг
34
#9
Я ж написал что это псевдокод. Надо писать нормально - т.е. работать с именами, если у вас кости называются специальным образом, и в зависимости от имени назначать частицам радиусы и цвета.

А wpos не работает потому что position/worldPosition - это вектора, массивы им нельзя назначить. Нужно сначала брать translate в переменную, а потом назначать его position частиц(worldPosition - read-only, так что работать придётся с position) в виде вектора.
 

Юрий.

Активный участник
Рейтинг
5
#10
Добрый день, Решатель! Всё искал как с Вами можно связаться (личка или мэйл), но на сайте не нашёл. Хотелось бы обсудить эту проблему, не забивая форум. 2 недели упорных попыток не дали результата. Частицы не двигаются. Локаторы per particle тоже. Короче... полная ж@па, уж извините. :((((( Изучил Д. Гоулда, скачал ещё какой-то файл .doc на русском по MEL..... Нигде не описан ПРИНЦИП работы с частицами и, главное, per particle управление, с примерами. Могу ли я написать Вам, и, если "да", то по какому адресу.
 

Юрий.

Активный участник
Рейтинг
5
#12
В общем, проблема так и осталась нерешённой. Но задача немного видоизменилась. Появилась следующая мысль - создать локаторы по количеству joints, привязать particles к соответствующим locators как к goals per particle с goal weight=1. Позиционировать локаторы в каждом фрейме в соответствии с координатами joints. Как видите - есть 2 вопроса. 1) - как присваивается goal per particle средствами MEL? 2) Как происходит позиционирование множества объектов (в нашем случае локаторов) в соответствии с перемещением ведущих объектов (joints)?

Очень рассчитываю на помощь.

С уважением.
Юра.
 

Тайл

Пользователь сайта
Рейтинг
2
#13
Не уверен, что goals per particle сгодится. Каждая "цель" действует на все частицы. Если у тебя будут 10 000 целей, тебе придется заполнять диагональную матрицу весов 10 000 x 10 000 элементов. Она одна займет 800 МБ.
ИМХО, лучше использовать пружины (c нулевой длиной при мин. энергии) - они не видят соседей, а только свои два конца.
 

Тайл

Пользователь сайта
Рейтинг
2
#14
И ваапще мне кажется, что joints не слишком удобны для молекул. Скелетон предполагает однонаправленность от главной точки к периферийным, в результате любые два связаных атома оказываются неравноправны: родитель может крутить потомком, а потомок родителем - нет.
 

Юрий.

Активный участник
Рейтинг
5
#15
Хм, я думал, что можно каждой частице назначить свою цель? Что - получается, что это невозможно? Странно. Почему же тогда атрибут называется goalPP? И что такое "пружины" и каким образом они могут быть полезны?
Что касается joints, хм, то тут есть над чем подумать. Мы задаём ключевые фреймы, а Мая сама рассчитывает пути... Кроме того, в белках есть так называемый backbone и sidechains. Последние никак не могут влиять на ориентацию первого. А если и влияют (например S-S bonds) то это выражается в координатах, которые мы и вводим как ключи.

С уважением.
Юра.
 

Тайл

Пользователь сайта
Рейтинг
2
#16
Извиняюсь за некоторую задержку. Новая идея, с которой я сейчас сижу, проглатывает время сутками.

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

Цели, которые называются Goals, действуют на каждую из частиц объекта Particle. Они используются Майей так: она вычисляет общий центр массы всех целей, получает точку в пространстве, и в эту точку начинают стягиваться _все_ частицы. Инерционность каждой частицы при движении задаётся величиной goalPP. Если там единица - инерции нет. Частица мгновенно перепрыгивает на цель и прилипает к ней. Если goalPP меньше единицы, движение инерционное и с затухающими колебаниями - типовое уравнение второго порядка.

Чтобы частицы притягивались каждая к своей точке, используются пружины. "Springs" - это тоже одиночный объект, наподобие Particle, и может содержать тысячи/миллионы пружин. На одном конце пружины обязательно должна быть частица, а на другом можно много чего - vertex, другую частицу, lattice point и т.д.. В результате каждая пружина тянет прицепленную к ней частицу. Тоже по уравнению второго порядка, с колебаниями.

Но это всё больше полезно для анимации - плавные туманы/ручейки и все такое. Если показывать инерционность-упругость не требуется, быстрее, наверное, просто "приклеить" частицы к нужным суставам.

Если именовать суставы согласованно с ID частиц, и нарушить пару правил хорошего тона, все можно сделать нехитрым скриптом ->
 

Тайл

Пользователь сайта
Рейтинг
2
#17
Извиняюсь, что форум распёрло из-за скрипта. Кроме того, что форум решил не сохранять в тексте отступы, этот пост ещё и запрещено редактировать :-\

Кто-нибудь знает, как опубликовать скрипт с сохранением отступов? Ладно, MEL - ему отступы по барабану, читать лишь неудобно. А как жить блендероведам? У питона-пайтона они принципиальны, это аналог расставленных определенным образом скобок.

Впрочем, ладно...
 

SAFE

Активный участник
Рейтинг
12
#18
Код можно разместить тут - http://everfall.com/paste/ а в форум вставить ссылку.
 

Тайл

Пользователь сайта
Рейтинг
2
#19
Спасибо за подсказку, SAFE!

Надо мне немного потренироваться. Значит, скрипты я кладу туды...А здесь пишу сцылу и добавляю скриншот, чтобы человек не тратил понапрасну время из-за одного только любопытства "глянуть на результат".

Несерьёзный код (28 строк включая пустые)) находится здесь:

http://www.everfall.com/paste/id.php?z6dxmxd77rrn

 

Вложения

  • 8 КБ Просмотров: 358

Тайл

Пользователь сайта
Рейтинг
2
#20
Раз уж SAFE снабдил меня такой классной ссылой, перемещаю туда первый скрипт с молекулами, а его местный клон удаляю.

Надпись на картинке "full size 320*200" переводится в данном случае как "Я не собирался выкладывать в форум большое изображение, так что кликать по картинке "для увеличения" смысла нет. Она окажется почти такая же по размерам"

2 Юрий.
Скрипт в 60 строк, создающий скелетон и привязывающий частицы к суставам, лежит здесь:

http://www.everfall.com/paste/id.php?ixq1ht32n7e0
 

Вложения

  • 6,8 КБ Просмотров: 336
Сверху