2013-02-16 2 views
0

Я столкнулся с несколькими проблемами с этим выражением в Maya, в основном в любое время, когда радиус меньше 1, вычисление слишком сильно отбрасывается.Автоматизация вращения

float $radius = `getAttr prefix66_calculations_shape.rad`; 
float $prevZval = `getAttr -time (frame -1) prefix66_driver.translateZ`; 
float $prevXval = `getAttr -time (frame -1) prefix66_driver.translateX`; 
float $Zval = prefix66_driver.translateZ - $prevZval; 
float $Xval = prefix66_driver.translateX - $prevXval; 
float $distance = ($Zval * $Zval) + ($Xval * $Xval); 
float $direction; 
$distance = sqrt($distance); 
if ($prevZval > prefix66_driver.translateZ) { 
    $direction = 360; 
} 
else { 
    $direction = 360; 
} 
float $rotation = ($distance/(2 * 3.142 * $radius)) * $direction; 
print $rotation; 
pCube1.rotateX = pCube1.rotateX + $rotation; 

Возможно, мой порядок операций неправильный?

+0

Чего вы пытаетесь достичь? Если это колесо автомобиля, вам нужно учесть угловое колесо вашего колеса в направлении движения. в любом случае do ** NOT ** use ** 'getAttr -time (frame -1) prefix66_driver.translateZ' ** кэшировать форму аннулирования последнего кадра. – joojaa

+0

Я прочитал ваше последнее сообщение, я потратил около 3 часов на узел framecache, хотя он не обновлялся динамически, как в случае, если я должен был подключить перевод Z в поток, что когда-либо имело значение, когда оно было подключено , он не обновляется со временем. Я не понимаю, как использовать node.cacheTx = objname.tx; node.tx = узел.cacheTx; будут работать, не будут ли они равными точно таким же значениям? –

+0

PS: Я пытаюсь автоматизировать скорость передвижения колеса, перемещаемого в локальном направлении, это работает почти без проблем, только проблема - это объекты меньшего размера с радиусом менее 1, кажется, неправильно оценивают. –

ответ

0

Я считаю, что я понял это :)

Queering старого traslation среднем, с новым среднем перевода даст мне истинный или ложный ответ, который является то, что мне нужно, чтобы изменить направление.

Также добавлено утверждение if, что если шар статичен и вращается, то колесо не поворачивается автоматически.

float $oldRotateAverage; 
float $oldTransAverage; 
float $direction; 

nurbsCircle1.DeltaTranslateX = nurbsCircle1.translateX - nurbsCircle1.LastTranslateX; 
nurbsCircle1.DeltaTranslateY = nurbsCircle1.translateY - nurbsCircle1.LastTranslateY; 
nurbsCircle1.DeltaTranslateZ = nurbsCircle1.translateZ - nurbsCircle1.LastTranslateZ; 
nurbsCircle1.LastTranslateX = nurbsCircle1.translateX; 
nurbsCircle1.LastTranslateY = nurbsCircle1.translateY; 
nurbsCircle1.LastTranslateZ = nurbsCircle1.translateZ; 
nurbsCircle1.Distance = mag(<<nurbsCircle1.DeltaTranslateX,nurbsCircle1.DeltaTranslateY,nurbsCircle1.DeltaTranslateZ>>); 

if ($oldTransAverage >= (nurbsCircle1.LastTranslateX + nurbsCircle1.LastTranslateY + nurbsCircle1.LastTranslateZ)){ 
    $direction = -360.00; 
} else { 
    $direction = 360.00; 
}; 

if (Sh54_anim.auto == 1) 
{ 
    Sh54_point_grp.rotateZ -= nurbsCircle1.Distance * $direction/2/3.14/2;  
}; 

if ((nurbsCircle1.rotateX + nurbsCircle1.rotateY + nurbsCircle1.rotateZ) != $oldRotateAverage && nurbsCircle1.Distance == $oldTransAverage){ 
    Sh54_anim.auto = 0; 
} else { 
    Sh54_anim.auto = 1; 
}; 

Sh54_point_grp.back_up = Sh54_point_grp.translateX; 
$oldRotateAverage = nurbsCircle1.rotateX + nurbsCircle1.rotateY + nurbsCircle1.rotateZ; 
$oldTransAverage = nurbsCircle1.translateX + nurbsCircle1.translateY + nurbsCircle1.translateZ; 
+0

