この、poleVector の方向は、ジョイントが3個以上のスケルトンでは、プリファードアングルとかで制御できるのですが、上のように2個のジョイントからなる骨では、向きを制御することが不可能のようです。
この骨も、Z軸に出てほしかったのですが、X軸の方を向いてしまっています。
この骨も、Z軸に出てほしかったのですが、X軸の方を向いてしまっています。
法則性が分かればよいのですが、なんかバラバラなんですよねー。
スクリプトで組んでいると、同じ角度のはずなのに、1個目と2個目で向きが違っている場合があったりして困ります。
目で見て確認するというのも効率が悪いので、poleVector の座標を計算して求めるのが良いでしょう。
汎用的に使えるよう複数の骨で構成されたIKにも対応させたいので、そこもふまえてスクリプトを作ります。
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 の方向へ加えています。
使い方としては、
使い方としては、
{
vector $p = tryCalcPV("ikHandle1");
move ($p.x) ($p.y) ($p.z) "locator1";
}
のように、ikHandle 名を渡すと座標が返ってくるので、何かオブジェクトをその座標へ移動さて poleVectorConstraint をします。
ikHandle の poleVector 座標を計算するスクリプトなので ikHandle を設定していないと計算できません。
poleVectorオブジェクトがコンストレイントされていたらIKを設定している骨の長さへ正規化できることになります。
ikHandle からは poleVector constraint も調べられるので、PVオブジェクトを見つけたら一気に移動までさせても良いのかな。

0 件のコメント:
コメントを投稿