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

Автоматическая чистка ключей анимации полученых из Camera Tracker

Тема в разделе "MAXScript", создана пользователем Максим Поклонов, 11 апр 2007.

Модераторы: Savin Denis
  1. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Привет всем. Я хочу сделать своеобразный Nose Gate для автоматической чистки ключей анимации взятой с Camera Tracker.
    Я сделал видеосъемку и отследил на ней тракером движущуюся точку. Точка в кадре то двигается, то не двигается. В те моменты когда она не двигается тракер все равно отслеживает хоть минимальное но движение. После этого я присвоил данные тракера к Dummy. И в тех местах, где Dummy статичен, он все равно слегка перемещается. С помощью этого скрипта я хочу отследить каждый участок такого статичного дрожания Dummy и кадрам этого участка назначить позицию начального кадра этого участка. Проще говоря я хочу устранить все незначительные колебания Dummy.

    for i=1 to 100 do

    -- Запускаем цикл на 100 кадров. Он будет обрабатывать
    -- каждый кадр используя следующий цикл [k]
    -- Этот цикл нужен для того, чтобы при обнаружении
    -- дрожащего участка переменная var не менялась
    -- в его рамках, а ее значение будет присвоено всем кадрам этого участка.

    (var=$dummy*.position

    -- В начале первого цикла присваиваем переменной var
    -- положение Dummy в текущем (начальном) кадре.
    -- После выполнения цикла [k] выполняется следующий
    -- виток цикла в котором переменной var
    -- присваивается новое значение.

    for k=i to k+=1 do(

    -- Этот цикл [k] сравнивает значение текущего кадра, со
    -- значением следующего кадра и при соответствии
    -- условиям производит замену значения текущего кадра на первичное
    -- значение данного участка (значение переменной var).

    if (at time k+1 $dummy*.position)>var+1 or
    (at time k+1 $dummy*.position)<var+1 do
    (at time k $dummy*.position)=var

    -- Если позиция в текущем кадре отличается от позиции в следующем кадре меньше
    -- чем на 1 (это значение условно. Оно означает величину дрожания)
    -- то текущему кадру присваивается значение переменной
    -- var, то есть начальному значению этого участка.

    i=k

    -- А переменной i (для цикла ) присваивается текущее значение k
    -- (цикла [k]), для того чтобы цикл продолжился
    -- не со следующего кадра а с кадра следующего после участка
    -- дрожания (обработанного циклом [k]).

    else continue)

    -- Иначе, если позиция в текущем кадре отличается от следующего
    -- больше чем на 1 (значит пошла какая-то анимация)
    -- и подолжается цикл .

    )

    Короче все это дело имеет примерно такой вид:

    for b in $* where classof b == dummy do(
    for i=1 to 100 do
    (var=b.position
    for k=i to k+=1 do(
    if (at time k+1 b.position)>var+1 or
    (at time k+1 b.position)<var+1 do
    (at time k b.position)=var
    i=k
    else continue
    )
    else continue
    )
    else continue
    )
    else exit


    Вобщем вся эта голематья не работает конечно, потому, что я безгоду неделя изучаю MaxScript, и еще не знаю синтаксис. Так что пожалуйста не смейтесь если я нагородил охинею, а помогите написать это правильно.

    зы: знаю, что Савин Денис не любит когда много текста, но извените по-проще не получилось ;)
     
  2. MaxWell

    MaxWell Знаток

    С нами с:
    06.06.2005
    Сообщения:
    1.086
    Симпатии:
    0
    Баллы:
    30
    Ну, будем надеяться на благосклонность Дениса. :)
     
  3. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Неужели все настолько безнадежно 8-|
     
  4. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Привет !

    У такого фильтра достаточно большая вероятность попортить движение на плавных участка (замедление/начало движения)


    Код:
    threshold = 6.1
    obj = $Dummy02
    select obj
    
    tbar = maxops.trackbar
    
    t_ = t = animationRange.start
    t_end = animationRange.end
    p1 = 0. 
    p2 = 0.
    
    at time t p1 = obj.pos
    at time t t = tbar.getNextKeyTime()
    
    animate on
    	while t_ < t and t <= t_end do 
    	( 
                    at time t p2 = obj.pos
    				
    		if (distance p1 p2) <= threshold then 
    		(
    			at time t obj.pos = p1
    			p2 = p1
    		) 
    		t_ = t
    		at time t t = tbar.getNextKeyTime()		
    		p1=p2 		
    	)
    
    
     
  5. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    To Savin Denis

    Привет. Рад тебя "видеть" )
    Ну что ж. Все получилось. Только ты был прав насчет вероятности попортить движение на плавных участках. В общем-то так оно и вышло. Получается, что скрипт держит позицию пока она в пределах параметра "threshold". Как только этот параметртр превышен, получается скачек.

    Я подумал, что если не уравнивать ключи, а может быть удалять, то кривая анимации будет плавно переходить от ключа к ключу, а трешхолдом настоить эти промежутки. Так рывки получились (

    С удалением ключей попробую сам разобраться только мне незнакомы некоторые команды:
    tbar = maxops.trackbar -- "tbar" это наверное переменная, а вот "maxops.trackbar" не знаю что это.

    И вобще кажется я пошел не тем путем. Если сделать анимацию трясущегося Dummy, который при этом еще и медленно движется в сторону, то после обработки скриптом он просто останется на месте (
    Может есть какая нибудь команда типа Normalize (ведь траектория движения по сути сплайн) или с помощью направления вектора можно как то решить, Что скажешь?
     

    Вложения:

    • 245731.jpg
      245731.jpg
      Размер файла:
      18,3 КБ
      Просмотров:
      54
  6. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Скажу что идеального решения скорее всего не будет
    оно где-то на стыке автоматической и ручной обработки.
    Тут кончно можно мудрить с различными степенями производных, или простыми фильтрами сглаживая треки и усредняя движение.
    Можно для эксперемента конвертнуть трек в wav файл и поэспрементировать с ним в звуковом редактореб благо фильтров там масса.

    tbar - содержит интерфейс что б можно было добраться до метода getNextKeyTime()
     
  7. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Спасибо Денис, в любом случае твоя помощь полезна мне для изучения . А поскольку скрипт работает ему без вопросов найдется применение.
     
  8. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    To Savin Denis:

    Привет Денис. Я снова сейчас вернулся к этой теме. Запустил этот скрипт, который у тебя получился и стало все ясно. Скрипт работает и работает классно и если в нем кое-что изменить то он будет вполне применим для того, зачем он изначально разрабатывался. Я сам не хочу лезть в него, раз уж профессионал его написал, то пусть профессионал его и правит.

    Я хочу именить немного его принцип. То есть вместо назначения позиции, подходящим по трешхолду ключам, я хочу просто удалять их. Таким образом интерполяция ключей анимации останется Безъе (я пробовал удалять ключи в ручную), то есть как надо. Так, своего рода и получится "чистка ключей, своего рода, пиксельной анимации". И еще я хочу сделать, так чтобы скрипт применялся к выделенным объектам. То есть все что выделено, загнать в массив и потом циклом перебрать его с прогонянием через скрипт. Я знаю как со стороны выглядит, когда новички в каком-то деле пытаются "умно выражаться" , так что извени еслив чё.
    Ну что, поможешь?
     
  9. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Подлиза :), лови

    Код:
    threshold = 6.1 
    sel = $selection as array
    for obj in sel do (
    
    bhc=obj.pos.controller
    select obj 
    tbar = maxops.trackbar 
    
    t_ = t = animationRange.start 
    t_end = animationRange.end 
    p1 = 0. 
    p2 = 0. 
    
    at time t p1 = obj.pos 
    at time t t = tbar.getNextKeyTime() 
    
    animate on 
    while t_ < t and t <= t_end do 
    ( 
    at time t p2 = obj.pos 
    
    if (distance p1 p2) <= threshold then 
    ( 
    deselectKeys bhc
    selectKeys bhc  t
    deleteKeys bhc #selection #slide #rightToLeft
    p2 = p1 
    ) 
    t_ = t 
    at time t t = tbar.getNextKeyTime() 
    p1=p2 
    ) 
    )
     
  10. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    или можно воспользоваться стандартным методом:
    reduceKeys $.pos.controller 7.1 1f
     
  11. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Привет Денис. Спасибо за скрипт. Я вовсе не хотел показаться "угодником", просто меня всегда тянуло к людям у которых можно чему-то научиться. И если человек чем-то профессионально занимается, это всегда у маня вызывало неподдельное уважение. Тем более профессионалов и раньше-то... а сейчас вообще днем с огнем...

    Все же программер из меня вряд ли получится. То ли мозг надо иметь какой то особенный то ли желание, то ли незню что. Поэтому не стал лезть в скрипт. Я сейчас ограничаился тем, что мне может дать MacroRecorder, для автоматизации некоторых процессов и скрипт-контроллеров. Вообще трудно изучать MaxScript при отсутствии литературы. Есть книжка с описанием команд. Минимум примеров и ничерта не понятно. Учиться надо на примерах!

    Слушай, а скрипт не сработал у меня, пишет:
    Код:
    6.1
    #($Point_Helper:Point01 @ [1.107010,0.000000,0.738007])
    -- No "map" function for undefined
    OK
    Блин, сложновато для меня ((( Сейчас усиленно пытаюсь разобраться как вообще там все работает, а где там ошибка "закопалась" наверное никогда не допру. Как ты это делаешь блин? (
     
  12. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210

    Да опечатка убери знак $ в строке цикла, пред sel. Вот так :

    Код:
    for obj in sel do (
     
  13. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Бли-и-и-и-н! Ну классно работает! Спасибищще!
    А теперь смый сложный вопрос. Есть ссылки на обучающую инфу по maxscript с примерами? (Книжка из 10 частей в переводе Алексеева В. В. уже есть, не помогает...)

    Ну вобщем спасибо Денис, все сработало как надо, как изначально и хотелось.
     
  14. Savin Denis vip

    Savin Denis Moderator Команда форума

    С нами с:
    05.05.2005
    Сообщения:
    1.633
    Симпатии:
    0
    Баллы:
    210
    Нет ничего лучше чем МахScript Help, дугую литературу даже не смотрел. а примером может послужить любой скрипт на scriptspot.com можно найти на любую тему и отполировать его так как тебе удобно.
     
  15. Максим Поклонов

    Максим Поклонов Мастер

    С нами с:
    07.07.2006
    Сообщения:
    305
    Симпатии:
    0
    Баллы:
    459
    Да зачем изучать МахScript, когда есть Савин Денис, который итак все знает )))

    Спасибо за советы, я обязательно воспользуюсь ими. (Портальчик со скриптами уже заценил)
     
Модераторы: Savin Denis

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