※ 注意 ※
この記事のリグは失敗例です。
記事のとおり作ると、記事の通り失敗します。
それでもよいという天の邪鬼な方に向けておくる、”Mayaで作る車輪リグ考察(失敗編3)
そろそろ成功例だけ載せてくれ、とお叱りを頂きそうな今日この頃。
それでも載せます失敗例。
前回、オブジェクトスペースを使った作戦は、方向転換時の挙動に難あり。あえなく廃棄。
今回は考え方を変えて、1フレームあたりの移動距離から回転角を求める方法をとることにしました。
毎フレームごと、移動距離から角度を計算し、足してゆきます。
イメージはこんな感じ。
またこれだけでは前進しているのか、後退しているのかの判別がつかないので、進む方向の指針となるガイドも追加します。イメージはこんな感じ。
以上、これらをMayaで実装しました。(Pymel)
import pymel.core as pm #車輪オブジェクト作成 oObj = pm.polyCylinder(n="Wheel_GEO", r=5, h=1,sz=1)[0] oObj.rotate.set(90,0,0) #回転制御用グループ作成 oRot = pm.group(n="Rot") #コントローラ作成 配置 oCtr = pm.curve( d=1, p=[(-5, 6, -2.5), (0, 6,-2.5), (0 ,6 ,-5), (7 ,6 ,0), (0 ,6 ,5), (0, 6 ,2.5), (-5, 6 ,2.5), (-5, 6 ,-2.5)], k=[ 0,1,2,3,4,5,6,7] ,n="CTR") pm.makeIdentity( apply=True ) #TOPグループ作成 oTOP = pm.group(n="TOP") pm.parent(oRot, oCtr) #Directionコントローラ oDir = pm.curve( d=1, p=[( -0.6, 0 , -1 ), (-0.6, 0, 1), (1.2, 0, 0), (-0.6, 0 ,-1)], k=[ 0,1,2,3] ,n="Dir") oDir.translate.set(10,0,0) pm.parent(oDir, oTOP) #コンストレイン pm.parentConstraint("CTR", "Dir", mo=True) #距離は測るヤツ oStartNull = pm.spaceLocator( p=(0, 0, 0)) pm.hide() oEndNull = pm.spaceLocator( p=(0, 5, 0)) pm.hide() oDst = pm.distanceDimension( oStartNull, oEndNull) pm.hide() pm.parent(oStartNull, oEndNull, oDst, oObj) #expression 実装 expName = "Wheel_SampleEXP03" exp = "//1フレーム前の位置(global変数)n" exp += "global vector $oldPos = <<0>>;;nn" exp += "//初期化n" exp += "int $frm = frame;n" exp += "float $rot = 0;n" exp += "int $dir = 1;nn" exp += "//1フレームあたりの移動距離n" exp += "float $dx = `getAttr -time $frm CTR.tx` - `getAttr -time ($frm-1) CTR.tx`;n" exp += "float $dz = `getAttr -time $frm CTR.tz` - `getAttr -time ($frm-1) CTR.tz`;n" exp += "$distance = sqrt($dx*$dx + $dz*$dz);n" exp += "//進んだ方向を判定n" exp += "float $dx2 = `getAttr -time ($frm+1) CTR.tx` - `getAttr -time $frm Dir.tx`;n" exp += "float $dz2 = `getAttr -time ($frm+1) CTR.tz` - `getAttr -time $frm Dir.tz`;n" exp += "$distance2 = sqrt($dx2*$dx2 + $dz2*$dz2);n" exp += "if ($distance2 > 10){n" exp += " $dir = -1;n" exp += "}else{n" exp += " $dir = 1;n" exp += "}nn" exp += "//車輪の半径を取得n" exp += "$r = distanceDimensionShape1.distance;nn" exp += "//移動に応じた回転角を計算n" exp += "$rot = rad_to_deg($distance / $r) * $dir;n" exp += "Rot.rotateZ -= $rot;n" pm.expression(string = exp, name = expName) pm.cycleCheck( e=0)
長いですが、コレをMayaで実行するとサンプルシーンが作成されます。
動かしていろいろ試してみます。
前回、問題だった車輪の向き変更時の問題は改善されました。
前進も後退もバッチリです。
モーションパスにも対応しました。
が、なんということでしょう。
スライド(ドリフト)時、車輪が回転してしまっています。
それ以外はだいじょぶそうなのに・・・。
今回の方法だと、軸とか関係なし問答無用で移動距離から角度を求めるので、この問題が起きたと思われます。
・・・あちらを立てればこちらが立たず。
移動距離から進行方法ベクトルの成分だけ抽出出来れば・・・。
切り替えて、次!
コメント