imagicdev のすべての投稿

VRMONLINE-NX ウィンドウを二枚

βテストにご参加いただきまことにありがとうございます。

GUIウィンドウを2枚表示するスクリプトサンプルです。

imguiは、Begin()-End()で一枚のウィンドウを表示します。
複数のウィンドウを表示する場合は、Begin-Endを必要な個数並べます。

ウィンドウの表示位置は、SetNextWindowPos()で指定します。
Begin()より前に指定してください。

ウィンドウの大きさは、標準のBegin()で表示されるウィンドウが、表示サイズを自動で記憶するため、SetNextWindowSizeConstraints()で条件を縛ってください。
SetNextWindowSize()でサイズを指定、SetNextWindowSizeConstraints()でリサイズ可能な範囲を指定します。

標準以外のBegin()については、今後の拡張をお待ち下さい。

#LAYOUT
import vrmapi


def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        vrmapi.ImGui().SetNextWindowPos(0,60)
        vrmapi.ImGui().SetNextWindowSize(320,200)
        vrmapi.ImGui().SetNextWindowSizeConstraints(320,200,480,240)
        vrmapi.ImGui().Begin("win10","Sample Window")

        cpos = obj.SYSTEM().GetGlobalCameraPos()
        vrmapi.ImGui().Text("SYSカメラ座標 =>"+str(cpos[0])+"  "+str(cpos[2]))

        if vrmapi.ImGui().Button("b1", "システムカメラ切り替えボタン"):
            if obj.IsViewGlobal():
                obj.SetViewGlobal(False)
            else:
                obj.SetViewGlobal(True)

        vrmapi.ImGui().End()

        vrmapi.ImGui().SetNextWindowPos(0,260)
        vrmapi.ImGui().SetNextWindowSize(480,120)
        vrmapi.ImGui().SetNextWindowSizeConstraints(480,120,480,120)
        vrmapi.ImGui().Begin("win11","2nd Window")
        vrmapi.ImGui().Text("第二ウィンドウ")
        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1
ウィンドウ表示サンプル

VRMONLINE-NX スクリプト仕様変更しました

βテストにご参加いただきまことにありがとうございます。

ビルド55を公開しました。

GetPosition()などのスクリプト関数の仕様を変更しました。仕様を変更した関数について、βテストご案内ページに一覧を掲載しています。
仕様変更にあわせて、スクリプトの書き換えをお願いします。

各関数の詳細は、スクリプトマニュアルをご参照ください。

GetPosition()は、データを関数の戻り値で返します。データは、list型です。

このバージョンでは、カメラモードについての関数を追加しています。SetViewGlobal()で、システムカメラの切り替えができます。

下記サンプルは、編成がID=5、地上カメラがID=8で設置したレイアウトのスクリプトです。

ボタンで、システムカメラの切り替え、表示対象を編成、地上カメラと切り替えることができます。

#LAYOUT
import vrmapi


def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        vrmapi.ImGui().Begin("win1","Sample Window")
        vrmapi.ImGui().Separator()
        vrmapi.ImGui().Text("ボタンテスト")
        
        train = obj.GetTrain(5)
        tpos = train.GetPosition()
        vrmapi.ImGui().Text("編成座標 =>"+str(tpos[0])+"  "+str(tpos[2]))
        
        cpos = obj.SYSTEM().GetGlobalCameraPos()
        vrmapi.ImGui().Text("SYSカメラ座標 =>"+str(cpos[0])+"  "+str(cpos[2]))

        if vrmapi.ImGui().Button("b1", "システムカメラ切り替えボタン"):
            if obj.IsViewGlobal():
                obj.SetViewGlobal(False)
            else:
                obj.SetViewGlobal(True)

        if vrmapi.ImGui().Button("b3", "地上カメラ"):
                obj.SetView(8)
        if vrmapi.ImGui().Button("b4", "編成カメラ"):
                obj.SetView(5)

        if obj.IsViewGlobal():
            vrmapi.ImGui().Text("システムカメラ")


        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1
