// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Physics
{
///
/// Implements a scale logic that will scale an object based on the
/// ratio of the distance between hands.
/// object_scale = start_object_scale * curr_hand_dist / start_hand_dist
///
/// Usage:
/// When a manipulation starts, call Setup.
/// Call Update any time to update the move logic and get a new rotation for the object.
///
internal class TwoHandScaleLogic
{
private Vector3 startObjectScale;
private float startHandDistanceMeters;
///
/// Initialize system with source info from controllers/hands
///
/// Array with positions of down pointers
/// Transform of gameObject to be manipulated
public virtual void Setup(Vector3[] handsPressedArray, Transform manipulationRoot)
{
startHandDistanceMeters = GetMinDistanceBetweenHands(handsPressedArray);
startObjectScale = manipulationRoot.transform.localScale;
}
///
/// update GameObject with new Scale state
///
/// Array with positions of down pointers, order should be the same as handsPressedArray provided in Setup
/// a Vector3 describing the new Scale of the object being manipulated
public virtual Vector3 UpdateMap(Vector3[] handsPressedArray)
{
var ratioMultiplier = GetMinDistanceBetweenHands(handsPressedArray) / startHandDistanceMeters;
return startObjectScale * ratioMultiplier;
}
private float GetMinDistanceBetweenHands(Vector3[] handsPressedArray)
{
var result = float.MaxValue;
for (int i = 0; i < handsPressedArray.Length; i++)
{
for (int j = i + 1; j < handsPressedArray.Length; j++)
{
var distance = Vector3.Distance(handsPressedArray[i], handsPressedArray[j]);
if (distance < result)
{
result = distance;
}
}
}
return result;
}
}
}