Ejemplo n.º 1
0
        void CheckMenuColliderOverlaps(IMenu menu, MenuHideData menuHideData)
        {
            var menuBounds = menu.localBounds;

            if (menuBounds.extents == Vector3.zero)
            {
                return;
            }

            Array.Clear(k_ColliderOverlaps, 0, k_ColliderOverlaps.Length);
            var hoveringCollider = false;
            var menuTransform    = menu.menuContent.transform;
            var menuRotation     = menuTransform.rotation;
            var viewerScale      = this.GetViewerScale();
            var center           = menuTransform.position + menuRotation * menuBounds.center * viewerScale;

            if (Physics.OverlapBoxNonAlloc(center, menuBounds.extents * viewerScale, k_ColliderOverlaps, menuRotation) > 0)
            {
                foreach (var overlap in k_ColliderOverlaps)
                {
                    if (overlap)
                    {
                        k_WorkspaceComponents.Clear();
                        overlap.GetComponents(k_WorkspaceComponents);
                        if (k_WorkspaceComponents.Count > 0)
                        {
                            hoveringCollider = true;
                        }

                        if (menu is MainMenu)
                        {
                            k_ButtonComponents.Clear();
                            overlap.GetComponents(k_ButtonComponents);
                            if (k_ButtonComponents.Count > 0)
                            {
                                hoveringCollider = true;
                            }
                        }
                    }
                }
            }

            // Only set if hidden--value is reset every frame
            if (hoveringCollider)
            {
                menuHideData.hideFlags |= MenuHideFlags.OverWorkspace;
            }
        }
Ejemplo n.º 2
0
        void AddAlternateMenu(IAlternateMenu alternateMenu, Transform rayOrigin)
        {
            if (m_ToolModule == null)
            {
                return;
            }

            foreach (var device in m_ToolModule.deviceData)
            {
                if (device.rayOrigin != rayOrigin)
                {
                    continue;
                }

                device.alternateMenus.Add(alternateMenu);
                var menuHideData = new MenuHideData();
                device.menuHideData[alternateMenu] = menuHideData;

                // Alternate menus must be visible the first frame or they are ignored in the priority list
                menuHideData.hideFlags = 0;

                break;
            }
        }
