Example #1
0
        void OnProxyActiveChanged(IProxy proxy)
        {
            proxy.hidden = !proxy.active;

            if (proxy.active)
            {
                var deviceData = m_ToolModule.deviceData;
                if (!deviceData.Any(dd => dd.proxy == proxy))
                {
                    var moduleLoaderCore = ModuleLoaderCore.instance;
                    var keyboardModule   = moduleLoaderCore.GetModule <KeyboardModule>();
                    var highlightModule  = moduleLoaderCore.GetModule <HighlightModule>();
                    foreach (var rayOriginPair in proxy.rayOrigins)
                    {
                        var node      = rayOriginPair.Key;
                        var rayOrigin = rayOriginPair.Value;

                        var systemDevices = m_DeviceInputModule.GetSystemDevices();
                        for (int j = 0; j < systemDevices.Count; j++)
                        {
                            var device = systemDevices[j];

                            // Find device tagged with the node that matches this RayOrigin node
                            var deviceNode = m_DeviceInputModule.GetDeviceNode(device);
                            if (deviceNode == node)
                            {
                                var newDeviceData = new DeviceData();
                                deviceData.Add(newDeviceData);
                                newDeviceData.proxy       = proxy;
                                newDeviceData.node        = node;
                                newDeviceData.rayOrigin   = rayOrigin;
                                newDeviceData.inputDevice = device;

                                if (!this.HasProvider <IProvidesAddRaycastSource>())
                                {
                                    continue;
                                }

                                // Add RayOrigin transform, proxy and ActionMapInput references to input module list of sources
                                this.AddRaycastSource(proxy, node, rayOrigin, source =>
                                {
                                    // Do not invalidate UI raycasts in the middle of a drag operation
                                    var eventData = source.eventData;
                                    if (!eventData.pointerDrag)
                                    {
                                        var sourceRayOrigin = source.rayOrigin;
                                        if (m_DirectSelectionModule != null && m_DirectSelectionModule.IsHovering(sourceRayOrigin))
                                        {
                                            return(false);
                                        }

                                        var currentRaycast = eventData.pointerCurrentRaycast;
                                        var hoveredObject  = currentRaycast.gameObject;

                                        // The manipulator needs rays to go through scene objects in order to work
                                        var isManipulator = hoveredObject && hoveredObject.GetComponentInParent <IManipulator>() != null;
                                        float sceneObjectDistance;
                                        var raycastObject = m_IntersectionModule.GetFirstGameObject(sourceRayOrigin, out sceneObjectDistance);
                                        var uiDistance    = currentRaycast.distance;

                                        // If the distance to a scene object is less than the distance to the hovered UI, invalidate the UI raycast
                                        if (!isManipulator && raycastObject && sceneObjectDistance < uiDistance && !ignoreList.Contains(raycastObject))
                                        {
                                            return(false);
                                        }
                                    }

                                    if (m_MenuModule != null && !m_MenuModule.IsValidHover(source))
                                    {
                                        return(false);
                                    }

                                    // Proceed only for raycast sources that haven't been blocked via IBlockUIInteraction
                                    if (source.blocked)
                                    {
                                        return(false);
                                    }

                                    return(true);
                                });
                            }
                        }

                        rayOrigin.name = string.Format("{0} Ray Origin", node);
                        var rayTransform = EditorXRUtils.Instantiate(m_ProxyRayPrefab.gameObject, rayOrigin, false).transform;
                        rayTransform.position = rayOrigin.position;
                        rayTransform.rotation = rayOrigin.rotation;
                        var dpr = rayTransform.GetComponent <DefaultProxyRay>();
                        this.InjectFunctionalitySingle(dpr);
                        m_DefaultRays.Add(rayOrigin, dpr);
                        if (highlightModule != null)
                        {
                            dpr.SetColor(highlightModule.highlightColor);
                            highlightModule.AddRayOriginForNode(node, rayOrigin);
                        }

                        if (keyboardModule != null)
                        {
                            keyboardModule.SpawnKeyboardMallet(rayOrigin);
                        }

                        var proxyExtras = m_ProxyExtras;
                        if (proxyExtras)
                        {
                            var extraData = proxyExtras.data;
                            List <GameObject> prefabs;
                            if (extraData.TryGetValue(rayOriginPair.Key, out prefabs))
                            {
                                foreach (var prefab in prefabs)
                                {
                                    var go = this.InstantiateUI(prefab);
                                    go.transform.SetParent(rayOriginPair.Value, false);
                                }
                            }
                        }

                        var tester = rayOriginPair.Value.GetComponentInChildren <IntersectionTester>();
                        tester.active = proxy.active;
                        m_IntersectionModule.AddTester(tester);

                        if (m_WorkspaceModule != null)
                        {
                            switch (node)
                            {
                            case Node.LeftHand:
                                m_WorkspaceModule.leftRayOrigin = rayOrigin;
                                break;

                            case Node.RightHand:
                                m_WorkspaceModule.rightRayOrigin = rayOrigin;
                                break;
                            }
                        }
                    }

                    if (m_ToolModule != null)
                    {
                        m_ToolModule.SpawnDefaultTools(proxy);
                    }

                    if (m_SerializedPreferences != null)
                    {
                        m_SerializedPreferences.DeserializePreferences();
                    }

                    if (m_WorkspaceModule != null)
                    {
                        m_WorkspaceModule.CreateSerializedWorkspaces();
                    }
                }
            }
        }
