Esempio n. 1
0
        protected override void OnDragEnded(BaseHandle handle, HandleEventData eventData)
        {
            var gridItem = m_DragObject.GetComponent <AssetGridItem>();

            var rayOrigin = eventData.rayOrigin;

            this.RemoveRayVisibilitySettings(rayOrigin, this);

            if (!this.IsOverShoulder(eventData.rayOrigin))
            {
                if (gridItem.m_PreviewObjectTransform)
                {
                    this.PlaceSceneObject(gridItem.m_PreviewObjectTransform, m_PreviewPrefabScale);
                }
                else
                {
                    switch (data.type)
                    {
                    case "Prefab":
                    case "Model":
#if UNITY_EDITOR
                        var go        = (GameObject)PrefabUtility.InstantiatePrefab(data.asset);
                        var transform = go.transform;
                        transform.position = gridItem.transform.position;
                        transform.rotation = MathUtilsExt.ConstrainYawRotation(gridItem.transform.rotation);
#else
                        var go = (GameObject)Instantiate(data.asset, gridItem.transform.position, gridItem.transform.rotation);
#endif

                        this.AddToSpatialHash(go);
                        break;
                    }
                }
            }

            StartCoroutine(HideGrabbedObject(m_DragObject.gameObject, gridItem.m_Cube));
        }
Esempio n. 2
0
        IEnumerator AnimateHide()
        {
            m_VisibilityState = VisibilityState.TransitioningOut;

            foreach (var kvp in m_Faces)
            {
                var face = kvp.Value;
                face.visible = false;
                face.ClearSubmenus();
            }

            this.RestartCoroutine(ref m_FrameRevealCoroutine, AnimateFrameReveal(m_VisibilityState));

            const float kTargetScale    = 0f;
            const float kSmoothTime     = 0.06875f;
            var         scale           = transform.localScale.x;
            var         smoothVelocity  = 0f;
            var         currentDuration = 0f;

            while (currentDuration < kSmoothTime)
            {
                scale                      = MathUtilsExt.SmoothDamp(scale, kTargetScale, ref smoothVelocity, kSmoothTime, Mathf.Infinity, Time.deltaTime);
                currentDuration           += Time.deltaTime;
                transform.localScale       = Vector3.one * scale;
                m_AlternateMenu.localScale = m_AlternateMenuOriginOriginalLocalScale * scale;
                yield return(null);
            }

            gameObject.SetActive(false);

            m_VisibilityState = VisibilityState.Hidden;

            var snapRotation = GetRotationForFaceIndex(GetClosestFaceIndexForRotation(currentRotation));

            m_MenuFaceRotationOrigin.localRotation = Quaternion.Euler(new Vector3(0, snapRotation, 0)); // set intended target rotation
            m_RotationState = RotationState.AtRest;
        }
Esempio n. 3
0
        private IEnumerator SnapToFace(int faceIndex, float snapSpeed)
        {
            if (m_RotationState == RotationState.Snapping)
            {
                yield break;
            }

            m_RotationState = RotationState.Snapping;

            // When the user releases their input while rotating the menu, snap to the nearest face
            StartCoroutine(AnimateFrameRotationShapeChange(m_RotationState));

            foreach (var face in m_MenuFaces)
            {
                face.EndVisuals();
            }

            float rotation           = currentRotation;
            float faceTargetRotation = GetRotationForFaceIndex(faceIndex);

            float smoothVelocity  = 0f;
            float smoothSnapSpeed = 0.5f;

            while (Mathf.Abs(Mathf.DeltaAngle(rotation, faceTargetRotation)) > k_RotationEpsilon)
            {
                smoothSnapSpeed = MathUtilsExt.SmoothDamp(smoothSnapSpeed, snapSpeed, ref smoothVelocity, 0.0625f, Mathf.Infinity, Time.unscaledDeltaTime);
                rotation        = Mathf.LerpAngle(rotation, faceTargetRotation, Time.unscaledDeltaTime * smoothSnapSpeed);
                m_MenuFaceRotationOrigin.localRotation = Quaternion.Euler(new Vector3(0, rotation, 0));
                yield return(null);
            }
            m_MenuFaceRotationOrigin.localRotation = Quaternion.Euler(new Vector3(0, faceTargetRotation, 0));

            // Target face index and rotation can be set separately, so both, must be kept in sync
            targetRotation = faceTargetRotation;

            m_RotationState = RotationState.AtRest;
        }
Esempio n. 4
0
        IEnumerator AnimateVisibility(bool visible, Action <PolyGridItem> callback)
        {
            var currentTime = 0f;

            // Item should always be at a scale of zero before becoming visible
            if (visible)
            {
                transform.localScale = Vector3.zero;
            }
#if INCLUDE_POLY_TOOLKIT
            else
            {
                data.modelImportCompleted     -= OnModelImportCompleted;
                data.thumbnailImportCompleted -= OnThumbnailImportCompleted;
            }
#endif

            var currentScale = transform.localScale;
            var targetScale  = visible ? m_IconScale * scaleFactor : Vector3.zero;

            while (currentTime < k_TransitionDuration)
            {
                currentTime         += Time.deltaTime;
                transform.localScale = Vector3.Lerp(currentScale, targetScale,
                                                    MathUtilsExt.SmoothInOutLerpFloat(currentTime / k_TransitionDuration));
                yield return(null);
            }

            transform.localScale = targetScale;

            if (callback != null)
            {
                callback(this);
            }

            m_VisibilityCoroutine = null;
        }
Esempio n. 5
0
    void OnDrawing(Vector3 cumulativeDelta, Vector3 headPosition)
    {
        if (currentLine)
        {
            Vector3 move = cumulativeDelta - manipulationDelta;
            Vector3 handPosition;
            if (GazeGestureUtils.GetManipulationHandPosition(out handPosition))
            {
                Vector3 fromHeadToModel = myPos - headPosition;
                Vector3 fromHeadToHand  = handPosition - headPosition;

                float moveAmplifier = fromHeadToModel.magnitude / fromHeadToHand.magnitude;

                if (moveAmplifier > 1)
                {
                    move *= moveAmplifier;
                }
                myPos += move;
            }

            CursorManager.Instance.ActiveCursor.transform.position = myPos;

            Vector3 pos = myPos;
            if (pointsList.Count == 0 || !MathUtilsExt.V3Equal(pointsList[pointsList.Count - 1], pos))
            {
                pointsList.Add(pos);
                currentLine.positionCount = pointsList.Count;
                currentLine.SetPosition(pointsList.Count - 1, pointsList[pointsList.Count - 1]);
            }
        }
        else
        {
            StartDrawing(cumulativeDelta, headPosition);
        }
        manipulationDelta = cumulativeDelta;
    }