Ejemplo n.º 3
0
        internal void SpawnDefaultTools(IProxy proxy)
        {
            var defaultTools = EditorXR.DefaultTools;

            if (defaultTools == null)
            {
                return;
            }

            var moduleLoaderCore  = ModuleLoaderCore.instance;
            var menuModule        = moduleLoaderCore.GetModule <EditorXRMenuModule>();
            var lockModule        = moduleLoaderCore.GetModule <LockModule>();
            var deviceInputModule = moduleLoaderCore.GetModule <DeviceInputModule>();
            var vacuumablesModule = moduleLoaderCore.GetModule <EditorXRVacuumableModule>();
            var vacuumables       = vacuumablesModule != null ? vacuumablesModule.vacuumables : new List <IVacuumable>();

            foreach (var device in deviceData)
            {
                var      inputDevice       = device.inputDevice;
                ToolData selectionToolData = null;

                if (device.proxy != proxy)
                {
                    continue;
                }

                var rayOrigin = device.rayOrigin;
                foreach (var toolType in defaultTools)
                {
                    HashSet <InputDevice> devices;
                    var toolData = SpawnTool(toolType, out devices, inputDevice, rayOrigin, deviceInputModule);
                    AddToolToDeviceData(toolData, devices);

                    var tool          = toolData.tool;
                    var selectionTool = tool as SelectionTool;
                    if (selectionTool)
                    {
                        selectionToolData = toolData;
                        if (lockModule != null)
                        {
                            selectionTool.hovered += lockModule.OnHovered;
                        }
                    }

                    var vacuumTool = tool as VacuumTool;
                    if (vacuumTool)
                    {
                        vacuumTool.defaultOffset = WorkspaceModule.DefaultWorkspaceOffset;
                        vacuumTool.defaultTilt   = WorkspaceModule.DefaultWorkspaceTilt;
                        vacuumTool.vacuumables   = vacuumables;
                    }
                }

                IMainMenu mainMenu;
                var       menuHideData = device.menuHideData;
                if (EditorXR.DefaultMenu != null)
                {
                    mainMenu               = (IMainMenu)menuModule.SpawnMenu(EditorXR.DefaultMenu, rayOrigin);
                    device.mainMenu        = mainMenu;
                    menuHideData[mainMenu] = new MenuHideData();
                }

                if (EditorXR.DefaultAlternateMenu != null)
                {
                    var alternateMenu = (IAlternateMenu)menuModule.SpawnMenu(EditorXR.DefaultAlternateMenu, rayOrigin);
                    menuHideData[alternateMenu] = new MenuHideData();
                    var radialMenu = alternateMenu as RadialMenu;
                    if (radialMenu)
                    {
                        radialMenu.itemWasSelected += menuModule.UpdateAlternateMenuOnSelectionChanged;
                    }
                }

                var undoMenu = menuModule.SpawnMenu <UndoMenu>(rayOrigin);
                var hideData = new MenuHideData();
                menuHideData[undoMenu] = hideData;
                hideData.hideFlags     = 0;

                // Setup ToolsMenu
                ToolsMenu toolsMenu  = null;
                var       toolsMenus = gameObject.GetComponents <ToolsMenu>();
                foreach (var m in toolsMenus)
                {
                    if (!m.enabled)
                    {
                        toolsMenu = m;
                        break;
                    }
                }

                if (!toolsMenu)
                {
                    toolsMenu = EditorXRUtils.AddComponent <ToolsMenu>(gameObject);
                }

                toolsMenu.enabled = true;
                this.ConnectInterfaces(toolsMenu, rayOrigin);
                this.InjectFunctionalitySingle(toolsMenu);
                device.toolsMenu    = toolsMenu;
                toolsMenu.rayOrigin = rayOrigin;
                toolsMenu.setButtonForType(typeof(IMainMenu), null);
                toolsMenu.setButtonForType(typeof(SelectionTool), selectionToolData != null ? selectionToolData.icon : null);

                var spatialMenu = EditorXRUtils.AddComponent <SpatialMenu>(gameObject);
                this.ConnectInterfaces(spatialMenu, rayOrigin);
                this.InjectFunctionalitySingle(spatialMenu);
                spatialMenu.Setup();
                device.spatialMenu = spatialMenu;
            }

            if (deviceInputModule != null)
            {
                deviceInputModule.UpdatePlayerHandleMaps();
            }
        }
