この、poleVector の方向は、ジョイントが3個以上のスケルトンでは、プリファードアングルとかで制御できるのですが、上のように2個のジョイントからなる骨では、向きを制御することが不可能のようです。
この骨も、Z軸に出てほしかったのですが、X軸の方を向いてしまっています。
この骨も、Z軸に出てほしかったのですが、X軸の方を向いてしまっています。
法則性が分かればよいのですが、なんかバラバラなんですよねー。
スクリプトで組んでいると、同じ角度のはずなのに、1個目と2個目で向きが違っている場合があったりして困ります。
目で見て確認するというのも効率が悪いので、poleVector の座標を計算して求めるのが良いでしょう。
汎用的に使えるよう複数の骨で構成されたIKにも対応させたいので、そこもふまえてスクリプトを作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | global proc vector tryCalcPV( string $HDL ) ///< ikHandle 名 /**************************************************************************/ /** @brief pole vector の位置を骨格の長さで計算する @return poleVector の座標を返す。 ******************************************************************************/ { // ジョイント名の取得 string $sj =`ikHandle -q -sj $HDL `; string $ee =`ikHandle -q -ee $HDL `; // 開始ジョイントの座標取得 vector $sp =`xform -q -ws -t $sj `; //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // // 骨格の長さを計算 //------------------------------------------------------------------------------ // 変数の初期化 float $length = 0.0; string $self = $ee ; // 階層分ループ while ( true ) { // 親のジョイント名 string $parent = firstParentOf( $self ); // 自分の座標と親の座標を取得 vector $p0 =`xform -q -ws -t $self `; vector $p1 =`xform -q -ws -t $parent `; // 骨の長さを計算 $length += mag( $p1 - $p0 ); // 終了判定 if (`plugNodeStripped $sj `==`plugNodeStripped $parent `) break ; // 切り替え $self = $parent ; } //------------------------------------------------------------------------------ // poleVector の座標を取得 vector $pv =`getAttr ( $HDL + ".pv" )`; // 計算用の要素を計算 vector $ep = $sp + $pv ; float $rate = $length / mag( $pv ); return ((1.0 - $rate ) * $sp + $rate * $ep ); } |
単に poleVector の方向を出しているのではなく、骨の長さを計算してpoleVector の方向へ加えています。
使い方としては、
使い方としては、
1 2 3 4 | { vector $p = tryCalcPV( "ikHandle1" ); move ( $p .x) ( $p .y) ( $p .z) "locator1" ; } |
のように、ikHandle 名を渡すと座標が返ってくるので、何かオブジェクトをその座標へ移動さて poleVectorConstraint をします。
ikHandle の poleVector 座標を計算するスクリプトなので ikHandle を設定していないと計算できません。
poleVectorオブジェクトがコンストレイントされていたらIKを設定している骨の長さへ正規化できることになります。
ikHandle からは poleVector constraint も調べられるので、PVオブジェクトを見つけたら一気に移動までさせても良いのかな。
0 件のコメント:
コメントを投稿