Esempio n. 6
0
        private IEnumerator AnimateVisibility(bool show)
        {
            if (m_VisibilityCoroutine != null)
            {
                yield break;
            }

            m_CanvasGroup.interactable = false;

            var smoothTime      = show ? 0.35f : 0.125f;
            var startingOpacity = m_CanvasGroup.alpha;
            var targetOpacity   = show ? 1f : 0f;
            var smoothVelocity  = 0f;
            var currentDuration = 0f;

            while (currentDuration < smoothTime)
            {
                startingOpacity     = MathUtilsExt.SmoothDamp(startingOpacity, targetOpacity, ref smoothVelocity, smoothTime, Mathf.Infinity, Time.unscaledDeltaTime);
                currentDuration    += Time.unscaledDeltaTime;
                m_CanvasGroup.alpha = startingOpacity * startingOpacity;
                yield return(null);
            }

            m_CanvasGroup.alpha = targetOpacity;

            if (show)
            {
                m_CanvasGroup.interactable = true;
            }
            else
            {
                m_TitleIcon.SetBlendShapeWeight(0, 0);
            }

            m_VisibilityCoroutine = null;
        }
Esempio n. 7
0
        private IEnumerator AnimateFrameReveal(VisibilityState visibilityState)
        {
            m_MenuFrameRenderer.SetBlendShapeWeight(1, 100f);
            const float zeroStartBlendShapePadding = 20f;                                                     // start the blendShape at a point slightly above the full hidden value for better visibility
            const float kLerpEmphasisWeight        = 0.25f;
            var         smoothTime = visibilityState == VisibilityState.TransitioningIn ? 0.1875f : 0.09375f; // slower if transitioning in
            var         currentBlendShapeWeight = m_MenuFrameRenderer.GetBlendShapeWeight(1);
            var         targetWeight            = visibilityState == VisibilityState.TransitioningIn ? 0f : 100f;
            var         smoothVelocity          = 0f;

            currentBlendShapeWeight = currentBlendShapeWeight > 0 ? currentBlendShapeWeight : zeroStartBlendShapePadding;

            var currentDuration = 0f;

            while (m_VisibilityState != VisibilityState.Hidden && currentDuration < smoothTime)
            {
                currentBlendShapeWeight = MathUtilsExt.SmoothDamp(currentBlendShapeWeight, targetWeight, ref smoothVelocity, smoothTime, Mathf.Infinity, Time.unscaledDeltaTime);
                currentDuration        += Time.unscaledDeltaTime;
                m_MenuFrameRenderer.SetBlendShapeWeight(1, currentBlendShapeWeight * currentBlendShapeWeight);
                m_MenuFacesMaterial.color = Color.Lerp(m_MenuFacesColor, k_MenuFacesHiddenColor, currentBlendShapeWeight * kLerpEmphasisWeight);
                yield return(null);
            }

            if (m_VisibilityState == visibilityState)
            {
                m_MenuFrameRenderer.SetBlendShapeWeight(1, targetWeight);
                m_MenuFacesMaterial.color = targetWeight > 0 ? m_MenuFacesColor : k_MenuFacesHiddenColor;
            }

            if (m_VisibilityState == VisibilityState.Hidden)
            {
                m_MenuFrameRenderer.SetBlendShapeWeight(0, 0);
            }

            m_FrameRevealCoroutine = null;
        }
Esempio n. 8
0
            internal static void DropPlayerHead(Transform playerHead)
            {
                var cameraRig  = CameraUtils.GetCameraRig();
                var mainCamera = CameraUtils.GetMainCamera().transform;

                // Hide player head to avoid jarring impact
                var playerHeadRenderers = playerHead.GetComponentsInChildren <Renderer>();

                foreach (var renderer in playerHeadRenderers)
                {
                    renderer.enabled = false;
                }

                var rotationDiff = MathUtilsExt.ConstrainYawRotation(Quaternion.Inverse(mainCamera.rotation) * playerHead.rotation);
                var cameraDiff   = cameraRig.position - mainCamera.position;

                cameraDiff.y = 0;
                var rotationOffset = rotationDiff * cameraDiff - cameraDiff;

                var endPosition   = cameraRig.position + (playerHead.position - mainCamera.position) + rotationOffset;
                var endRotation   = cameraRig.rotation * rotationDiff;
                var viewDirection = endRotation * Vector3.forward;

                evr.StartCoroutine(UpdateCameraRig(endPosition, viewDirection, () =>
                {
                    playerHead.hideFlags     = defaultHideFlags;
                    playerHead.parent        = mainCamera;
                    playerHead.localRotation = Quaternion.identity;
                    playerHead.localPosition = Vector3.zero;

                    foreach (var renderer in playerHeadRenderers)
                    {
                        renderer.enabled = true;
                    }
                }));
            }
Esempio n. 9
0
        IEnumerator HideRay()
        {
            m_Tip.transform.localScale = Vector3.zero;

            // cache current width for smooth animation to target value without snapping
            var         currentWidth    = m_LineRenderer.widthStart;
            const float kTargetWidth    = 0f;
            const float kSmoothTime     = 0.1875f;
            var         smoothVelocity  = 0f;
            var         currentDuration = 0f;

            while (currentDuration < kSmoothTime)
            {
                currentDuration          += Time.deltaTime;
                currentWidth              = MathUtilsExt.SmoothDamp(currentWidth, kTargetWidth, ref smoothVelocity, kSmoothTime, Mathf.Infinity, Time.deltaTime);
                m_LineRenderer.widthStart = currentWidth;
                m_LineRenderer.widthEnd   = currentWidth;
                yield return(null);
            }

            m_LineRenderer.widthStart = kTargetWidth;
            m_LineRenderer.widthEnd   = kTargetWidth;
            m_RayVisibilityCoroutine  = null;
        }
