Step 03:2つのベクトルの織りなす角度を求めて、回転した角度を計算する
現在の「向き」を示す「座標」はわかりました。ではこの情報からどうやって「角度」を求めるのでしょうか。
向きを示す「座標」は下図のように考えると、向きを示す「ベクトル」と捉えることができます。
つまり、初期値の向きを示すベクトルと現在の向きを示すベクトルの織りなす角度を計算すればよいのです。
Utilityノード「angleBetween」を使う
「angleBetween」ノードがこの問題を解決します。
そもそもこのノードは「2つのベクトルの織りなす角度を取得する」ためのものなので、もうズバリこれ。
NodeEditorで「angleBetween」ノードを作り、vector1とvector2に先ほどのbendVectorの値を接続します。
そして、vectorの接続を切ります。
すると、初期値として値が残ったと思います。Attribute Eritorから、アトリビュートに数値が残っていることが確認できます。
これでBend成分の角度取得が可能になりました。
試しに同じ階層にcubeを作成して、angleBetweenノードのEulerアトリビュートを接続してみると......
できました! 試しにねじらせてみても......
動かない! ハラショー!
こんな感じで3軸回転状態からBend成分のみを抽出することが可能になるわけです。
おまけ:Expressionでbendの回転成分を計算してみる
上記ではUtilityノードを使いましたが、Expressionでも実現が可能です。
MELコマンドにも「angleBetween」という「2つのベクトルの織りなす角度を取得する」ためのコマンドがあるので、これを使ってみます。
まず、bendVectorの初期値の定義と現在の値の取得を書きます。
float $defVec[] = {1.0,0.0,0.0};
float $aimVex[] = {decomposeMatrix1.outputTranslateX,
decomposeMatrix1.outputTranslateY,
decomposeMatrix1.outputTranslateZ};
次に、この2つの織りなす角度をangleBetweenコマンドで計算します。
float $angleBetween[] = `angleBetween -euler
-v1 $defVec[0] $defVec[1] $defVec[2]
-v2 $aimVex[0] $aimVex[1] $aimVex[2]`;
-eulerフラグを立てておけば、「anglenBetween」ノードと同様に結果をオイラー回転で返してくれるので、便利ですね。
この結果を、以下のようにcubeのrotateに接続すれば......
pCube1.rotateX = $angleBetween[0];
pCube1.rotateY = $angleBetween[1];
pCube1.rotateZ = $angleBetween[2];
できました! 挙動も良さそうです。
なお、Expressionでリギングを行う上での注意として、Evaluationを「Always」から「On demand」に変更しておいてください。
「Always」のままだと強制的に毎フレーム処理が走ってしまうので、場合によってはシーンに過負荷を与えてしまうことがあります。
いかがでしょうか!? 割と簡単に回転成分からBend成分だけを抽出することができたと思います。
「ベクトル」と聞くと何だか難しいイメージが先行してしまうかもしれませんが、3Dツールを通じて改めて見ると、「ノード制御に便利な考え方」としてみることができるのではないでしょうか。Mayaなど3D制作に従事する方ならば、きっとイメージもつかみやすいはず。
さて、今回はBend成分での制御のみを取り上げましたが、ではRoll成分での制御はいったいどのようにしたら良いのでしょうか。次回はQuaternionにも少し触れ、Roll制御について一例をご紹介したいと思います。
では今回はこの辺で!
サヨナラ! サヨナラ! サヨナラ!!
Profile.
-
山本智人/Tomohito Yamamoto(COYOTE 3DCG STUDIO)
ゲーム開発会社にてグラフィックアーティストとして、モデリング・モーション・エフェクト・UIなどオールラウンドのグラフィック制作を経験後、テクニカルアーティストに転身。現在は株式会社クリーク・アンド・リバー社 COYOTE 3DCG STUDIOにて、社内外問わずアーティストのDCCツールサポートや制作パイプラインの提案・作成・運用を行う。特にアニメーション制御やモーション制作周りのテクニカルサポート・リガーとして様々なプロジェクトに従事