рад видеть, что вы решили это. Извините, я не мог сэкономить время в последнее время. Его отличное учебное упражнение, чтобы заставить части машины работать по отношению друг к другу с выражениями в Maya, однако, как только вы получите простой материал, вы скоро захотите рулевое управление, занос, подвеску и т. Д. Скоро вы подражаете всему, что происходит в физике моделирование. Вы будете удивлены, насколько легко создать жесткую систему кузова, чтобы получить тот же эффект. В последнее время я видел, как кто-то делает убедительный танк с динамикой. Он двигался по неровной местности, и ступени грохотали очень реалистично. –

+0

Очень интересно, единственное, чего я не достиг, это масштабирование буровой установки и сохранение скорости/анимации. –

+0

@JulianMann не спускаются с голосования только потому, что я просматриваю свою учетную запись. Мне сказали это сделать С.О., я изменил свои ответы, потому что мои ответы правильные, вы, возможно, помогли мне, однако правильный ответ в моем сценарии не ваш. –

1

Вращательная часть вашего кода выглядит нормально. Однако у вас есть блок if/else, который возвращает одно и то же в обоих случаях, и, как упоминалось в @joojaa, вы можете избежать getAttr -time, если кешируете значения перевода. На самом деле вам следует полностью избегать getAttr и setAttr.

Вместо этого обратитесь к атрибутам, которые хотите напрямую, и Майя создаст для вас соединения. Это намного быстрее и менее подвержено ошибкам при переименовании узлов и т. Д.

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

Допустим, у вас есть цилиндр под названием колесо, которое вращается вокруг своего локального X и основателями в группу узлов, которая называется управлением:

Добавить векторную атрибут: control.lastTranslate
Добавить векторную атрибут: control.deltaTranslate
Добавить float: control.distance

Вот выражение, которое сохранит изменение в переводе, а затем поверните колесо в зависимости от пройденного расстояния.

// When deltaTranslate is calculated, lastTranslate still has its previous value. 
control.deltaTranslateX = control.translateX - control.lastTranslateX; 
control.deltaTranslateY = control.translateY - control.lastTranslateY; 
control.deltaTranslateZ = control.translateZ - control.lastTranslateZ; 
control.lastTranslateX = control.translateX; 
control.lastTranslateY = control.translateY; 
control.lastTranslateZ = control.translateZ; 
control.distance = mag(<<control.deltaTranslateX,control.deltaTranslateY,control.deltaTranslateZ>>); 

// Get radius from history node (or somewhere) and move the wheel's hub off the floor. 
wheel.translateY = polyCylinder1.radius; 

// add rotation to the wheel 
float $tau = 6.283185307179586; 
wheel.rotateX = wheel.rotateX + (control.distance* -360.0)/(polyCylinder1.radius * $tau); 

Лучше всего протестировать подобные вещи, анимируя, а не перетягивая узлы вокруг.

Если вы хотите, чтобы колесо направлялось в направлении движения, вы могли бы добавить локатор в translate + deltaTranslate и подключить ограничение цели.

например.

aimLocator.translateX = (control.deltaTranslateX/control.distance) + control.translateX; 
aimLocator.translateY = (control.deltaTranslateY/control.distance) + control.translateY; 
aimLocator.translateZ = (control.deltaTranslateZ/control.distance) + control.translateZ; 

Деление по расстоянию нормализует смещение. Вероятно, вы должны проверить, что расстояние не равно нулю.

+0

Это кажется довольно многообещающим @julian! У меня была небольшая игра с ним, но как я могу «переключиться» или рассчитать направление с переворачиванием колеса, чтобы говорить с прицельным ограничением. Я не совсем понимаю, но то, что я, кажется, очень хорошо работает благодаря вам! –

+0

Я понимаю, что вы имеете в виду. Вышеприведенное выражение знает, насколько далеко вы продвинулись, а не вы идете вперед или назад. Есть несколько вариантов. Чтобы автоматически переключиться с прямого на обратное, вы можете сравнить направление, в котором вы находитесь, в направлении, в котором вы двигаетесь. Это означает, что вы вручную контролируете направление, с которым вы сталкиваетесь. В качестве альтернативы вы можете автоматически установить ориентацию в направлении движения. В этом случае колеса всегда перемещаются вперед, и у вас нет ручного управления. Я отредактирую свой ответ с подробностями каждого, как только у меня появится шанс. –

+0

Спасибо, кучи! Это было бы прекрасно! –