Esempio n. 10
0
        IEnumerator AnimatePulseColor()
        {
            const float kTargetDuration = 1f;

            m_PulseDuration = 0f;
            var maxShaderLineRadius            = new Vector3(0.03f, 0f, 100f);
            var minShaderLineRadius            = new Vector3(0.005f, 0f, 100f);
            var currentVector3ShaderLineRadius = m_HintLineMaterial.GetVector(k_ShaderLineRadiusPropertyName);
            var currentColor = m_ScrollLineRenderer.colorStart; // The line stand & end colors are the same; fetch only one of them

            while (m_PulseDuration < kTargetDuration)
            {
                var shapedDuration = MathUtilsExt.SmoothInOutLerpFloat(m_PulseDuration / kTargetDuration);
                var newColor       = Color.Lerp(currentColor, m_PulseColor, shapedDuration);
                m_ScrollLineRenderer.colorStart = newColor;
                m_ScrollLineRenderer.colorEnd   = newColor;
                m_PulseDuration += Time.unscaledDeltaTime * 5;
                m_HintLineMaterial.SetVector(k_ShaderLineRadiusPropertyName, Vector3.Lerp(currentVector3ShaderLineRadius, maxShaderLineRadius, shapedDuration));
                yield return(null);
            }

            while (m_PulseDuration > 0f)
            {
                var shapedDuration = MathUtilsExt.SmoothInOutLerpFloat(m_PulseDuration / kTargetDuration);
                var newColor       = Color.Lerp(m_VisibleColor, m_PulseColor, shapedDuration);
                m_ScrollLineRenderer.colorStart = newColor;
                m_ScrollLineRenderer.colorEnd   = newColor;
                m_PulseDuration -= Time.unscaledDeltaTime * 1.5f;
                m_HintLineMaterial.SetVector(k_ShaderLineRadiusPropertyName, Vector3.Lerp(minShaderLineRadius, maxShaderLineRadius, shapedDuration));
                yield return(null);
            }

            m_ScrollLineRenderer.colorStart = m_VisibleColor;
            m_ScrollLineRenderer.colorEnd   = m_VisibleColor;
            m_PulseDuration = 0f;
        }
Esempio n. 11
0
        IEnumerator ShowButtonList()
        {
            m_ButtonList.gameObject.SetActive(true);

            const float kTargetDuration  = 0.5f;
            var         currentAlpha     = m_ButtonListCanvasGroup.alpha;
            var         kTargetAlpha     = 1f;
            var         transitionAmount = 0f;
            var         velocity         = 0f;
            var         currentDuration  = 0f;

            while (currentDuration < kTargetDuration)
            {
                currentDuration              += Time.deltaTime;
                transitionAmount              = MathUtilsExt.SmoothDamp(transitionAmount, 1f, ref velocity, kTargetDuration, Mathf.Infinity, Time.deltaTime);
                m_ButtonListGrid.spacing      = new Vector2(0f, Mathf.Lerp(m_HiddenButtonListYSpacing, 0f, transitionAmount));
                m_ButtonListCanvasGroup.alpha = Mathf.Lerp(currentAlpha, kTargetAlpha, transitionAmount);
                yield return(null);
            }

            m_ButtonListGrid.spacing      = new Vector2(0f, 0f);
            m_ButtonListCanvasGroup.alpha = 1f;
            m_ShowButtonListCoroutine     = null;
        }
Esempio n. 12
0
        IEnumerator AnimateShow()
        {
            m_VisibilityState = VisibilityState.TransitioningIn;

            foreach (var kvp in m_Faces)
            {
                kvp.Value.visible = true;
            }

            this.RestartCoroutine(ref m_FrameRevealCoroutine, AnimateFrameReveal(m_VisibilityState));

            const float faceDelay = 0.1f;
            var         count     = 0;

            foreach (var face in m_Faces)
            {
                face.Value.Reveal(count++ *faceDelay);
            }

            const float kTargetScale    = 1f;
            const float kSmoothTime     = 0.125f;
            var         scale           = 0f;
            var         smoothVelocity  = 0f;
            var         currentDuration = 0f;

            while (currentDuration < kSmoothTime)
            {
                scale                      = MathUtilsExt.SmoothDamp(scale, kTargetScale, ref smoothVelocity, kSmoothTime, Mathf.Infinity, Time.deltaTime);
                currentDuration           += Time.deltaTime;
                transform.localScale       = Vector3.one * scale;
                m_AlternateMenu.localScale = m_AlternateMenuOriginOriginalLocalScale * scale;
                yield return(null);
            }

            m_VisibilityState = VisibilityState.Visible;
        }
Esempio n. 13
0
        void UpdateVisuals(ITooltip tooltip, TooltipUI tooltipUI, Transform target, float lerp)
        {
            var tooltipTransform = tooltipUI.transform;

            var tooltipText = tooltipUI.text;

            if (tooltipText)
            {
                tooltipText.text = tooltip.tooltipText;
            }

            var viewerScale = getViewerScale();

            tooltipTransform.localScale = m_TooltipScale * lerp * viewerScale;

            var placement = tooltip as ITooltipPlacement;

            // Adjust for alignment
            var offset = Vector3.zero;

            if (placement != null)
            {
                switch (placement.tooltipAlignment)
                {
                case TextAlignment.Right:
                    offset = Vector3.left;
                    break;

                case TextAlignment.Left:
                    offset = Vector3.right;
                    break;
                }
            }

            var rectTransform = tooltipUI.GetComponent <RectTransform>();
            var rect          = rectTransform.rect;
            var halfWidth     = rect.width * 0.5f;
            var halfHeight    = rect.height * 0.5f;

            if (placement != null)
            {
                offset *= halfWidth * rectTransform.lossyScale.x;
            }
            else
            {
                offset = Vector3.back * k_Offset;
            }

            MathUtilsExt.SetTransformOffset(target, tooltipTransform, offset * lerp, Quaternion.identity);

            if (placement != null)
            {
                var source   = placement.tooltipSource;
                var toSource = tooltipTransform.InverseTransformPoint(source.position);

                // Position spheres: one at source, one on the closest edge of the tooltip
                var spheres = tooltipUI.spheres;
                spheres[0].position = source.position;

                var attachedSphere = spheres[1];
                var boxSlope       = halfHeight / halfWidth;
                var toSourceSlope  = Mathf.Abs(toSource.y / toSource.x);

                halfHeight *= Mathf.Sign(toSource.y);
                halfWidth  *= Mathf.Sign(toSource.x);
                attachedSphere.localPosition = toSourceSlope > boxSlope
                                        ? new Vector3(0, halfHeight)
                                        : new Vector3(halfWidth, 0);

                // Align dotted line
                var attachedSpherePosition = attachedSphere.position;
                toSource = source.position - attachedSpherePosition;
                var midPoint   = attachedSpherePosition + toSource * 0.5f;
                var dottedLine = tooltipUI.dottedLine;
                var length     = toSource.magnitude;
                var uvRect     = dottedLine.uvRect;
                var worldScale = 1 / viewerScale;
                uvRect.width      = length * k_UVScale * worldScale;
                uvRect.xMin      += k_UVScrollSpeed * Time.unscaledDeltaTime;
                dottedLine.uvRect = uvRect;

                var dottedLineTransform = dottedLine.transform.parent.GetComponent <RectTransform>();
                dottedLineTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, length / tooltipTransform.lossyScale.x);
                dottedLineTransform.position = midPoint;
                dottedLineTransform.rotation = Quaternion.LookRotation(toSource, -tooltipTransform.forward);
            }
        }
