using UnityEngine;
using Ximmerse.XR.Utils;
using Ximmerse.XR.Internal;
using System.Collections;
using System.Linq;
namespace Ximmerse.XR.Tag
{
///
/// Implement tracing capabilities and handle appropriate events.
///
public class XRTracking : MonoBehaviour
{
#region Property
TrackingManager trackingManager;
GameObject tracking_clone;
private long predTimestampNano = 0;
private Vector3 poslost;
GameObject followGo;
Quaternion rotlost;
TagTracking tagTracking;
private TrackingEvent trackingEvent;
private bool first = false;
private bool exit = false;
private bool onfirstTrackingEnter = false;
private bool onTrackingEnter = false;
private bool onTrackingStay = false;
private bool onTrackingExit = false;
private bool trackingstate;
int index = 0;
long timestamp = 0;
int state = 0;
float posX = 0;
float posY = 0;
float posZ = 0;
float rotX = 0;
float rotY = 0;
float rotZ = 0;
float rotW = 0;
float confidence = 0;
float marker_distance = 0;
#endregion
#region Unity
private void Start()
{
CloneTagTracking();
trackingEvent = gameObject.GetComponent();
}
private void Update()
{
tagTracking = GetComponent();
TagTracking();
if (trackingEvent != null)
{
if (OnFirstTrackingEnter())
{
trackingEvent.onFirstTrackingEvent?.Invoke();
}
if (OnTrackingEnter())
{
trackingEvent.onTrackingEnter?.Invoke();
}
if (OnTrackingStay())
{
trackingEvent.onTrackingStay?.Invoke();
}
if (OnTrackingExit())
{
trackingEvent.onTrackingExit?.Invoke();
}
}
}
#endregion
#region Method
///
/// Correct the coordinate information.
///
private void CloneTagTracking()
{
trackingManager = TrackingManager.Instance;
if (trackingManager == null)
{
trackingManager = new GameObject("TagTracking Manager").AddComponent();
}
tracking_clone = new GameObject(gameObject.name);
tracking_clone.transform.parent = trackingManager.transform;
}
///
/// Tag Tracking function
///
private void TagTracking()
{
#if !UNITY_EDITOR
NativePluginApi.Unity_getTagTracking2(tagTracking.TrackId,
ref index, ref timestamp, ref state, ref posX, ref posY, ref posZ,
ref rotX, ref rotY, ref rotZ, ref rotW,
ref confidence, ref marker_distance);
#endif
if (TagProfileLoading.Instance!=null)
{
trackingstate = IsTracking();
if (trackingstate)
{
poslost = Vector3.zero;
rotlost = new Quaternion(0, 0, 0, 1);
tracking_clone.transform.localPosition = new Vector3(posX, posY, posZ);
tracking_clone.transform.localRotation = new Quaternion(rotX, rotY, rotZ, rotW);
gameObject.transform.position = tracking_clone.transform.position;
gameObject.transform.rotation = tracking_clone.transform.rotation;
if (tagTracking.DebugView)
{
DrawDebugView(tagTracking.Size);
}
}
else
{
if (tagTracking.TrackingIsLost == LostState.FollowHead)
{
if (poslost == Vector3.zero && rotlost == new Quaternion(0, 0, 0, 1))
{
poslost = gameObject.transform.position;
rotlost = gameObject.transform.rotation;
if (followGo == null)
{
followGo = new GameObject();
}
followGo.transform.position = poslost;
followGo.transform.rotation = rotlost;
if (trackingManager.xROrigin != null)
{
followGo.transform.parent = trackingManager.xROrigin.Camera.transform;
}
else
{
followGo.transform.parent = FindObjectOfType().transform;
throw new System.Exception("XR Origin is not found");
}
}
gameObject.transform.position = followGo.transform.position;
gameObject.transform.rotation = followGo.transform.rotation;
}
}
}
}
///
/// Plot the axes
///
///
private void DrawDebugView(float size)
{
RxDraw.DrawWirePlane(transform.position, transform.rotation, size, size, Color.green);
if (trackingManager.xROrigin != null)
{
var textRotation = Quaternion.LookRotation(transform.position - trackingManager.xROrigin.Camera.transform.position);
textRotation = textRotation.PitchNYaw();
string debugTxt = tagTracking.TrackId.ToString();
RxDraw.Text3D(transform.position, textRotation, 0.02f, debugTxt, Color.green);
}
else
{
var textRotation = Quaternion.LookRotation(transform.position - FindObjectOfType().transform.position);
textRotation = textRotation.PitchNYaw();
string debugTxt = tagTracking.TrackId.ToString();
RxDraw.Text3D(transform.position, textRotation, 0.02f, debugTxt, Color.green);
}
RxDraw.DrawTranslateGizmos(transform.position, transform.rotation, size * 0.85f);
}
///
/// Get the Tag tracking status
///
///
protected bool IsTracking()
{
if (TagProfileLoading.Instance.TrackingTagList.Contains(tagTracking.TrackId))
{
return true;
}
else return false;
}
///
/// First identification
///
///
private bool OnFirstTrackingEnter()
{
if (trackingstate && first == false)
{
first = true;
onfirstTrackingEnter = true;
}
else if (trackingstate && first == true)
{
onfirstTrackingEnter = false;
}
return onfirstTrackingEnter;
}
///
/// Identify
///
///
private bool OnTrackingEnter()
{
if (trackingstate && onTrackingEnter == false && onTrackingStay == false)
{
onTrackingEnter = true;
onTrackingStay = true;
}
else
{
onTrackingEnter = false;
}
return onTrackingEnter;
}
///
/// Identifying
///
///
private bool OnTrackingStay()
{
if (trackingstate)
{
onTrackingStay = true;
exit = true;
}
else
{
onTrackingStay = false;
}
return onTrackingStay;
}
///
/// lose
///
///
private bool OnTrackingExit()
{
if (trackingstate == false && exit)
{
exit = false;
onTrackingExit = true;
}
else
{
onTrackingExit = false;
}
return onTrackingExit;
}
#endregion
}
}