Maya特效教程
Maya特效教程:Maya表達(dá)式控制動力學(xué)動畫之大腳車
編輯:Penny來源:發(fā)布時間:2010-06-28
1.先創(chuàng)建一個大腳車的簡單模型,要有必要的部件,例如四個輪子及軸和車身。效果測試滿意后可以用細(xì)模替代。再創(chuàng)建一塊崎嶇的地面。
2.創(chuàng)建四個長方體,作為輪子位置的參考物。
3.將四個長方體與地面進(jìn)行幾何體和法線約束,然后調(diào)整到車輪的位置。
附圖:
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表示輪軸的傾斜角,以上命令是控制輪子一方面受地形影響一方面受輪軸角度限制。關(guān)于clamp函數(shù)參考幫助文件。
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.定義四輪構(gòu)成體系($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軸向車身和自身的位移加速度和重力的影響而計算得出,車輪與地面的高度受壓力影響,壓力大時車輪與地面相對距離減小,壓力小時車輪與地面相對距離加大。模擬輪胎受壓變形。未考慮車身角度傾斜和車身轉(zhuǎn)動的扭矩的影響。對于地形特別崎嶇的環(huán)境,這將有較大的誤差。
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);//定義不同情況下的支持力計算方法,沒辦法,一時沒有精確的算法,按線性比例和平方比及指數(shù)關(guān)系都會出問題。
$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軸位置
避免輪子小幅度的長久的震蕩。當(dāng)其位移變化幅度?。?.03)時,強(qiáng)制其靜止。其中$nw[$i]是計數(shù)器,記錄連續(xù)小幅度位移(小于0.03)變化的幀數(shù),在這我定義的為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;
下面這一段限制了輪子與車身的最大位移量及限制了前后幀間輪子位移變化的極限值,這些限制在大腳車高速在起伏比較大的地面上行駛時有用,若低速行駛,可以不考慮這些限制。
避免車身小幅度的長久的震蕩。當(dāng)其長時間(15幀)位移變化幅度小(0.03)時,強(qiáng)制其相對四個輪子構(gòu)成的系統(tǒng)靜止($Tby=$Twyv+4;)。
其中$nb是計數(shù)器,記錄車身小幅度位移變化的幀數(shù),我定義的為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表示車身的高度
當(dāng)車身與輪子構(gòu)成的系統(tǒng)之間的y軸向的位移超過0.8個單位時,強(qiáng)制其為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.計算車身的旋轉(zhuǎn)角度,具體思路與計算車身y軸位移的相同,不同的是要通過四個輪子的空間位置計算車輪系統(tǒng)的角度及角加速度,通過車輪系統(tǒng)計算出來的角度及角加速度計算出車身的角度及角加速度。具體的一些比例系數(shù)大部分是試驗結(jié)果。
$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的位置指示物體驅(qū)動四個輪子運動。
a1.translateX=b1.translateX=aaaa.translateX+3;
a2.translateX=b2.translateX=aaaa.translateX+7;
a1.translateZ=a2.translateZ=aaaa.translateZ+2;
b1.translateZ=b2.translateZ=aaaa.translateZ-2;
對于aaaa這個物體,我用關(guān)鍵幀控制其位移??梢钥紤]用表達(dá)式控制,控制速度順應(yīng)地形的變化。例如在上坡時速度會減速,下坡時會加速。這個表達(dá)式應(yīng)該比較簡單,有興趣的朋友自己寫寫。
好了,大腳車的表達(dá)式基本就介紹完了,現(xiàn)在把全部表達(dá)式列出來,如下,供大家參考。表達(dá)式還有許多不足之處,望大家多多指正。例如不管坡度多么大,大腳車是不會翻滾的,呵呵。
* 以下是全部表達(dá)式,僅供參考
global float $Twa[],$Twy[],$Tby,$Twyv,$Twb,$a[],$T[],
$Twu,$Twv,$Vwy[],$Vby,
$Awy[],$Aby,$Awu[],$Awv[],$g=9.8,
$angerBu,$angerBv,$angerWu,$angerWv,$u,$v,
$abu,$abv,$vbu,$vbv,$aby,$u1,$u2,$v1,$v2, $au[],$av[],$angerWu1,$angerWu2,$angerWv1,
$angerWv2;
float $Fw[],$Nw[],$M=5,$m=0.5,$kau=0.02,$kav=0.04,
$kw=10*($m+$M/4)*$g,$kb=5*$M*$g,
$ku=250,$kv=200,$t=0.03;
int $i,$j,$nw[],$nb,$nu,$nv;
$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));
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;
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;
$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;
$Twyv=($Twy[1]+$Twy[2]+$Twy[3]+$Twy[4])/4;
$Tby=$Twyv+4.0;
}
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;
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;
$Twy[$i]=clamp($Tby-5,$Tby-3,$Twy[$i]);
if($Twa[$i]<-0.1)
$Twy[$i]=$a[$i]+1.3;
$Twy[$i]=clamp($T[$i]-0.4,$T[$i]+0.4,$Twy[$i]);
$T[$i]=$Twy[$i];
}
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;//difine $Tby
$Twyv=($Twy[1]+$Twy[2]+$Twy[3]+$Twy[4])/4;
$Twb=$Tby-$Twyv-4;
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;
$twu=($Twy[1]+$Twy[2])-($Twy[3]+$Twy[4]);
$twv=($Twy[1]+$Twy[3])-($Twy[4]+$Twy[2]);
$angerWu=-asind($twu/8)*0.9;
$angerWv=-asind($twv/10)*0.9;
$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;
}
wheel_l1.translateY=$Twy[1];
wheel_l2.translateY=$Twy[2];
wheel_r1.translateY=$Twy[3];
wheel_r2.translateY=$Twy[4];
body.translateY=$Tby;
body.rotateX=$angerBu;
body.rotateZ=$angerBv;
a1.translateX=b1.translateX=aaaa.translateX+3;
a2.translateX=b2.translateX=aaaa.translateX+7;
a1.translateZ=a2.translateZ=aaaa.translateZ+2;
b1.translateZ=b2.translateZ=aaaa.translateZ-2;
print($Awy[3]+", "+$Vwy[3]+", "+$Twy[3]+", "
+$Twa[3]+" "+$nw[3]+"
"+
$angerWu1+" "+b1.rotateX+" "+(wheel_r1.rotateX-90));
2.創(chuàng)建四個長方體,作為輪子位置的參考物。
3.將四個長方體與地面進(jìn)行幾何體和法線約束,然后調(diào)整到車輪的位置。
附圖:
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表示輪軸的傾斜角,以上命令是控制輪子一方面受地形影響一方面受輪軸角度限制。關(guān)于clamp函數(shù)參考幫助文件。
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.定義四輪構(gòu)成體系($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軸向車身和自身的位移加速度和重力的影響而計算得出,車輪與地面的高度受壓力影響,壓力大時車輪與地面相對距離減小,壓力小時車輪與地面相對距離加大。模擬輪胎受壓變形。未考慮車身角度傾斜和車身轉(zhuǎn)動的扭矩的影響。對于地形特別崎嶇的環(huán)境,這將有較大的誤差。
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);//定義不同情況下的支持力計算方法,沒辦法,一時沒有精確的算法,按線性比例和平方比及指數(shù)關(guān)系都會出問題。
$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軸位置
避免輪子小幅度的長久的震蕩。當(dāng)其位移變化幅度?。?.03)時,強(qiáng)制其靜止。其中$nw[$i]是計數(shù)器,記錄連續(xù)小幅度位移(小于0.03)變化的幀數(shù),在這我定義的為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;
下面這一段限制了輪子與車身的最大位移量及限制了前后幀間輪子位移變化的極限值,這些限制在大腳車高速在起伏比較大的地面上行駛時有用,若低速行駛,可以不考慮這些限制。
避免車身小幅度的長久的震蕩。當(dāng)其長時間(15幀)位移變化幅度小(0.03)時,強(qiáng)制其相對四個輪子構(gòu)成的系統(tǒng)靜止($Tby=$Twyv+4;)。
其中$nb是計數(shù)器,記錄車身小幅度位移變化的幀數(shù),我定義的為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表示車身的高度
當(dāng)車身與輪子構(gòu)成的系統(tǒng)之間的y軸向的位移超過0.8個單位時,強(qiáng)制其為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.計算車身的旋轉(zhuǎn)角度,具體思路與計算車身y軸位移的相同,不同的是要通過四個輪子的空間位置計算車輪系統(tǒng)的角度及角加速度,通過車輪系統(tǒng)計算出來的角度及角加速度計算出車身的角度及角加速度。具體的一些比例系數(shù)大部分是試驗結(jié)果。
$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的位置指示物體驅(qū)動四個輪子運動。
a1.translateX=b1.translateX=aaaa.translateX+3;
a2.translateX=b2.translateX=aaaa.translateX+7;
a1.translateZ=a2.translateZ=aaaa.translateZ+2;
b1.translateZ=b2.translateZ=aaaa.translateZ-2;
對于aaaa這個物體,我用關(guān)鍵幀控制其位移??梢钥紤]用表達(dá)式控制,控制速度順應(yīng)地形的變化。例如在上坡時速度會減速,下坡時會加速。這個表達(dá)式應(yīng)該比較簡單,有興趣的朋友自己寫寫。
好了,大腳車的表達(dá)式基本就介紹完了,現(xiàn)在把全部表達(dá)式列出來,如下,供大家參考。表達(dá)式還有許多不足之處,望大家多多指正。例如不管坡度多么大,大腳車是不會翻滾的,呵呵。
* 以下是全部表達(dá)式,僅供參考
global float $Twa[],$Twy[],$Tby,$Twyv,$Twb,$a[],$T[],
$Twu,$Twv,$Vwy[],$Vby,
$Awy[],$Aby,$Awu[],$Awv[],$g=9.8,
$angerBu,$angerBv,$angerWu,$angerWv,$u,$v,
$abu,$abv,$vbu,$vbv,$aby,$u1,$u2,$v1,$v2, $au[],$av[],$angerWu1,$angerWu2,$angerWv1,
$angerWv2;
float $Fw[],$Nw[],$M=5,$m=0.5,$kau=0.02,$kav=0.04,
$kw=10*($m+$M/4)*$g,$kb=5*$M*$g,
$ku=250,$kv=200,$t=0.03;
int $i,$j,$nw[],$nb,$nu,$nv;
$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));
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;
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;
$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;
$Twyv=($Twy[1]+$Twy[2]+$Twy[3]+$Twy[4])/4;
$Tby=$Twyv+4.0;
}
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;
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;
$Twy[$i]=clamp($Tby-5,$Tby-3,$Twy[$i]);
if($Twa[$i]<-0.1)
$Twy[$i]=$a[$i]+1.3;
$Twy[$i]=clamp($T[$i]-0.4,$T[$i]+0.4,$Twy[$i]);
$T[$i]=$Twy[$i];
}
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;//difine $Tby
$Twyv=($Twy[1]+$Twy[2]+$Twy[3]+$Twy[4])/4;
$Twb=$Tby-$Twyv-4;
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;
$twu=($Twy[1]+$Twy[2])-($Twy[3]+$Twy[4]);
$twv=($Twy[1]+$Twy[3])-($Twy[4]+$Twy[2]);
$angerWu=-asind($twu/8)*0.9;
$angerWv=-asind($twv/10)*0.9;
$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;
}
wheel_l1.translateY=$Twy[1];
wheel_l2.translateY=$Twy[2];
wheel_r1.translateY=$Twy[3];
wheel_r2.translateY=$Twy[4];
body.translateY=$Tby;
body.rotateX=$angerBu;
body.rotateZ=$angerBv;
a1.translateX=b1.translateX=aaaa.translateX+3;
a2.translateX=b2.translateX=aaaa.translateX+7;
a1.translateZ=a2.translateZ=aaaa.translateZ+2;
b1.translateZ=b2.translateZ=aaaa.translateZ-2;
print($Awy[3]+", "+$Vwy[3]+", "+$Twy[3]+", "
+$Twa[3]+" "+$nw[3]+"
"+
$angerWu1+" "+b1.rotateX+" "+(wheel_r1.rotateX-90));