Esempio n. 14
0
        bool DoTwoHandedScaling(ConsumeControlDelegate consumeControl)
        {
            foreach (var linkedObject in linkedObjects)
            {
                if (((LocomotionTool)linkedObject).m_Rotating)
                {
                    return(false);
                }
            }

            if (this.IsSharedUpdater(this))
            {
                var crawl = m_LocomotionInput.crawl;
                if (crawl.isHeld)
                {
                    if (m_AllowScaling)
                    {
                        var otherGripHeld = false;
                        foreach (var linkedObject in linkedObjects)
                        {
                            var otherLocomotionTool = (LocomotionTool)linkedObject;
                            if (otherLocomotionTool == this)
                            {
                                continue;
                            }

                            var otherLocomotionInput = otherLocomotionTool.m_LocomotionInput;
                            if (otherLocomotionInput == null) // This can occur if crawl is pressed when EVR is opened
                            {
                                continue;
                            }

                            var otherCrawl = otherLocomotionInput.crawl;
                            if (otherCrawl.isHeld)
                            {
                                otherGripHeld = true;
                                consumeControl(crawl);
                                consumeControl(otherCrawl);

                                // Also consume thumbstick axes to disable radial menu
                                consumeControl(m_LocomotionInput.horizontal);
                                consumeControl(m_LocomotionInput.vertical);
                                consumeControl(otherLocomotionInput.horizontal);
                                consumeControl(otherLocomotionInput.vertical);

                                // Pre-emptively consume thumbstick press to override UndoMenu
                                consumeControl(m_LocomotionInput.scaleReset);
                                consumeControl(otherLocomotionInput.scaleReset);

                                // Also pre-emptively consume world-reset
                                consumeControl(m_LocomotionInput.worldReset);
                                consumeControl(otherLocomotionInput.worldReset);

                                var thisPosition   = cameraRig.InverseTransformPoint(rayOrigin.position);
                                var otherRayOrigin = otherLocomotionTool.rayOrigin;
                                var otherPosition  = cameraRig.InverseTransformPoint(otherRayOrigin.position);
                                var distance       = Vector3.Distance(thisPosition, otherPosition);

                                this.AddRayVisibilitySettings(rayOrigin, this, false, false);
                                this.AddRayVisibilitySettings(otherRayOrigin, this, false, false);

                                var rayToRay = otherPosition - thisPosition;
                                var midPoint = thisPosition + rayToRay * 0.5f;

                                rayToRay.y = 0; // Use for yaw rotation

                                var pivotYaw = MathUtilsExt.ConstrainYawRotation(cameraRig.rotation);

                                if (!m_Scaling)
                                {
                                    m_StartScale     = this.GetViewerScale();
                                    m_StartDistance  = distance;
                                    m_StartMidPoint  = pivotYaw * midPoint * m_StartScale;
                                    m_StartPosition  = cameraRig.position;
                                    m_StartDirection = rayToRay;
                                    m_StartYaw       = cameraRig.rotation.eulerAngles.y;

                                    otherLocomotionTool.m_Scaling       = true;
                                    otherLocomotionTool.m_Crawling      = false;
                                    otherLocomotionTool.m_StartCrawling = false;

                                    m_ViewerScaleVisuals.leftHand  = rayOrigin;
                                    m_ViewerScaleVisuals.rightHand = otherRayOrigin;
                                    m_ViewerScaleVisuals.gameObject.SetActive(true);

                                    foreach (var obj in linkedObjects)
                                    {
                                        var locomotionTool = (LocomotionTool)obj;
                                        locomotionTool.HideScaleFeedback();
                                        locomotionTool.HideRotateFeedback();
                                        locomotionTool.HideMainButtonFeedback();
                                        locomotionTool.ShowResetScaleFeedback();
                                    }
                                }

                                m_Scaling       = true;
                                m_StartCrawling = false;
                                m_Crawling      = false;

                                var currentScale = Mathf.Clamp(m_StartScale * (m_StartDistance / distance), k_MinScale, k_MaxScale);

                                var scaleReset     = m_LocomotionInput.scaleReset;
                                var scaleResetHeld = scaleReset.isHeld;

                                var otherScaleReset     = otherLocomotionInput.scaleReset;
                                var otherScaleResetHeld = otherScaleReset.isHeld;

                                // Press both thumb buttons to reset scale
                                if (scaleResetHeld && otherScaleResetHeld)
                                {
                                    m_AllowScaling = false;

                                    rayToRay = otherRayOrigin.position - rayOrigin.position;
                                    midPoint = rayOrigin.position + rayToRay * 0.5f;
                                    var currOffset = midPoint - cameraRig.position;

                                    cameraRig.position = midPoint - currOffset / currentScale;
                                    cameraRig.rotation = Quaternion.AngleAxis(m_StartYaw, Vector3.up);

                                    ResetViewerScale();
                                }

                                var worldReset     = m_LocomotionInput.worldReset;
                                var worldResetHeld = worldReset.isHeld;
                                if (worldResetHeld)
                                {
                                    consumeControl(worldReset);
                                }

                                var otherWorldReset     = otherLocomotionInput.worldReset;
                                var otherWorldResetHeld = otherWorldReset.isHeld;
                                if (otherWorldResetHeld)
                                {
                                    consumeControl(otherWorldReset);
                                }

                                // Press both triggers to reset to origin
                                if (worldResetHeld && otherWorldResetHeld)
                                {
                                    m_AllowScaling     = false;
                                    cameraRig.position = VRView.headCenteredOrigin;
                                    cameraRig.rotation = Quaternion.identity;

                                    ResetViewerScale();
                                }

                                if (m_AllowScaling)
                                {
                                    var yawSign         = Mathf.Sign(Vector3.Dot(Quaternion.AngleAxis(90, Vector3.down) * m_StartDirection, rayToRay));
                                    var currentYaw      = m_StartYaw + Vector3.Angle(m_StartDirection, rayToRay) * yawSign;
                                    var currentRotation = Quaternion.AngleAxis(currentYaw, Vector3.up);
                                    midPoint = currentRotation * midPoint * currentScale;

                                    var pos = m_StartPosition + m_StartMidPoint - midPoint;
                                    cameraRig.position = pos;

                                    cameraRig.rotation = currentRotation;

                                    this.SetViewerScale(currentScale);
                                }
                                break;
                            }
                        }

                        if (!otherGripHeld)
                        {
                            CancelScale();
                        }
                    }
                }
                else
                {
                    CancelScale();
                }
            }

            return(m_Scaling);
        }
