myara CG blog

CG Design Blog. Thoughts, experiments and experiences.

SI | ゆれもの、そしてobj と obj の角度と距離の取得方法

ちょっと前までやっていたプロジェクトでゆれもの作業があったんですが、スペックが低いリアルタイム系なのでシミュレーションとかはNGでした。リアルタイムエンジンのシミュレーション機能というオプションなどありません。全てはFCurveのみというプロジェクトでした。

それでゆれものを100%手動で付けるのは嫌だから、スプラインIK+スプリングを使う事にしました。

syflex も試してみましたが、大変なことになっていたのでやめました。
コリジョンがないけど、どうせ最後に手動で直さなきゃいけないからいいか。

骨にスプラインIKを付けて、このsIKコントローラーにスプリングを付けるというやり方です。
最終的にsIKをプロットして、スプリングを消して、FCurveを手動で編集というやり方。

それで、MTSpring は結構良い感じなんですけど、スクリプトで自動化するのが難しそうだったから SI の Tail を使う事にしました。

MTSpring のHelge Mathee の記事(英語)
MTSpring(Youtube動画)

MTSpring は手動でスプリングを作って、回転とスケールで合わせてスプリングを増やしていくという作業になります。
手動でやってもいいけど、キャラクター何10体もあるとさすがに作業の途中で死にたくなります。

今回もまた似たようなスペックのプロジェクトでまたゆれもの作業があります。今回はもう少し余裕があるので、MTSpringを自動化することに決めました。

説明したとおり、MTSpring は回転とスケールでコントローラーに合わせる方法しかないので、その回転とスケールの自動取得方法が必要となってきます。

それで今日はずっと難しい三角法を使って、色々やってみて惜しいところまでいきましたがコンストレインとカーブを使えば楽じゃん?!と気づきました。処理が遅くてもいいからね、1,2秒ぐらいしか変わらないと思うし。

それで、このファンクションを作りました:


function getRot(objA, objB){
DirectionCnsPath = "D:\\Constraints\\DirectionCnsY.Preset"
var c = objA.Kinematics.AddConstraint(DirectionCnsPath, objB, 0)
DeleteObj(c)
}


D:\\Constraints\\DirectionCnsY.Preset は自分でカスタマイズしたDirection コンストレインのプリセットです。

今回は Y 軸を次のオブジェクトに向かせたかったけど、DirectionのデフォルトオプションはX軸で回転を合わせてくれます。このオプションをスクリプトで変えて、コンストレインを消すとなぜかXに戻ってしまいます。
それで、自分のコンストレインプリゼットを作ることにしました。

そのやり方は簡単です。コンストレインして、好きなようにいじって、Presetファイルに保存。
そして、コンストレインを付ける時にコンストレインの名前じゃなくて自分のプリセットのパスにすれば良い。

よし、次は長さです。

オブジェクトとオブジェクトの距離もまた難しい三角法で色々試していましたが、やっぱりカーブを作って、そのカーブの長さを取得するだけで十分!と気づきました。何時間も無駄にしました。


function getLength(objA, objB){
Ax = objA.Kinematics.Global.posx.value
Ay = objA.Kinematics.Global.posy.value
Az = objA.Kinematics.Global.posz.value
Bx = objB.Kinematics.Global.posx.value
By = objB.Kinematics.Global.posy.value
Bz = objB.Kinematics.Global.posz.value

var crv = SICreateCurve("crvlist", 1, 1);
SIAddPointOnCurveAtEnd("crvlist", Ax, Ay, Az, false, 0, null);
SIAddPointOnCurveAtEnd("crvlist", Bx, By, Bz, false, 0, null);

length = crv.ActivePrimitive.Geometry.curves(0).length
DeleteObj(crv)

return length
}


距離と回転値分かっていれば、あとはこっちのもんですね!


では、また。