まとめ
さて、本当はここからスキニングについて解説しようと思っていたのですが、時間がなくなってしまったので、ここで簡単にまとめて終わりにしたいと思います。スキニングについては Kavan らの論文に大変よくまとまっているので、ぜひ読んでみてください。特にデュアルクォータニオンのスキニングを自分で実装しようという場合には、この文献の 4.1 節「Coping with Antipodality」は必読です。
この解説ではデュアルクォータニオンの次のような表現を導出しました。
$$ d(\vec{a},\ \theta,\ \vec{c},\ l) = \left(\cos\frac{\theta + \epsilon l}{2},\ \sin\frac{\theta + \epsilon l}{2}\,( \vec{a}\ – \epsilon\,\vec{a}\times\vec{c})\right) $$
この表現にはいくつかのメリットがあります。ひとつは、回転の中心 \(\vec{c}\) が組込まれていることです。回転と移動を別々に表現してしまうと回転は常に原点のまわりで行なわれることになり、これで補間の計算をすると結果が座標系に依存してしまうのですが、デュアルクォータニオンは回転の中心が組込まれているため、座標系に依存しない結果が得られます。これは回転と移動をクォータニオンとベクトルで別々にあらわした場合と決定的に違うところです。ただ、このメリットは回転と移動をまとめて行なえばいいだけなので、同次座標系の4×4の行列にもこの特徴はあります。
また、このデュアルクォータニオンの表現は、一定の微小変換を連続して行なうことで得られました。つまり、何もしない状態(単位行列)から最終的な状態に向かって、ひとつの小さな操作を連続的に行なって得られるものなので、空間全体を回転と移動だけで変換するのに最も短かい経路で(リー空間上を直線的に(※))遷移させるものになります。そして、連続的な変化は実数パラメータ \(\theta,\ l\) としてあらわされるので、補間のパラメータと共にこれらのパラメータを変化させれば、最短経路での補間が実現できるわけです。
こうしてみると、デュアルクォータニオンは回転と移動を同時に補間するときに威力を発揮するわけですが、逆に言うと補間をしないのならばデュアルクォータニオンを使う意味はないとも言えます。3×3の回転行列をクォータニオンであらわすのは、それだけで十分メリットがあったわけですが、補間をしないのであれば、3次元の移動ベクトルをわざわざクォータニオンで表現する必要はありません。
ゲーム開発において、補間が必要になるのはキャラクターのアニメーションとスキニングの2つくらいです。しかし、アニメーションは通常回転しか含みません。移動が含まれるのはキャラクターの骨が外れたり伸びたりするような場合だけです。ですので、デュアルクォータニオンが必要になってくるのはスキニングくらいなのですが、これにはゲームエンジンが対応している必要があります。自前でゲームエンジンを持っている場合なら問題ありませんが、例えば Unity はデュアルクォータニオンのスキニングに対応していないので、難易度が高くなります。
私は Unity 3.5 の頃に頂点シェーダーでスキニングを実装したことがあって、そのときにデュアルクォータニオンにも対応したので、アセットとしてリリースしようかなと考えたこともあったのですが、Unity 4 になって、モバイルでも CPU のスキニングが超速くなったため、頂点シェーダーのスキニングがお蔵入りになってしまいました。Unity が CPU スキニングでデュアルクォータニオンに対応してくれればいいのに、と思わなくもないのですが、いまだに実装されてないのは需要がないからなんだろうなと思います。実際、行列の線形補間でなんとかなっていたので、デュアルクォータニオンってそんなに必要なものではないわけです。
しかし、デュアルクォータニオンがより多くの開発者に認知され、「Unity 早くデュアルクォータニオンのスキニングに対応しろよ!」という声が大きくなれば、そのうち実装されるんじゃないかなーという期待をしつつ、この解説を終わりにしたいと思います。
大変すばらしい解説、ありがとうございました。
ロボット工学で良く出てくるので、すごい参考になりました。
ロボット工学では良く使われるのですね。知りませんでした! コメントありがとうございます。
いつも大変お世話になっております。
3ページ目の
回転と移動をあらわした行列 A は Z の指数関数で表現できます。
A=eZ
そして、この行列 A に対応したデュアルクォータニオン d は
d=e^θ(axi+ayj+azk)+ϵ(vxi+vyj+vzk)
で計算できます。
の部分の質問なんですがこの文が書かれていたところの前に書かれていた文書のi,j,kとX,Y,Zの対応関係で出てきた1/2はどこに消えたのですか?
ご指摘の通り、1/2が抜けていましたので修正いたしました。
ありがとうございます!