Ejemplo n.º 4
0
        internal void UpdateMenuVisibilities()
        {
            k_ActiveDeviceData.Clear();
            m_RayModule.ForEachProxyDevice(deviceData => { k_ActiveDeviceData.Add(deviceData); });

            foreach (var deviceData in k_ActiveDeviceData)
            {
                IAlternateMenu alternateMenu = null;
                var            menuHideData  = deviceData.menuHideData;

                // Always display the highest-priority alternate menu, and hide all others.
                var alternateMenus = deviceData.alternateMenus;
                foreach (var menu in alternateMenus)
                {
                    var hideData = menuHideData[menu];
                    if ((hideData.hideFlags & MenuHideFlags.Hidden) == 0 &&
                        (alternateMenu == null || menu.priority >= alternateMenu.priority))
                    {
                        alternateMenu = menu;
                    }

                    hideData.hideFlags |= MenuHideFlags.OtherMenu;
                }

                deviceData.alternateMenu = alternateMenu;
                menuHideData[alternateMenu].hideFlags = 0;
                var          mainMenu           = deviceData.mainMenu;
                var          customMenu         = deviceData.customMenu;
                MenuHideData customMenuHideData = null;

                var mainMenuVisible    = mainMenu != null && menuHideData[mainMenu].hideFlags == 0;
                var mainMenuSuppressed = mainMenu != null && ((menuHideData[mainMenu].hideFlags & MenuHideFlags.Occluded) != 0);

                var alternateMenuData    = menuHideData[alternateMenu];
                var alternateMenuVisible = alternateMenuData.hideFlags == 0;

                var customMenuVisible = false;
                if (customMenu != null)
                {
                    customMenuHideData = menuHideData[customMenu];
                    customMenuVisible  = customMenuHideData.hideFlags == 0;
                }

                // Temporarily hide customMenu if other menus are visible or should be
                if (customMenuVisible && (mainMenuVisible || mainMenuSuppressed))
                {
                    customMenuHideData.hideFlags |= MenuHideFlags.OtherMenu;
                }

                // Kick the alternate menu to the other hand if a main menu or custom menu is visible
                if (alternateMenuVisible && (mainMenuVisible || customMenuVisible) && alternateMenu is RadialMenu)
                {
                    foreach (var otherDeviceData in k_ActiveDeviceData)
                    {
                        if (otherDeviceData == deviceData)
                        {
                            continue;
                        }

                        SetAlternateMenuVisibility(otherDeviceData.rayOrigin, true);
                        break;
                    }
                }

                // Check if menu bounds overlap with any workspace colliders
                foreach (var kvp in menuHideData)
                {
                    CheckMenuColliderOverlaps(kvp.Key, kvp.Value);
                }

                // Check if there are currently any held objects, or if the other hand is in proximity for scaling
                CheckDirectSelection(deviceData, menuHideData, alternateMenuVisible);
            }

            // Set show/hide timings
            foreach (var deviceData in k_ActiveDeviceData)
            {
                foreach (var kvp in deviceData.menuHideData)
                {
                    var hideFlags = kvp.Value.hideFlags;
                    if ((hideFlags & ~MenuHideFlags.Hidden & ~MenuHideFlags.OtherMenu) == 0)
                    {
                        kvp.Value.autoHideTime = Time.time;
                    }

                    if (hideFlags != 0)
                    {
                        var menuHideData = kvp.Value;
                        menuHideData.lastHideFlags = menuHideData.hideFlags;
                        kvp.Value.autoShowTime     = Time.time;
                    }
                }
            }

            // Apply MenuHideFlags to UI visibility
            foreach (var deviceData in k_ActiveDeviceData)
            {
                var mainMenu = deviceData.mainMenu;
                if (mainMenu != null)
                {
                    var mainMenuHideData      = deviceData.menuHideData[mainMenu];
                    var mainMenuHideFlags     = mainMenuHideData.hideFlags;
                    var lastMainMenuHideFlags = mainMenuHideData.lastHideFlags;

                    var permanentlyHidden    = (mainMenuHideFlags & MenuHideFlags.Hidden) != 0;
                    var wasPermanentlyHidden = (lastMainMenuHideFlags & MenuHideFlags.Hidden) != 0;

                    //Temporary states take effect after a delay
                    var temporarilyHidden = (mainMenuHideFlags & MenuHideFlags.Temporary) != 0 &&
                                            Time.time > mainMenuHideData.autoHideTime + k_MainMenuAutoHideDelay;
                    var wasTemporarilyHidden = (lastMainMenuHideFlags & MenuHideFlags.Temporary) != 0 &&
                                               Time.time > mainMenuHideData.autoShowTime + k_MainMenuAutoShowDelay;

                    // If the menu is focused, only hide if Hidden is set (e.g. not temporary) in order to hide the selected tool
                    if (permanentlyHidden || wasPermanentlyHidden || !mainMenu.focus && (temporarilyHidden || wasTemporarilyHidden))
                    {
                        mainMenu.menuHideFlags = mainMenuHideFlags;
                    }

                    // Disable the main menu activator if any temporary states are set
                    deviceData.toolsMenu.mainMenuActivatorInteractable = (mainMenuHideFlags & MenuHideFlags.Temporary) == 0 &&
                                                                         mainMenu.menuContent;
                }

                // Show/hide custom menu, if it exists
                var customMenu = deviceData.customMenu;
                if (customMenu != null)
                {
                    customMenu.menuHideFlags = deviceData.menuHideData[customMenu].hideFlags;
                }

                var alternateMenus = deviceData.alternateMenus;
                foreach (var menu in alternateMenus)
                {
                    menu.menuHideFlags = deviceData.menuHideData[menu].hideFlags;
                }

                UpdateAlternateMenuForDevice(deviceData);
                m_RayModule.UpdateRayForDevice(deviceData, deviceData.rayOrigin);
            }

            foreach (var deviceData in k_ActiveDeviceData)
            {
                foreach (var kvp in deviceData.menuHideData)
                {
                    kvp.Value.hideFlags &= ~MenuHideFlags.Temporary;
                }
            }

            m_DeviceInputModule.UpdatePlayerHandleMaps();
        }