Article:

LVMX-SDKはNeosVR内で作られた仮想マシン「LVMX」をターゲットにしたCコンパイラとそのライブラリ、加えてwebで動作するシミュレータからなるSDKです。

LVMXはLogiX Virtual Machine Xの略です。LogiXはNeosVR内で利用できるノードプログラミングの名称で、それによって作られたVirtual Machineなのでこのような名前になっています。(最後のXは飾り文字です。)


1. 概要

NeosVR内ではノード型プログラミングがサポートされています。いま現状VR機器としてVR内でキーボードのように快適に文字を入力できるデバイスは発明されていません。よって、VR内では文字を利用したプログラミングが困難です。なので、ノード型プログラミングを採用するのは非常に理にかなっています。

また、ノードはそれ単体で動作することから、単体テストが容易です。この特性によって、複数人がそれぞれ機能ブロックを作り、合成するといったことが非常に高速に行えます。NeosVRがウリにしている「他人との共同作業」にはこの特性がかなり活きていると思います。

しかし、ノード型プログラミングにも問題はあります。

  1. バージョン管理が難しい(既存のgitなどの仕組みを利用できない)
  2. コード量が膨大になると編集作業が破綻する
  3. NeosVR外で閲覧・編集が不可能

このようにメリット・デメリットが存在するので、適用する問題によってノードによる開発と、コードによる開発を使い分けたいですよね。しかし、NeosVRでは現在ノード型以外のプログラミング手段は提供されていません。

そこで、既存のノードのシステムで仮想マシンを構成し、そのマシンのためのコンパイラを作成することで、コードベースでの開発を可能にするという手法を取ることにしました。これがLVMXです。

2. LVMXの仕組み

LVMXはスタックマシンの計算モデルを持った計算機です。

この表にある命令を実行することができます。この命令番号と引数を、実行してほしい順番に記載したファイルを読み込ませることでアプリケーションが動作するわけです。

Neos内でこの規模のアプリケーションを動かそうと思うと毎フレーム100クロック程度が限界です。なので、できるだけ複雑な計算を行う命令を用意することで、低クロックでもある程度実用可能な性能が出るようにしています。

3. LVMXでNeos内のオブジェクトにアクセスする方法

NEOS内にはまだ数値や文字列を入力として任意のコンポーネントをオブジェクトに付与したり、任意のコンポーネントのフィールドにアクセスする手段はありません。

そこで、LVMXでは「テンプレートシステム」を採用しています。

これは、開発者がある程度Neos内でDynamic Fieldなどを利用したオブジェクトのテンプレートを作成しておくことで、LogiXからでもアクセスできるようにするものです。

要するに、アセットとコードを分けて開発するといったニュアンスです。

例えば、大きさとマテリアルの色に対してDynamicFieldを設定したBoxをテンプレートとして登録しておけば(アセットの開発)、LVMXの"CreateSlotFromTemplate(CSFT)“命令でこのテンプレートをコピーして新しくワールドに作成し、“Store Dynamic Variable(STORED)“命令で色を変えたり、大きさを変えたりすることができるようになります(コードの開発)。

4. LVMX Compiler

2章で、使いたい命令番号を順番に記載していけばプログラムが作れることを説明しました。しかしながら、プリミティブな命令を自力で並べるのは限界があります。そこで、Cコンパイラを作成しました。これによって、C言語によりアプリケーションが作成可能になります。

アプリケーションの作成例はgithubにあります。

コンパイラ本体はPythonで作成しました。これは、1. AWS Lambdaに乗せてオンラインコンパイラにしたかった 2. pythonを食わず嫌いしていたので食ったら普通に嫌いだった 3. でもある程度作っちゃったのでそのまま作った の3つの理由によるものです。

ただライブラリが極端に充実していたのでその点は非常に良かったですね。

また、本来なら既存のllvmなどのシステムを使いたかったのですが、特殊命令多めでスタックマシン用のとなると難しそうだったので今回は自力で作ることにしました。

通常のC言語の仕様に加えて、__raw組み込み関数を追加しています。__raw(戻り型, 命令ニーモニック文字リテラル, 命令引数, 通常引数…)の構文で使えます。

これは、1. sinやcosをはじめオブジェクト操作などたくさんの特殊命令を同時多発的に実装できる, 2. ランタイムの仕様が変わってもすぐ対応できる の2つの利点があります。

lvmxlib/lvmx.hを見ると、raw組み込み関数を#defineで簡単に使えるようにするコードが書いてあり、どう使うのかがひと目でわかるかと思います。

今現在Cのほとんどの機能をサポートしていますが、最後のツメとしてstaticなどのストレージクラス指定子やconst、そして関数ポインタが実装されていません。割とこれがないと困るのですがそれよりもNeosVR内での動作の高速化やSimulatorの機能の充実化のほうを優先度高としているのでその問題が解決次第、取り組もうと思います。

5. LVMX Simulator

LVMX Simulatorはwebブラウザーで動作するLVMXのシミュレータです。コンパイラーで吐き出したバイナリを読み込んで実行できます。

LVMXの応用先として今Papylus-Crawlerというアイテムを作っていて、これは要するにVR内で動作するスマートフォンです。

LVMX自体はテンプレートさえあればNeos内の様々なオブジェクトを扱えるのですが、それをすべてシミュレートするのは不可能に近い話です。

なので、シミュレータではスマホアプリに限定してシミュレーション機能を強化しています。

例えば、電卓アプリをシミュレートすると、NeosVR内でもともとこう動作していた電卓アプリが、

NeosVR内画面

こう表示されます。

LVMX Simulatorの画面

実際にWEB上で触って動作確認できます。

このシミュレータの充実により、 Neosの外でアプリケーションを開発し、VR内の持ち込むということが可能になります。

最後に

勘違いされると嫌なので書きますが、このプロジェクトは「ノードプログラミングなんて馬鹿げてる。どうしてもコードしか書きたくないからやった。」というものではありません。正味「できるからやった」「実用性はともかく作るのが面白そう」くらいの動機しかありません。実際、作っててとても楽しかったです。

よくNeosの話を他人にすると「コード以外で実装したくない」と拒絶されます。気持ちはわからないでもないというか、私も初めはそう思っていたのですが、今では試さない理由ばかり述べて、まず試してみなかったことを恥じています。プログラマーはコードが自分のすべてになりがちなので情が乗ってしまいがちですが、それも考えものですね。

VR内でプログラミングができることは素晴らしいことです。まずフィードバックが超高速です。単純に考えれば、PCモニタでプログラムして、ビルドしてヘッドセットをかぶってテストして修正して…というイテレーションよりも、VR内で使ってたらちょっと操作感が気になったのでその場で修正したというオーガニックに速いイテレーションのほうが非常優れたユーザビリティを形成することは間違いありません。

実際に、NeosVR内には本当に優れたユーザビリティのアイテムがたくさんあります。VR内のエディターでなければ、これは生まれなかったでしょう。

まぁでも本文中でも述べましたがそれぞれに利点欠点があるので、NeosVRでVMがネイティブサポートされたり、PC上のエディタが存在したらどんなに素晴らしいことか… とは思います。

あ、あと開発メンバー(?)というか、もっとゆるい感じでいいんですけどお話できる人を募集してます!気軽にNeosVRでDM送ってください~~~