No More Retake

3DCG屋さん向けTips&Referenceサイト

メニュー

Maya:車輪でリグ考察(了)

車輪リグ考察。
前回、フレーム単位で移動距離から回転角を求める方法を試しました。
大旨よさげだったのですが、しかし、どうもうまくいかない場合がありました。
車輪がスライドした場合です。

進行方向ではない向きの移動も回転計算に含んでいるのが原因です。
移動ベクトルから、進行方向のベクトルのみ抽出できれば良いのですが・・・。

Gear_05要約すると。

Gear_06
はて、どうしたものか。でいろいろ調べた結果、”内積”使うと良いのでは、と。
内積についてはこちらのサイトを参考にしました。
難しい話はそちらに任せるとして、

前回の考え方に、この内積を組み込んだものを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_SampleEXP04"
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 += "//進行方向ベクトルn"
exp += "float $dx2 = `getAttr -time $frm CTR.tx` - `getAttr -time $frm Dir.tx`;n"
exp += "float $dz2 = `getAttr -time $frm CTR.tz` - `getAttr -time $frm Dir.tz`;n"
exp += "//正規化n"
exp += "vector $unitDir = `unit<<$dx2, 0 ,$dz2>>`;n"

exp += "//内積使って距離を算出n"
exp += "float $distance = dot(<<$dx, 0,$dz>> , $unitDir);n"

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でサンプル作成していますが、他の3DCGソフトでも考え方がそのまま流用できるはずです。極端な話、Nuke等のコンポジットソフトでも作れるかと)

軽い気持ちで始めた車輪リグでしたが、内積まで使うハメになるとは。
みんなどうやってるんだろう?
もっと簡単な方法ないものか?

詳しい方、教えてくれる奇特な方、大歓迎です。

内積 参考URL
http://marupeke296.com/COL_Basic_No1_InnerAndOuterProduct.html
Related Posts Plugin for WordPress, Blogger...

関連記事

コメントをお待ちしております

このサイトについて

3DCG Tipsサイト。Houdiniの記事が多めです。

RSS

follow us in feedly

Archives

  • 2024 (4)
  • 2023 (2)
  • 2022 (9)
  • 2021 (14)
  • 2020 (46)
  • 2019 (17)
  • 2018 (33)
  • 2017 (29)
  • 2016 (36)
  • 2015 (64)
  • 2014 (54)
  • 2013 (60)
  • 2012 (55)

スポンサードリンク

言語切り替え

  • English (United States)
  • 日本語

スポンサードリンク

言語切り替え

  • English (United States)
  • 日本語

Houdiniを使えるようになる本