// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using UnityEngine;
using UnityEngine.Serialization;
namespace Microsoft.MixedReality.Toolkit.Utilities.Solvers
{
///
/// InBetween solver positions an object in-between two tracked transforms.
///
[AddComponentMenu("Scripts/MRTK/SDK/InBetween")]
public class InBetween : Solver
{
[SerializeField]
[Tooltip("Distance along the center line the object will be located. 0.5 is halfway, 1.0 is at the first transform, 0.0 is at the second transform.")]
[Range(0f, 1f)]
private float partwayOffset = 0.5f;
///
/// Distance along the center line the object will be located. 0.5 is halfway, 1.0 is at the first transform, 0.0 is at the second transform.
///
public float PartwayOffset
{
get { return partwayOffset; }
set { partwayOffset = Mathf.Clamp(value, 0.0f, 1.0f); }
}
[SerializeField]
[Tooltip("Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field.")]
[HideInInspector]
[FormerlySerializedAs("trackedObjectForSecondTransform")]
private TrackedObjectType secondTrackedObjectType = TrackedObjectType.Head;
///
/// Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field.
///
public TrackedObjectType SecondTrackedObjectType
{
get { return secondTrackedObjectType; }
set
{
if (secondTrackedObjectType != value)
{
secondTrackedObjectType = value;
UpdateSecondSolverHandler();
}
}
}
///
/// Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field.
///
[Obsolete("Use SecondTrackedObjectType property instead")]
public TrackedObjectType TrackedObjectForSecondTransform
{
get { return secondTrackedObjectType; }
set
{
if (secondTrackedObjectType != value)
{
secondTrackedObjectType = value;
UpdateSecondSolverHandler();
}
}
}
[SerializeField]
[Tooltip("This transform overrides any Tracked Object as the second point for the In Between.")]
[HideInInspector]
private Transform secondTransformOverride = null;
///
/// This transform overrides any Tracked Object as the second point for the In Between
///
public Transform SecondTransformOverride
{
get { return secondTransformOverride; }
set
{
if (secondTransformOverride != value)
{
secondTransformOverride = value;
UpdateSecondSolverHandler();
}
}
}
private SolverHandler secondSolverHandler;
protected void OnValidate()
{
UpdateSecondSolverHandler();
}
protected override void Start()
{
base.Start();
// We need to get the secondSolverHandler ready before we tell them both to seek a tracked object.
secondSolverHandler = gameObject.AddComponent();
secondSolverHandler.UpdateSolvers = false;
UpdateSecondSolverHandler();
}
///
public override void SolverUpdate()
{
if (SolverHandler != null && secondSolverHandler != null)
{
if (SolverHandler.TransformTarget != null && secondSolverHandler.TransformTarget != null)
{
AdjustPositionForOffset(SolverHandler.TransformTarget, secondSolverHandler.TransformTarget);
}
}
}
private void AdjustPositionForOffset(Transform targetTransform, Transform secondTransform)
{
if (targetTransform != null && secondTransform != null)
{
Vector3 centerline = targetTransform.position - secondTransform.position;
GoalPosition = secondTransform.position + (centerline * partwayOffset);
}
}
private void UpdateSecondSolverHandler()
{
if (secondSolverHandler != null)
{
secondSolverHandler.TrackedTargetType = secondTrackedObjectType;
if (secondTrackedObjectType == TrackedObjectType.CustomOverride && secondTransformOverride != null)
{
secondSolverHandler.TransformOverride = secondTransformOverride;
}
}
}
}
}