using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Scripting;
using Unity.Collections;
using Unity.Jobs;
using System.IO;
using System;
using Ximmerse.XR.Utils;
using Ximmerse.XR.Internal;
using Ximmerse.XR.Collections;
namespace Ximmerse.XR
{
///
/// Track event.
///
/// Array of all tracked markers.
/// Array of all untracked markers.
/// Array of newly tracked markers.
/// Array of lost tracked markers.
public delegate void TrackEvent(NativeArray tracked, NativeArray unTracked, NativeArray added, NativeArray lost);
///
/// Ximmerse XR manager.
///
[Preserve]
[DefaultExecutionOrder(-20000)]
[AddComponentMenu(".")]//dont add this component manually, it will be added by XR loader.
public sealed class XRManager : MonoBehaviour
{
static XRManager instance;
public static XRManager Instance
{
get => instance;
}
///
/// Event is fired per frame, describes the markers' tracking status
///
public static event TrackEvent OnTrackUpdate;
///
/// Event is fired per frame, after processing the tracking data.
///
public static event Action OnPostTrackUpdate;
xNativeList trackingResultsPerFrame = xNativeList.Create(64);
Camera m_mainCam;
public Camera mainCam
{
get
{
if (!m_mainCam)
{
m_mainCam = Camera.main;
}
return m_mainCam;
}
}
Matrix4x4 mainCameraAwakePose;
private void Awake()
{
instance = this;
}
private void OnDestroy()
{
if (ReferenceEquals(instance, this))
{
instance = null;
}
}
private IEnumerator Start()
{
StartCoroutine(CleanJob());
while (!mainCam)
{
yield return null;
}
mainCameraAwakePose = Matrix4x4.TRS(mainCam.transform.position, mainCam.transform.rotation, Vector3.one);
}
private void Update()
{
if (!SDKVariants.IsSupported || !Application.isPlaying || !mainCam)
{
return;
}
SvrPluginAndroid.Unity_setFrame(Time.frameCount);
//Matrix4x4 trans = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one);
//if (mainCam.transform.parent)
//{
// var m1 = mainCam.transform.root.localToWorldMatrix;
// var m2 = mainCam.transform.GetChild(0).localToWorldMatrix;
// trans = m1 * m2;
//}
XDevicePlugin.UpdateTracking(mainCam.transform.parent ? mainCam.transform.parent.localToWorldMatrix : mainCameraAwakePose, out TrackingSummary summary);
trackingResultsPerFrame.Clear();
trackingResultsPerFrame.AddRange(summary.tracked);
try
{
//Debug.LogFormat("Summary of tracking: {0}, unTracked = {1}, newTracked = {2}, lost = {3}", summary.tracked.Length, summary.unTracked.Length, summary.newTracked.Length, summary.lostTracked.Length);
OnTrackUpdate?.Invoke(summary.tracked, summary.unTracked, summary.newTracked, summary.lostTracked);
}
catch (Exception e)
{
Debug.LogException(e);
}
//Draw gizmos of tracked marker:
if (SDKVariants.DrawTrackedMarkerGizmos)
{
foreach (var tracked in summary.tracked)
{
float size = tracked.size;
//if(markerCfgInfo.markerType == ConfigMarkerType.MarkerGroup_Submarker || markerCfgInfo.markerType == ConfigMarkerType.SingleMarker)
{
RxDraw.DrawWirePlane(tracked.worldPose.position, tracked.worldPose.rotation, size, size, new Color(0.2f, 0.88f, 0.2f, 1));
var textRotation = Quaternion.LookRotation(transform.position - mainCam.transform.position);
textRotation = textRotation.PitchNYaw();
string debugTxt = tracked.id.ToString();
if (SDKVariants.DrawDetailTrackedInfo)
{
Vector3 p = tracked.worldPose.position;
Vector3 e = tracked.worldPose.rotation.eulerAngles.PrettyAngle();
float confidence = tracked.trackedConfidence;
debugTxt =
$"{tracked.id.ToString()}\r\n P={p.ToString("F2")} \r\n Q={e.ToString("F2")} \r\n Distance={tracked.trackedDistance.ToString("F2")}m \r\n Confidence = {confidence.ToString("F3")}";
}
RxDraw.Text3D(tracked.worldPose.position, tracked.worldPose.rotation, 0.012f, debugTxt, new Color(0.96f, 0.9f, 0.93f, 1));
}
RxDraw.DrawTranslateGizmos(tracked.worldPose.position, tracked.worldPose.rotation, size * 0.85f);
}
}
summary.Dispose();
OnPostTrackUpdate?.Invoke();
}
IEnumerator CleanJob()
{
var eof = new WaitForEndOfFrame();
while (true)
{
yield return eof;
trackingResultsPerFrame.Clear();
}
}
public static TrackingResult GetTrackingResult(int id)
{
if (!instance)
{
return default(TrackingResult);
}
var l = instance.trackingResultsPerFrame;
foreach (var t in l)
{
if (t.id == id)
{
return t;
}
}
return default(TrackingResult);
}
}
}