Esempio n. 15
0
        public void ProcessInput(ActionMapInput input, ConsumeControlDelegate consumeControl)
        {
            var blinkInput = (BlinkLocomotion)input;

            if (m_State == State.Moving)
            {
                return;
            }

            foreach (var linkedObject in linkedObjects)
            {
                if (linkedObject.Equals(this))
                {
                    continue;
                }

                var blinkTool = (BlinkLocomotionTool)linkedObject;
                if (blinkTool.m_State != State.Inactive)
                {
                    return;
                }
            }

            var yawValue     = blinkInput.yaw.value;
            var forwardValue = blinkInput.forward.value;

            m_Grip  = blinkInput.grip.isHeld ? blinkInput.grip : null;
            m_Thumb = blinkInput.thumb.isHeld ? blinkInput.thumb : null;

            if (this.IsSharedUpdater(this))
            {
                if (m_Grip != null)
                {
                    if (m_AllowScaling)
                    {
                        var otherGrip = false;
                        foreach (var linkedObject in linkedObjects)
                        {
                            if (linkedObject.Equals(this))
                            {
                                continue;
                            }

                            var blinkTool = (BlinkLocomotionTool)linkedObject;
                            if (blinkTool.m_Grip != null)
                            {
                                otherGrip = true;
                                consumeControl(m_Grip);
                                consumeControl(blinkTool.m_Grip);

                                var thisPosition   = cameraRig.InverseTransformPoint(rayOrigin.position);
                                var otherRayOrigin = blinkTool.rayOrigin;
                                var otherPosition  = cameraRig.InverseTransformPoint(otherRayOrigin.position);
                                var distance       = Vector3.Distance(thisPosition, otherPosition);

                                var rayToRay = otherPosition - thisPosition;
                                var midPoint = thisPosition + rayToRay * 0.5f;

                                rayToRay.y = 0;                                 // Use for yaw rotation

                                var pivotYaw = MathUtilsExt.ConstrainYawRotation(cameraRig.rotation);

                                if (!m_Scaling)
                                {
                                    m_StartScale     = this.GetViewerScale();
                                    m_StartDistance  = distance;
                                    m_StartMidPoint  = pivotYaw * midPoint * m_StartScale;
                                    m_StartPosition  = cameraRig.position;
                                    m_StartDirection = rayToRay;
                                    m_StartYaw       = cameraRig.rotation.eulerAngles.y;

                                    m_EnableJoystick           = false;
                                    blinkTool.m_EnableJoystick = false;

                                    CreateViewerScaleVisuals(rayOrigin, otherRayOrigin);
                                }

                                m_Scaling = true;

                                var currentScale = m_StartScale * (m_StartDistance / distance);

                                // Press both thumb buttons to reset
                                if (m_Thumb != null && blinkTool.m_Thumb != null)
                                {
                                    m_AllowScaling = false;

                                    rayToRay = otherRayOrigin.position - rayOrigin.position;
                                    midPoint = rayOrigin.position + rayToRay * 0.5f;
                                    var currOffset = midPoint - cameraRig.position;
                                    this.SetViewerScale(1f);
                                    cameraRig.position = midPoint - currOffset / currentScale;
                                    cameraRig.rotation = Quaternion.AngleAxis(m_StartYaw, Vector3.up);

                                    consumeControl(m_Thumb);
                                    consumeControl(blinkTool.m_Thumb);

                                    if (m_ViewerScaleVisuals)
                                    {
                                        ObjectUtils.Destroy(m_ViewerScaleVisuals.gameObject);
                                    }
                                }

                                if (currentScale < k_MinScale)
                                {
                                    currentScale = k_MinScale;
                                }

                                if (currentScale > k_MaxScale)
                                {
                                    currentScale = k_MaxScale;
                                }

                                if (m_AllowScaling)
                                {
                                    var yawSign         = Mathf.Sign(Vector3.Dot(Quaternion.AngleAxis(90, Vector3.down) * m_StartDirection, rayToRay));
                                    var currentYaw      = m_StartYaw + Vector3.Angle(m_StartDirection, rayToRay) * yawSign;
                                    var currentRotation = Quaternion.AngleAxis(currentYaw, Vector3.up);
                                    midPoint = currentRotation * midPoint * currentScale;

                                    cameraRig.position = m_StartPosition + m_StartMidPoint - midPoint;
                                    cameraRig.rotation = currentRotation;

                                    this.SetViewerScale(currentScale);

                                    m_ViewerScaleVisuals.viewerScale = currentScale;
                                    m_BlinkVisuals.viewerScale       = currentScale;
                                    Shader.SetGlobalFloat(k_WorldScaleProperty, 1f / currentScale);
                                }
                                break;
                            }
                        }

                        if (!otherGrip)
                        {
                            CancelScale();
                        }
                    }
                }
                else
                {
                    CancelScale();
                }
            }

            bool isVive = proxyType == typeof(ViveProxy);

            if (m_EnableJoystick && (!isVive || m_Thumb != null))
            {
                var viewerCamera = CameraUtils.GetMainCamera();

                if (Mathf.Abs(yawValue) > Mathf.Abs(forwardValue))
                {
                    if (!Mathf.Approximately(yawValue, 0))
                    {
                        if (node == Node.LeftHand)
                        {
                            var direction = viewerCamera.transform.right;
                            direction.y = 0;
                            direction.Normalize();

                            Translate(yawValue, isVive, direction);
                        }
                        else
                        {
                            var speed     = yawValue * k_SlowRotationSpeed;
                            var threshold = isVive ? k_RotationThresholdVive : k_RotationThreshold;
                            if (Mathf.Abs(yawValue) > threshold)
                            {
                                speed = k_FastRotationSpeed * Mathf.Sign(yawValue);
                            }

                            cameraRig.RotateAround(viewerCamera.transform.position, Vector3.up, speed * Time.deltaTime);
                        }

                        consumeControl(blinkInput.yaw);
                    }
                }
                else
                {
                    if (!Mathf.Approximately(forwardValue, 0))
                    {
                        var direction = Vector3.up;

                        if (node == Node.LeftHand)
                        {
                            direction   = viewerCamera.transform.forward;
                            direction.y = 0;
                            direction.Normalize();
                        }

                        Translate(forwardValue, isVive, direction);
                        consumeControl(blinkInput.forward);
                    }
                }
            }

            if (blinkInput.blink.wasJustPressed && !m_BlinkVisuals.outOfMaxRange)
            {
                m_State = State.Aiming;
                this.HideDefaultRay(rayOrigin);
                this.LockRay(rayOrigin, this);

                m_BlinkVisuals.ShowVisuals();

                consumeControl(blinkInput.blink);
            }
            else if (m_State == State.Aiming && blinkInput.blink.wasJustReleased)
            {
                this.UnlockRay(rayOrigin, this);
                this.ShowDefaultRay(rayOrigin);

                if (!m_BlinkVisuals.outOfMaxRange)
                {
                    m_BlinkVisuals.HideVisuals();
                    StartCoroutine(MoveTowardTarget(m_BlinkVisuals.locatorPosition));
                }
                else
                {
                    m_BlinkVisuals.enabled = false;
                    m_State = State.Inactive;
                }
            }
        }
