2008/8/21

忘れてるんじゃなくて、そもそもわかって・・・いや、何でもありません、モゴモゴ  VRMスクリプト禅問答
【怎麼生】

http://caldia.blog.shinobi.jp/Entry/238/

【説破】 4.0.9.8

その1。SetEventTime/After/Timer命令の第4パラメータ(時間)は変数に対応していません。SCRIPTマニュアルの記述上も、変数が使えるとは書いてありません(使えない、とも書いてありませんがw)。加えて、VRMビュワー起動時のスクリプト文法チェックは甘々で、しばしば変数対応していないパラメータに対して書かれた変数名を無視し(エラーにならずにビュワーが起動してしまう)加えて、該当部分を勝手に“0”と解釈して動作しているように見えます。

で、SetEventTime/After/Timer命令が、第4パラメータが0(ミリ秒)の場合にどのような挙動を取るかはソースコードを読まないと何とも言えませんし、ボクの記憶が正しければ、4.0.1.x時代は何も起きませんでした。が、字義通りに解釈すれば、Caldia氏がやったことは「0秒毎にメソッドを実行しろ」という意味になりますから、まぁ、おかしなことが起こっても驚くには値しません。以上。

その2。簡単な実験をしてみましょう。何でもいいので、適当なオブジェクトに以下のスクリプトを書き込み、ビュワーを起動してみてください。
DrawMessage "ちょっとしたテスト"
すると、起動したビュワーのログウィンドウに以下に示すような表示が現れるはずです。

クリックすると元のサイズで表示します

この実験でわかるのは、宣言部(メソッドの外側)に書かれたスクリプト命令の処理が実行されるタイミングは、“VRMViewer V4”が“Startup OK”するよりも早い、ということに尽きます。


*     *     *


以下は、過分にボクの想像に拠るところが大きいので話半分に読んでください。

VRMビュワーは、相矛盾する2つの命題を満たすべく設計されているものと思われます。

(A) ハードウェアの性能は、余すところなく使い切りたい。具体的には、フレームレート(1秒辺りの描画枚数で、動作の滑らかさに影響する)最大を目指してハードウェアの性能の許す範囲内で描画を繰り返す。
(B) ユーザーが体験する仮想世界の時間は、ハードウェアの性能に関わらず一定にしたい。具体的には、超高性能PCでもVRMが動作するギリギリ性能のPCでも、50Km/hで走行する編成の見た目上の速度は同じになる。

命題Aは、とにかく1秒なら1秒の間に、実行できるだけのCPU/GPU命令を実行することを意味しており、逆に命題Bは、PCの性能に関わらず、1秒の間に実行される内容を同じにしたい、という意味になります。これが“矛盾”と呼ぶ所以です。

この矛盾を解決するために、多くのリアルタイム描画をおこなうソフトウェアでは、命題A用のプログラムAと、命題B用のプログラムBが互いに独立して動作するようにします。プログラムBは、常に一定の間隔(多分、VRMでは1ミリ秒毎)で黙々と計算をおこない、オブジェクトのあるべき座標を記録し続けます。これに対し、プログラムAは、描画をやって(座標計算よりも圧倒的に時間がかかる)手があく都度、その時点でプログラムBが計算した座標を調べて、それに従って描画をおこない、また手が空いたら同じことを繰り返します。こうすることで、PCの性能が高ければ高いほど滑らかに描画されるけれども見た目上の速度は変化しない、が実現されます。

で、ログウィンドウに表示されるところの“VRMViewer V4”は、おそらくはプログラムAの方が出しているメッセージです。“Startup OK”はリアルタイム描画に必要な準備・初期化が終わって最初の1コマが描画出来ました(ビュワー画面が表示されました)の意なのでしょう。逆に、VRMスクリプトの処理はプログラムBが担当していて、VRMViewer V4が初期化を済ませていようがいまいが、既に処理は開始されている、というのが先の実験が示唆する事実です。

ログウィンドウ自身は、おそらくはユーザーのみならず開発者のデバッグ目的も兼ねて実装されていて、レイアウターで〔運転〕をクリックした直後にバッファエリアが確保されていると思われます。

で、本題に戻りますが、Caldia氏が試みたことは、VRMViewer V4がStartup OKになる以前から一定間隔でScreenShot命令を実行する、ということに他ならず、そしてこの時点では取得されるべきスクリーンショット=描画結果はまだ得られていないので、具体的にどういう理屈で何が起こるかはわかりませんが、少なくとも意図通りには動作しなくて当然だろう、が結論になります。

個人的な経験則によると、スクリーンショットの取得のみならず、具体的なアクションを伴うスクリプト処理は、少なくともビュワー起動開始から100ミリ秒以上経ってからおこなうのがセオリーです。この“100ミリ秒”は、PCの性能によっては、もっと長くとるべきだったり、短くても大丈夫だったりするかも知れません。って、何度同じ事をアチコチに書いてきたことか。

さらに余談ですが、ScreenShot命令を使って動画用の一定間隔のスクリーンショットを取得するのは、よほど超高速(CPU・GPUのみならず、HDDの応答速度やそのI/O速度も含めて)のPCでないと安定したそれが取得できないはずです。これは、本稿に示した理屈から導かれる結論で、そして事実そうであり、大雑把に言えば、プログラムBの論理のみからでは一定間隔の描画をプログラムAへ要求することは原理的に不可能だ、という話なのですが、もういいです。黙って[F4]キーを押し続けるか、ビデオで録画しましょう。
0

2008/8/21  20:27

投稿者:Caldia
あー本当だ。
マニュアルにも「変数」じゃなくて「時間」と書いていますね。
指摘ありがとうございます。
切腹。

コメントを書く

この記事にはコメントを投稿できません




teacup.ブログ “AutoPage”
AutoPage最新お知らせ