Quaternionから普通の行列に変換…

今回、3Dの話よりも、僕が大好きな数学を見てみましょう。実は、昔会社のquaternion計算を作ったことがあります。その前は、学生時代の研究や個人作業などでquaternionライブラリを書いたことがあります。先ほど、個人ライブラリのコードを見て、一つの事実が明らかになってしまいました。僕のコードは並列計算のためのプログラムなのに、実は半分しかやってなかった。ショック…Altivecの為に作ったのに、半分しか並列化されないなんて、凹みました。Quaternionから行列に変換方法はこのような数式です。


| 1 - 2y2 - 2z2 2xy - 2wz 2xz + 2wy |
Mat = | 2xy + 2wz 1 - 2x2 - 2z2 2yz - 2wx |
| 2xz - 2wy 2yz + 2wx 1 - 2x2 - 2y2 |
PS2のVUとAltivecはベクトルユニットなので、一つのコマンドで、4つの計算を一発で計算することができます。例えば「MULA.xyzw ACC, VF04, VF05」と言う命令はこの計算を行います…一期に…

ACC.x = VF04.x × VF05.x
ACC.y = VF04.y × VF05.y
ACC.z = VF04.z × VF05.z
ACC.w = VF04.w × VF05.w

で…下の計算は簡単に並列化にしました。VF04の内容はquaternionの(x, y, z, w)で、VF05は(2, 2, 2, 2)です。

VF06.xyzw = VF04.xyzw × VF04.x
VF07.xyzw = VF04.xyzw × VF04.y
VF08.xyzw = VF04.xyzw × VF04.z
VF09.xyzw = VF04.xyzw × VF04.w
VF06.xyzw = VF05.xyzw × VF06.xyzw
VF07.xyzw = VF05.xyzw × VF07.xyzw
VF08.xyzw = VF05.xyzw × VF08.xyzw
VF09.xyzw = VF05.xyzw × VF09.xyzw

さて、これからは問題…どうやってこの値から行列に入れるんだろう?やっぱり、一つ一つしかないよね。先ほど、無理矢理試してみたら、このようなコードになってしまいました。

VF10 = (1, 0, 0, 0)
VF10.yz = VF10.yz + VF06.yz
VF10.x = VF10.x - VF07.y
VF10.x = VF10.x - VF08.z
VF10.y = VF10.y - VF08.z
VF10.z = VF10.z + VF08.y

VF11 = (0, 1, 0, 0)
VF11.xz = VF11.xz + VF08.xz
VF11.x = VF11.x + VF09.z
VF11.z = VF11.z - VF09.x
VF11.y = VF11.y - VF06.x
VF11.y = VF11.y - VF08.z

VF12 = (0, 0, 1, 0)
VF12.xy = VF12.xy + VF08.xy
VF12.x = VF12.x - VF10.y
VF12.z = VF12.z + VF10.x
VF12.z = VF12.z - VF06.x
VF12.z = VF12.z - VF07.y

う〜ん…全然並列のプログラムじゃないんですか…どうだろう?皆様、どうやって高速のquaternionから行列の計算をやるんだろう?誰か、教えて…

やっぱ、これを買わないと…

Vector Game Math Processors (Wordware Game Math Library)

Vector Game Math Processors (Wordware Game Math Library)