Esempio n. 16
0
        IEnumerator PlaceSceneObjectCoroutine(Transform obj, Vector3 targetScale)
        {
            var go = obj.gameObject;

            // Don't let us direct select while placing
            this.RemoveFromSpatialHash(go);

            var start    = Time.realtimeSinceStartup;
            var currTime = 0f;

            obj.parent = null;
            var startScale     = obj.localScale;
            var startPosition  = ObjectUtils.GetBounds(obj).center;
            var pivotOffset    = obj.position - startPosition;
            var startRotation  = obj.rotation;
            var targetRotation = MathUtilsExt.ConstrainYawRotation(startRotation);

            //Get bounds at target scale and rotation (scaled and rotated from bounds center)
            var origScale = obj.localScale;

            obj.localScale = targetScale;
            obj.rotation   = targetRotation;
            var rotationDiff      = Quaternion.Inverse(startRotation) * targetRotation;
            var scaleDiff         = targetScale.magnitude / startScale.magnitude;
            var targetPivotOffset = rotationDiff * pivotOffset * scaleDiff;

            obj.position = startPosition + targetPivotOffset;
            var bounds = ObjectUtils.GetBounds(obj);

            obj.localScale    = origScale;
            obj.localRotation = startRotation;
            obj.position      = startPosition + pivotOffset;

            // We want to position the object so that it fits within the camera perspective at its original scale
            var camera      = CameraUtils.GetMainCamera();
            var halfAngle   = camera.fieldOfView * 0.5f;
            var perspective = halfAngle + k_InstantiateFOVDifference;
            var camPosition = camera.transform.position;
            var forward     = startPosition - camPosition;

            var distance       = bounds.size.magnitude / Mathf.Tan(perspective * Mathf.Deg2Rad);
            var targetPosition = bounds.center;

            if (distance > forward.magnitude && obj.localScale != targetScale)
            {
                targetPosition = camPosition + forward.normalized * distance;
            }

            startPosition  += pivotOffset;
            targetPosition += targetPivotOffset;

            while (currTime < k_GrowDuration)
            {
                currTime = Time.realtimeSinceStartup - start;
                var t        = currTime / k_GrowDuration;
                var tSquared = t * t;
                obj.localScale = Vector3.Lerp(startScale, targetScale, tSquared);
                obj.position   = Vector3.Lerp(startPosition, targetPosition, tSquared);
                obj.rotation   = Quaternion.Lerp(startRotation, targetRotation, tSquared);
                yield return(null);
            }
            obj.localScale             = targetScale;
            Selection.activeGameObject = go;

            this.AddToSpatialHash(go);
#if UNITY_EDITOR
            Undo.IncrementCurrentGroup();
#endif
        }
Esempio n. 17
0
        void UpdateVisuals(ITooltip tooltip, TooltipUI tooltipUI, Transform target, float lerp)
        {
            var tooltipTransform = tooltipUI.transform;

            lerp = MathUtilsExt.SmoothInOutLerpFloat(lerp);             // shape the lerp for better presentation

            var tooltipText = tooltipUI.text;

            if (tooltipText)
            {
                tooltipText.text  = tooltip.tooltipText;
                tooltipText.color = Color.Lerp(Color.clear, Color.white, lerp);
            }

            var viewerScale = this.GetViewerScale();

            tooltipTransform.localScale = m_TooltipScale * lerp * viewerScale;

            TooltipData toolTipData;

            m_Tooltips.TryGetValue(tooltip, out toolTipData);
            var highlightMaterial = toolTipData != null ? toolTipData.customHighlightMaterial : m_HighlightMaterial;

            tooltipUI.highlight.material = highlightMaterial;

            m_TooltipBackgroundMaterial.SetColor("_Color", Color.Lerp(UnityBrandColorScheme.darker, m_OriginalBackgroundColor, lerp));

            var placement = tooltip as ITooltipPlacement;

            // Adjust for alignment
            var offset = Vector3.zero;

            if (placement != null)
            {
                switch (placement.tooltipAlignment)
                {
                case TextAlignment.Right:
                    offset = Vector3.left;
                    break;

                case TextAlignment.Left:
                    offset = Vector3.right;
                    break;
                }
            }

            var rectTransform = tooltipUI.GetComponent <RectTransform>();
            var rect          = rectTransform.rect;
            var halfWidth     = rect.width * 0.5f;
            var halfHeight    = rect.height * 0.5f;

            if (placement != null)
            {
                offset *= halfWidth * rectTransform.lossyScale.x;
            }
            else
            {
                offset = Vector3.back * k_Offset * this.GetViewerScale();
            }

            MathUtilsExt.SetTransformOffset(target, tooltipTransform, offset * lerp, Quaternion.identity);

            if (placement != null)
            {
                var source   = placement.tooltipSource;
                var toSource = tooltipTransform.InverseTransformPoint(source.position);

                // Position spheres: one at source, one on the closest edge of the tooltip
                var spheres = tooltipUI.spheres;
                spheres[0].position = source.position;

                var attachedSphere = spheres[1];
                var boxSlope       = halfHeight / halfWidth;
                var toSourceSlope  = Mathf.Abs(toSource.y / toSource.x);

                halfHeight *= Mathf.Sign(toSource.y);
                halfWidth  *= Mathf.Sign(toSource.x);
                attachedSphere.localPosition = toSourceSlope > boxSlope
                                        ? new Vector3(0, halfHeight)
                                        : new Vector3(halfWidth, 0);

                // Align dotted line
                var attachedSpherePosition = attachedSphere.position;
                toSource = source.position - attachedSpherePosition;
                var midPoint   = attachedSpherePosition + toSource * 0.5f;
                var dottedLine = tooltipUI.dottedLine;
                var length     = toSource.magnitude;
                var uvRect     = dottedLine.uvRect;
                var worldScale = 1 / viewerScale;
                uvRect.width      = length * k_UVScale * worldScale;
                uvRect.xMin      += k_UVScrollSpeed * Time.deltaTime;
                dottedLine.uvRect = uvRect;

                var dottedLineTransform = dottedLine.transform.parent.GetComponent <RectTransform>();
                dottedLineTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, length / tooltipTransform.lossyScale.x);
                dottedLineTransform.position = midPoint;
                dottedLineTransform.rotation = Quaternion.LookRotation(toSource, -tooltipTransform.forward);
            }
        }
