示例#1
0
        void CheckDirectSelection(DeviceData deviceData, Dictionary <IMenu, MenuHideData> menuHideData, bool alternateMenuVisible)
        {
            if (m_DirectSelectionModule == null)
            {
                return;
            }

            var viewerScale       = this.GetViewerScale();
            var rayOrigin         = deviceData.rayOrigin;
            var rayOriginPosition = rayOrigin.position;
            var heldObjects       = m_DirectSelectionModule.GetHeldObjects(rayOrigin);

            // If this hand is holding any objects, hide its menus
            var hasDirectSelection = heldObjects != null && heldObjects.Count > 0;

            if (hasDirectSelection)
            {
                foreach (var kvp in menuHideData)
                {
                    // Only set if hidden--value is reset every frame
                    kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection;
                }

                foreach (var otherDeviceData in k_ActiveDeviceData)
                {
                    if (otherDeviceData == deviceData)
                    {
                        continue;
                    }

                    var otherRayOrigin = otherDeviceData.rayOrigin;
                    if (alternateMenuVisible)
                    {
                        SetAlternateMenuVisibility(otherRayOrigin, true);
                    }

                    // If other hand is within range to do a two-handed scale, hide its menu as well
                    if (m_DirectSelectionModule.IsHovering(otherRayOrigin) || m_DirectSelectionModule.IsScaling(otherRayOrigin) ||
                        Vector3.Distance(otherRayOrigin.position, rayOriginPosition) < k_TwoHandHideDistance * viewerScale)
                    {
                        foreach (var kvp in otherDeviceData.menuHideData)
                        {
                            // Only set if hidden--value is reset every frame
                            kvp.Value.hideFlags |= MenuHideFlags.HasDirectSelection;
                        }

                        break;
                    }
                }
            }
        }
