Beispiel #1
0
            static bool Overlaps(Transform rayOrigin, Collider trigger)
            {
                var radius = DirectSelection.GetPointerLength(rayOrigin);

                var colliders = Physics.OverlapSphere(rayOrigin.position, radius, -1, QueryTriggerInteraction.Collide);

                foreach (var collider in colliders)
                {
                    if (collider == trigger)
                    {
                        return(true);
                    }
                }

                return(false);
            }
Beispiel #2
0
            static bool Overlaps(Transform rayOrigin, Collider trigger)
            {
                var radius = DirectSelection.GetPointerLength(rayOrigin);

                var totalColliders = Physics.OverlapSphereNonAlloc(rayOrigin.position, radius, s_CachedColliders, -1, QueryTriggerInteraction.Collide);

                for (var colliderIndex = 0; colliderIndex < totalColliders; colliderIndex++)
                {
                    if (s_CachedColliders[colliderIndex] == trigger)
                    {
                        return(true);
                    }
                }

                return(false);
            }
Beispiel #3
0
        void Awake()
        {
            Nested.evr = this;             // Set this once for the convenience of all nested classes

            ClearDeveloperConsoleIfNecessary();

            m_DirectSelection = new DirectSelection();
            m_Interfaces      = new Interfaces();
            m_Menus           = new Menus();
            m_MiniWorlds      = new MiniWorlds();
            m_Rays            = new Rays();
            m_Tools           = new Tools();
            m_UI          = new UI();
            m_Viewer      = new Viewer();
            m_Vacuumables = new Vacuumables();

            m_HierarchyModule     = AddModule <HierarchyModule>();
            m_ProjectFolderModule = AddModule <ProjectFolderModule>();

            VRView.cameraRig.parent    = transform;          // Parent the camera rig under EditorVR
            VRView.cameraRig.hideFlags = defaultHideFlags;
            if (VRSettings.loadedDeviceName == "OpenVR")
            {
                // Steam's reference position should be at the feet and not at the head as we do with Oculus
                VRView.cameraRig.localPosition = Vector3.zero;
            }

            var hmdOnlyLayerMask = 0;

            if (m_PreviewCameraPrefab)
            {
                var go = ObjectUtils.Instantiate(m_PreviewCameraPrefab);
                m_CustomPreviewCamera = go.GetComponentInChildren <IPreviewCamera>();
                if (m_CustomPreviewCamera != null)
                {
                    VRView.customPreviewCamera     = m_CustomPreviewCamera.previewCamera;
                    m_CustomPreviewCamera.vrCamera = VRView.viewerCamera;
                    hmdOnlyLayerMask = m_CustomPreviewCamera.hmdOnlyLayerMask;
                    m_Interfaces.ConnectInterfaces(m_CustomPreviewCamera);
                }
            }
            VRView.cullingMask = UnityEditor.Tools.visibleLayers | hmdOnlyLayerMask;

            m_DeviceInputModule = AddModule <DeviceInputModule>();
            m_DeviceInputModule.InitializePlayerHandle();
            m_DeviceInputModule.CreateDefaultActionMapInputs();
            m_DeviceInputModule.processInput           = ProcessInput;
            m_DeviceInputModule.updatePlayerHandleMaps = m_Tools.UpdatePlayerHandleMaps;

            m_UI.Initialize();

            m_KeyboardModule = AddModule <KeyboardModule>();

            m_DragAndDropModule        = AddModule <DragAndDropModule>();
            m_InputModule.rayEntered  += m_DragAndDropModule.OnRayEntered;
            m_InputModule.rayExited   += m_DragAndDropModule.OnRayExited;
            m_InputModule.dragStarted += m_DragAndDropModule.OnDragStarted;
            m_InputModule.dragEnded   += m_DragAndDropModule.OnDragEnded;

            m_TooltipModule = AddModule <TooltipModule>();
            m_Interfaces.ConnectInterfaces(m_TooltipModule);
            m_InputModule.rayEntered += m_TooltipModule.OnRayEntered;
            m_InputModule.rayExited  += m_TooltipModule.OnRayExited;

            m_PixelRaycastModule               = AddModule <PixelRaycastModule>();
            m_PixelRaycastModule.ignoreRoot    = transform;
            m_PixelRaycastModule.raycastCamera = m_UI.eventCamera;

            m_HighlightModule = AddModule <HighlightModule>();
            m_ActionsModule   = AddModule <ActionsModule>();

            m_LockModule = AddModule <LockModule>();
            m_LockModule.updateAlternateMenu = (rayOrigin, o) => m_Menus.SetAlternateMenuVisibility(rayOrigin, o != null);

            m_SelectionModule              = AddModule <SelectionModule>();
            m_SelectionModule.selected    += m_Rays.SetLastSelectionRayOrigin;          // when a selection occurs in the selection tool, call show in the alternate menu, allowing it to show/hide itself.
            m_SelectionModule.getGroupRoot = GetGroupRoot;

            m_SpatialHashModule = AddModule <SpatialHashModule>();
            m_SpatialHashModule.shouldExcludeObject = go => go.GetComponentInParent <EditorVR>();
            m_SpatialHashModule.Setup();

            m_IntersectionModule = AddModule <IntersectionModule>();
            m_Interfaces.ConnectInterfaces(m_IntersectionModule);
            m_IntersectionModule.Setup(m_SpatialHashModule.spatialHash);

            m_Menus.mainMenuTools = m_Tools.allTools.Where(t => !m_Tools.IsPermanentTool(t)).ToList();             // Don't show tools that can't be selected/toggled

            m_WorkspaceModule = AddModule <WorkspaceModule>();
            m_WorkspaceModule.workspaceCreated   += m_Vacuumables.OnWorkspaceCreated;
            m_WorkspaceModule.workspaceCreated   += m_MiniWorlds.OnWorkspaceCreated;
            m_WorkspaceModule.workspaceCreated   += (workspace) => { m_DeviceInputModule.UpdatePlayerHandleMaps(); };
            m_WorkspaceModule.workspaceDestroyed += m_Vacuumables.OnWorkspaceDestroyed;
            m_WorkspaceModule.workspaceDestroyed += (workspace) => { m_Interfaces.DisconnectInterfaces(workspace); };
            m_WorkspaceModule.workspaceDestroyed += m_MiniWorlds.OnWorkspaceDestroyed;

            UnityBrandColorScheme.sessionGradient = UnityBrandColorScheme.GetRandomGradient();

            m_SceneObjectModule = AddModule <SceneObjectModule>();
            m_SceneObjectModule.shouldPlaceObject = (obj, targetScale) =>
            {
                foreach (var miniWorld in m_MiniWorlds.worlds)
                {
                    if (!miniWorld.Contains(obj.position))
                    {
                        continue;
                    }

                    var referenceTransform = miniWorld.referenceTransform;
                    obj.transform.parent = null;
                    obj.position         = referenceTransform.position + Vector3.Scale(miniWorld.miniWorldTransform.InverseTransformPoint(obj.position), miniWorld.referenceTransform.localScale);
                    obj.rotation         = referenceTransform.rotation * Quaternion.Inverse(miniWorld.miniWorldTransform.rotation) * obj.rotation;
                    obj.localScale       = Vector3.Scale(Vector3.Scale(obj.localScale, referenceTransform.localScale), miniWorld.miniWorldTransform.lossyScale);
                    return(false);
                }

                return(true);
            };

            m_Viewer.AddPlayerModel();

            m_Rays.CreateAllProxies();

            // In case we have anything selected at start, set up manipulators, inspector, etc.
            EditorApplication.delayCall += OnSelectionChanged;
        }