Esempio n. 18
0
            public void OnDragging()
            {
                if (m_Resizing)
                {
                    var viewerScale     = m_WorkspaceUI.GetViewerScale();
                    var pointerPosition = m_WorkspaceUI.GetPointerPosition(rayOrigin);
                    var dragVector      = (pointerPosition - m_DragStart) / viewerScale;
                    var bounds          = m_WorkspaceUI.bounds;
                    var transform       = m_WorkspaceUI.transform;

                    var positionOffsetForward = Vector3.Dot(dragVector, transform.forward) * 0.5f;
                    var positionOffsetRight   = Vector3.Dot(dragVector, transform.right) * 0.5f;

                    switch (m_Direction)
                    {
                    default:
                        bounds.size         = m_BoundsSizeStart + Vector3.back * Vector3.Dot(dragVector, transform.forward);
                        positionOffsetRight = 0;
                        break;

                    case ResizeDirection.Back:
                        bounds.size         = m_BoundsSizeStart + Vector3.forward * Vector3.Dot(dragVector, transform.forward);
                        positionOffsetRight = 0;
                        break;

                    case ResizeDirection.Left:
                        bounds.size           = m_BoundsSizeStart + Vector3.left * Vector3.Dot(dragVector, transform.right);
                        positionOffsetForward = 0;
                        break;

                    case ResizeDirection.Right:
                        bounds.size           = m_BoundsSizeStart + Vector3.right * Vector3.Dot(dragVector, transform.right);
                        positionOffsetForward = 0;
                        break;

                    case ResizeDirection.Front | ResizeDirection.Left:
                        bounds.size = m_BoundsSizeStart + Vector3.left * Vector3.Dot(dragVector, transform.right)
                                      + Vector3.back * Vector3.Dot(dragVector, transform.forward);
                        break;

                    case ResizeDirection.Front | ResizeDirection.Right:
                        bounds.size = m_BoundsSizeStart + Vector3.right * Vector3.Dot(dragVector, transform.right)
                                      + Vector3.back * Vector3.Dot(dragVector, transform.forward);
                        break;

                    case ResizeDirection.Back | ResizeDirection.Left:
                        bounds.size = m_BoundsSizeStart + Vector3.left * Vector3.Dot(dragVector, transform.right)
                                      + Vector3.forward * Vector3.Dot(dragVector, transform.forward);
                        break;

                    case ResizeDirection.Back | ResizeDirection.Right:
                        bounds.size = m_BoundsSizeStart + Vector3.right * Vector3.Dot(dragVector, transform.right)
                                      + Vector3.forward * Vector3.Dot(dragVector, transform.forward);
                        break;
                    }

                    if (m_WorkspaceUI.resize != null)
                    {
                        m_WorkspaceUI.resize(bounds);
                    }

                    var currentExtents = m_WorkspaceUI.bounds.extents;
                    var extents        = bounds.extents;
                    var absRight       = Mathf.Abs(positionOffsetRight);
                    var absForward     = Mathf.Abs(positionOffsetForward);
                    var positionOffset = transform.right * (absRight - (currentExtents.x - extents.x)) * Mathf.Sign(positionOffsetRight)
                                         + transform.forward * (absForward - (currentExtents.z - extents.z)) * Mathf.Sign(positionOffsetForward);

                    m_WorkspaceUI.transform.parent.position = m_PositionStart + positionOffset * viewerScale;
                    m_WorkspaceUI.OnResizing(rayOrigin);
                }
                else
                {
                    MathUtilsExt.SetTransformOffset(rayOrigin, m_WorkspaceUI.transform.parent, m_PositionOffset, m_RotationOffset);
                    m_WorkspaceUI.OnMoving(rayOrigin);
                }
            }
