這篇教程是我剛剛在網絡上看到的用MAYA表達式制作探索車動畫的教程。難度一般,之前對MAYA表達式接觸不多。通過這篇教程大概搞清楚了MAYA表達式的使用方法。發到腳本之家,希望對大家也有用吧。一起來學習MAYA表達式吧:
1.先創建一個大腳車的簡單模型,要有必要的部件,例如四個輪子及軸和車身。效果測試滿意後可以用細模替代。再創建一塊崎岖的地面。
2.創建四個長方體,作為輪子位置的參考物。
3.將四個長方體與地面進行幾何體和法線約束,然後調整到車輪的位置。
附圖:
4.定義輪子相對各自參考物的傾斜角,如下:
$a[1]=a1.translateY;
$a[2]=a2.translateY;
$a[3]=b1.translateY;
$a[4]=b2.translateY;
wheel_r1.rotateX=clamp(max((-$angerWu1+85),(b1.rotateX+90)), min((-$angerWu1+120),(b1.rotateX+90)),(b1.rotateX+90));
wheel_r2.rotateX=clamp(max((-$angerWu2+85),(b2.rotateX+90)), min((-$angerWu1+120),(b2.rotateX+90)),(b2.rotateX+90));
wheel_l1.rotateX=clamp(max((-$angerWu1+85),(a1.rotateX+90)), min((-$angerWu2+120),(a1.rotateX+90)),(a1.rotateX+90));
wheel_l2.rotateX=clamp(max((-$angerWu2+85),(a2.rotateX+90)), min((-$angerWu2+120),(a2.rotateX+90)),(a2.rotateX+90));
$a[1]-$a[4]表示四個輪子參考物的y軸向的位置。$angerWu1,$angerWu2表示輪軸的傾斜角,以上命令是控制輪子一方面受地形影響一方面受輪軸角度限制。關於clamp函數參考幫助文件。
5.定義輪子和車身x,z軸向的位置:具體命令如下:
wheel_r1.translateX=b1.translateX;
wheel_r2.translateX=b2.translateX;
wheel_l1.translateX=a1.translateX;
wheel_l2.translateX=a2.translateX;
wheel_r1.translateZ=b1.translateZ;
wheel_r2.translateZ=b2.translateZ;
wheel_l1.translateZ=a1.translateZ;
wheel_l2.translateZ=a2.translateZ;
body.translateX=(wheel_l1.translateX+wheel_l2.translateX+wheel_r1.translateX+wheel_r2.translateX)/4;
body.translateZ=(wheel_l1.translateZ+wheel_l2.translateZ+wheel_r1.translateZ+wheel_r2.translateZ)/4;
輪子位置為其各自參照物位置控制。車身位置是近似計算,簡單的說,車身就是取四個輪子空間位置的平均值。
6.定義四個輪子中心的y軸向的初始位置
if(frame==1)
{
$nb=$nu=$nv=0;
$Awy[1]=$Awy[2]=$Awy[3]=$Awy[4]=$Aby=0;
$Twyv=$Vwy[1]=$Vwy[2]=$Vwy[3]=$Vwy[4]=$Vby=0;
$Twy[1]=a1.translateY+1.4;
$Twy[2]=a2.translateY+1.4;
$Twy[3]=b1.translateY+1.4;
$Twy[4]=b2.translateY+1.4;
1.4為輪子受車身及自身重力後離地面的高度。
7.定義四輪構成體系($angerWu,$angerWv)的橫向和縱向的傾斜角,定義車身($angerBu,$angerBv)的橫向和縱向的傾斜角。
$abu=$abv=$awu=$awv=0;
$vbu=$vbv=0;
$u=$v=0;
$twu=($Twy[1]+$Twy[2])-($Twy[3]+$Twy[4]);
$twv=($Twy[1]+$Twy[3])-($Twy[4]+$Twy[2]);
$angerWu=-asind($twu/8);
$angerWv=-asind($twv/10);
$angerBu=$angerWu;
$angerBv=$angerWv;
8.定義車身的y軸向的初始位置
9.計算四個輪子的y軸向的位移,其中輪子所受到的壓力為y軸向車身和自身的位移加速度和重力的影響而計算得出,車輪與地面的高度受壓力影響,壓力大時車輪與地面相對距離減小,壓力小時車輪與地面相對距離加大。模擬輪胎受壓變形。未考慮車身角度傾斜和車身轉動的扭矩的影響。對於地形特別崎岖的環境,這將有較大的誤差。
if(frame>1)
{
for($i=1;$i<5;$i++)
{
$Twa[$i]=$Twy[$i]-$a[$i]-1.4;
$Fw[$i]=1*$M*$Aby/4+1*$M*$au[$i]+1*$M*$av[$i];
if($Twa[$i]>0.1)
$Nw[$i]=-0.2*$kw*($Twa[$i]/0.5) ;
else
$Nw[$i]=-1*$kw*$Twa[$i]*abs($Twa[$i]/0.5);//定義不同情況下的支持力計算方法,沒辦法,一時沒有精確的算法,按線性比例和平方比及指數關系都會出問題。
$Awy[$i]=($Nw[$i]-$Fw[$i])/$m;//輪子加速度
$Awy[$i]=clamp(-1000,1000,$Awy[$i]);//限制加速度最大值
$Vwy[$i]=($Vwy[$i]+1.5*$Awy[$i]*$t)*1.0-$Vwy[$i]*0.2;
$Twy[$i]=$Twy[$i]+$Vwy[$i]*$t+0.5*$Awy[$i]*$t*$t;//y軸位置
避免輪子小幅度的長久的震蕩。當其位移變化幅度小(0.03)時,強制其靜止。其中$nw[$i]是計數器,記錄連續小幅度位移(小於0.03)變化的幀數,在這我定義的為15幀。
if(abs($Twa[$i])<0.03)
$nw[$i]+=1;
else
$nw[$i]=0;
if($nw[$i]<15)
$Twy[$i]=$Twy[$i];
else
$Twy[$i]=$a[$i]+1.4;
下面這一段限制了輪子與車身的最大位移量及限制了前後幀間輪子位移變化的極限值,這些限制在大腳車高速在起伏比較大的地面上行駛時有用,若低速行駛,可以不考慮這些限制。
避免車身小幅度的長久的震蕩。當其長時間(15幀)位移變化幅度小(0.03)時,強制其相對四個輪子構成的系統靜止($Tby=$Twyv+4;)。
其中$nb是計數器,記錄車身小幅度位移變化的幀數,我定義的為15幀。另外下面的程序定義了車身的位移加速度和速度的計算方法。
if(abs($Twb)<0.051)
$nb+=1;
else
$n=0;
if($nb<15)
$Tby=$Tby+$Vby*$t+0.5*$Aby*$t*$t;
else
$Tby=$Twyv+4;
$Twyv=($Twy[1]+$Twy[2]+$Twy[3]+$Twy[4])/4;
$Twb=$Tby-$Twyv-4;//4表示車身的高度
當車身與輪子構成的系統之間的y軸向的位移超過0.8個單位時,強制其為0.8。
if(abs($Twb)>0.8)
$Tby=$Twyv+4.0+sign($Twb)*0.8;
$Aby=-$kb*$Twb*abs($Twb);
$Vby=$Vby+$Aby*$t-sign($Vby)*0.5;
12.計算車身的旋轉角度,具體思路與計算車身y軸位移的相同,不同的是要通過四個輪子的空間位置計算車輪系統的角度及角加速度,通過車輪系統計算出來的角度及角加速度計算出車身的角度及角加速度。具體的一些比例系數大部分是試驗結果。
$twu=($Twy[1]+$Twy[2])-($Twy[3]+$Twy[4]);
$twv=($Twy[1]+$Twy[3])-($Twy[4]+$Twy[2]);
$angerWu=-asind($twu/8);
$angerWv=-asind($twv/10);
$u=$angerBu-$angerWu;
$abu=-$ku*sign($u)*($u/2)*($u/2);
$vbu=$vbu+$abu*$t-$vbu*0.5;
$angerBu=$angerBu+$vbu*$t+0.5*$abu*$t*$t;
$angerBu=clamp($angerWu-10,$angerWu+10,$angerBu);
$v=$angerBv-$angerWv;
$abv=-$kv*sign($v)*($v/3)*($v/3);
$vbv=$vbv+$abv*$t-sign($vbv)*5;
$angerBv=$angerBv+$vbv*$t+0.5*$abv*$t*$t;
$angerBv=clamp($angerWv-20,$angerWv+20,$angerBv);
if(abs($u<1))
$nu+=1;
else
$nu=0;
if($nu<15)
$angerBu=$angerBu;
else
$angerBu=$angerWu;
if(abs($v<1))
$nv+=1;
else
$nv=0;
if($nv<15)
$angerBv=$angerBv;
else
$angerBv=$angerWv;
$angerWv1=asind(0.2*($Twy[1]-$Twy[2]));
$angerWv2=asind(0.2*($Twy[3]-$Twy[4]));
$v1=$angerBv-$angerWv1;
$v2=$angerBv-$angerWv2;
$av[1]=-$kav*$v1;
$av[2]=$kav*$v1;
$av[3]=-$kav*$v2;
$av[4]=$kav*$v2;
$angerWu1=asind(0.25*($Twy[1]-$Twy[3]));
$angerWu2=asind(0.25*($Twy[2]-$Twy[4]));
$u1=$angerBu-$angerWu1;
$u2=$angerBu-$angerWu2;
$au[1]=-$kau*$u1;
$au[2]=-$kau*$u2;
$au[3]=$kau*$u1;
$au[4]=$kau*$u2;
13.給輪子及車身賦值
我定義了一個名為aaaa的位置指示物體驅動四個輪子運動。
a1.translateX=b1.translateX=aaaa.tra