/// <summary> /// Get a fixed-size double array from an area description metadata. /// </summary> /// <returns><c>true</c>, if a double array of the specified size was found, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="expectedCount">Expected size of the array.</param> /// <param name="value">Output value for the specified key.</param> private static bool _MetadataGetDoubleArray(IntPtr rawMetadata, string key, int expectedCount, out double[] value) { value = new double[expectedCount]; IntPtr rawValue = IntPtr.Zero; uint rawValueSize = 0; if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_get(rawMetadata, key, ref rawValueSize, ref rawValue) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0} Unable to get metadata value.\n" + Environment.StackTrace, value)); return(false); } if (rawValueSize != DOUBLE_BYTE_COUNT * expectedCount) { // Unexpected size change Debug.Log(string.Format("key={0} Unexpected byte size {1}.\n" + Environment.StackTrace, key, rawValueSize)); return(false); } Marshal.Copy(rawValue, value, 0, expectedCount); return(true); }
/// <summary> /// Get an Int64 value from an area description metadata. /// </summary> /// <returns><c>true</c>, if an Int64 value was found, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="value">Output value for the specified key.</param> private static bool _MetadataGetInt64(IntPtr rawMetadata, string key, out Int64 value) { value = 0; IntPtr rawValue = IntPtr.Zero; uint rawValueSize = 0; if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_get(rawMetadata, key, ref rawValueSize, ref rawValue) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0} Unable to get metadata value.\n" + Environment.StackTrace, key)); return(false); } if (rawValueSize != INT64_BYTE_COUNT) { // Unexpected size change Debug.Log(string.Format("key={0} Unexpected byte size {1}.\n" + Environment.StackTrace, key, rawValueSize)); return(false); } value = Marshal.ReadInt64(rawValue); return(true); }
/// <summary> /// Get a string value from an area description metadata. /// </summary> /// <returns><c>true</c>, if a string value was found, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="value">Output value for the specified key.</param> private static bool _MetadataGetString(IntPtr rawMetadata, string key, out string value) { value = String.Empty; IntPtr rawValue = IntPtr.Zero; uint rawValueSize = 0; if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_get(rawMetadata, key, ref rawValueSize, ref rawValue) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0} Unable to get metadata value.\n" + Environment.StackTrace, key)); return(false); } byte[] rawValueArray = new byte[rawValueSize]; Marshal.Copy(rawValue, rawValueArray, 0, (int)rawValueSize); try { value = Encoding.UTF8.GetString(rawValueArray); } catch (Exception e) { Debug.Log(string.Format("key={0} Error during UTF-8 decoding {1}.\n" + Environment.StackTrace, key, e.Message)); return(false); } return(true); }
/// <summary> /// Delete an area description. /// </summary> /// <returns> /// Returns true if the area description file is found and can be removed. /// </returns> public bool Delete() { #if UNITY_EDITOR try { if (File.Exists(EMULATED_ADF_SAVE_PATH + m_uuid + EMULATED_ADF_EXTENSION)) { File.Delete(EMULATED_ADF_SAVE_PATH + m_uuid + EMULATED_ADF_EXTENSION); return(true); } } catch (IOException ioException) { Debug.LogError("IO error in Area Description save/load emulation:\n" + ioException.Message); } return(false); #else int returnValue = AreaDescriptionAPI.TangoService_deleteAreaDescription(m_uuid); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not delete area description.\n" + Environment.StackTrace); return(false); } return(true); #endif }
/// <summary> /// Free a previously gotten Metadata pointer. /// </summary> /// <param name="metadataPtr">Metadata pointer to free.</param> private static void _FreeMetadataPtr(IntPtr metadataPtr) { if (metadataPtr != IntPtr.Zero) { AreaDescriptionAPI.TangoAreaDescriptionMetadata_free(metadataPtr); } }
/// <summary> /// Delete an area description. /// </summary> /// <returns> /// Returns true if the area description file is found and can be removed. /// </returns> public bool Delete() { int returnValue = AreaDescriptionAPI.TangoService_deleteAreaDescription(m_uuid); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not delete area description.\n" + Environment.StackTrace); return(false); } return(true); }
/// <summary> /// Set an Int64 value in an area description metadata. /// </summary> /// <returns><c>true</c>, if Int64 value was set, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="value">New value.</param> private static bool _MetadataSetInt64(IntPtr rawMetadata, string key, Int64 value) { if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_set(rawMetadata, key, INT64_BYTE_COUNT, ref value) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0}, value={1} Unable to set metadata value.\n" + Environment.StackTrace, key, value)); return(false); } return(true); }
/// <summary> /// Set a string value in an area description metadata. /// </summary> /// <returns><c>true</c>, if string value was set, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="value">New value.</param> private static bool _MetadataSetString(IntPtr rawMetadata, string key, string value) { if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_set(rawMetadata, key, (uint)Encoding.UTF8.GetByteCount(value), value) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0}, value={1} Unable to set metadata value.\n" + Environment.StackTrace, key, value)); return(false); } return(true); }
/// <summary> /// Saves the current area description, returning the area description saved. /// /// You can only save an area description while connected to the Tango Service and if you have enabled Area /// Learning mode. If you loaded an ADF before connecting, then calling this method appends any new learned /// areas to that ADF and returns the same UUID. If you did not load an ADF, this method creates a new ADF and /// a new UUID for that ADF. /// </summary> /// <returns> /// AreaDescription instance for the newly saved area description if saved successfully, <c>null</c> otherwise. /// /// See logcat for details of why the saved failed. /// </returns> public static AreaDescription SaveCurrent() { byte[] rawUUID = new byte[Common.UUID_LENGTH]; if (AreaDescriptionAPI.TangoService_saveAreaDescription(rawUUID) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not save area description.\n" + Environment.StackTrace); return(null); } string uuid = Encoding.UTF8.GetString(rawUUID); return(AreaDescription.ForUUID(uuid)); }
/// <summary> /// Get the low level metadata pointer for an area description. /// /// Make sure to free this with FreeMetadataPtr when you are done with it. /// </summary> /// <returns>A metadata pointer or <c>IntPtr.Zero</c> if it could not be loaded.</returns> private IntPtr _GetMetadataPtr() { IntPtr value = IntPtr.Zero; int returnValue = AreaDescriptionAPI.TangoService_getAreaDescriptionMetadata(m_uuid, ref value); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("Could not get metadata pointer for uuid {0}.\n" + Environment.StackTrace, m_uuid)); return(IntPtr.Zero); } return(value); }
/// <summary> /// Set a fixed-size double array in an area description metadata. /// </summary> /// <returns><c>true</c>, if the double array was set, <c>false</c> otherwise.</returns> /// <param name="rawMetadata">Area description metadata pointer.</param> /// <param name="key">Key name.</param> /// <param name="value">New value.</param> private static bool _MetadataSetDoubleArray(IntPtr rawMetadata, string key, double[] value) { uint arrayByteCount = (uint)(DOUBLE_BYTE_COUNT * value.Length); if (AreaDescriptionAPI.TangoAreaDescriptionMetadata_set(rawMetadata, key, arrayByteCount, value) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log(string.Format("key={0}, value={1} Unable to set metadata value.\n" + Environment.StackTrace, key, value)); return(false); } return(true); }
/// <summary> /// Get a list of all area description UUIDs on the device. /// </summary> /// <returns>List of string UUIDs.</returns> private static string[] _GetUUIDList() { IntPtr rawListString = IntPtr.Zero; int returnValue = AreaDescriptionAPI.TangoService_getAreaDescriptionUUIDList(ref rawListString); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not get ADF list from device.\n" + Environment.StackTrace); return(null); } string listString = _ReadUTF8String(rawListString); return(listString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); }
/// <summary> /// Save the metadata for this area description. /// </summary> /// <returns>Returns <c>true</c> if the metadata was successfully saved, <c>false</c> otherwise.</returns> /// <param name="metadata">Metadata to save.</param> public bool SaveMetadata(Metadata metadata) { IntPtr rawMetadata = _GetMetadataPtr(); if (rawMetadata == IntPtr.Zero) { return(false); } bool anyErrors = false; if (!_MetadataSetString(rawMetadata, "name", metadata.m_name)) { anyErrors = true; } if (!_MetadataSetInt64(rawMetadata, "date_ms_since_epoch", (metadata.m_dateTime.Ticks - METADATA_EPOCH.Ticks) / DATETIME_TICKS_PER_MS)) { anyErrors = true; } double[] tform = new double[7]; tform[0] = metadata.m_transformationPosition[0]; tform[1] = metadata.m_transformationPosition[1]; tform[2] = metadata.m_transformationPosition[2]; tform[3] = metadata.m_transformationRotation[0]; tform[4] = metadata.m_transformationRotation[1]; tform[5] = metadata.m_transformationRotation[2]; tform[6] = metadata.m_transformationRotation[3]; if (!_MetadataSetDoubleArray(rawMetadata, "transformation", tform)) { anyErrors = true; } if (!anyErrors) { int returnValue = AreaDescriptionAPI.TangoService_saveAreaDescriptionMetadata(m_uuid, rawMetadata); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not save metadata values.\n" + Environment.StackTrace); anyErrors = true; } } _FreeMetadataPtr(rawMetadata); return(!anyErrors); }
/// <summary> /// Get a list of all area description UUIDs on the device. /// </summary> /// <returns>List of string UUIDs.</returns> private static string[] _GetUUIDList() { #if UNITY_EDITOR try { DirectoryInfo directory = new DirectoryInfo(EMULATED_ADF_SAVE_PATH); if (directory.Exists) { FileInfo[] fileInfo = directory.GetFiles(); List <string> uuids = new List <String>(); for (int i = 0; i < fileInfo.Length; i++) { if (fileInfo[i].Extension == EMULATED_ADF_EXTENSION) { uuids.Add(Path.GetFileNameWithoutExtension(fileInfo[i].Name)); } } return(uuids.ToArray()); } } catch (IOException ioException) { Debug.LogError("IO error in Area Description save/load emulation:\n" + ioException.Message); } return(new string[0]); #else IntPtr rawListString = IntPtr.Zero; int returnValue = AreaDescriptionAPI.TangoService_getAreaDescriptionUUIDList(ref rawListString); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not get ADF list from device.\n" + Environment.StackTrace); return(null); } string listString = _ReadUTF8String(rawListString); return(listString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); #endif }
/// <summary> /// Save the metadata for this area description. /// </summary> /// <returns>Returns <c>true</c> if the metadata was successfully saved, <c>false</c> otherwise.</returns> /// <param name="metadata">Metadata to save.</param> public bool SaveMetadata(Metadata metadata) { #if UNITY_EDITOR try { using (StreamWriter streamWriter = new StreamWriter(File.Open(EMULATED_ADF_SAVE_PATH + m_uuid + EMULATED_ADF_EXTENSION, FileMode.Create))) { metadataXmlSerializer.Serialize(streamWriter, metadata); } } catch (IOException ioException) { Debug.LogError("IO error in Area Description save/load emulation:\n" + ioException.Message); return(false); } return(true); #else IntPtr rawMetadata = _GetMetadataPtr(); if (rawMetadata == IntPtr.Zero) { return(false); } bool anyErrors = false; if (!_MetadataSetString(rawMetadata, "name", metadata.m_name)) { anyErrors = true; } if (!_MetadataSetInt64(rawMetadata, "date_ms_since_epoch", (metadata.m_dateTime.Ticks - METADATA_EPOCH.Ticks) / DATETIME_TICKS_PER_MS)) { anyErrors = true; } double[] tform = new double[7]; tform[0] = metadata.m_transformationPosition[0]; tform[1] = metadata.m_transformationPosition[1]; tform[2] = metadata.m_transformationPosition[2]; tform[3] = metadata.m_transformationRotation[0]; tform[4] = metadata.m_transformationRotation[1]; tform[5] = metadata.m_transformationRotation[2]; tform[6] = metadata.m_transformationRotation[3]; if (!_MetadataSetDoubleArray(rawMetadata, "transformation", tform)) { anyErrors = true; } if (!anyErrors) { int returnValue = AreaDescriptionAPI.TangoService_saveAreaDescriptionMetadata(m_uuid, rawMetadata); if (returnValue != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not save metadata values.\n" + Environment.StackTrace); anyErrors = true; } } _FreeMetadataPtr(rawMetadata); return(!anyErrors); #endif }
/// <summary> /// Saves the current area description, returning the area description saved. /// /// You can only save an area description while connected to the Tango Service and if you have enabled Area /// Learning mode. If you loaded an area description before connecting, then calling this method appends any /// new learned areas to that area description and returns an area description with the same UUID. If you did /// not load an area description, this method creates a new area description and a new UUID for that area /// description. /// </summary> /// <returns> /// AreaDescription instance for the newly saved area description if saved successfully, <c>null</c> otherwise. /// /// See logcat for details of why a saved failed. /// </returns> public static AreaDescription SaveCurrent() { #if UNITY_EDITOR if (!EmulatedAreaDescriptionHelper.m_usingEmulatedDescriptionFrames) { Debug.LogError("Error in Area Description save emulation:\nNo current emulated area description."); return(null); } // If we don't have an existing UUID, this is a 'new' Area Description, so we'll have to create it. if (string.IsNullOrEmpty(EmulatedAreaDescriptionHelper.m_currentUUID)) { // Just use a .net GUID for the UUID. string uuid = Guid.NewGuid().ToString(); EmulatedAreaDescriptionHelper.m_currentUUID = uuid; try { Directory.CreateDirectory(EMULATED_ADF_SAVE_PATH); using (StreamWriter streamWriter = new StreamWriter(File.Open(EMULATED_ADF_SAVE_PATH + uuid + EMULATED_ADF_EXTENSION, FileMode.Create))) { Metadata metadata = new Metadata(); metadata.m_name = "Unnamed"; metadata.m_dateTime = DateTime.Now; metadata.m_transformationPosition = new double[3]; metadata.m_transformationRotation = new double[] { 0, 0, 0, 1 }; metadataXmlSerializer.Serialize(streamWriter, metadata); } } catch (IOException ioException) { Debug.LogError("IO error in Area Description save/load emulation:\n" + ioException.Message); return(null); } return(AreaDescription.ForUUID(uuid)); } else { // Since we don't actually save any description of the area in emulation, // if we're using an existing UUID, we don't have to do anything but return it. return(AreaDescription.ForUUID(EmulatedAreaDescriptionHelper.m_currentUUID)); } #else byte[] rawUUID = new byte[Common.UUID_LENGTH]; if (AreaDescriptionAPI.TangoService_saveAreaDescription(rawUUID) != Common.ErrorType.TANGO_SUCCESS) { Debug.Log("Could not save area description.\n" + Environment.StackTrace); return(null); } // Don't want to include the null terminator in the C# string. string uuid = Encoding.UTF8.GetString(rawUUID, 0, Common.UUID_LENGTH - 1); return(AreaDescription.ForUUID(uuid)); #endif }