旋转自动化

旋转自动化

问题描述:

我在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

你想达到什么目的?如果它是一辆汽车的车轮,则需要考虑您的车轮朝向行驶​​方向。无论如何做**不**使用**'getAttr -time(frame -1)prefix66_driver.translateZ' **缓存表格的最后一帧。 – joojaa 2013-02-16 12:18:40

+0

我读过你的最后一篇文章,虽然没有动态更新,但我花了大约3小时的时间在framecache节点上,因为如果我要将translate Z连接到流中,连接时的价值是多少它不会随着时间更新。 我不明白如何使用node.cacheTx = objname.tx; node.tx =节点。cacheTx;会工作,但他们不等于完全相同的值? – 2013-02-17 00:27:12

+0

PS:我试图自动化局部方向移动的车轮的滚动速度,这几乎可以无缝地工作,只有问题是半径小于1的较小物体似乎评估错误。 – 2013-02-17 00:28:41

我相信我已经想通了:)

Queering老翻译中平均水平,新的翻译一般会给我一个真或假的答案,这正是我需要改变方向。

还添加了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中的表达式相互联系起来,但是一旦你得到简单的东西,你很快就会想要转向,打滑,悬挂等等。你很快就会发现自己模仿物理中发生的一切模拟。让你感到惊讶的是,建立一个刚体系统以获得相同的效果是多么容易。我最近看到有人用dynamica制造出令人信服的坦克。它在不平坦的地形上行驶,踏板非常逼真。 – 2013-03-21 17:47:41

+0

非常有趣,我唯一没有做到的就是缩放钻机,仍然保持速度/动画。 – 2013-03-25 05:20:38

+0

@JulianMann不会因为我正在审查我的帐户而拒绝投票。我被告知由S.O做这件事,我改变了我的答案,因为我的答案是正确的,你可能帮了我,但是正确的答案是在我的脚本不是你的。 – 2013-12-18 04:42:28

代码的旋转部分看起来没问题。但是,在这两种情况下,您都有一个if/else块返回相同的内容,如@ joojaa所述,如果缓存翻译值,则可以避免getAttr -time。事实上,你应该完全避免表达式中的getAttrsetAttr

而是直接引用您想要的属性,Maya将为您创建连接。当您重命名节点等时,这会更快,更不容易出错。

要缓存翻译值并计算位置变化,可以将属性添加到节点并在表达式中使用它们。

比方说,你有一个缸称为车轮绕其局部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); 

最好通过动画而不是在视图中拖动节点来测试这种事情。

如果您想让轮子瞄准行驶方向,您可以在翻译+ 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!我已经有了一些玩法,但是我怎样才能“转换”或通过翻转转轮来计算方向,从而以目标限制来说话。我不完全了解,但是我的工作似乎很好,谢谢你! – 2013-02-18 08:11:26

+0

我明白你的意思了。上面的表达只知道你走了多远,而不知道你是前进还是后退。有几个选项。要自动从前进到后退,您可以将您面对的方向与正在移动的方向进行比较。这意味着你手动控制你所面对的方向。或者,您可以自动将方向设置为您正在移动的方向。在这种情况下,车轮总是向前滚动,而且没有手动控制。只要有机会,我会尽快编辑我的答案和每个细节。 – 2013-02-19 00:43:30

+0

谢谢堆!那太好了! – 2013-02-19 01:02:25