スキップしてメイン コンテンツに移動

PoseModeで体のねじれの値に平均値を入れる

 体のコントローラの値はすべて同じ値が入っているべきだと思っているので、そうなるようなスクリプトをChatGPTくんに作ってもらいました。 内容としては、 アーマチュア(PoseMode)の選択しているコントローラ(ボーン)のXYZの回転(オイラー)がズレている場合平均値を代入してくれるというものです。 Mayaと違って複数ボーンに同じ値を入れるのが結構めんどい(Alt押しながらEnter)ので。 PoseModeじゃないといけなかったり、選択しているキーフレームを取得するのが難しかったりしたので現在のフレームを対象としています。 import bpy import math # アクティブなオブジェクトを取得 active_object = bpy.context.active_object # オブジェクトが存在し、Poseモードであることを確認 if active_object and active_object.mode == 'POSE': # アクティブなポーズのフレーム番号を取得 frame_current = bpy.context.scene.frame_current # 選択されているボーンのリストを取得 selected_bones = [bone for bone in active_object.pose.bones if bone.bone.select] # ボーンごとの各軸回転の合計を初期化 total_rotation_x = 0.0 total_rotation_y = 0.0 total_rotation_z = 0.0 for bone in selected_bones: # ボーンの各軸回転を取得し合計に加算 total_rotation_x += bone.rotation_euler.x total_rotation_y += bone.rotation_euler.y total_rotation_z += bone.rotation_euler.z # 各軸の回転の平均値を計算 average_r

RotationOrderを変更するMEL

よくFKで肩を回転させているとき、ジンバルロックになるので、ローテーションオーダーを変更することがあります。
そのまま変更してもカーブの値はそのままなのでポーズが変わってしまいます。それを防ぐためにxformコマンドを使用するのですが、一つのキーに対してしか適用されません。

なので、選択しているオブジェクトのキー全てに対してxformコマンドを適用するようなスクリプトを作りました。
オブジェクトを選択した状態で下記のMELを実行すればできると思います。
RotationOrderを変更する前処理としてXYZがバラバラにキーを持っていたとしても、その時間にキーを挿入しています。
//一番でかい時間の値を把握する
string $nodes[] = `ls -sl`;
int $rotXkeyNum,$rotYkeyNum,$rotZkeyNum;
//-attributeでどのアトリビュートを参照するか指定してる
$rotXkeyNum = `keyframe -attribute rotateX -query -keyframeCount $nodes[0]`;//キーの数をカウントする
$rotYkeyNum = `keyframe -attribute rotateY -query -keyframeCount $nodes[0]`;//キーの数をカウントする
$rotZkeyNum = `keyframe -attribute rotateZ -query -keyframeCount $nodes[0]`;//キーの数をカウントする
float $rotXlastTime[] = `keyframe -attribute rotateX -index ($rotXkeyNum-1) -query $nodes[0]`;//指定したインデックスの値を返す(指定したカーブの最後の時間の値を返す)
float $rotYlastTime[] = `keyframe -attribute rotateY -index ($rotYkeyNum-1) -query $nodes[0]`;//指定したインデックスの値を返す(指定したカーブの最後の時間の値を返す)
float $rotZlastTime[] = `keyframe -attribute rotateZ -index ($rotZkeyNum-1) -query $nodes[0]`;//指定したインデックスの値を返す(指定したカーブの最後の時間の値を返す)

//冒頭のフレームに移動 スライスを時間がそれになるまで続ける
currentTime -e `playbackOptions -query -min`;//再生範囲の最初
for($i=0; $i<$rotXkeyNum; $i++){
    setKeyframe -at rotateY -insert -time `currentTime -q`;
    setKeyframe -at rotateZ -insert -time `currentTime -q`;
    currentTime -edit `findKeyframe -attribute "rotateX" -which next`;
}
currentTime -e `playbackOptions -query -min`;//再生範囲の最初
for($i=0; $i<$rotYkeyNum; $i++){
    setKeyframe -at rotateX -insert -time `currentTime -q`;
    setKeyframe -at rotateZ -insert -time `currentTime -q`;
    currentTime -edit `findKeyframe -attribute "rotateY" -which next`;
}
currentTime -e `playbackOptions -query -min`;//再生範囲の最初
for($i=0; $i<$rotZkeyNum; $i++){
    setKeyframe -at rotateX -insert -time `currentTime -q`;
    setKeyframe -at rotateY -insert -time `currentTime -q`;
    currentTime -edit `findKeyframe -attribute "rotateZ" -which next`;
}

currentTime -e `playbackOptions -query -min`;//再生範囲の最初