Example #2
0
        void DespawnTool(DeviceData device, ITool tool)
        {
            var toolType = tool.GetType();

            if (!IsDefaultTool(toolType))
            {
                // Remove the tool if it is the current tool on this device tool stack
                if (device.currentTool == tool)
                {
                    var topTool = device.toolData.Peek();
                    if (topTool == null || topTool.tool != device.currentTool)
                    {
                        Debug.LogError("Tool at top of stack is not current tool.");
                        return;
                    }

                    if (device.customMenu != null)
                    {
                        device.menuHideData.Remove(device.customMenu);
                        device.customMenu = null;
                    }

                    var oldTool = device.toolData.Pop();
                    oldTool.input.active = false;
                    topTool            = device.toolData.Peek();
                    device.currentTool = topTool.tool;

                    // Pop this tool off any other stack that references it (for single instance tools)
                    foreach (var otherDeviceData in deviceData)
                    {
                        if (otherDeviceData != device)
                        {
                            // Pop this tool off any other stack that references it (for single instance, multi-device tools)
                            var otherTool = otherDeviceData.currentTool;
                            if (otherTool == tool)
                            {
                                oldTool = otherDeviceData.toolData.Pop();
                                oldTool.input.active = false;
                                var otherToolData = otherDeviceData.toolData.Peek();
                                if (otherToolData != null)
                                {
                                    otherDeviceData.currentTool = otherToolData.tool;
                                }

                                if (tool is IExclusiveMode)
                                {
                                    SetToolsEnabled(otherDeviceData, true);
                                }
                            }

                            // Pop this tool of any other stack that references it (for IMultiDeviceTools)
                            if (tool is IMultiDeviceTool)
                            {
                                otherDeviceData.toolsMenu.deleteToolsMenuButton(toolType, typeof(SelectionTool));

                                if (otherTool.GetType() == toolType)
                                {
                                    oldTool = otherDeviceData.toolData.Pop();
                                    oldTool.input.active = false;
                                    var otherToolData = otherDeviceData.toolData.Peek();
                                    if (otherToolData != null)
                                    {
                                        otherDeviceData.currentTool = otherToolData.tool;
                                        this.DisconnectInterfaces(otherTool, otherDeviceData.rayOrigin);
                                        UnityObjectUtils.Destroy((MonoBehaviour)otherTool);
                                    }
                                }
                            }

                            // If the tool had a custom menu, the custom menu would spawn on the opposite device
                            var customMenu = otherDeviceData.customMenu;
                            if (customMenu != null)
                            {
                                otherDeviceData.menuHideData.Remove(customMenu);
                                otherDeviceData.customMenu = null;
                            }
                        }
                    }
                }

                this.DisconnectInterfaces(tool, device.rayOrigin);

                // Exclusive tools disable other tools underneath, so restore those
                if (tool is IExclusiveMode)
                {
                    SetToolsEnabled(device, true);
                }

                UnityObjectUtils.Destroy((MonoBehaviour)tool);
            }
        }
Example #3
0
        internal bool IsValidHover(IRaycastSource source)
        {
            var eventData      = source.eventData;
            var currentRaycast = eventData.pointerCurrentRaycast;
            var go             = eventData.pointerDrag;

            if (!go)
            {
                go = currentRaycast.gameObject;
            }

            if (!go)
            {
                return(true);
            }

            if (go == gameObject)
            {
                return(true);
            }

            var        rayOrigin  = eventData.rayOrigin;
            DeviceData deviceData = null;

            foreach (var currentDevice in m_ToolModule.deviceData)
            {
                if (currentDevice.rayOrigin == rayOrigin)
                {
                    deviceData = currentDevice;
                    break;
                }
            }

            if (deviceData != null)
            {
                if (go.transform.IsChildOf(deviceData.rayOrigin)) // Don't let UI on this hand block the menu
                {
                    return(false);
                }

                var   scaledPointerDistance = currentRaycast.distance / this.GetViewerScale();
                var   menuHideFlags         = deviceData.menuHideData;
                var   mainMenu = deviceData.mainMenu;
                IMenu openMenu = mainMenu;
                if (deviceData.customMenu != null && menuHideFlags[mainMenu].hideFlags != 0)
                {
                    openMenu = deviceData.customMenu;
                }

                if (openMenu == null)
                {
                    return(false);
                }

                if (scaledPointerDistance < openMenu.localBounds.size.y + k_MenuHideMargin)
                {
                    // Only set if hidden--value is reset every frame
                    menuHideFlags[openMenu].hideFlags |= MenuHideFlags.OverUI;
                    return(true);
                }

                return(menuHideFlags[openMenu].hideFlags != 0);
            }

            return(true);
        }