Maya特效教程
Maya特效教程:Maya表達(dá)式控制動(dòng)力學(xué)動(dòng)畫(huà)之大腳車(chē)
編輯:Penny來(lái)源:發(fā)布時(shí)間:2010-06-28
1.先創(chuàng)建一個(gè)大腳車(chē)的簡(jiǎn)單模型,要有必要的部件,例如四個(gè)輪子及軸和車(chē)身。效果測(cè)試滿意后可以用細(xì)模替代。再創(chuàng)建一塊崎嶇的地面。
2.創(chuàng)建四個(gè)長(zhǎng)方體,作為輪子位置的參考物。
3.將四個(gè)長(zhǎng)方體與地面進(jìn)行幾何體和法線約束,然后調(diào)整到車(chē)輪的位置。
附圖:
4.定義輪子相對(duì)各自參考物的傾斜角,如下:
$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]表示四個(gè)輪子參考物的y軸向的位置。$angerWu1,$angerWu2表示輪軸的傾斜角,以上命令是控制輪子一方面受地形影響一方面受輪軸角度限制。關(guān)于clamp函數(shù)參考幫助文件。
5.定義輪子和車(chē)身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;
輪子位置為其各自參照物位置控制。車(chē)身位置是近似計(jì)算,簡(jiǎn)單的說(shuō),車(chē)身就是取四個(gè)輪子空間位置的平均值。
6.定義四個(gè)輪子中心的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為輪子受車(chē)身及自身重力后離地面的高度。
7.定義四輪構(gòu)成體系($angerWu,$angerWv)的橫向和縱向的傾斜角,定義車(chē)身($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.定義車(chē)身的y軸向的初始位置
9.計(jì)算四個(gè)輪子的y軸向的位移,其中輪子所受到的壓力為y軸向車(chē)身和自身的位移加速度和重力的影響而計(jì)算得出,車(chē)輪與地面的高度受壓力影響,壓力大時(shí)車(chē)輪與地面相對(duì)距離減小,壓力小時(shí)車(chē)輪與地面相對(duì)距離加大。模擬輪胎受壓變形。未考慮車(chē)身角度傾斜和車(chē)身轉(zhuǎn)動(dòng)的扭矩的影響。對(duì)于地形特別崎嶇的環(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);//定義不同情況下的支持力計(jì)算方法,沒(méi)辦法,一時(shí)沒(méi)有精確的算法,按線性比例和平方比及指數(shù)關(guān)系都會(huì)出問(wè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軸位置
避免輪子小幅度的長(zhǎng)久的震蕩。當(dāng)其位移變化幅度?。?.03)時(shí),強(qiáng)制其靜止。其中$nw[$i]是計(jì)數(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;
下面這一段限制了輪子與車(chē)身的最大位移量及限制了前后幀間輪子位移變化的極限值,這些限制在大腳車(chē)高速在起伏比較大的地面上行駛時(shí)有用,若低速行駛,可以不考慮這些限制。
避免車(chē)身小幅度的長(zhǎng)久的震蕩。當(dāng)其長(zhǎng)時(shí)間(15幀)位移變化幅度?。?.03)時(shí),強(qiáng)制其相對(duì)四個(gè)輪子構(gòu)成的系統(tǒng)靜止($Tby=$Twyv+4;)。
其中$nb是計(jì)數(shù)器,記錄車(chē)身小幅度位移變化的幀數(shù),我定義的為15幀。另外下面的程序定義了車(chē)身的位移加速度和速度的計(jì)算方法。
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表示車(chē)身的高度
當(dāng)車(chē)身與輪子構(gòu)成的系統(tǒng)之間的y軸向的位移超過(guò)0.8個(gè)單位時(shí),強(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.計(jì)算車(chē)身的旋轉(zhuǎn)角度,具體思路與計(jì)算車(chē)身y軸位移的相同,不同的是要通過(guò)四個(gè)輪子的空間位置計(jì)算車(chē)輪系統(tǒng)的角度及角加速度,通過(guò)車(chē)輪系統(tǒng)計(jì)算出來(lái)的角度及角加速度計(jì)算出車(chē)身的角度及角加速度。具體的一些比例系數(shù)大部分是試驗(yàn)結(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.給輪子及車(chē)身賦值
我定義了一個(gè)名為aaaa的位置指示物體驅(qū)動(dòng)四個(gè)輪子運(yùn)動(dòng)。
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;
對(duì)于aaaa這個(gè)物體,我用關(guān)鍵幀控制其位移??梢钥紤]用表達(dá)式控制,控制速度順應(yīng)地形的變化。例如在上坡時(shí)速度會(huì)減速,下坡時(shí)會(huì)加速。這個(gè)表達(dá)式應(yīng)該比較簡(jiǎn)單,有興趣的朋友自己寫(xiě)寫(xiě)。
好了,大腳車(chē)的表達(dá)式基本就介紹完了,現(xiàn)在把全部表達(dá)式列出來(lái),如下,供大家參考。表達(dá)式還有許多不足之處,望大家多多指正。例如不管坡度多么大,大腳車(chē)是不會(huì)翻滾的,呵呵。
* 以下是全部表達(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)建四個(gè)長(zhǎng)方體,作為輪子位置的參考物。
3.將四個(gè)長(zhǎng)方體與地面進(jìn)行幾何體和法線約束,然后調(diào)整到車(chē)輪的位置。
附圖:
4.定義輪子相對(duì)各自參考物的傾斜角,如下:
$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]表示四個(gè)輪子參考物的y軸向的位置。$angerWu1,$angerWu2表示輪軸的傾斜角,以上命令是控制輪子一方面受地形影響一方面受輪軸角度限制。關(guān)于clamp函數(shù)參考幫助文件。
5.定義輪子和車(chē)身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;
輪子位置為其各自參照物位置控制。車(chē)身位置是近似計(jì)算,簡(jiǎn)單的說(shuō),車(chē)身就是取四個(gè)輪子空間位置的平均值。
6.定義四個(gè)輪子中心的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為輪子受車(chē)身及自身重力后離地面的高度。
7.定義四輪構(gòu)成體系($angerWu,$angerWv)的橫向和縱向的傾斜角,定義車(chē)身($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.定義車(chē)身的y軸向的初始位置
9.計(jì)算四個(gè)輪子的y軸向的位移,其中輪子所受到的壓力為y軸向車(chē)身和自身的位移加速度和重力的影響而計(jì)算得出,車(chē)輪與地面的高度受壓力影響,壓力大時(shí)車(chē)輪與地面相對(duì)距離減小,壓力小時(shí)車(chē)輪與地面相對(duì)距離加大。模擬輪胎受壓變形。未考慮車(chē)身角度傾斜和車(chē)身轉(zhuǎn)動(dòng)的扭矩的影響。對(duì)于地形特別崎嶇的環(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);//定義不同情況下的支持力計(jì)算方法,沒(méi)辦法,一時(shí)沒(méi)有精確的算法,按線性比例和平方比及指數(shù)關(guān)系都會(huì)出問(wè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軸位置
避免輪子小幅度的長(zhǎng)久的震蕩。當(dāng)其位移變化幅度?。?.03)時(shí),強(qiáng)制其靜止。其中$nw[$i]是計(jì)數(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;
下面這一段限制了輪子與車(chē)身的最大位移量及限制了前后幀間輪子位移變化的極限值,這些限制在大腳車(chē)高速在起伏比較大的地面上行駛時(shí)有用,若低速行駛,可以不考慮這些限制。
避免車(chē)身小幅度的長(zhǎng)久的震蕩。當(dāng)其長(zhǎng)時(shí)間(15幀)位移變化幅度?。?.03)時(shí),強(qiáng)制其相對(duì)四個(gè)輪子構(gòu)成的系統(tǒng)靜止($Tby=$Twyv+4;)。
其中$nb是計(jì)數(shù)器,記錄車(chē)身小幅度位移變化的幀數(shù),我定義的為15幀。另外下面的程序定義了車(chē)身的位移加速度和速度的計(jì)算方法。
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表示車(chē)身的高度
當(dāng)車(chē)身與輪子構(gòu)成的系統(tǒng)之間的y軸向的位移超過(guò)0.8個(gè)單位時(shí),強(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.計(jì)算車(chē)身的旋轉(zhuǎn)角度,具體思路與計(jì)算車(chē)身y軸位移的相同,不同的是要通過(guò)四個(gè)輪子的空間位置計(jì)算車(chē)輪系統(tǒng)的角度及角加速度,通過(guò)車(chē)輪系統(tǒng)計(jì)算出來(lái)的角度及角加速度計(jì)算出車(chē)身的角度及角加速度。具體的一些比例系數(shù)大部分是試驗(yàn)結(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.給輪子及車(chē)身賦值
我定義了一個(gè)名為aaaa的位置指示物體驅(qū)動(dòng)四個(gè)輪子運(yùn)動(dòng)。
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;
對(duì)于aaaa這個(gè)物體,我用關(guān)鍵幀控制其位移??梢钥紤]用表達(dá)式控制,控制速度順應(yīng)地形的變化。例如在上坡時(shí)速度會(huì)減速,下坡時(shí)會(huì)加速。這個(gè)表達(dá)式應(yīng)該比較簡(jiǎn)單,有興趣的朋友自己寫(xiě)寫(xiě)。
好了,大腳車(chē)的表達(dá)式基本就介紹完了,現(xiàn)在把全部表達(dá)式列出來(lái),如下,供大家參考。表達(dá)式還有許多不足之處,望大家多多指正。例如不管坡度多么大,大腳車(chē)是不會(huì)翻滾的,呵呵。
* 以下是全部表達(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));
招生熱線
快速導(dǎo)航
入學(xué)要求 | 課程設(shè)置 | 暴雪動(dòng)態(tài) | 我要報(bào)名
學(xué)員作品 | 就業(yè)學(xué)員 | 招生問(wèn)答 | 暴雪簡(jiǎn)介
公司作品 | 周邊介紹 | 教學(xué)環(huán)境 | 乘車(chē)路線
學(xué)生作品