システムカメラに切り替え
地上カメラに切り替え
編成カメラに切り替え

GUIサンプル ツリーと数値入力

βテストにご参加いただきまことにありがとうございます。

次のサンプルは、GUIらしいギミックです。

GUI部品をそのまま多数並べると、見通しが悪くなります。
これを避けるためにGUI部品を目的ごとに分類、ツリー構造にします。

TreeNode()とTreePop()の組み合わせで、1つのツリーになります。
ツリーは親子構造にもできます。TreeNode()の中にTreeNode-TreePopの組み合わせを入れることで親子構造になります。
TreePop()は、ツリーが開いているときに、ツリーの終了をあらわす関数です。
TreeNode()が開くとtrueが帰ります。ifで検出して、開いているときにGUIを表示、最後にTreePop()を記述します。
ツリーが閉じているときは、記述不要です。

このサンプルでは、ツリーのなかに数値入力部品を配置しています。
入力系の部品は、変数に入力値を渡すため、Pythonでは一工夫が必要になります。
本実装では、list型変数を入力関数に渡しています。
InputFloat()、InputInt()は、それぞれ浮動小数点数、整数を入力します。サンプルでは、それぞれの値を受け渡しするためにfNum、nNum変数をlist型で初期化しています。
list型変数の最初の要素に値を入れます。

PushItemWidth()は、GUI部品の表示幅を設定します。設定しない場合、標準の表示幅になります。見た目が微妙になるため、表示幅を制御したほうがよいです。
PushItemWidth()は、PopItemWidth()と必ず組にしてください。

#LAYOUT
import vrmapi

nNum = [0]
fNum = [0.0]

def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        global nNum
        global fNum
        vrmapi.ImGui().Begin("win1","Sample Window")

        if vrmapi.ImGui().TreeNode("tree1", "Tree-A"):
            vrmapi.ImGui().PushItemWidth(160.0)
            vrmapi.ImGui().InputFloat("f1", "浮動小数点数", fNum)
            vrmapi.ImGui().InputInt("n1", "整数", nNum)
            vrmapi.ImGui().PopItemWidth()
            vrmapi.ImGui().TreePop()

        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1
実行結果

GUIサンプル ボタン

βテストにご参加いただきまことにありがとうございます。

次はボタンのサンプルです。

ボタンは、クリックするとtrueを返します。ifでボタンが押されたことを検出します。

サンプルでは、ボタンが押されたことを記録するために、整数値を持つbtn変数をグローバル変数として用意しています。
frameイベントの最初にグローバル変数を使うことを宣言するため、global btnを記述します。
(記述しない場合、btnという名前のローカル変数になってしまいます。)

Begin()-End()の間に、Button()を記述します。ボタンは、入力をもつGUI部品のため、この部品だけのタグをつけます。サンプルでは、”b1″としています。

ifでボタンが押されたらbtn変数に1を代入します。

次にボタンが押されたことをあらわすメッセージを表示します。btn変数が1ならば、ボタンが押されたことになりますのでifで検出します。

ifでGUIの状態変化を検出、状態を記録する変数はグローバル変数にすることがポイントです。

#LAYOUT
import vrmapi

btn = 0

def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        global btn

        vrmapi.ImGui().Begin("win1","Sample Window")

        vrmapi.ImGui().Text("ボタンテスト")
        vrmapi.ImGui().Text("btn変数の状態 =>"+str(btn))
        if vrmapi.ImGui().Button("b1", "ボタンその1"):
            btn = 1
        if btn == 1:
            vrmapi.ImGui().Text("ボタンをクリックした")

        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1
実行結果

GUIサンプル ウィンドウを開く

βテストにご参加いただきまことにありがとうございます。

ビルド50では、スクリプトからNXシステムに組み込まれているGUI=ImGuiを利用できるようになりました。
ImGuiの基本的な機能を利用できる関数を実装しています。

