1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

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

Тема в разделе "Maya", создана пользователем Юрий., 28 мар 2006.

Модераторы: Dark™, Skif
  1. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Добрый день!
    Очень прошу помочь новичку в Майа в вопросе, который связан с моделированием для научных целей (биология).
    У меня есть 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 они привязывались автоматически и двигались вместе?

    С уважением.
    Юра.
     
  2. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    Количество joints - постоянная величина?
     
  3. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    В этом-то всё и дело :( Нет, зависит от импортируемого белка :((( Но, в принципе, если это поможет запрограммировать управление, я могу в диалоговом окне ввода (там у меня много разных настроек прописано - имя файла, тайминг, метод при получении структуры молекулы, углы и т.д.) прописать запрос на количество joints. Это мы знаем (количество атомов) для каждого импортируемого белка или ДНК.
     
  4. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    Т.е. для каждой структуры после импорта количество джоинтов не меняется?
    Тогда вам просто нужно на импорте эмиттить нужное кол-во частиц - в любом месте сцены, а потом сделать 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. Юрий.

    Юрий. Активный участник

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

    С уважением и благодарностью.
    Юра.
     
  6. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    в run-time expressions .id - это текущий номер частицы. Эти экспрешны перебирают все частицы в цикле. Если бы это был другой экспрешн - не particle run-time, то он двигал бы всё облако. Но это именно run-time, и он будет перебирать каждую частицу, двигая её куда надо.

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

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Большое спасибо! Попробую в субботу.
     
  8. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Попробовал сделать так

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

    Что-то не работает. Может, чего не так я написал?
     
  9. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    Я ж написал что это псевдокод. Надо писать нормально - т.е. работать с именами, если у вас кости называются специальным образом, и в зависимости от имени назначать частицам радиусы и цвета.

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

    Юрий. Активный участник

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

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Мой мэйл, если кто ещё захочет помочь ==> yuribp+(at)+mail+ru
     
  12. Юрий.

    Юрий. Активный участник

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

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

    С уважением.
    Юра.
     
  13. Тайл

    Тайл Пользователь сайта

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

    Тайл Пользователь сайта

    С нами с:
    15.10.2005
    Сообщения:
    26
    Симпатии:
    0
    Баллы:
    2
    И ваапще мне кажется, что joints не слишком удобны для молекул. Скелетон предполагает однонаправленность от главной точки к периферийным, в результате любые два связаных атома оказываются неравноправны: родитель может крутить потомком, а потомок родителем - нет.
     
  15. Юрий.

    Юрий. Активный участник

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

    С уважением.
    Юра.
     
  16. Тайл

    Тайл Пользователь сайта

    С нами с:
    15.10.2005
    Сообщения:
    26
    Симпатии:
    0
    Баллы:
    2
    Извиняюсь за некоторую задержку. Новая идея, с которой я сейчас сижу, проглатывает время сутками.

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

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

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

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

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

    Тайл Пользователь сайта

    С нами с:
    15.10.2005
    Сообщения:
    26
    Симпатии:
    0
    Баллы:
    2
    Извиняюсь, что форум распёрло из-за скрипта. Кроме того, что форум решил не сохранять в тексте отступы, этот пост ещё и запрещено редактировать :-\

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

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

    SAFE Активный участник

    С нами с:
    11.09.2004
    Сообщения:
    223
    Симпатии:
    0
    Баллы:
    11
    Код можно разместить тут - http://everfall.com/paste/ а в форум вставить ссылку.
     
  19. Тайл

    Тайл Пользователь сайта

    С нами с:
    15.10.2005
    Сообщения:
    26
    Симпатии:
    0
    Баллы:
    2
    Спасибо за подсказку, SAFE!

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

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

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

     

    Вложения:

    • 43.jpg
      43.jpg
      Размер файла:
      8 КБ
      Просмотров:
      65
  20. Тайл

    Тайл Пользователь сайта

    С нами с:
    15.10.2005
    Сообщения:
    26
    Симпатии:
    0
    Баллы:
    2
    Раз уж SAFE снабдил меня такой классной ссылой, перемещаю туда первый скрипт с молекулами, а его местный клон удаляю.

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

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

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

    Вложения:

    • 44.jpg
      44.jpg
      Размер файла:
      6,8 КБ
      Просмотров:
      67
Модераторы: Dark™, Skif

Поделиться этой страницей