Esempio n. 19
0
            internal void UpdateMiniWorlds(ConsumeControlDelegate consumeControl)
            {
                if (m_MiniWorldIgnoreListDirty)
                {
                    UpdateMiniWorldIgnoreList();
                    m_MiniWorldIgnoreListDirty = false;
                }

                var objectsGrabber = evr.m_DirectSelection.objectsGrabber;

                foreach (var kvp in m_MiniWorldInputs)
                {
                    kvp.Key.ProcessInput(kvp.Value, consumeControl);
                }

                // 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;
                    miniWorldRayOrigin.position   = referenceTransform.position + Vector3.Scale(miniWorld.miniWorldTransform.InverseTransformPoint(originalRayOrigin.position), miniWorld.referenceTransform.localScale);
                    miniWorldRayOrigin.rotation   = referenceTransform.rotation * Quaternion.Inverse(miniWorld.miniWorldTransform.rotation) * originalRayOrigin.rotation;
                    miniWorldRayOrigin.localScale = Vector3.Scale(inverseScale, referenceTransform.localScale);

                    var directSelection = evr.m_DirectSelection;

                    // 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 (directSelection != null && 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;

                                    if (directSelection != 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
                                if (directSelection != null)
                                {
                                    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))
                                {
                                    if (directSelection != null)
                                    {
                                        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
                                    if (directSelection != null)
                                    {
                                        objectsGrabber.DropHeldObjects(miniWorldRayOrigin, out positionOffsets, out rotationOffsets);
                                        miniWorldRay.originalPositionOffsets = positionOffsets;
                                        miniWorldRay.originalRotationOffsets = rotationOffsets;
                                        miniWorldRay.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 (evr.m_Viewer.IsOverShoulder(originalRayOrigin))
                                {
                                    evr.m_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;
                }
            }
Esempio n. 20
0
        // Animate the LocalScale of the asset towards a common/unified scale
        // used when the asset is magnetized/attached to the proxy, after grabbing it from the asset grid
        IEnumerator ShowGrabbedObject()
        {
            var currentLocalScale            = m_DragObject.localScale;
            var currentPreviewOffset         = Vector3.zero;
            var currentPreviewRotationOffset = Quaternion.identity;

            if (m_PreviewObjectClone)
            {
                currentPreviewOffset = m_PreviewObjectClone.localPosition;
            }

            var         currentTime     = 0f;
            var         currentVelocity = 0f;
            const float kDuration       = 1f;

            var targetScale    = Vector3.one * k_IconPreviewScale;
            var pivotOffset    = Vector3.zero;
            var rotationOffset = Quaternion.AngleAxis(30, Vector3.right);

            if (m_PreviewObjectClone)
            {
                var viewerScale  = this.GetViewerScale();
                var maxComponent = m_PreviewBounds.size.MaxComponent() / viewerScale;
                targetScale = Vector3.one * maxComponent;

                // Object will preview at the same size when grabbed
                var previewExtents = m_PreviewBounds.extents / viewerScale;
                pivotOffset = m_PreviewPivotOffset / viewerScale;

                // If bounds are greater than offset, set to bounds
                if (previewExtents.y > pivotOffset.y)
                {
                    pivotOffset.y = previewExtents.y;
                }

                if (previewExtents.z > pivotOffset.z)
                {
                    pivotOffset.z = previewExtents.z;
                }

                if (maxComponent < k_MinPreviewScale)
                {
                    // Object will be preview at the minimum scale
                    targetScale = Vector3.one * k_MinPreviewScale;
                    pivotOffset = pivotOffset * scaleFactor + (Vector3.up + Vector3.forward) * 0.5f * k_MinPreviewScale;
                }

                if (maxComponent > k_MaxPreviewScale)
                {
                    // Object will be preview at the maximum scale
                    targetScale = Vector3.one * k_MaxPreviewScale;
                    pivotOffset = pivotOffset * scaleFactor + (Vector3.up + Vector3.forward) * 0.5f * k_MaxPreviewScale;
                }
            }

            while (currentTime < kDuration - 0.05f)
            {
                if (m_DragObject == null)
                {
                    yield break; // Exit coroutine if m_GrabbedObject is destroyed before the loop is finished
                }
                currentTime             = MathUtilsExt.SmoothDamp(currentTime, kDuration, ref currentVelocity, 0.5f, Mathf.Infinity, Time.deltaTime);
                m_DragObject.localScale = Vector3.Lerp(currentLocalScale, targetScale, currentTime);

                if (m_PreviewObjectClone)
                {
                    m_PreviewObjectClone.localPosition = Vector3.Lerp(currentPreviewOffset, pivotOffset, currentTime);
                    m_PreviewObjectClone.localRotation = Quaternion.Lerp(currentPreviewRotationOffset, rotationOffset, currentTime); // Compensate for preview origin rotation
                }

                yield return(null);
            }

            m_DragObject.localScale = targetScale;
        }
 public void Update(Transform parent)
 {
     MathUtilsExt.SetTransformOffset(parent, transform, m_LocalPositionOffset, m_RotationOffset);
 }
Esempio n. 22
0
        void UpdateVisuals(ITooltip tooltip, TooltipData tooltipData, float lerp)
        {
            var target            = tooltipData.GetTooltipTarget(tooltip);
            var tooltipUI         = tooltipData.tooltipUI;
            var placement         = tooltipData.placement;
            var orientationWeight = tooltipData.orientationWeight;
            var tooltipTransform  = tooltipUI.transform;

            lerp = MathUtilsExt.SmoothInOutLerpFloat(lerp); // shape the lerp for better presentation
            var transitionLerp = MathUtilsExt.SmoothInOutLerpFloat(1.0f - Mathf.Clamp01((Time.time - tooltipData.transitionTime) / k_ChangeTransitionDuration));

            var viewerScale = this.GetViewerScale();

            tooltipTransform.localScale = m_TooltipScale * lerp * viewerScale;

            // Adjust for alignment
            var offset = GetTooltipOffset(tooltipUI, placement, tooltipData.transitionOffset * transitionLerp);

            // The rectTransform expansion is handled in the Tooltip dynamically, based on alignment & text length
            var rotationOffset = Quaternion.identity;
            var camTransform   = CameraUtils.GetMainCamera().transform;

            if (Vector3.Dot(camTransform.forward, target.forward) < 0)
            {
                rotationOffset *= k_FlipYRotation;
            }

            if (Vector3.Dot(camTransform.up, target.up) + orientationWeight < 0)
            {
                rotationOffset *= k_FlipZRotation;
                tooltipData.orientationWeight = -k_TextOrientationWeight;
            }
            else
            {
                tooltipData.orientationWeight = k_TextOrientationWeight;
            }

            MathUtilsExt.SetTransformOffset(target, tooltipTransform, offset * lerp, rotationOffset);

            if (placement != null)
            {
                //TODO: Figure out why rect gives us different height/width than GetWorldCorners
                tooltipUI.rectTransform.GetWorldCorners(k_Corners);
                var bottomLeft = k_Corners[0];
                var halfWidth  = (bottomLeft - k_Corners[2]).magnitude * 0.5f;
                var halfHeight = (bottomLeft - k_Corners[1]).magnitude * 0.5f;

                var source   = placement.tooltipSource;
                var toSource = tooltipTransform.InverseTransformPoint(source.position);

                // Position spheres: one at source, one on the closest edge of the tooltip
                var spheres = tooltipUI.spheres;
                spheres[0].position = source.position;

                var attachedSphere = spheres[1];
                var boxSlope       = halfHeight / halfWidth;
                var toSourceSlope  = Mathf.Abs(toSource.y / toSource.x);

                var parentScale = attachedSphere.parent.lossyScale;
                halfHeight *= Mathf.Sign(toSource.y) / parentScale.x;
                halfWidth  *= Mathf.Sign(toSource.x) / parentScale.y;
                attachedSphere.localPosition = toSourceSlope > boxSlope
                    ? new Vector3(0, halfHeight)
                    : new Vector3(halfWidth, 0);

                // Align dotted line
                var attachedSpherePosition = attachedSphere.position;
                toSource = source.position - attachedSpherePosition;
                var midPoint   = attachedSpherePosition + toSource * 0.5f;
                var dottedLine = tooltipUI.dottedLine;
                var length     = toSource.magnitude;
                var uvRect     = dottedLine.uvRect;
                var worldScale = 1 / viewerScale;
                uvRect.width      = length * k_UVScale * worldScale;
                uvRect.xMin      += k_UVScrollSpeed * Time.deltaTime;
                dottedLine.uvRect = uvRect;

                var dottedLineTransform = dottedLine.transform.parent.GetComponent <RectTransform>();
                dottedLineTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, length / tooltipTransform.lossyScale.x);
                dottedLineTransform.position = midPoint;
                dottedLineTransform.rotation = Quaternion.LookRotation(toSource, -tooltipTransform.forward);
            }
        }
 public void GetCurrentOffsets(Transform parent)
 {
     MathUtilsExt.GetTransformOffset(parent, transform, out m_LocalPositionOffset, out m_RotationOffset);
     m_OriginalLocalPositionOffset = m_LocalPositionOffset;
 }