using UnityEngine;
using System.Collections.Generic;
using Lean.Common;
namespace Lean.Touch
{
/// This class stores a snapshot of where a finger was at a specific point in time, and provides methods to look back in time to find a point based on a time.
public class LeanSnapshot
{
/// The age of the finger when this snapshot was created.
public float Age;
/// The screen position of the finger when this snapshot was created.
public Vector2 ScreenPosition;
/// This will return the world position of this snapshot based on the distance from the camera.
public Vector3 GetWorldPosition(float distance, Camera camera = null)
{
// Make sure the camera exists
camera = LeanHelper.GetCamera(camera);
if (camera != null)
{
var point = new Vector3(ScreenPosition.x, ScreenPosition.y, distance);
return camera.ScreenToWorldPoint(point);
}
else
{
Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.");
}
return default(Vector3);
}
public static List InactiveSnapshots = new List(1000);
/// Return the last inactive snapshot, or allocate a new one.
public static LeanSnapshot Pop()
{
if (InactiveSnapshots.Count > 0)
{
var index = InactiveSnapshots.Count - 1;
var snapshot = InactiveSnapshots[index];
InactiveSnapshots.RemoveAt(index);
return snapshot;
}
return new LeanSnapshot();
}
/// This will return the recorded position of the current finger when it was at 'targetAge'.
public static bool TryGetScreenPosition(List snapshots, float targetAge, ref Vector2 screenPosition)
{
if (snapshots != null && snapshots.Count > 0)
{
// Below start?
var snapshotF = snapshots[0];
if (targetAge <= snapshotF.Age)
{
screenPosition = snapshotF.ScreenPosition; return true;
}
// After end?
var snapshotL = snapshots[snapshots.Count - 1];
if (targetAge >= snapshotL.Age)
{
screenPosition = snapshotL.ScreenPosition; return true;
}
// Interpolate to find screenPosition at targetAge
var lowerIndex = GetLowerIndex(snapshots, targetAge);
var upperIndex = lowerIndex + 1;
var lower = snapshots[lowerIndex];
var upper = upperIndex < snapshots.Count ? snapshots[upperIndex] : lower;
var across = Mathf.InverseLerp(lower.Age, upper.Age, targetAge);
screenPosition = Vector2.Lerp(lower.ScreenPosition, upper.ScreenPosition, across);
return true;
}
return false;
}
/// This will return snapshot information at the specified index, if it exists.
/// NOTE: This assumes snapshots does not contain any null elements.
public static bool TryGetSnapshot(List snapshots, int index, ref float age, ref Vector2 screenPosition)
{
if (index >= 0 && index < snapshots.Count)
{
var snapshot = snapshots[index];
age = snapshot.Age;
screenPosition = snapshot.ScreenPosition;
return true;
}
return true;
}
/// This will get the index of the closest snapshot whose age is under targetAge
/// NOTE: This assumes snapshots does not contain any null elements.
public static int GetLowerIndex(List snapshots, float targetAge)
{
if (snapshots != null)
{
var count = snapshots.Count;
if (count > 0)
{
for (var i = count - 1; i >= 0; i--)
{
if (snapshots[i].Age <= targetAge)
{
return i;
}
}
}
return 0;
}
return -1;
}
}
}