Render.ru

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

Рейтинг
51
#1
Привет всем. Я хочу сделать своеобразный 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, и еще не знаю синтаксис. Так что пожалуйста не смейтесь если я нагородил охинею, а помогите написать это правильно.

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

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#4
Привет !

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


Код:
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 		
	)
 
Рейтинг
51
#5
To Savin Denis

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

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

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

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

Вложения

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#6
Скажу что идеального решения скорее всего не будет
оно где-то на стыке автоматической и ручной обработки.
Тут кончно можно мудрить с различными степенями производных, или простыми фильтрами сглаживая треки и усредняя движение.
Можно для эксперемента конвертнуть трек в wav файл и поэспрементировать с ним в звуковом редактореб благо фильтров там масса.

tbar - содержит интерфейс что б можно было добраться до метода getNextKeyTime()
 
Рейтинг
51
#7
Спасибо Денис, в любом случае твоя помощь полезна мне для изучения . А поскольку скрипт работает ему без вопросов найдется применение.
 
Рейтинг
51
#8
To Savin Denis:

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

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

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#9
Подлиза :), лови

Код:
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 
) 
)
 

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#10
или можно воспользоваться стандартным методом:
reduceKeys $.pos.controller 7.1 1f
 
Рейтинг
51
#11
Привет Денис. Спасибо за скрипт. Я вовсе не хотел показаться "угодником", просто меня всегда тянуло к людям у которых можно чему-то научиться. И если человек чем-то профессионально занимается, это всегда у маня вызывало неподдельное уважение. Тем более профессионалов и раньше-то... а сейчас вообще днем с огнем...

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

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

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#12

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

Код:
for obj in sel do (
 
Рейтинг
51
#13
Бли-и-и-и-н! Ну классно работает! Спасибищще!
А теперь смый сложный вопрос. Есть ссылки на обучающую инфу по maxscript с примерами? (Книжка из 10 частей в переводе Алексеева В. В. уже есть, не помогает...)

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

Savin Denis

Модератор форума
Команда форума
Рейтинг
138
#14
Нет ничего лучше чем МахScript Help, дугую литературу даже не смотрел. а примером может послужить любой скрипт на scriptspot.com можно найти на любую тему и отполировать его так как тебе удобно.
 
Рейтинг
51
#15
Да зачем изучать МахScript, когда есть Савин Денис, который итак все знает )))

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