Привет всем. Я хочу сделать своеобразный 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, и еще не знаю синтаксис. Так что пожалуйста не смейтесь если я нагородил охинею, а помогите написать это правильно.
зы: знаю, что Савин Денис не любит когда много текста, но извените по-проще не получилось 😉
У такого фильтра достаточно большая вероятность попортить движение на плавных участка (замедление/начало движения)
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
)
Привет. Рад тебя "видеть" )
Ну что ж. Все получилось. Только ты был прав насчет вероятности попортить движение на плавных участках. В общем-то так оно и вышло. Получается, что скрипт держит позицию пока она в пределах параметра "threshold". Как только этот параметртр превышен, получается скачек.
Я подумал, что если не уравнивать ключи, а может быть удалять, то кривая анимации будет плавно переходить от ключа к ключу, а трешхолдом настоить эти промежутки. Так рывки получились (
С удалением ключей попробую сам разобраться только мне незнакомы некоторые команды:
tbar = maxops.trackbar -- "tbar" это наверное переменная, а вот "maxops.trackbar" не знаю что это.
И вобще кажется я пошел не тем путем. Если сделать анимацию трясущегося Dummy, который при этом еще и медленно движется в сторону, то после обработки скриптом он просто останется на месте (
Может есть какая нибудь команда типа Normalize (ведь траектория движения по сути сплайн) или с помощью направления вектора можно как то решить, Что скажешь?
Скажу что идеального решения скорее всего не будет
оно где-то на стыке автоматической и ручной обработки.
Тут кончно можно мудрить с различными степенями производных, или простыми фильтрами сглаживая треки и усредняя движение.
Можно для эксперемента конвертнуть трек в wav файл и поэспрементировать с ним в звуковом редактореб благо фильтров там масса.
tbar - содержит интерфейс что б можно было добраться до метода getNextKeyTime()
Привет Денис. Я снова сейчас вернулся к этой теме. Запустил этот скрипт, который у тебя получился и стало все ясно. Скрипт работает и работает классно и если в нем кое-что изменить то он будет вполне применим для того, зачем он изначально разрабатывался. Я сам не хочу лезть в него, раз уж профессионал его написал, то пусть профессионал его и правит.
Я хочу именить немного его принцип. То есть вместо назначения позиции, подходящим по трешхолду ключам, я хочу просто удалять их. Таким образом интерполяция ключей анимации останется Безъе (я пробовал удалять ключи в ручную), то есть как надо. Так, своего рода и получится "чистка ключей, своего рода, пиксельной анимации". И еще я хочу сделать, так чтобы скрипт применялся к выделенным объектам. То есть все что выделено, загнать в массив и потом циклом перебрать его с прогонянием через скрипт. Я знаю как со стороны выглядит, когда новички в каком-то деле пытаются "умно выражаться" , так что извени еслив чё.
Ну что, поможешь?
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
)
)
Привет Денис. Спасибо за скрипт. Я вовсе не хотел показаться "угодником", просто меня всегда тянуло к людям у которых можно чему-то научиться. И если человек чем-то профессионально занимается, это всегда у маня вызывало неподдельное уважение. Тем более профессионалов и раньше-то... а сейчас вообще днем с огнем...
Все же программер из меня вряд ли получится. То ли мозг надо иметь какой то особенный то ли желание, то ли незню что. Поэтому не стал лезть в скрипт. Я сейчас ограничаился тем, что мне может дать MacroRecorder, для автоматизации некоторых процессов и скрипт-контроллеров. Вообще трудно изучать MaxScript при отсутствии литературы. Есть книжка с описанием команд. Минимум примеров и ничерта не понятно. Учиться надо на примерах!
Слушай, а скрипт не сработал у меня, пишет:
6.1
#($Point_Helper:Point01 @ [1.107010,0.000000,0.738007])
-- No "map" function for undefined
OK
Блин, сложновато для меня ((( Сейчас усиленно пытаюсь разобраться как вообще там все работает, а где там ошибка "закопалась" наверное никогда не допру. Как ты это делаешь блин? (
Бли-и-и-и-н! Ну классно работает! Спасибищще!
А теперь смый сложный вопрос. Есть ссылки на обучающую инфу по maxscript с примерами? (Книжка из 10 частей в переводе Алексеева В. В. уже есть, не помогает...)
Ну вобщем спасибо Денис, все сработало как надо, как изначально и хотелось.
Нет ничего лучше чем МахScript Help, дугую литературу даже не смотрел. а примером может послужить любой скрипт на scriptspot.com можно найти на любую тему и отполировать его так как тебе удобно.
Доступ к резюме доступен только по пакетному доступу HR менеджерам зарегистрированных компаний. Узнать о вариантах корпоративных пакетов можно по ссылке.
Максим Поклонов
Я сделал видеосъемку и отследил на ней тракером движущуюся точку. Точка в кадре то двигается, то не двигается. В те моменты когда она не двигается тракер все равно отслеживает хоть минимальное но движение. После этого я присвоил данные тракера к 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, и еще не знаю синтаксис. Так что пожалуйста не смейтесь если я нагородил охинею, а помогите написать это правильно.
зы: знаю, что Савин Денис не любит когда много текста, но извените по-проще не получилось 😉
MaxWell
Максим Поклонов
Savin Denis
У такого фильтра достаточно большая вероятность попортить движение на плавных участка (замедление/начало движения)
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 )Максим Поклонов
Привет. Рад тебя "видеть" )
Ну что ж. Все получилось. Только ты был прав насчет вероятности попортить движение на плавных участках. В общем-то так оно и вышло. Получается, что скрипт держит позицию пока она в пределах параметра "threshold". Как только этот параметртр превышен, получается скачек.
Я подумал, что если не уравнивать ключи, а может быть удалять, то кривая анимации будет плавно переходить от ключа к ключу, а трешхолдом настоить эти промежутки. Так рывки получились (
С удалением ключей попробую сам разобраться только мне незнакомы некоторые команды:
tbar = maxops.trackbar -- "tbar" это наверное переменная, а вот "maxops.trackbar" не знаю что это.
И вобще кажется я пошел не тем путем. Если сделать анимацию трясущегося Dummy, который при этом еще и медленно движется в сторону, то после обработки скриптом он просто останется на месте (
Может есть какая нибудь команда типа Normalize (ведь траектория движения по сути сплайн) или с помощью направления вектора можно как то решить, Что скажешь?
Вложения
Savin Denis
оно где-то на стыке автоматической и ручной обработки.
Тут кончно можно мудрить с различными степенями производных, или простыми фильтрами сглаживая треки и усредняя движение.
Можно для эксперемента конвертнуть трек в wav файл и поэспрементировать с ним в звуковом редактореб благо фильтров там масса.
tbar - содержит интерфейс что б можно было добраться до метода getNextKeyTime()
Максим Поклонов
Максим Поклонов
Привет Денис. Я снова сейчас вернулся к этой теме. Запустил этот скрипт, который у тебя получился и стало все ясно. Скрипт работает и работает классно и если в нем кое-что изменить то он будет вполне применим для того, зачем он изначально разрабатывался. Я сам не хочу лезть в него, раз уж профессионал его написал, то пусть профессионал его и правит.
Я хочу именить немного его принцип. То есть вместо назначения позиции, подходящим по трешхолду ключам, я хочу просто удалять их. Таким образом интерполяция ключей анимации останется Безъе (я пробовал удалять ключи в ручную), то есть как надо. Так, своего рода и получится "чистка ключей, своего рода, пиксельной анимации". И еще я хочу сделать, так чтобы скрипт применялся к выделенным объектам. То есть все что выделено, загнать в массив и потом циклом перебрать его с прогонянием через скрипт. Я знаю как со стороны выглядит, когда новички в каком-то деле пытаются "умно выражаться" , так что извени еслив чё.
Ну что, поможешь?
Savin Denis
Savin Denis
reduceKeys $.pos.controller 7.1 1f
Максим Поклонов
Все же программер из меня вряд ли получится. То ли мозг надо иметь какой то особенный то ли желание, то ли незню что. Поэтому не стал лезть в скрипт. Я сейчас ограничаился тем, что мне может дать MacroRecorder, для автоматизации некоторых процессов и скрипт-контроллеров. Вообще трудно изучать MaxScript при отсутствии литературы. Есть книжка с описанием команд. Минимум примеров и ничерта не понятно. Учиться надо на примерах!
Слушай, а скрипт не сработал у меня, пишет:
Блин, сложновато для меня ((( Сейчас усиленно пытаюсь разобраться как вообще там все работает, а где там ошибка "закопалась" наверное никогда не допру. Как ты это делаешь блин? (
Savin Denis
Да опечатка убери знак $ в строке цикла, пред sel. Вот так :
Максим Поклонов
А теперь смый сложный вопрос. Есть ссылки на обучающую инфу по maxscript с примерами? (Книжка из 10 частей в переводе Алексеева В. В. уже есть, не помогает...)
Ну вобщем спасибо Денис, все сработало как надо, как изначально и хотелось.
Savin Denis
Максим Поклонов
Спасибо за советы, я обязательно воспользуюсь ими. (Портальчик со скриптами уже заценил)