クォータービュー表示ロジック(2)
考えた結果、おそらく、3D系にかなり似たロジックになってきた気がする。
考えた中で最も効率が良さそうなのは、以下のロジックを使い、カメラに写るオブジェクト(=描画の為に計算が必要なオブジェクト)を絞る手法だった。
- 世界の全空間を、適切なサイズの立方体のブロックに区切る。
- この立方体のブロックは、内部に存在する全オブジェクトへのリファレンスをテーブル(以下、オブジェクトテーブル)として持つ、という事にする。
- カメラの視界に、一部分でも入っているブロックを調べ、集め、リスト化する(以下、ブロックリスト)。
- 集めたブロックに含まれる全オブジェクトをリスト化し(以下、総合オブジェクトテーブル)、前回検討したsortを使うやり方で描画する。
この方法は、計算対象を絞るだけでなく、以下のメリットも見込める。
- カメラがあまり動かないのであれば、少し前に調べたブロックリストを再利用でき、更なる高速化が望める可能性がある。
- オブジェクトがあまり動かない/動いたとしてもブロック間をまたぐ移動があまり多くないのであれば、ブロック間を移動したオブジェクトは移動履歴のようなものに記憶しておいて、前回調べた時のオブジェクトテーブルのうち、変動したもののみを総合オブジェクトテーブルに反映させる事で、毎回、総合オブジェクトテーブルを更新するよりも負荷を低くできる可能性がある。
デメリットは以下の通り。
- 計算が面倒。
- 前述の方法で普段の負荷を減らすと、逆に、カメラ視野内のブロックが大きく変動した時の負荷が目立つようになる。
- インクリメンタル/マルチスレッド的に計算するような手法を使えば目立たなくなるが、それを考慮したコードを書く手間が更に増える。
- 同様に、ブロックリストを再利用したり、移動履歴を保持したりするコードを書かなくてはならない。何も考えずに書くよりも更に手間が掛かる。
このデメリットのうち、多くは、関数指向プログラミングを採用する事で軽減できるような気がした。
そこで、実装用言語は、D言語ではなくHaskell+SDLに変更する事にした。
とりあえず、この方針で実装してみる。
あとで。