//ローテーションオーダーの値を取る
$rotOrderNum = `getAttr .rotateOrder`;
//キーの数が揃っているはず
$rotXkeyNum = `keyframe -attribute rotateX -query -keyframeCount $nodes[0]`;//キーの数をカウントする
for($i = 0; $i <$rotXkeyNum;$i++){
    setAttr .rotateOrder $rotOrderNum;

    xform -rotateOrder xzy;//xzy
    setKeyframe .rotate;
    
    currentTime -edit `findKeyframe -attribute "rotateX" -which next`;
}

2021/12/26追記

Animbotに全く同じ機能すでに付いていました。Animbot流石すぎる・・・。


実行したあと警告が出ますが、ローテーションオーダーを変更したことを他の人に伝えないとアニメーションの見た目が変わってしまうから。みたいな感じだと思います。

コメント

このブログの人気の投稿

マニピュレータの軸方向を変更するスクリプト

回転や移動をするとき、マニピュレータの軸を切り替えるとき、WやEを押しながら左クリック長押しでパイメニューが出てきてそれで変更していると思います。 パイメニューが出てくるまでに若干のラグがあったり、頻繁に切り替える機能のため、ショートカットでできたほうが楽かと思い作ってみました。 下のコードをコピって好きなショートカットに設定してみてください。 カチャカチャ切り替えられるようになります。移動と回転両方に対応してます int $count = `manipRotateContext -q -mode Rotate`;//現在の状況 switch($count){ case 0: print("global\n"); manipRotateContext -e -mode 1 Rotate; manipMoveContext -edit -mode 1 Move; break;//caseのコロンのあとスペースが必要 case 1: print("gimbal\n"); manipRotateContext -e -mode 2 Rotate;manipMoveContext -edit -mode 2 Move; break; case 2: print("local\n"); manipRotateContext -e -mode 0 Rotate;manipMoveContext -edit -mode 0 Move; break; }

自分で用意したMMDのモデルをQuickRiggingToolでセットアップする

  Cascadeurでは、男女や猫のモデルが用意されていますが、自分で用意したモデルで作りたくなりますよね。最近追加されたQuickRiggingToolを使って、セットアップする手順を紹介します。 今回はMMDのモデルをMayaに読み込んで、ボーンを編集しスキンを調整し、リギングします。その時の注意点をまとめていきます。もちろん他のモデルでもリグのセットアップの仕方は同じです。 MMDのデータからMayaに読み込むときのプラグインはmmd-transporterを使用しました。MMDのデータの利用規約は作者によって異なります。MMD以外のソフトで使用することを禁止している場合もあるので、利用規約をしっかり読んでください。 必要な骨 ボーンの設定画面 Cascadeurのクイックリギングツールで必要な骨は、このような感じです。MMDの骨で一番特徴的なのは、腰のボーンが上半身の親になっていないことです。他にもIK用だったりルート用のボーンも用意されているので、下記の手順で削除してしまいましょう。 ・Mayaでスキニングされている状態で骨を編集する。 スキンされたジョイントへの移動ツール Mayaの機能で、スキニングされている状態で骨の位置や数を調整できます。リギングメニューにしてからスキン>スキンされたジョイントの移動です。 調整手順 1. 足のIK用のボーンを削除します。 2. sentaaというボーンの子供にjouhanshinとkahanshinがくっついています。jouhanshinを腰のルートにするので、足の付根の間くらいの位置に移動させ、jouhanshinをkahanshinの親にします。 ボーン構成 3. 肩のボーンが多いので、hidarisakotsuを飛ばしてjouhanshin2とhidarikataでつなぎます。右も同様に行います ボーンの位置を移動 ウェイトの具合を確認 4. つま先に関節がないので、それも設定します。ashikubisakiという足の末端のボーンを移動し、その末端に対してウェイトを設定します。 5. jouhanshinの位置が腰より前にあると、後々変な動きになってしまうので、それを調整します。 胸のボーン位置調整 6. ボーン足したり引いたりしているので、その分のスキンの調整をしなくてはなりません。調整にはSIWeigh

MatchTransform

 普段ペアレントコンストレイントを使ってオブジェクトの位置合わせをしていましたが、位置合わせ用のコマンドあったんですね。ペアレントコンストレイントをいちいち消さなくても大丈夫。 スクリプトエディターにコピペしてシェルフにドラッグしてください。1つ目のオブジェクトの位置に2つの目をあわせます。 選択順はコンストレイントと同じにしてあります。 string $nodes[] = `ls -sl`; matchTransform -pos -rot $nodes[1] $nodes[0];