もどる
face.gif とにかく回せ!! 00/03/26
ぐりんぐりん 顔のアニメーションができました!!いや〜、やっぱりグラフィックってなんか 「形」があるからホント「できた」って感じがします。プログラムでこれを動かしたときなんか もー、感涙もんですよ(ね?)。

上のアニメーションGIFを見ればわかるよーに、顔は「八方向」分だけ手書き、という方向にしました。 NaGu-Ruは、X-Y軸メイン(再サイドビューです)の2Dゲームにするので、このY軸回転させた画像に加え、DelphiXの画像合成関数を 使ってZ軸回転を表現できます。それなら、X軸回転も・・・といきたいのはやまやまですが、 X軸回転画像についても8方向分用意するとなると、8×8で64パターンも必要になります。 ひとつの顔グラフィックは32×32だから、32×32×64×2 = 2の17乗byte = 131072byte = 128kbyte となりますね。さらに、体の分もありますからさらに2倍で256kbyteとなります。それと、手足も付け加えて多めに見て 512kbyteくらいになりそうです。これを10人分用意するとなると、512×10 = 5120kbyte = 約5MB!! しかも、顔グラフィックは「表情」がない状態でこれですから、二倍になると考えても大体10MBにもなります(マジで!?)。 というわけで、画像はY軸、Z軸回転のみをサポートすることにしました。

さらに、システムがあまりにも不安定になってきたということで、再インストールしてたら 「Windowsのパスワードが書いてあるやつ」がどっかいっちゃってて 探しに探したところ、なんと捜し求めていた3D関連の資料がどさどさっ、と出てきました。 棚からdevilmanさんです。ということで、「時代は3Dだ」とか一人で思ってくるくると回すことを決意しました。

いつこの資料がなくなるかわからないので、ここに書いておきます。いわゆるオブジェクト用変換行列は 次のようになります。ちなみに行列は4×4行列です(呼び名忘れた)。

オブジェクト用変換行列 = |Z軸回転行列|×|X軸回転行列|×|Y軸回転行列|×|平行移動行列|

行列を知っている方(高校生くらいのひと)ならこの式がいかに面倒くさいかをわかると思います。 ぱっとみ掛け算四回のくせして、実際には192回も掛け算(と足し算)をしなくてはならないのです!!! (間違えてたらすんません)いくら最近はCPU速いぜー、とかいってみても、さすがにこれはつらいです。 なんせ、192回ですよ!!!泣く子も黙りますよ、これ!! というわけで、必殺高速化の出番ですね。

まずは、X,Y,Z軸回転行列と平行移動行列の中身を書き出してみます。 また、各軸に対しての回転角度はそれぞれRx,Ry,Rzとし、移動量はlx,ly,lzとする。

X軸回転行列
1
0
0
0
0
CosRx
SinRx
0
0
-SinRx
CosRx
0
0
0
0
1
Y軸回転行列
CosRy
0
-SinRy
0
0
1
0
0
SinRy
0
CosRy
0
0
0
0
1
Z軸回転行列
CosRz
SinRz
0
0
-SinRz
CosRz
0
0
0
0
1
0
0
0
0
1
平行移動行列
1
0
0
0
0
1
0
0
0
0
1
0
lx
ly
lz
1
こうなります。これを順番にZ,X,Y,平行へと順番に合成していけばいいんです....。 ってどう見ても大変そうですね。高速化のためには一度「出来上がった代物」としての 行列を見ておく必要がありそうですので、これを手動で計算してみます。えーと...

CosRzCosRy+SinRzSinRxSinRy
SinRzCosRx
CosRz-SinRy+SinRzSinRxCosRy
0
-SinRzCosRy+CosRzSinRxSinRy
CosRzCosRx
-SinRz-SinRy+CosRzSinRxCosRy
0
CosRxSinRy
-SinRx
CosRxCosRy
0
lx
ly
lz
1
こうなりました(書くのが面倒だったのでプログラム作りました(^^;))。 ではこのへんで高速化の手法を考えてみます。 真っ先に思いついたのは掛け算がおそいなら、それを減らそう、ってことで 「三角関数同士の掛け算をテーブルにしよう」って方法です。 方法としては、まず、Sinカーブを256度系とか4096度系とかにして テーブルに入れておきます。コサインの値はサインのものに90度角度を加えたものなので、 その法則を利用してメモリを節約します。
んで、つぎに掛け算ずみテーブルを作ります。これはサインでの角度を 二つ入れるとそれに対応する値が返ってくる、ってものです。 テーブルのサイズは、先ほど設定した〜度系っていうのの2乗分だけ 必要です(4096度系なら4096*4096個必要)。メモリ的にはおそらく 256度系がめいっぱいだと思います。これだとメモリも256kbyteですむのでお手ごろです。 ちなみに、1024度系だと4096kbyte=4MBもいるのでかなり非実用的です。 さらに4096度系だと64MBもメモリが必要になります。完璧無理ですね。ということで、 ここでは256度系を使用することにしましょう。

ほかには、三角関数同士の掛け算部分を加法定理で掛け算を足し算にしてやる、ってのが ありますが、面倒くさそうなのでやめます。

というわけで、テーブルにより掛け算部分がかなり減りますねー。 この時点で掛け算が必要なところは、16こですがこれがなくなります。 僕は今作ってるやつで4096度系を使っているので、これを256度系に変換する必要がありますが、 4096度系での角度 ÷ 16 = 256度系の角度と計算できますが、これは 4096度系の角度 右シフト 4 = 256度系の角度というように、シフト一発で計算できますので 遅くないはず(むしろ速い?)。実際には、X,Y,Z軸それぞれの回転角度があるので、 三回シフトが必要になります。それと、足し算四回ですね。これで遅けりゃ CPUに文句を言ってください(^^;)

とはいえ、あくまでこれは行列を作っただけです。この後、実際に使える形(ベクトル)に もってくには、16回の掛け算が必要になります・・・・。まぁこれはあきらめるしかない、 と思っています。どうしても高速化したいって人は固定小数点でも使ってみてはいかがでしょうか。 (テンション低いな・・・・)

次へ進む





もどる