2020年10月12日月曜日

カプセル型のコントローラを作成してみる

 今回はこんな感じのリグを作成してみます。


 まずは、カーブオブジェクトで、カプセル1個、キューブ2個、八面体1個を作成します。
 何とかして作成してください。
 そして、それぞれ "capsule_ctrl","sp_ctrl"(StartPosition),"ep_ctrl"(EndPosition),"radius_ctrl"みたいに名前を付けておきましょう。


 でも、これがいちばん面倒だったりします。特にカプセルが。

 そんなときは、こちらのツールを試してみるのも良いと思います。
 ツールウィンドウから作成しても良いですが面倒なのでコマンドでやっちゃいます。

{
    source "curveTools/tryCurveObject.mel";
    
    string $suf ="_ctrl";

    string $ctr0 =("capsule"+$suf);
    string $ctr1 =("sp"+$suf);
    string $ctr2 =("ep"+$suf);
    string $ctr3 =("radius"+$suf);
    
    rename `tryCurveObject.capsule 1 1 16 "y" "z"` $ctr0;
    
    rename `tryCurveObject.cube 0.2 0.2 0.2 "x" "y"` $ctr1;
    rename `tryCurveObject.cube 0.2 0.2 0.2 "x" "y"` $ctr2;
    
    rename `tryCurveObject.sphere 0.2 4 "x" "y"` $ctr3;
    
}

  作り終わったら curve shape の色も変えておきましょう。
 そしたら、"capsule","radius_axis"のトランスフォームノードを作成します。

{
	string $root ="capsule";
	string $axs3 ="radius_axis";
	
	group -em -name $root;
	group -em -name $axs3;
	
}

いままで作ったノードを、こんな感じに階層化します。


ここから、"capsule_ctrl"の編集を開始です。

まずは、Control Vertexの番号を記録します。

下側


"capsule_ctrl.cv[41:45]" "capsule_ctrl.cv[47:51]" "capsule_ctrl.cv[53:57]" "capsule_ctrl.cv[59:87]"


次に上側


"capsule_ctrl.cv[0:40]" "capsule_ctrl.cv[46]" "capsule_ctrl.cv[52]" "capsule_ctrl.cv[58]"


今度は、カプセルの上側の半球のEdit Pointを選択します。
これを、球になる見えるように移動させます。



ここで、先ほど記録しておいた下側の Control Vertex

"capsule_ctrl.cv[41:45]" "capsule_ctrl.cv[47:51]" "capsule_ctrl.cv[53:57]" "capsule_ctrl.cv[59:87]"

を選択して、[Animation] Deform -> Cluster を実行します。



次に上側の Control Vertex

"capsule_ctrl.cv[41:45]" "capsule_ctrl.cv[47:51]" "capsule_ctrl.cv[53:57]" "capsule_ctrl.cv[59:87]"

を選択して、[Animation] Deform -> Cluster を実行します。


そうすると、下半球を操作するクラスタと上半球を操作するクラスタが出来たと思います。


このクラスタをそれぞれ"sp_ctrl"と"ep_ctrl"で pointConstraintするのですが、このままでは微妙にずれてしまうので、クラスタのピボットを原点に移動させる必要があります。


"cluster1Handle"と"cluster2Handle"のアトリビュートエディタで編集します。Local Space のほうを先に編集すれば World Space はゼロになったかも・・・。



カプセルの初期状態にするため、"ep_ctrl"の translateY を 1にしますが、今のままでは、tranlateX や translateZ に数値を入れると半球がズレてしまいます。


これを回避させるために、クラスターを aimConstraintで向き合うように拘束します。

クラスタの Local Rotation Axis を表示させると、どの軸を aimConstraintさせれば良いのか、なんとなく分かるかと思います。

スクリプトだとこんな感じです。

{
    aimConstraint -aim 0  1 0 "cluster2Handle" "cluster1Handle";
    aimConstraint -aim 0 -1 0 "cluster1Handle" "cluster2Handle";
    
}

これで"sp_ctrl""ep_ctrl"を移動させてもカプセル状のまま伸び縮みしてくれます。


 ここまで来たら、アウトライナに表示されている clusterHandleは非表示にしちゃいましょう。
 カプセルの編集と、開始位置、終了位置のコントローラは終了です。


次に、カプセルの半径を制御するために "radius_ctrl"の接続を始めます。
まずは、"radius_axis"を"cluster1Handle"で pointConstraint, orientConstraint を掛けます。

ここから NodeEditor。

"radius_ctrl","cluster1Handle","cluster2Handle","sp_ctrl","ep_ctrl"を表示します。shapeは省いて、transformノードだけにして、こんな風に配置します。


左から"radius_ctrl","cluster1Handle"

右端に上から "sp_ctrl","ep_ctrl","cluster2Handle"と並んでいます。


まず "radius_ctrl.translateX"を"cluster1Handle.scaleX","cluster1Handle.scaleY","cluster1Handle.scaleZ" に接続します。


ビューでカーブオブジェクトが変な風になりますが、気にせず進めます。

"cluster1Handle.scale"を"sp_ctrl.scale","ep_ctrl.scale","cluster2Handle.scale" に接続。


最後に、"cluster1Handle.scale"を"radius_ctrl.scale"に接続。


ここまで来たら"radius_ctrl.translateX" を 1 にします。というか、"radius_ctrl.translateX"を操作することでカプセルの大きさが変化するかと思います。


マイナス方向へのスケールは、あまり好ましくないので、"radius_ctrl"のtranslateXにリミットでもかけておきましょう。


これで、長さと半径の制御が出来るようになりました。

ただ、このままだと"capsule_ctrl"を移動させたときに、カプセルのシェイプと、"sp_ctrl","ep_ctrl","radius_ctrl"が離れていってしまいます。


次はこれを回避させます。

まずは、"capsule_ctrl"と"radius_axis"の Inherits Transform を Off にします。


で、簡単な順に接続していきましょうか。

Node Editor に"cluster1Handle"と"radius_axis"を表示させ Input and output connctions を表示させます。

かなりのノードが表示されますが、"cluster1Handle"と"radius_axis"、その間にある「radius_axis_pointConstraint1」「radius_axis_orientConstraint1」だけにします。


ここで、せっかく設定したのですが「radius_axis_pointConstraint1」「radius_axis_orientConstraint1」は削除します。

代わりに、「decomposeMatrix」を作成して接続し直します。


次に、"cluster1Handle","cluster2Handle"を Node Editor に表示させ、Onput connectionsを表示させます。


またまた大量にノードが表示されますが、この中から、"cluster1Handle","cluster2Handle","cluster1","cluster2"だけにします。


それぞれのクラスタハンドルとクラスタの World Matrix[0] と Matrix の間に multMatrixノードを挟み込みます。


次は"capsule_ctrl"からのマトリクス計算のノードを作成したいので、アウトライナで"capsule_ctrl"を選択して現在の Node Editor へ追加します。


composeMatrixノードを追加して、"capsule_ctrl.translate"を接続。

inverseMatrixノードを追加して、composeMatrixを接続します。


そしたら、最後に inverseMatrix.outputMatrix とクラスタに接続している multMatrix.matrixIn[1] へ接続します。


あとは、アトリビュートをロックしたり隠したりして完成です。


何個も作る場合は、これまでの手順をスクリプトに起こせば、マウスをクリックするだけの簡単なお仕事にできますね。

cluster コマンドの戻り値は文字配列型で、[0]がクラスタ名、[1]にクラスタハンドル名というのを覚えておくと捗ります。


0 件のコメント:

コメントを投稿