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

Размещение цепочки на сплайне.

Тема в разделе "Анимация", создана пользователем INCUS, 16 дек 2011.

Модераторы: Артер
  1. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Всем привет..
    Давно хотел спросить и сегодня созрел.
    Цепочка из, допустим, костей > SplineIK Solver > указываю на сплайн (Окружность, ровная, итераций хватает..)
    Пожалуйста, кто-нибудь, скажите почему кости криво размещаются на сплайне, т.е, не совсем пивотами ?
    Почему это происходит, и как это победить ?
    При анимации по кругу заметен общий люфт.
     

    Вложения:

    • 2518942.jpg
      2518942.jpg
      Размер файла:
      48,1 КБ
      Просмотров:
      98
  2. Deruz

    Deruz Знаток

    С нами с:
    06.10.2008
    Сообщения:
    2.070
    Симпатии:
    46
    Баллы:
    77
    Первый наводящий вопрос; На фига это нужно?

    Т.е. какова цель такого создания?
    Может можно проще организовать... :)
     
  3. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Ну, как нафига?
    А цепь велосипедная ? две шестерёнки..как положено...делаешь, делаешь, а тут, ётить, вот такое на выходе.
     
  4. Deruz

    Deruz Знаток

    С нами с:
    06.10.2008
    Сообщения:
    2.070
    Симпатии:
    46
    Баллы:
    77
    Всё это иначе делается и кости там на фиг не нужны!
    Учите мат-часть. :)

    P.S. Кости лишь там, где деформация сетки - остальное иначе.
     
  5. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    На мат часть мне указывать не нужно.
    Я просто прошу ответить на вопрос, который я задал.
    Кости я выбрал как пример для простоты и показательности проблемы моего вопроса.
    Подобная хрень происходит и в случае со слинкованной геометрией.
     
  6. Deruz

    Deruz Знаток

    С нами с:
    06.10.2008
    Сообщения:
    2.070
    Симпатии:
    46
    Баллы:
    77
    Чё те сделать надо скажи.
     
  7. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Делать - ничё. Просто, или подсказать как с такой "болтанкой" бороться,
    или успокоить меня и сказать, что это в максе традиционно и не стоит мозгопара.
     

    Вложения:

    • 2526267.jpg
      2526267.jpg
      Размер файла:
      493,1 КБ
      Просмотров:
      101
  8. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Попробуйте анимировать велосипедную цепь с помощью Path Constraint и LookAt Constraint.
    Или такой способ тоже не подходит для этой задачи? Похожая задача есть в этом уроке.
     
  9. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Спасибо за участие. Подходить-то подходит...есть у меня эта книга в бумаге вместе с диском, на котором есть этот трак от танка...
    Всё нормуль, ничего не болтает.
    Но, всё это сложновато, по сравнению с заявленной простотой использования Spline IK Solver.
    Мне удобнее допускать своё незнание , чем неполноценность инструмента, который специально под это заточен.
    Хотелось бы от него увидеть сухую немецкую точность.
     
  10. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    В чем именно состоит сложность? Попробуйте выполнить этот простой пример:
    Создаем один сплайн Circle и конвертируем его в Editable Spline.
    Создаем один чайник Teapot. Выделяем сплайн и чайник.
    Запускаем скрипт. В новом окне нажимаем кнопку Apply.
    Анимируем % Along Path чайника, который находится в начале сплайна.
    Код:
    try (destroydialog igorznag_path_lookat) catch()
    rollout igorznag_path_lookat "Chain. Path. LookAt."
    (
    --gui
    radiobuttons rb_cs ""  labels:#("Count:", "Spacing:") pos:[5,5] columns:1
    spinner sp_count "" range:[2,1e9,10] fieldWidth:60 type:#integer pos:[65,5]
    spinner sp_spacing "" range:[0,1e9,0] fieldWidth:60 type:#worldunits pos:[65,22]
    checkbox chb_taf "Flip. Object LookAt Axis = X" pos:[5,42]
    radiobuttons rb_stoa "Object Upnode Axis"  labels:#("Y", "Z") pos:[5,60]
    checkbox chb_stoaf "Flip" pos:[80,77]
    label lbl_info "Spline Upnode Axis = Z" pos:[5,95]
    button btn_apply "Apply" pos:[140,60] width:60 height:50
    button btn_update "Update" pos:[145,10]
    --functions
    fn update_cs =
    (
    if(selection.count==2)then
    (
    spline_path=undefined; obj=undefined; 
    spline_types=#(SplineShape,line);cl1=classof selection[1];cl2=classof selection[2]
    if(finditem spline_types cl1!=0 and finditem spline_types cl2==0)then 
    (spline_path=selection[1];obj=selection[2])
    if(finditem spline_types cl2!=0 and finditem spline_types cl1==0)then 
    (spline_path=selection[2];obj=selection[1])
    if(spline_path!=undefined)then
    (
    if numSplines spline_path==1 then
    (
    spline_length=0; sl_a=getSegLengths spline_path 1
    if(sl_a.count>0)then spline_length=sl_a[sl_a.count]
    if rb_cs.state==1 then sp_spacing.value=1.0*spline_length/sp_count.value 
    if rb_cs.state==2 then 
    (
    if(sp_spacing.value>0)then
    (
    v=int(1.0*spline_length/sp_spacing.value)
    if v<2 then v=2; sp_count.value=v
    )--if(sp_spacing.value>0)then
    else sp_count.value=2
    )--if rb_cs.state==2 then 
    )--if numSplines spline_path==1 then
    )--if(spline_path!=undefined)then
    )--if(selection.count==2)then
    )--fn update_cs =
    --events
    on btn_apply pressed do
    (
    if(selection.count==2)then
    (
    spline_path=undefined; obj=undefined; 
    spline_types=#(SplineShape,line);cl1=classof selection[1];cl2=classof selection[2]
    if(finditem spline_types cl1!=0 and finditem spline_types cl2==0)then 
    (spline_path=selection[1];obj=selection[2])
    if(finditem spline_types cl2!=0 and finditem spline_types cl1==0)then 
    (spline_path=selection[2];obj=selection[1])
    if(spline_path!=undefined)then
    (
    if numSplines spline_path==1 then
    (
    undo on 
    ( 
    with animate off
    (
    objs_temp_a=#(); objs_count=sp_count.value
    script_continue=true
    if objs_count>1000 then script_continue=queryBox "Continue?" title:"Count is a big number!"
    if(script_continue==true)then
    (
    for i=1 to objs_count do
    (
    maxOps.cloneNodes obj cloneType:#instance newNodes:&n
    append objs_temp_a n[1];
    )--for i=1 to objs_count do
    d=undefined
    for i=1 to objs_temp_a.count do 
    (
    if i==1 then
    (
    objs_temp_a[i].pos.controller = Path_Constraint() 
    c=objs_temp_a[i].pos.controller; c.path=spline_path
    c.percent.controller=bezier_float();
    setBeforeORT c.percent.controller #cycle
    setAfterORT c.percent.controller #cycle
    --
    d=dummy();d.pos.controller=Path_Constraint() 
    c=d.pos.controller;c.path=spline_path
    setBeforeORT c.percent.controller #cycle 
    setAfterORT c.percent.controller #cycle
    c.percent.controller = float_script() 
    c.percent.controller.AddObject "obj1_percent" objs_temp_a[1].pos.controller.percent.controller
    c.percent.controller.script="obj1_percent.value"
    )--if(i==1)then
    
    if i>1 then
    (
    objs_temp_a[i].pos.controller=Path_Constraint()
    c=objs_temp_a[i].pos.controller;c.path=spline_path
    setBeforeORT c.percent.controller #cycle 
    setAfterORT c.percent.controller #cycle
    c.percent.controller = float_script() 
    c.percent.controller.AddObject "obj1_percent" objs_temp_a[1].pos.controller.percent.controller
    c.percent.controller.script="obj1_percent.value+"+(((1.0/objs_count)*(i-1)) as string)
    )--if i>1 then
    
    objs_temp_a[i].rotation.controller = LookAt_Constraint();
    c=objs_temp_a[i].rotation.controller
    c.target_axis=0;c.lookat_vector_length=0;c.target_axisFlip=chb_taf.checked
    objs_temp_a[i].rotation.controller.upnode_world = off
    objs_temp_a[i].rotation.controller.pickUpNode=spline_path
    c.upnode_ctrl=1;c.StoUP_axis=rb_stoa.state;c.StoUP_axisFlip=chb_stoaf.checked;
    c.upnode_axis=2
    if(i<objs_temp_a.count)then c.appendTarget objs_temp_a[i+1] 100
    if(i==objs_temp_a.count)then c.appendTarget d 100
    )--for i=1 to objs_temp_a.count do 
    select objs_temp_a; selectMore d
    redrawViews()
    )--if(script_continue==true)then
    )--with animate off
    )--undo off
    )--if numSplines spline_path==1then
    )--if(spline_path!=undefined)then
    )--if(selection.count==2)then
    )--on btn_apply pressed do
    --
    on igorznag_path_lookat open do
    (
    sp_spacing.enabled=false
    update_cs()
    )--on igorznag_path_lookat open do
    --
    on rb_cs changed arg do
    (
    sp_count.enabled=true;sp_spacing.enabled=true
    if(arg==1)then sp_spacing.enabled=false
    if(arg==2)then sp_count.enabled=false
    update_cs()
    )--on rb_cs changed arg do
    --
    on sp_count entered do update_cs()
    on sp_spacing entered do update_cs()
    on btn_update pressed do update_cs()
    ); createdialog igorznag_path_lookat 210 115
     
  11. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Большое спасибо за скрипт. Однозначно пригодится. Но...
    Понимаешь, именно из-за того, что траки в твоём скрипте не находятся в иерархии как кости, мы тоже получаем на резких поворотах сплайна вот такие недочёты.
    Когда путь прямой, между траками одно расстояние, а на повороте, хоть и малозаметно, но уже другое.
     

    Вложения:

    • 3040657.jpg
      3040657.jpg
      Размер файла:
      76,6 КБ
      Просмотров:
      94
  12. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    Расстояние между поинтами разное отсюда и просветы .Будет скрипт выравнивающий расстояние между любым количеством поинтов на сплайне с любой формой всё будет работать нормально.Есть однако мысль использовать MassFx для таких целей так как вышеперечисленных способах не учитывается естественный провис сочленений (хоть цепи хоть трака) между движущимися элементами (опорными катками танков к примеру).
     
  13. igorznag

    igorznag Знаток

    С нами с:
    23.04.2010
    Сообщения:
    1.256
    Симпатии:
    173
    Баллы:
    65
    Попробуйте такой вариант:
    Создаем один сплайн Circle и конвертируем его в Editable Spline.
    Создаем один чайник Teapot. Выделяем сплайн и чайник.
    Запускаем скрипт. В новом окне нажимаем кнопку Apply.
    Анимируем % Along Path чайника, который находится в начале сплайна.
    Чем меньше Seg Length, тем меньше недочетов и тем больше вычислений.
    Seg Length работает также, как Seg Length в модификаторе Normalize Spline.
    Скрипт проверяет только половину длины сплайна и ищет подходящее место.
    Объект Dummy и Plane являются вспомогательными и не нужно их удалять.
    Код:
    try (destroydialog igorznag_spline_ik) catch()
    rollout igorznag_spline_ik "SplineIK"
    (
    --gui
    spinner sp_count "Count:" range:[2,1e9,10] fieldWidth:60 type:#integer pos:[32,5]
    spinner sp_spacing "Spacing:" range:[0,1e9,10] fieldWidth:60 type:#worldunits pos:[21,22]
    spinner sp_precision "Seg Length:" range:[0,1e9,1] fieldWidth:60 type:#worldunits pos:[5,40]
    checkbox chb_taf "Flip. Object LookAt Axis = X" pos:[5,57]
    radiobuttons rb_stoa "Object Upnode Axis"  labels:#("Y", "Z") pos:[5,75]
    checkbox chb_stoaf "Flip" pos:[80,92]
    label lbl_info "Spline Upnode Axis = Z" pos:[5,110]
    button btn_apply "Apply" pos:[130,75] width:50 height:50
    --events
    on btn_apply pressed do
    (
    if(selection.count==2)then
    (
    spline_path=undefined; obj=undefined; 
    spline_types=#(SplineShape,line);cl1=classof selection[1];cl2=classof selection[2]
    if(finditem spline_types cl1!=0 and finditem spline_types cl2==0)then 
    (spline_path=selection[1];obj=selection[2])
    if(finditem spline_types cl2!=0 and finditem spline_types cl1==0)then 
    (spline_path=selection[2];obj=selection[1])
    if(spline_path!=undefined)then
    (
    if numSplines spline_path==1 then
    (
    undo on 
    ( 
    with animate off
    (
    len=curveLength spline_path 1
    if(sp_precision.value>0 and sp_precision.value<sp_spacing.value)then
    if(sp_precision.value<len and sp_spacing.value<len)then
    (
    spline_path.optimize=false;spline_path.adaptive=false;spline_path.steps=100;
    objs_temp_a=#(); objs_count=sp_count.value
    for i=1 to objs_count do
    (
    maxOps.cloneNodes obj cloneType:#instance newNodes:&n
    append objs_temp_a n[1];
    )--for i=1 to objs_count do
    --
    d=plane();d.name="igorznag_splineIK"; 
    d.width=0;d.length=0;d.widthsegs=1;d.lengthsegs=1;
    d.pos.controller=Position_Constraint()
    c=d.pos.controller;c.constraints.appendTarget objs_temp_a[1] 100
    d_end=dummy();d_end.pos.controller=position_xyz();
    --
    for i=1 to objs_temp_a.count do 
    (
    if(i==1)then 
    (
    objs_temp_a[i].pos.controller=Path_Constraint() 
    c=objs_temp_a[i].pos.controller;c.path=spline_path
    c.percent.controller=linear_float();
    setBeforeORT c.percent.controller #cycle 
    setAfterORT c.percent.controller #cycle
    )
    
    if(i>1)then objs_temp_a[i].pos.controller=position_xyz();
    objs_temp_a[i].rotation.controller = LookAt_Constraint();
    c=objs_temp_a[i].rotation.controller
    c.target_axis=0;c.lookat_vector_length=0;c.target_axisFlip=chb_taf.checked
    objs_temp_a[i].rotation.controller.upnode_world = off
    objs_temp_a[i].rotation.controller.pickUpNode=spline_path
    c.upnode_ctrl=1;c.StoUP_axis=rb_stoa.state;c.StoUP_axisFlip=chb_stoaf.checked;
    c.upnode_axis=2
    if(i<objs_temp_a.count)then c.appendTarget objs_temp_a[i+1] 100
    if(i==objs_temp_a.count)then c.appendTarget d_end 100
    )--for i=1 to objs_temp_a.count do 
    
    --script
    d.rotation.controller=rotation_script()
    c=d.rotation.controller
    setBeforeORT c #cycle; setAfterORT c #cycle
    c.AddObject "igorznag_spline_path" spline_path
    c.AddObject "igorznag_dummy_end" d_end.pos.controller
    for i=1 to objs_temp_a.count do 
    c.AddObject ("igorznag_obj"+(i as string)) objs_temp_a[i].pos.controller
    str=""
    str+="with animate off ( try (";str+="\n"
    str+="spacing="+(sp_spacing.value as string);str+="\n"
    str+="precision="+(sp_precision.value as string);str+="\n"
    str+="len=curveLength igorznag_spline_path 1";str+="\n"
    str+="if(len>0)then";str+="\n"
    str+="(";str+="\n"
    str+="vert_coord_offset=igorznag_obj1.value";str+="\n"
    str+="temp_percent=nearestPathParam igorznag_spline_path 1 vert_coord_offset";str+="\n"
    str+="temp_precision_offset=(pathToLengthParam  igorznag_spline_path 1 temp_percent)*len";str+="\n"
    for i=2 to objs_temp_a.count do
    (
    str+="temp_precision=0;temp_precision_global=temp_precision_offset;";str+="\n"
    str+="dist_min=1e9;vert_coord=vert_coord_offset;";str+="\n"
    str+="while temp_precision < len/2.0 do";str+="\n"
    str+="(";str+="\n"
    str+="t=1.0*temp_precision_global/len";str+="\n"
    str+="vert_coord_temp=lengthInterp igorznag_spline_path 1 t";str+="\n"
    str+="dist_temp=abs((distance vert_coord_temp vert_coord)-spacing)";str+="\n"
    str+="if(dist_temp<dist_min)then";str+="\n"
    str+="(";str+="\n"
    str+="dist_min=dist_temp;";str+="\n"
    str+="temp_precision_offset=temp_precision_global";str+="\n"
    str+="vert_coord_offset=vert_coord_temp";str+="\n"
    str+=")";str+="\n"
    str+="temp_precision+=precision";str+="\n"
    str+="temp_precision_global+=precision";str+="\n"
    str+="if(temp_precision_global>len)then temp_precision_global-=len";str+="\n"
    str+=")--while";str+="\n"
    str+="igorznag_obj"+(i as string)+".value=vert_coord_offset";str+="\n"
    )--for i=2 to 2 do--objs_temp_a.count do
    --d_end
    str+="temp_precision=0;temp_precision_global=temp_precision_offset;";str+="\n"
    str+="dist_min=1e9;vert_coord=vert_coord_offset;";str+="\n"
    str+="while temp_precision < len/2.0 do";str+="\n"
    str+="(";str+="\n"
    str+="t=1.0*temp_precision_global/len";str+="\n"
    str+="vert_coord_temp=lengthInterp igorznag_spline_path 1 t";str+="\n"
    str+="dist_temp=abs((distance vert_coord_temp vert_coord)-spacing)";str+="\n"
    str+="if(dist_temp<dist_min)then";str+="\n"
    str+="(";str+="\n"
    str+="dist_min=dist_temp;";str+="\n"
    str+="temp_precision_offset=temp_precision_global";str+="\n"
    str+="vert_coord_offset=vert_coord_temp";str+="\n"
    str+=")";str+="\n"
    str+="temp_precision+=precision";str+="\n"
    str+="temp_precision_global+=precision";str+="\n"
    str+="if(temp_precision_global>len)then temp_precision_global-=len";str+="\n"
    str+=")--while";str+="\n"
    str+="igorznag_dummy_end.value=vert_coord_offset";str+="\n"
    --d_end
    str+="print \"da\"";str+="\n"
    str+=")--if(precision<spacing and ";str+="\n"
    str+=")catch (quat 0 0 0 1))--try with animate off";str+="\n"
    str+="quat 0 0 0 1";
    c.script=str
    --
    select objs_temp_a; selectmore d; selectmore d_end
    redrawViews()
    )--if(sp_precision.value<len and sp_spacing.value<len)then
    )--with animate off
    )--undo off
    )--if numSplines spline_path==1then
    )--if(spline_path!=undefined)then
    )--if(selection.count==2)then
    )--on btn_apply pressed do
    --
    ); createdialog igorznag_spline_ik 190 135
     
  14. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    Ё-!.Только за то,что напечатал столько уже можно сказать ОГРОМНОЕ СПАСИБО!Война и мир.Жаль,что времени нет и в плотную заняться и всё проверить(но скрипт скачал).Спасибо!
     
  15. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    iqorznaq
    Ну, да, ..съезд/разъезд уже стал меньше намного...
    Но скрипток дуже макс подвешивает...
    Выделил бокс и сплайн и запустил как велено...поставил Count=23 - во вьюпорте 0,5 фпс(Seg Length = 25mm) ........а на трекбаре ползун скачет аж через 25 кадров. Видно как Макс покрывается потом.
    Делаю Seg Length = 10, и жму Play, ....Макс на время делается недоступным, а потом восстанавливается без всякого проигрывания, как буд-то его ни очём сейчас не попросили. Не тянет он что-то.
    Проц у меня четырёхголовый, правда, и памяти 8 г,.. Win7 64x. Max 2013.
     
  16. monah_62

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

    С нами с:
    13.02.2010
    Сообщения:
    1
    Симпатии:
    0
    Баллы:
    2
    И у меня такая же проблема присоеденяюсь... Все таки хотелось узнать из -за чего это происходит и как с этим бороться!?
     
  17. Сhin@man

    Сhin@man Активный участник

    С нами с:
    04.12.2012
    Сообщения:
    81
    Симпатии:
    1
    Баллы:
    7
    http://www.youtube.com/watch?v=UTWCt2yYwIc
     
  18. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Почему - то "Левшу" вспомнил....
    Chin@man , мы в этой теме не учим танцевать саму блоху. Мы тут обсуждаем какой выбрать шрифт для надписи на гвоздиках к подковам, которыми блоха подкована.
     
  19. INCUS

    INCUS Знаток

    С нами с:
    03.08.2010
    Сообщения:
    857
    Симпатии:
    30
    Баллы:
    29
    Почему - то "Левшу" вспомнил....
    Chin@man , мы в этой теме не учим танцевать саму блоху. Мы тут обсуждаем какой выбрать шрифт для надписи на гвоздиках к подковам, которыми блоха подкована.
     
  20. diwian diwian

    diwian diwian Мастер

    С нами с:
    05.06.2010
    Сообщения:
    4.742
    Симпатии:
    74
    Баллы:
    83
    INCUS. Мышка похоже "лоджитековская"-двойные срабатывания.
     
Модераторы: Артер

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