実験
Gauche-gl で 3 次元図形言語
Lightweight Language Weekend Lightning Talk「Gauche-glによる、3次元図形言語」発表資料。 『計算機プログラムの構造と解釈』 に出てくる「図形言語」と「ストリーム」という 2 つのアイディアを組み合わせ、 Gauche-gl を経由して OpenGL フレームワークに取り込んでみました。
以下は当日発表に使った発表資料です。 よかったらダウンロードしてみてください:
- プログラムのソースコード
- Gauche-gl の動く環境が必要。
- コマンドラインで「gosh ./demo.scm」として実行してください。
- 映像のすべてのコマの静止画像(PNG 画像約 2000 枚、2.36 MB)
- 20 fps くらいでスライドショーが出来れば、当日の映像をほぼ再現できます。
- 長すぎるカットは短くしています。
- だれかこれを動画ファイルにしてくれると嬉しいんですが……。
図形言語
元ネタは『計算機プログラムの構造と解釈 第ニ版』2.2.4「例:図形言語」です。 高林哲さんによるGuile-gtkを使った実装 など、すでにいくつかの実装例が公開されています。
ペインタ
図形言語は、ペインタという基本要素からなっています。 ペインタは図形を描画する手続きとして実装します。
たとえば、立方体を各手続き cube を作るとします。 Gauche-gl を使えばこんな風にかけます:
(define (cube) (glut-solid-cube 1.0))
次にこの cube に赤い色をつけて、 これを red-cube と名づけます:
(define red-cube (paint-red cube))
paint-red という手続きは、 ペインタを引数にとって、 それを赤く塗った新しいペインタを作って返します。 こうして得られた red-cube もまた、cube と同じペインタの仲間です。
つまり、 ペインタを変形・結合してあらたなペインタを合成することができるので、 入れ子構造にすれば複雑な図形処理も簡単に実現できます。
アニメーション、時間の表現
3 次元の静止画像が描けたら、 次はこれをアニメーションさせたくなります。 しかし、 アニメーションをさせるためには時間というものをどう扱うか、 よく考えないといけません。
現実の時間は連続的ですが、 コンピュータグラフィックスのアニメーションの時間は、 離散的です。 つまり、静止画像で出来た「コマ」をたくさん用意して、 それらを順番に切り替えることで、 それがあたかも動いているかのように見せるわけです。
フィルムとコマ
アニメーションを映画のフィルムのアナロジーで考えると、 コマはある時刻が割り当てられたひとつのペインタであると考えられます。 そこで、 コマを次のような時刻を表す整数とペインタの対で表現します:
(t . painter)
たとえば、30 コマ目に赤い立方体の絵をだすのなら、 そのコマは (30 . red-cube) となります。
時間
そこでまず離散的な時間というものを、 連続する整数のリストとしてイメージします。
(1 2 3 4 ...)
1 秒間に 20 コマ表示させるとすれば、 5 分間で 6000 コマです。 つまり 1 から 6000 まであればいいことになります。
(1 2 3 4 ... 5998 5999 6000)
この程度のリストなら、 メモリのこともそれほど気にせずに作ってもよいでしょう。
しかし、 2 時間の映画を作るとき、 あるいはいつ終わるか分からないゲームなどを考えるときは、 このようなリストをそのまま作るのは不可能です。
ストリーム
『計算機プログラムの構造と解釈 第ニ版』の 3.5 節に ストリーム というテクニックが載っています。 これはとても面白いテクニックで、 有限のメモリの中に無限に続くリストのようなものを作ることが出来ます。 これを使えば、 いつ終わるか分からないアニメーションでも実現できるわけです。
- 遅延評価を使った遅延リスト
- 無限リストの表現が可能
- 内部状態を持つことなく時間経過を表現することが出来る
図形言語+ストリーム
- アニメーションが作れる
- Flash のようにプログラマブル、しかも Scheme で書ける
- モデルデータ、アニメーションシーケンスの扱いを工夫すれば、デザイナーとのコラボレーションも可能?