mixedreality/com.microsoft.mixedreality..../SDK/Features/UX/Scripts/Tooltips/ToolTipUtility.cs

122 lines
5.7 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.UI
{
/// <summary>
/// Static class providing useful functions for
/// finding ToolTip Attach point information.
/// </summary>
public static class ToolTipUtility
{
private const int NumPivotLocations = 8;
/// <summary>
/// Avoid running this query in Update function because calculating Vector3.Distance requires sqr root calculation (expensive)
/// Instead, find strategic moments to update nearest pivot (i.e. only once when ToolTip becomes active)
/// </summary>
/// <param name="anchor">Transform of object serving as anchor for tooltip</param>
/// <param name="contentParent">Transform for the tooltip content</param>
/// <param name="localPivotPositions">list of positions to find the closest</param>
/// <param name="pivotType">pivot type needed for calculation of closest</param>
/// <returns>Vector3 the point in localPivotPositions which is closest to the anchor position</returns>
public static Vector3 FindClosestAttachPointToAnchor(Transform anchor, Transform contentParent, Vector3[] localPivotPositions, ToolTipAttachPoint pivotType)
{
Vector3 currentPivot;
Vector3 nearPivot = Vector3.zero;
Vector3 anchorPosition = anchor.position;
float nearDist = Mathf.Infinity;
if (localPivotPositions == null || localPivotPositions.Length < NumPivotLocations)
{
return nearPivot;
}
switch (pivotType)
{
case ToolTipAttachPoint.Center:
return nearPivot;
// Search all pivots
case ToolTipAttachPoint.Closest:
for (int i = 0; i < localPivotPositions.Length; i++)
{
currentPivot = localPivotPositions[i];
float sqrDist = (anchorPosition - contentParent.TransformPoint(currentPivot)).sqrMagnitude;
if (sqrDist < nearDist)
{
nearDist = sqrDist;
nearPivot = currentPivot;
}
}
break;
// Search corner pivots
case ToolTipAttachPoint.ClosestCorner:
for (int i = (int)ToolTipAttachPoint.BottomRightCorner; i < (int)ToolTipAttachPoint.TopLeftCorner; i++)
{
currentPivot = localPivotPositions[i];
float sqrDist = (anchorPosition - contentParent.TransformPoint(currentPivot)).sqrMagnitude;
if (sqrDist < nearDist)
{
nearDist = sqrDist;
nearPivot = currentPivot;
}
}
break;
// Search middle pivots
case ToolTipAttachPoint.ClosestMiddle:
for (int i = (int)ToolTipAttachPoint.BottomMiddle; i < (int)ToolTipAttachPoint.LeftMiddle; i++)
{
currentPivot = localPivotPositions[i];
float sqrDist = (anchorPosition - contentParent.TransformPoint(currentPivot)).sqrMagnitude;
if (sqrDist < nearDist)
{
nearDist = sqrDist;
nearPivot = currentPivot;
}
}
break;
default:
// For all other types, just use the array position or contentParent
// position if there is no array provided.
nearPivot = localPivotPositions.Length == 0
? contentParent.position
: localPivotPositions[(int)pivotType];
break;
}
return nearPivot;
}
/// <summary>
/// gets an array of pivot positions
/// </summary>
/// <param name="pivotPositions">ref array that gets filled with positions</param>
/// <param name="localContentSize">the xy scale of the tooltip</param>
public static void GetAttachPointPositions(ref Vector3[] pivotPositions, Vector2 localContentSize)
{
if (pivotPositions == null || pivotPositions.Length < NumPivotLocations)
{
pivotPositions = new Vector3[NumPivotLocations];
}
// Get the extents of our content size
localContentSize *= 0.5f;
pivotPositions[(int)ToolTipAttachPoint.BottomMiddle] = new Vector3(0f, -localContentSize.y, 0f);
pivotPositions[(int)ToolTipAttachPoint.TopMiddle] = new Vector3(0f, localContentSize.y, 0f);
pivotPositions[(int)ToolTipAttachPoint.LeftMiddle] = new Vector3(-localContentSize.x, 0f, 0f); // was right
pivotPositions[(int)ToolTipAttachPoint.RightMiddle] = new Vector3(localContentSize.x, 0f, 0f); // was left
pivotPositions[(int)ToolTipAttachPoint.BottomLeftCorner] = new Vector3(-localContentSize.x, -localContentSize.y, 0f); // was right
pivotPositions[(int)ToolTipAttachPoint.BottomRightCorner] = new Vector3(localContentSize.x, -localContentSize.y, 0f); // was left
pivotPositions[(int)ToolTipAttachPoint.TopLeftCorner] = new Vector3(-localContentSize.x, localContentSize.y, 0f); // was right
pivotPositions[(int)ToolTipAttachPoint.TopRightCorner] = new Vector3(localContentSize.x, localContentSize.y, 0f); // was left
}
}
}