示例#2
0
        internal void UpdateMiniWorlds()
        {
            if (m_MiniWorldIgnoreListDirty)
            {
                UpdateMiniWorldIgnoreList();
                m_MiniWorldIgnoreListDirty = false;
            }

            // Update MiniWorldRays
            foreach (var ray in m_Rays)
            {
                var miniWorldRayOrigin = ray.Key;
                var miniWorldRay       = ray.Value;

                if (!miniWorldRay.proxy.active)
                {
                    miniWorldRay.tester.active = false;
                    continue;
                }

                var miniWorld    = miniWorldRay.miniWorld;
                var inverseScale = miniWorld.miniWorldTransform.lossyScale.Inverse();

                if (float.IsInfinity(inverseScale.x) || float.IsNaN(inverseScale.x)) // Extreme scales cause transform errors
                {
                    continue;
                }

                // Transform into reference space
                var originalRayOrigin  = miniWorldRay.originalRayOrigin;
                var referenceTransform = miniWorld.referenceTransform;
                var miniWorldTransform = miniWorld.miniWorldTransform;
                var position           = originalRayOrigin.position;
                miniWorldRayOrigin.position   = referenceTransform.TransformPoint(miniWorldTransform.InverseTransformPoint(position));
                miniWorldRayOrigin.rotation   = referenceTransform.rotation * Quaternion.Inverse(miniWorldTransform.rotation) * originalRayOrigin.rotation;
                miniWorldRayOrigin.localScale = Vector3.Scale(inverseScale, referenceTransform.localScale);

                // Set miniWorldRayOrigin active state based on whether controller is inside corresponding MiniWorld
                var originalPointerPosition = position + originalRayOrigin.forward * m_DirectSelectionModule.GetPointerLength(originalRayOrigin);
                var isContained             = miniWorld.Contains(originalPointerPosition);
                miniWorldRay.tester.active = isContained;
                miniWorldRayOrigin.gameObject.SetActive(isContained);

                var miniWorldRayObjects = m_DirectSelectionModule.GetHeldObjects(miniWorldRayOrigin);
                var originalRayObjects  = m_DirectSelectionModule.GetHeldObjects(originalRayOrigin);

                var hasPreview = miniWorldRay.hasPreview;
                if (miniWorldRayObjects == null && originalRayObjects == null && !hasPreview)
                {
                    miniWorldRay.isContained = isContained;
                    continue;
                }

                var wasContained       = miniWorldRay.isContained;
                var dragStartedOutside = miniWorldRay.dragStartedOutside;
                if (isContained != wasContained)
                {
                    // Early out if we grabbed a real-world object that started inside a mini world
                    if (!isContained && miniWorldRayObjects == null)
                    {
                        miniWorldRay.isContained = false;
                        continue;
                    }

                    // Transfer objects to and from original ray and MiniWorld ray (e.g. outside to inside mini world)
                    var from = isContained ? originalRayOrigin : miniWorldRayOrigin;
                    var to   = isContained ? miniWorldRayOrigin : originalRayOrigin;

                    KeyValuePair <Transform, MiniWorldRay>?overlapPair = null;
                    MiniWorldRay incomingPreview = null;

                    // Try to transfer objects between MiniWorlds
                    if (miniWorldRayObjects != null && !isContained)
                    {
                        foreach (var kvp in m_Rays)
                        {
                            var otherRayOrigin = kvp.Key;
                            var otherRay       = kvp.Value;
                            if (originalRayOrigin == otherRay.originalRayOrigin && otherRay != miniWorldRay && otherRay.isContained)
                            {
                                overlapPair = kvp;
                                from        = miniWorldRayOrigin;
                                to          = otherRayOrigin;
                                break;
                            }
                        }
                    }

                    if (originalRayObjects != null && isContained && !dragStartedOutside)
                    {
                        //Check for other miniworlds' previews entering this ray's miniworld
                        foreach (var kvp in m_Rays)
                        {
                            var otherRay = kvp.Value;
                            if (originalRayOrigin == otherRay.originalRayOrigin && otherRay != miniWorldRay && otherRay.hasObjects)
                            {
                                incomingPreview = otherRay;
                                from            = originalRayOrigin;
                                to = miniWorldRayOrigin;
                                break;
                            }
                        }
                    }

                    var pointerLengthDiff = m_DirectSelectionModule.GetPointerLength(to) - m_DirectSelectionModule.GetPointerLength(from);
                    m_DirectSelectionModule.TransferHeldObjects(from, to, Vector3.forward * pointerLengthDiff);

                    if (overlapPair.HasValue)
                    {
                        var kvp = overlapPair.Value;
                        miniWorldRay.TransferObjects(kvp.Value, kvp.Key);
                    }

                    if (incomingPreview != null)
                    {
                        incomingPreview.ExitPreviewMode(this);
                        incomingPreview.TransferObjects(miniWorldRay);
                        m_DirectSelectionModule.ResumeGrabbers(incomingPreview.node);
                    }

                    if (!isContained)
                    {
                        m_RayWasContained[originalRayOrigin] = false; //Prevent ray from showing
                    }
                }

                if (dragStartedOutside)
                {
                    miniWorldRay.isContained = isContained;
                    continue;
                }

                var node = miniWorldRay.node;

                if (miniWorldRayObjects != null && !isContained && wasContained)
                {
                    var containedInOtherMiniWorld = false;
                    foreach (var world in m_Worlds)
                    {
                        if (miniWorld != world && world.Contains(originalPointerPosition))
                        {
                            containedInOtherMiniWorld = true;
                        }
                    }

                    // Transfer objects from miniworld to preview state
                    // Don't switch to previewing the objects we are dragging if we are still in another mini world
                    if (!containedInOtherMiniWorld)
                    {
                        // Check for player head
                        var playerHead = false;
                        foreach (var obj in miniWorldRayObjects)
                        {
                            if (obj.CompareTag(EditorXR.VRPlayerTag))
                            {
                                playerHead = true;
                                m_DirectSelectionModule.DropHeldObjects(node);
                                break;
                            }
                        }

                        if (!playerHead)
                        {
                            var scaleFactor = this.GetViewerScale() / miniWorld.referenceTransform.localScale.x;
                            miniWorldRay.EnterPreviewMode(this, scaleFactor);
                            m_DirectSelectionModule.SuspendGrabbers(node);
                        }
                    }
                }

                if (hasPreview)
                {
                    // Check if we have just entered another miniworld
                    var enterOther = false;
                    foreach (var kvp in m_Rays)
                    {
                        var otherRay       = kvp.Value;
                        var otherMiniWorld = otherRay.miniWorld;
                        if (otherMiniWorld != miniWorld && otherRay.node == node && otherMiniWorld.Contains(originalPointerPosition))
                        {
                            miniWorldRay.ExitPreviewMode(this);
                            m_DirectSelectionModule.ResumeGrabbers(node);
                            enterOther = true;
                            break;
                        }
                    }

                    if (!enterOther)
                    {
                        if (!isContained)
                        {
                            miniWorldRay.UpdatePreview();
                        }
                        else if (!wasContained)
                        {
                            miniWorldRay.ExitPreviewMode(this);
                            m_DirectSelectionModule.ResumeGrabbers(node);
                        }
                    }
                }

                miniWorldRay.isContained = isContained;
            }

            // Update ray visibilities
            foreach (var deviceData in m_ToolModule.deviceData)
            {
                var proxy = deviceData.proxy;
                if (!proxy.active)
                {
                    continue;
                }

                UpdateRayContainment(deviceData);
            }
        }