using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.IO;
using System;
using Object = UnityEngine.Object;
using System.Threading;
using System.Threading.Tasks;
namespace Ximmerse.XR
{
///
/// Internal object : represents a json file that defines the calibration data path and marker reference.
///
[System.Serializable]
internal class TrackedObjectJson
{
[System.Serializable]
public class CardGroupJson
{
public string CalibFile;
public string ModeType;
public int GroupID;
public int[] Markers;
public float[] MarkersSize;
}
[System.Serializable]
public class SingleCardJson
{
public string CalibFile;
public int[] Markers;
public float[] MarkersSize;
}
[SerializeField]
public CardGroupJson CARD_GROUP;
[SerializeField]
public SingleCardJson CARD_SINGLE;
public bool IsCardGroup
{
get
{
return CARD_GROUP != null && !string.IsNullOrEmpty(CARD_GROUP.CalibFile) && CARD_GROUP.GroupID >= 0;
}
}
#region Ext Methods
///
/// Fills the trackable json's content to a dictionary map where key = markerID, value = marker's config info.
///
/// Configuration map.
public void FillDictionary(Dictionary configurationMap)
{
var jsonObj = this;
var map = configurationMap;
if (jsonObj.CARD_SINGLE.Markers != null && jsonObj.CARD_SINGLE.MarkersSize != null && !string.IsNullOrEmpty(jsonObj.CARD_SINGLE.CalibFile) &&
jsonObj.CARD_SINGLE.Markers.Length == jsonObj.CARD_SINGLE.MarkersSize.Length && jsonObj.CARD_SINGLE.Markers.Length > 0)
{
for (int j = 0, jsonObjCARD_SINGLEMarkersLength = jsonObj.CARD_SINGLE.Markers.Length; j < jsonObjCARD_SINGLEMarkersLength; j++)
{
int markerID = jsonObj.CARD_SINGLE.Markers[j];
float markerSize = jsonObj.CARD_SINGLE.MarkersSize[j];
var markerConfigInfo = new MarkerConfigInfo()
{
MarkerID = markerID,
MarkerConfigSize = markerSize,
markerType = ConfigMarkerType.SingleMarker,
GroupType = string.Empty,
};
if (!map.ContainsKey(markerID))
{
map.Add(markerID, markerConfigInfo);
}
else
{
map[markerID] = markerConfigInfo;
}
}
}
//For card_group:
else if (jsonObj.CARD_GROUP.Markers != null && jsonObj.CARD_GROUP.MarkersSize != null && !string.IsNullOrEmpty(jsonObj.CARD_GROUP.CalibFile) &&
jsonObj.CARD_GROUP.Markers.Length == jsonObj.CARD_GROUP.MarkersSize.Length && jsonObj.CARD_GROUP.Markers.Length > 0)
{
//add marke group:
{
int groupID = jsonObj.CARD_GROUP.GroupID;
float markerSize = jsonObj.CARD_GROUP.MarkersSize[0];
var markerConfigInfo = new MarkerConfigInfo()
{
MarkerID = groupID,
MarkerConfigSize = markerSize,
markerType = ConfigMarkerType.GroupNode,
GroupType = jsonObj.CARD_GROUP.ModeType.ToUpper(),
};
if (!map.ContainsKey(groupID))
{
map.Add(groupID, markerConfigInfo);
}
else
{
map[groupID] = markerConfigInfo;
}
}
//add sub-marker:
{
for (int j = 0, jsonObjCARD_GROUPMarkersLength = jsonObj.CARD_GROUP.Markers.Length; j < jsonObjCARD_GROUPMarkersLength; j++)
{
int markerID = jsonObj.CARD_GROUP.Markers[j];
float markerSize = jsonObj.CARD_GROUP.MarkersSize[j];
var markerConfigInfo = new MarkerConfigInfo()
{
MarkerID = markerID,
MarkerConfigSize = markerSize,
markerType = ConfigMarkerType.MarkerGroup_Submarker,
GroupType = string.Empty,
};
if (!map.ContainsKey(markerID))
{
map.Add(markerID, markerConfigInfo);
}
else
{
map[markerID] = markerConfigInfo;
}
}
}
}
}
#endregion
}
///
/// Tracking item.
///
[System.Serializable]
public class TrackingItem
{
///
/// Editor only
///
public UnityEngine.Object JSONConfig = null;
///
/// The name of the json file.
///
public string jsonName;
///
/// The content of the json.
///
public string jsonContent;
[SerializeField]
internal int[] m_MarkerIDs;
///
/// The marker IDs inside the Json file
///
public int[] MarkerIDs
{
get => m_MarkerIDs;
}
///
/// The datas
///
[SerializeField]
[HideInInspector]
internal byte[] m_Data;
///
/// Marker size
///
[SerializeField]
internal float[] m_MarkerSizes;
///
/// The marker size.
///
public float[] MarkerSizes
{
get => m_MarkerSizes;
}
[SerializeField]
internal bool m_TrackedAsGroup;
///
/// If true, the markers are taken in a group when being tracked, as reference group id.
/// If false, the markers are tracked seperately as single piece.
///
public bool TrackedAsGroup
{
get => m_TrackedAsGroup;
}
[System.NonSerialized]
internal TrackedObjectJson trackableJson;
}
///
/// Marker config info : a single marker object's config info from JSON.
///
internal struct MarkerConfigInfo
{
///
/// The marker identifier.
///
public int MarkerID;
///
/// The size of the marker config.
///
public float MarkerConfigSize;
///
/// 是 Marker 组还是 单个Marker ?
///
public ConfigMarkerType markerType;
///
/// The type of the group : controller | cube | map
///
public string GroupType;
}
///
/// Config marker type.
///
internal enum ConfigMarkerType
{
///
/// The marker is config as a single card
///
SingleMarker = 0,
///
/// The marker is config as a sub-card of the group
///
MarkerGroup_Submarker = 1,
///
/// This is a top-group.
///
GroupNode = 2,
}
[CreateAssetMenu(menuName = "Ximmerse/Tracking Profile", fileName = "TrackingProfile")]
public sealed class ObjectTrackingProfile : ScriptableObject
{
[System.NonSerialized]
bool m_IsLoaded;
///
/// Has the tracking profile loaded by tracking system ?
///
/// true if is loaded; otherwise, false.
public bool IsLoaded
{
get
{
return m_IsLoaded;
}
internal set
{
m_IsLoaded = value;
}
}
[Multiline(3)]
public string Description;
///
/// Config the tracking items.
///
[SerializeField]
TrackingItem[] items = new TrackingItem[] {
};
///
/// Gets the tracking items.
///
/// The tracking items.
public TrackingItem[] trackingItems
{
get
{
return items;
}
}
[SerializeField]
bool m_TrackBeacons = true;
///
/// Gets a value indicating whether this track beacon.
///
/// true if track beacon; otherwise, false.
public bool TrackBeacons
{
get
{
return m_TrackBeacons;
}
}
///
/// Customize tracking calibration files.
///
[SerializeField, Tooltip("If true, enables additional object tracking. Develoeprs may add the tracking calibration files by drag and drop to the below area.")]
bool m_CustomTrackingCalibrationFiles;
///
/// Gets a value indicating whether this customize tracking
/// calibration files.
///
/// true if custom tracking calibration files; otherwise, false.
public bool CustomTrackingCalibrationFiles
{
get
{
return m_CustomTrackingCalibrationFiles;
}
}
private void OnEnable()
{
}
private void Awake()
{
//Copies json and dat to internal path :
if (Application.platform == RuntimePlatform.Android)
{
if (s_BuiltTrackingItemsToCopy == null)
{
s_BuiltTrackingItemsToCopy = new List();
}
s_BuiltTrackingItemsToCopy.AddRange(this.trackingItems);
if (!copyThreadStarted)
Task.Run(CopyData);
}
}
static List s_BuiltTrackingItemsToCopy = null;
private static bool copyThreadStarted = false;
///
/// Copy built player's tracking files to internal storage.
///
private static void CopyData()
{
Thread.Sleep(10);
while (string.IsNullOrEmpty(SDKVariants.kTrackingDataDir_Internal))
{
Thread.Sleep(10);
}
foreach (var item in s_BuiltTrackingItemsToCopy)
{
string jsonPath = Path.Combine(SDKVariants.kTrackingDataDir_Internal, item.jsonName);
string dataPath = Path.Combine(SDKVariants.kTrackingDataDir_Internal, Path.GetFileNameWithoutExtension(item.jsonName) + ".dat");
if (!File.Exists(jsonPath))
{
File.WriteAllText(jsonPath, item.jsonContent);
Debug.LogFormat("Tracking profile : {0} has been copied to internal path", item.jsonName);
}
if (!File.Exists(dataPath))
{
File.WriteAllBytes(dataPath, item.m_Data);
Debug.LogFormat("Tracking data : {0} has been copied to internal path", item.jsonName);
}
}
s_BuiltTrackingItemsToCopy = null;
}
}
}