- BrightObjectのスキニング(IK編)- |
- BrightObjectのスキニング(IK編)- IK(Inverse Kinematics)というのは、先端のジョイントを動かしたら、 その子ジョイント以下のボーンの姿勢が勝手に決まるというアルゴリズムです。 イメージを言うと、以下のように動かした場合、 ↓ こんな感じになるように動きます。 先端のジョイントを上に上げると、その親ボーン(親のジョイント位置)もいい具合につられて動きます。 これを表現する手法がIKです。 次の赤ジョイントが青ジョイントへ向かっていくアルゴリズムを考えます。 一番の親となるジョイントの座標が原点となるように、 赤ジョイントと青ジョイントの座標値から、親ジョイントの座標値を減算します。 イメージ的には下図のようになります。 ※以下、白いジョイントやボーンは気にせず、赤ジョイントと青ジョイントだけに注目してください。 原点と考えているジョイントから目標位置へのベクトルを算出します。(青色のベクトル) ピンク色のベクトルが青色のベクトルに合わさるように回転をさせます。 回転には外積で回転軸を算出、内積で回転角度を算出し、クオータニオンで回転させます。 このようになると思います。 赤ジョイントと青ジョイントの座標値に、先ほど減算した座標値を加算します。 回転移動されたので、赤ジョイントの座標値は変わります。青ジョイントは元の位置に戻るだけです。 次に、先ほど原点に考えたジョイントの1つ子となるジョイントを原点と考え、 そのジョイントの座標値を、赤ジョイント・青ジョイントの座標値から減算します。 同じように、原点と考えているジョイントから目標位置へのベクトルを算出し、(青色のベクトル) ピンク色のベクトルが青色のベクトルに合わさるように回転をさせます。 こんな感じに移動することとなります。 赤ジョイントと青ジョイントの座標値に、先ほど減算した座標値を加算します。 回転移動が反映しています。 このような処理を、親ジョイントから子ジョイントまで繰り返していくと、 先端のジョイント(上でいう赤ジョイント)が目標座標(上でいう青ジョイント)に近づいていきます。 Cyclic-Coordinate-Descent(CCD)法と言うみたいです。 下記サイトが結構分かりやすいです。 CCD-IK and Particle-IK BrightObjectのIKは上の動作説明をそのまま適用しています。 スキニングで頂点を回転させる時は、各ジョイントが持つIK用の回転クオータニオンを用いて、 FKと同じように子ジョイント(末端)から親ジョイント(始端)へ向かって、回転処理をさせていきます。 もちろん、子ジョイントの回転クオータニオンは親ジョイントの回転クオータニオンと合成していきます。 ただし、描画する順番は、親ジョイント(始端)から子ジョイント(末端)とします。 FKもIKも、スキニングをする際には、各ジョイントが何かしらの回転クオータニオンを持っているため、 ・頂点を原点周りに平行移動 ・クオータニオンを行列化 ・重みを反映させて頂点を回転移動 ・平行移動した分を戻す という同じ手順を踏みます。 なので、CCD-IK自体を実際に使っている場合というのは、 ボーンをマウスでIKで移動させるときに使っています。 (BrightObjectのメニュー「IKでジョイントを回転」を選択したときです) |