ImGuiは、イベント駆動で動作するWin32などのGUIと異なり、Direct3D、OpenGLなど3DAPIと親和性の高い、直接駆動が特徴です。

3D APIの描画シーケンスの1つとして、毎フレーム実行します。実行結果は関数の戻り値であらわされます。

ウィンドウを開く

最初のサンプルは、ウィンドウを生成するコードです。非常に簡単です。

Begin()とEnd()を実行するだけで、ウィンドウが生成されます。
Begin()とEnd()の間に、ウィンドウに表示するGUI部品を記述します。

毎フレーム実行するため、レイアウトスクリプトのinitイベントでSetEventFrame()を実行します。

frameイベントには、Begin()-End()とテスト用にウィンドウにテキストを表示するText()を記述します。

ImGuiで重要なことは、ウィンドウ、GUI部品を部品名で識別していることです。同じ名前の部品を使用すると入力できなくなります。
これを避けるため、タグを部品に設定します。タグをすべての部品で一意の名前にすることで、部品名の衝突を避けることができます。
(ImGuiを呼び出す前に内部でラベルとタグから部品名を生成しています。)

#LAYOUT
import vrmapi
def vrmevent(obj,ev,param):
    if ev == 'init':
        obj.SetEventFrame()
    elif ev == 'broadcast':
        dummy = 1
    elif ev == 'timer':
        dummy = 1
    elif ev == 'time':
        dummy = 1
    elif ev == 'after':
        dummy = 1
    elif ev == 'frame':
        vrmapi.ImGui().Begin("tag_w","Sample Window")
        vrmapi.ImGui().Text("テキスト表示サンプル")
        vrmapi.ImGui().End()
    elif ev == 'keydown':
        dummy = 1
実行結果

VRMONLINE-NX βテスト期間を延長しました

βテストにご参加いただきまことにありがとうございます。

シェーダー開発が予定より大幅に遅れているため、VRMONLINE-NXのβテスト期間を5/31まで延長しました。現在組み込んでいますテスト用シェーダーにかわる正式シェーダーが、実装完了した時点で正式リリースに移行する予定です。

[VRMONLINE-NX] ビルド46を公開しました

βテストへご参加いただきまことにありがとうございます。

ビルド46を公開しました。このバージョンでは、地形テクスチャーの内部データ構造を少しリッチなフォーマットに変更、ブラシストロークの半透明の挙動をフォトショップなどのペイントツールにみられる書き味にしました。

次回以降の更新でテクスチャーのリプレース機能をご提供できる予定です。(現在テスト中。)

正式シェーダーの開発はまだ時間がかかりそうです。搭載までお待ち下さい。

VRMONLINE-NX ビルド40を公開しました

βテストにご参加いただきまことにありがとうございます。

ビルド40を公開しました。一見してわかる違いは、ブラシツールのツールボックスへの組み込みです。地形ツール>ブラシ選択の流れが、ボタン一つで行えます。地形ツール関連は、GUIの移動などがあります。詳細はマニュアルのリファレンスページをご参照ください。

部品パレットなどのツリーは、ダブルクリックで開閉できるようになりました。スムーズなオペレーションが可能です。

地形のVRM5互換モードは、初期設定を自動で行う処理を追加しました。テクスチャーを用意する手間がなくなりました。

ビルド40では、クラウドの通信処理、地形テクスチャーのRGB変換にあったバグを修正しています。

VRMONLINE-NX 細かい改良

βテストへご参加いただきまことにありがとうございます。

ただいま、各ツールの使い心地を向上させるためのブラッシュアップをすすめています。

次回更新では、部品、レイヤーパレットのツリーをダブルクリックで開けるようになります。また、ラベルにランドマーク機能を追加。システムカメラのときに、指定ラベルのボタンを押すと、システムカメラの位置が自動的にランドマークの位置に飛びます。「試運転」ですばやく表示位置を変更でき便利です。

配置した部品、ラベルを選択したらプロパティが自動で開けるようにできないか実験をすすめています。