Lisp:Geometry

Lisp:Geometry

(Shiro: 私はNichimen Geometryになってから、 プラグイン書き等で少々いじったにすぎないので、 Symbolics時代のこととか、周辺事情にもあまり詳しくないっす。 識者の方、がんがん修正してください)。 

(khashi) 情報追加しといたんですが、まとまりがなくなってしまったんで、適当に整理しといてください。

Geometryとは

Lispで書かれたモデリングツール。 もともとSymbolicsのグラフィックス・パッケージS-Products のモデリング・モジュール。 1981年公開の映画「トロン」のモデリングを担当してたLarry Maloneによって開発された。 このツールが最初に日本でデモされたのは1985年の筑波博覧会アメリカ館。 市販されてから20年の歴史を持っている。 尚且つ20年間1人のプログラマによってメンテナンスされている。 開発当初は、ZetalispとFlaversで記述されていた。 その後Symbolics Common LispとNew Flavorsに移行した。 Symbolics倒産後、事業を引き継いだニチメン・グラフィックスでSGIのAllegro Common Lisp & CLOSに移植され、その後Windows上(NT)にも移植される。 ニチメン自体の経営の不調によりニチメングラフィックスはアメリカから撤退することになり、現在はIZWareでメンテナンスが継続されている。

もともとSymbolicsのS-Productsは、S-Geometry、S-Dynamics、S-RenderとS-Paintで構成されており、当時のCG製作のすべての作業をカバーしていた。 もちろんそのすべてがLispで記述されていた。 

アニメーション・システムS-Dynamicsもスクリプト方式という独自のコンセプトに基づいたものになっていた。 現在主流のケーフレーム方式と異なり、動きを要素に分解しおのおの要素を制御する方式であった。 また、もちろん制御する部分からLisp関数の呼び出しも可能であった。 開発者Craig Reynoldsは、同じくトロンのアニメーション担当者であった。

1980年代後半にCGをやっていた人は大抵使っているのでは? 私がこのへんに関わるようになったのは1993年頃で、 その頃は既にハードウェアの主力はSGIに なっていて、Symbolicsは部屋の隅でホコリをかぶっていた。

Symbolics上のGeometryをCommon Lispに移植して、IRIXや後にWindowsで 走るようにしたものが、Nichimen Geometryとして、 ニチメンの子会社だったニチメングラフィクスから出ていた。 3Dツール全体を称してNichimen N-Worldとも言ってた (version 3以降だっけ?)。

Nichimen Geometryはローポリゴンモデラーとしてかなり定評があった、と思う。 スクウェアではFF7の時にかなり使った。

アニメーションツールにも特徴があり、 アニメーションのレイヤリングがエレガントに出来たのを覚えている。

その後、ニチメンは次世代バージョンとしてMiraiだとか、 廉価版バージョンNendoを投入するも、マーケットシェアはAliasや SoftImageに押されて延びず、結局ニチメンはCGから撤退した。2001年頃だったっけ。

ニチメングラフィクスのIPは、旧ニチメンLAオフィスの開発陣が 設立したIZWareに引き継がれた。 今でも開発はやっているみたい。

1996年頃は、ニチメンのLAオフィスはCulver Cityにあって、 Marina del ReyにあったSquare LAのオフィスから車ですぐだった。 Square LAオフィス立ち上げ時には機材を借りたりだとか結構御世話になった。

Geometryとオブジェクト指向

GeometryはもともとSymbolics上のオブジェクトシステムFlavorsで 書かれていたんだと思う。私がいじってたNichimen Geometryの頃は CLOS (Common Lisp Object System)になっていた。

現在の3Dツールは大抵C++で書かれていると思うが、Geometryの オブジェクトアーキテクチャは粒度が違っていた。例えば 多面体オブジェクトにqueryすれば頂点オブジェクトのリスト、 エッジオブジェクトのリスト、facetオブジェクトのリスト、等が返って来る。 各頂点オブジェクトは座標、法線等のアトリビュート以外に、 その頂点に接続しているエッジのリストを持っているし、 エッジの方は自分がつないでいる頂点オブジェクトへのポインタを持っている。 つまりオブジェクト同士が相互リンクをはりまくっているわけだ。 全てCLOSインスタンスなので、CLOS標準のインスペクタなんかで 中身を調べながら、いもづる式にオブジェクトを手繰ってゆくことができる。

