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; } } }