夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

SceneUnderstandingを学ぶ NavMesh-Simple シーン 機能編 その①

本日はツールの調査枠です。

前回はキーボードの入力によって変更できるNavMesh-Simpleシーンで行える機能を見ていきました。

redhologerbera.hatenablog.com

SceneUnderstandingはMRTKとは2020年末現在独立したツールであるため、アプリでの組み込みなどの勉強として本日はキーを押したときに動いている処理を調査します。

〇SampleInputManager

NavMesh-Simpleでのインプットは[SceneUnderstandingMenu]オブジェクトにアタッチされている[SampleInputManager]コンポーネントが担っています。

f:id:Holomoto-Sumire:20201227193529j:plain

[SampleInputManager]コンポーネントの中で[AddDefaultCommands()](140行目あたり)というメソッドで処理が定義されています。

  private void AddDefaultCommands()
        {
            // First batch of device-only commands
            if (suManager.QuerySceneFromDevice)
            {
                inputActions.Add(InputAction.Create("Update", KeyCode.None, "Displays the latest data.", async () => await SuManager.DisplayDataAsync()));

                inputActions.Add(InputAction.Create("Toggle Auto Refresh", KeyCode.None, "Turns automatic updates on or off", () =>
                {
                    SuManager.AutoRefresh = !SuManager.AutoRefresh;
                    if (!SuManager.AutoRefresh)
                    {
                        SuManager.TimeElapsedSinceLastAutoRefresh = SuManager.AutoRefreshIntervalInSeconds;
                    }
                }));
            }

            inputActions.Add(InputAction.Create("Toggle Scene Objects", KeyCode.Alpha1, "Show / hide processed scene objects", async () =>
            {
                SuManager.RenderSceneObjects = !SuManager.RenderSceneObjects;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Toggle Labels", KeyCode.P, "Enable / Disable labels for scene objects", async () =>
            {
                labeler.DisplayTextLabels = !labeler.DisplayTextLabels;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Scene Objects Quad", KeyCode.Alpha2, "Quad Mode", async () =>
            {
                SuManager.SceneObjectRequestMode = RenderMode.Quad;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Scene Objects Mesh", KeyCode.Alpha3, "Mesh Mode", async () =>
            {
                SuManager.SceneObjectRequestMode = RenderMode.Mesh;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Scene Objects Wireframe", KeyCode.Alpha4, "Wireframe Mode", async () =>
            {
                SuManager.SceneObjectRequestMode = RenderMode.Wireframe;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Scene Objects Mask", KeyCode.None, "Mask Mode", async () =>
            {
                SuManager.SceneObjectRequestMode = RenderMode.QuadWithMask;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Toggle Platforms", KeyCode.Alpha5, "Enable / Disable large horizontal surfaces", async () =>
            {
                SuManager.RenderPlatformSceneObjects = !SuManager.RenderPlatformSceneObjects;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Toggle Background", KeyCode.Alpha6, "Enable / Disable background objects", async () =>
            {
                SuManager.RenderBackgroundSceneObjects = !SuManager.RenderBackgroundSceneObjects;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Toggle Unknown", KeyCode.Alpha7, "Enable / Disable unknown objects", async () =>
            {
                SuManager.RenderUnknownSceneObjects = !SuManager.RenderUnknownSceneObjects;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Toggle Inferred", KeyCode.Alpha8, "Enable / Disable completely inferred surfaces (requires refresh)", () =>
            {
                SuManager.RequestInferredRegions = !SuManager.RequestInferredRegions;
            }));

            inputActions.Add(InputAction.Create("Toggle World", KeyCode.Alpha9, "Show or hide the world mesh", async () =>
            {
                SuManager.RenderWorldMesh = !SuManager.RenderWorldMesh;
                await SuManager.DisplayDataAsync();
            }));

            inputActions.Add(InputAction.Create("Mesh Coarse", KeyCode.None, "Low quality mesh", () =>
            {
                SuManager.MeshQuality = SceneUnderstanding.SceneMeshLevelOfDetail.Coarse;
            }));

            inputActions.Add(InputAction.Create("Mesh Medium", KeyCode.None, "Medium quality mesh", () =>
            {
                SuManager.MeshQuality = SceneUnderstanding.SceneMeshLevelOfDetail.Medium;
            }));

            inputActions.Add(InputAction.Create("Mesh Fine", KeyCode.None, "High quality mesh", () =>
            {
                SuManager.MeshQuality = SceneUnderstanding.SceneMeshLevelOfDetail.Fine;
            }));

            inputActions.Add(InputAction.Create("Mesh Unlimited", KeyCode.None, "Unlimited quality mesh", () =>
            {
                SuManager.MeshQuality = SceneUnderstanding.SceneMeshLevelOfDetail.Unlimited;
            }));

            inputActions.Add(InputAction.Create("Toggle MiniMap", KeyCode.M, "Show or hide the mini map", MiniMapToggle));

            inputActions.Add(InputAction.Create("Toggle Ghost Mode", KeyCode.O, "Enable / Disable Ghost Mode (Scene Objects will be invisible but still occlude)", async () =>
            {
                SuManager.IsInGhostMode = !SuManager.IsInGhostMode;
                await SuManager.DisplayDataAsync();
            }));

            // Last batch of device-only commands
            if (suManager.QuerySceneFromDevice)
            {
                inputActions.Add(InputAction.Create("Increase Radius", KeyCode.None, "Increase the range used to query the environment", () =>
                {
                    float fTempFloat = SuManager.BoundingSphereRadiusInMeters + 5.0f;
                    fTempFloat = Mathf.Clamp(fTempFloat, 5.0f, 100.0f);
                    SuManager.BoundingSphereRadiusInMeters = fTempFloat;
                }));

                inputActions.Add(InputAction.Create("Decrease Radius", KeyCode.None, "Decrease the range used to query the environment", () =>
                {
                    float fTempFloat = SuManager.BoundingSphereRadiusInMeters - 5.0f;
                    fTempFloat = Mathf.Clamp(fTempFloat, 5.0f, 100.0f);
                    SuManager.BoundingSphereRadiusInMeters = fTempFloat;
                }));

            }

            inputActions.Add(InputAction.Create("Save Data", KeyCode.L, "Saves the current scene to storage", SaveData));

            inputActions.Add(InputAction.Create("Toggle Help", KeyCode.H, "Shows or hides the help menu", menu.Toggle));
        }

ここでは実行中に[SampleInputManager]コンポーネントのイベントである[inputAction]にデフォルトのイベントを追加しています。

f:id:Holomoto-Sumire:20201227195640j:plain

〇ToggleSceneObject

[1]キーを入力することで発火するイベントです。

 inputActions.Add(InputAction.Create("Toggle Scene Objects", KeyCode.Alpha1, "Show / hide processed scene objects", async () =>
            {
                SuManager.RenderSceneObjects = !SuManager.RenderSceneObjects;
                await SuManager.DisplayDataAsync();
            }));

ここではSuManager.RenderSceneObjectsのオンオフを切り替えています。

SuManagerとはSceneUnderstandingManagerコンポーネントに当たります。このRenderSceneObjectsのTrue・Falseを切り替えます。

        [Header("Render Filters")]
        [Tooltip("Toggles display of all scene objects, except for the world mesh.")]
        public bool RenderSceneObjects = true;

これによりSceneUnderstandingManagerコンポーネントの533行目当たりの処理が実行されます。

          // If requested, scene objects can be excluded from the generation, the World Mesh is considered
            // a separate object hence is not affected by this filter
            if (RenderSceneObjects == false && suObject.Kind != SceneUnderstanding.SceneObjectKind.World)
            {
                return false;
            }

ここはオブジェクトを作成する際に走るメソッドで、RenderSceneObjectsがfalseの場合SceneUnderstanding.SceneObject suObjectがfalseが返されます。

これによってメッシュが非表示になります。

〇Toggle Labels

[P]キーを入力することで壁や床、天井のラベル表示を切り替えます。

f:id:Holomoto-Sumire:20201226225803j:plainf:id:Holomoto-Sumire:20201226231058j:plain

            inputActions.Add(InputAction.Create("Toggle Labels", KeyCode.P, "Enable / Disable labels for scene objects", async () =>
            {
                labeler.DisplayTextLabels = !labeler.DisplayTextLabels;
                await SuManager.DisplayDataAsync();
            }));

ToggleSceneObject同様label.DysplayTextLabelsのオンオフが切り替えられています。

長くなってしまったので続きは次回行います。