Beispiel #4
0
            internal void UpdateMiniWorlds()
            {
                if (m_MiniWorldIgnoreListDirty)
                {
                    UpdateMiniWorldIgnoreList();
                    m_MiniWorldIgnoreListDirty = false;
                }

                var objectsGrabber    = evr.GetNestedModule <DirectSelection>().objectsGrabber;
                var sceneObjectModule = evr.GetModule <SceneObjectModule>();
                var viewer            = evr.GetNestedModule <Viewer>();

                // 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;
                    miniWorldRayOrigin.position   = referenceTransform.TransformPoint(miniWorldTransform.InverseTransformPoint(originalRayOrigin.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 = originalRayOrigin.position + originalRayOrigin.forward * DirectSelection.GetPointerLength(originalRayOrigin);
                    var isContained             = miniWorld.Contains(originalPointerPosition);
                    miniWorldRay.tester.active = isContained;
                    miniWorldRayOrigin.gameObject.SetActive(isContained);

                    var directSelectInput = (DirectSelectInput)miniWorldRay.directSelectInput;
                    var dragObjects       = miniWorldRay.dragObjects;

                    if (dragObjects == null)
                    {
                        var heldObjects = objectsGrabber.GetHeldObjects(miniWorldRayOrigin);
                        if (heldObjects != null)
                        {
                            // Only one ray can grab an object, otherwise PlaceObject is called on each trigger release
                            // This does not prevent TransformTool from doing two-handed scaling
                            var otherRayHasObject = false;
                            foreach (var otherRay in m_Rays.Values)
                            {
                                if (otherRay != miniWorldRay && otherRay.dragObjects != null)
                                {
                                    otherRayHasObject = true;
                                }
                            }

                            if (!otherRayHasObject)
                            {
                                miniWorldRay.dragObjects = heldObjects;
                                var scales          = new Vector3[heldObjects.Length];
                                var dragGameObjects = new GameObject[heldObjects.Length];
                                for (var i = 0; i < heldObjects.Length; i++)
                                {
                                    var dragObject = heldObjects[i];
                                    scales[i]          = dragObject.transform.localScale;
                                    dragGameObjects[i] = dragObject.gameObject;
                                }

                                var totalBounds      = ObjectUtils.GetBounds(dragGameObjects);
                                var maxSizeComponent = totalBounds.size.MaxComponent();
                                if (!Mathf.Approximately(maxSizeComponent, 0f))
                                {
                                    miniWorldRay.previewScaleFactor = Vector3.one * (k_PreviewScale * Viewer.GetViewerScale() / maxSizeComponent);
                                }

                                miniWorldRay.originalScales = scales;
                            }
                        }
                    }

                    // Transfer objects to and from original ray and MiniWorld ray (e.g. outside to inside mini world)
                    if (isContained != miniWorldRay.wasContained)
                    {
                        var pointerLengthDiff = DirectSelection.GetPointerLength(miniWorldRayOrigin) - DirectSelection.GetPointerLength(originalRayOrigin);
                        var from = isContained ? originalRayOrigin : miniWorldRayOrigin;
                        var to   = isContained ? miniWorldRayOrigin : originalRayOrigin;
                        if (isContained || miniWorldRay.dragObjects == null)
                        {
                            objectsGrabber.TransferHeldObjects(from, to, pointerLengthDiff * Vector3.forward);
                        }
                    }

                    // Transfer objects between MiniWorlds
                    if (dragObjects == null)
                    {
                        if (isContained)
                        {
                            foreach (var kvp in m_Rays)
                            {
                                var otherRayOrigin = kvp.Key;
                                var otherRay       = kvp.Value;
                                var otherObjects   = otherRay.dragObjects;
                                if (otherRay != miniWorldRay && !otherRay.wasContained && otherObjects != null)
                                {
                                    dragObjects = otherObjects;
                                    miniWorldRay.dragObjects        = otherObjects;
                                    miniWorldRay.originalScales     = otherRay.originalScales;
                                    miniWorldRay.previewScaleFactor = otherRay.previewScaleFactor;

                                    otherRay.dragObjects = null;

                                    var heldObjects = objectsGrabber.GetHeldObjects(otherRayOrigin);
                                    if (heldObjects != null)
                                    {
                                        objectsGrabber.TransferHeldObjects(otherRayOrigin, miniWorldRayOrigin,
                                                                           Vector3.zero);              // Set the new offset to zero because the object will have moved (this could be improved by taking original offset into account)
                                    }

                                    break;
                                }
                            }
                        }
                    }

                    if (isContained && !miniWorldRay.wasContained)
                    {
                        Rays.HideRay(originalRayOrigin, true);
                        Rays.LockRay(originalRayOrigin, this);
                    }

                    if (!isContained && miniWorldRay.wasContained)
                    {
                        Rays.UnlockRay(originalRayOrigin, this);
                        Rays.ShowRay(originalRayOrigin, true);
                    }

                    if (dragObjects == null)
                    {
                        miniWorldRay.wasContained = isContained;
                        continue;
                    }

                    var previewScaleFactor = miniWorldRay.previewScaleFactor;
                    var positionOffsets    = miniWorldRay.originalPositionOffsets;
                    var rotationOffsets    = miniWorldRay.originalRotationOffsets;
                    var originalScales     = miniWorldRay.originalScales;

                    if (directSelectInput.select.isHeld)
                    {
                        if (isContained)
                        {
                            // Scale the object back to its original scale when it re-enters the MiniWorld
                            if (!miniWorldRay.wasContained)
                            {
                                for (var i = 0; i < dragObjects.Length; i++)
                                {
                                    var dragObject = dragObjects[i];
                                    dragObject.localScale = originalScales[i];
                                    MathUtilsExt.SetTransformOffset(miniWorldRayOrigin, dragObject, positionOffsets[i], rotationOffsets[i]);
                                }

                                // Add the object (back) to TransformTool
                                objectsGrabber.GrabObjects(miniWorldRay.node, miniWorldRayOrigin, directSelectInput, dragObjects);
                            }
                        }
                        else
                        {
                            // Check for player head
                            for (var i = 0; i < dragObjects.Length; i++)
                            {
                                var dragObject = dragObjects[i];
                                if (dragObject.CompareTag(k_VRPlayerTag))
                                {
                                    objectsGrabber.DropHeldObjects(miniWorldRayOrigin);

                                    // Drop player at edge of MiniWorld
                                    miniWorldRay.dragObjects = null;
                                    dragObjects = null;
                                    break;
                                }
                            }

                            if (dragObjects == null)
                            {
                                continue;
                            }

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

                                // Don't switch to previewing the objects we are dragging if we are still in another mini world
                                if (!containedInOtherMiniWorld)
                                {
                                    for (var i = 0; i < dragObjects.Length; i++)
                                    {
                                        var dragObject = dragObjects[i];

                                        // Store the original scale in case the object re-enters the MiniWorld
                                        originalScales[i] = dragObject.localScale;

                                        dragObject.localScale = Vector3.Scale(dragObject.localScale, previewScaleFactor);
                                    }

                                    // Drop from TransformTool to take control of object
                                    objectsGrabber.DropHeldObjects(miniWorldRayOrigin, out positionOffsets, out rotationOffsets);
                                    foreach (var kvp in m_Rays)
                                    {
                                        var otherRay = kvp.Value;
                                        if (otherRay.originalRayOrigin == miniWorldRay.originalRayOrigin)
                                        {
                                            otherRay.originalPositionOffsets = positionOffsets;
                                            otherRay.originalRotationOffsets = rotationOffsets;
                                            otherRay.originalScales          = originalScales;
                                            otherRay.wasHeld = true;
                                        }
                                    }
                                }

                                for (var i = 0; i < dragObjects.Length; i++)
                                {
                                    var dragObject = dragObjects[i];
                                    var rotation   = originalRayOrigin.rotation;
                                    var position   = originalRayOrigin.position
                                                     + rotation * Vector3.Scale(previewScaleFactor, positionOffsets[i]);
                                    MathUtilsExt.LerpTransform(dragObject, position, rotation * rotationOffsets[i]);
                                }
                            }
                        }

                        // Release the current object if the trigger is no longer held
                        if (directSelectInput.select.wasJustReleased)
                        {
                            var rayPosition = originalRayOrigin.position;
                            for (var i = 0; i < dragObjects.Length; i++)
                            {
                                var dragObject = dragObjects[i];

                                // If the user has pulled an object out of the MiniWorld, use PlaceObject to grow it back to its original scale
                                if (!isContained)
                                {
                                    if (viewer.IsOverShoulder(originalRayOrigin))
                                    {
                                        sceneObjectModule.DeleteSceneObject(dragObject.gameObject);
                                    }
                                    else
                                    {
                                        dragObject.localScale = originalScales[i];
                                        var rotation = originalRayOrigin.rotation;
                                        dragObject.position = rayPosition + rotation * positionOffsets[i];
                                        dragObject.rotation = rotation * rotationOffsets[i];
                                    }
                                }
                            }

                            miniWorldRay.dragObjects = null;
                            miniWorldRay.wasHeld     = false;
                        }

                        miniWorldRay.wasContained = isContained;
                    }
                }
            }