Beispiel #1
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 #2
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 #3
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;
                    }
                }
            }