旋转自动化
我在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;
也许我的操作顺序是错误的?
我相信我已经想通了:)
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;
很高兴看到你解决它。对不起,我最近没有空闲时间。这是一个非常好的学习练习,可以让机器零件与Maya中的表达式相互联系起来,但是一旦你得到简单的东西,你很快就会想要转向,打滑,悬挂等等。你很快就会发现自己模仿物理中发生的一切模拟。让你感到惊讶的是,建立一个刚体系统以获得相同的效果是多么容易。我最近看到有人用dynamica制造出令人信服的坦克。它在不平坦的地形上行驶,踏板非常逼真。 – 2013-03-21 17:47:41
非常有趣,我唯一没有做到的就是缩放钻机,仍然保持速度/动画。 – 2013-03-25 05:20:38
@JulianMann不会因为我正在审查我的帐户而拒绝投票。我被告知由S.O做这件事,我改变了我的答案,因为我的答案是正确的,你可能帮了我,但是正确的答案是在我的脚本不是你的。 – 2013-12-18 04:42:28
代码的旋转部分看起来没问题。但是,在这两种情况下,您都有一个if/else块返回相同的内容,如@ joojaa所述,如果缓存翻译值,则可以避免getAttr -time
。事实上,你应该完全避免表达式中的getAttr
和setAttr
。
而是直接引用您想要的属性,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;
按距离划分将标准化偏移量。你应该检查一下距离不是零。
这似乎很有希望@ julian!我已经有了一些玩法,但是我怎样才能“转换”或通过翻转转轮来计算方向,从而以目标限制来说话。我不完全了解,但是我的工作似乎很好,谢谢你! – 2013-02-18 08:11:26
我明白你的意思了。上面的表达只知道你走了多远,而不知道你是前进还是后退。有几个选项。要自动从前进到后退,您可以将您面对的方向与正在移动的方向进行比较。这意味着你手动控制你所面对的方向。或者,您可以自动将方向设置为您正在移动的方向。在这种情况下,车轮总是向前滚动,而且没有手动控制。只要有机会,我会尽快编辑我的答案和每个细节。 – 2013-02-19 00:43:30
谢谢堆!那太好了! – 2013-02-19 01:02:25
你想达到什么目的?如果它是一辆汽车的车轮,则需要考虑您的车轮朝向行驶方向。无论如何做**不**使用**'getAttr -time(frame -1)prefix66_driver.translateZ' **缓存表格的最后一帧。 – joojaa 2013-02-16 12:18:40
我读过你的最后一篇文章,虽然没有动态更新,但我花了大约3小时的时间在framecache节点上,因为如果我要将translate Z连接到流中,连接时的价值是多少它不会随着时间更新。 我不明白如何使用node.cacheTx = objname.tx; node.tx =节点。cacheTx;会工作,但他们不等于完全相同的值? – 2013-02-17 00:27:12
PS:我试图自动化局部方向移动的车轮的滚动速度,这几乎可以无缝地工作,只有问题是半径小于1的较小物体似乎评估错误。 – 2013-02-17 00:28:41