何でもオブジェクトのリストであるということは、いろんな操作が そのオブジェクトに対するメソッドをmapするだけでできるということだ。 操作をmap, mapでつないでゆくスタイルを見慣れていると、 ネストしたforループには戻りたくなくなる。

多分、このアーキテクチャはOO的には綺麗なんだけれど、 数百万ポリゴンなんてシーンを扱おうとすると、 頂点を頂点オブジェクトのリストで持つなんて方法は効率が悪くなりすぎる。 Mayaなんかは頂点そのものは独立したオブジェクトじゃない。 ポリゴンオブジェクトが座標や法線を配列で持っているにすぎない。 他の3Dツールでもそうではないか。 将来、計算機の能力が数段階あがれば、また「全てオブジェクト」の世界に 戻れるかもしれない。

ところで、C++やJavaのオブジェクトシステムは大事なところを他人に 触らせないようにするメカニズムがごてごてついているが、CLOSは全く逆で、 全てがオープンだ。一応、パッケージシステムでもってモジュール毎の 独立性は保たれていて、うっかり人のモジュールを壊してしまうなんて ことはないのだけれど、その気になれば人のモジュールの奥深くに入っていって 内緒のメソッドを叩くなんてことができる。 それどころかそのメソッドを再定義しちゃったりすることさえできる。 何でもありなんである。

しかも、ソースが無くて、手元にコンパイルされたバイナリしか無くても そういうことが出来るのだ。Lispリスナーからaproposとdescribeを使って行けば、 相手がバイナリであろうとクラスとメソッドの一覧、クラスの内部構造、 メソッドの引数、等が分かってしまう。

CLOSでは、メソッドコンビネーションというメカニズムを使って、 既存のメソッドに簡単に「ラッパーメソッド」を定義できる。 その既存メソッドが呼ばれる前や後に呼ばれるメソッドを後から定義できるってこと。 究極のフックと言えるかも。既存メソッドがたとえコンパイルされたバイナリで あっても構わない。

そうなると、例えばこんなむちゃができた。 ある巨大なシーン(地形データ)を編集したいのだが、実際のデータはシーンを 碁盤の目状に分割したタイルで持つ。諸事情から、全体を一気に編集して 後で切断するという手がとれず、デザイナーは常に数タイルづつのデータを 読み込んで編集するという必要があった。 その場合、タイルの切れ目の部分が問題になる。そこの頂点を うかつに動かしてしまうと隣のタイルに合わなくなるからだ。

いろいろ調べたら、頂点を動かす時には必ず内部メソッドmoveが呼ばれて いるのがわかった。コンパイルされているアプリケーションの内部 メソッドだが、フックをかけて調べてみれば引数の内容もわかる。 そこで、(move <vertex> <vector>)メソッドのaroundメソッドを定義して、 特定の属性がついている頂点は特定の方向にしか動かせないように した。本来のmoveメソッドの前後で座標値を調べて、該当する頂点の 場合は無理矢理座標値を上書きしてしまうのだ。

行儀の良いJavaプログラマが白眼を剥いてひっくりかえりそうな話、かもしれない。

他にも、aroundメソッドは特定のバグを回避するためなんかに良く使った。

今、ポピュラーな3Dツール、Maya, XSI, Max等はいずれもスクリプト言語で 機能を拡張する手段を提供しているけれど、 内部のオブジェクトをスクリプトに見せるオブジェクトにマッピングしなければ ならないし、その手間をちょっと惜しんだために スクリプトからいじれない機能が出てしまったりとか、 内部オブジェクトをスクリプトで拡張できないとか、 制限が多い。

Lispで書かれていれば、拡張言語=本体の記述言語、である。 スクリプト言語のようにインタラクティブに開発できて、 しかも作ったものはそのままコンパイルされたプラグインになる。

そういう点では、Geometryは最もLispらしいアプリケーションのひとつだった んじゃないだろうか。

Tag: CLOS


Last modified : 2013/04/25 22:12:15 UTC