Loading Runtime/ARCoreExtensionsConfig.asset +1 −1 Original line number Diff line number Diff line Loading @@ -14,5 +14,5 @@ MonoBehaviour: m_EditorClassIdentifier: CloudAnchorMode: 1 SemanticMode: 0 GeospatialMode: 0 GeospatialMode: 2 StreetscapeGeometryMode: 0 Runtime/Resources/ARFAnchorTrackingPrefab.prefab +106 −0 Original line number Diff line number Diff line %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!1 &919512057412407595 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - component: {fileID: 5663275178603938767} - component: {fileID: 2250489381470411502} - component: {fileID: 5243785181569724411} - component: {fileID: 4959683567476516339} m_Layer: 0 m_Name: PurpleSphere m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &5663275178603938767 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 20, y: 20, z: 20} m_ConstrainProportionsScale: 1 m_Children: [] m_Father: {fileID: 6911754431728604849} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &2250489381470411502 MeshFilter: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} --- !u!23 &5243785181569724411 MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - {fileID: 2100000, guid: a64202207c2bc6042a40ad749c6eabf1, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 m_StitchLightmapSeams: 1 m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &4959683567476516339 SphereCollider: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Material: {fileID: 0} m_IncludeLayers: serializedVersion: 2 m_Bits: 0 m_ExcludeLayers: serializedVersion: 2 m_Bits: 0 m_LayerOverridePriority: 0 m_IsTrigger: 0 m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 m_Radius: 0.5 m_Center: {x: 0, y: 0, z: 0} --- !u!1 &6911754431728604848 GameObject: m_ObjectHideFlags: 0 Loading Loading @@ -33,6 +138,7 @@ Transform: - {fileID: 6911754433267149346} - {fileID: 6911754433204531549} - {fileID: 5348077246929615354} - {fileID: 5663275178603938767} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &6911754432812775762 Loading Runtime/Scripts/WorldAnalysisARFoundation.cs +28 −6 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ using System.Collections; using System.Linq; using ETSI.ARF.OpenAPI.WorldStorage; using ETSI.ARF.WorldStorage.REST; using Unity.XR.CoreUtils; //Implementation of the WorldAnalysis interface public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface Loading Loading @@ -50,6 +51,11 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface /// </summary> private bool isChekingAvailabilityRunning = false; /// <summary> /// Anchor manager /// </summary> private ARAnchorManager m_anchorManager; /// <summary> /// Informations regarding a subscription to a pose /// </summary> Loading Loading @@ -77,6 +83,9 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface m_trackableModules = new List<WorldAnalysisARFoundationModule>(); WorldAnalysisARFoundationModuleImage imageModule = new WorldAnalysisARFoundationModuleImage(); m_trackableModules.Add(imageModule); WorldAnalysisARFoundationModuleGeospatial geospatialModule = new WorldAnalysisARFoundationModuleGeospatial(); m_trackableModules.Add(geospatialModule); #if UNITY_IOS WorldAnalysisARFoundationModuleMesh meshModule = new WorldAnalysisARFoundationModuleMesh(); m_trackableModules.Add(meshModule); Loading Loading @@ -158,7 +167,9 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface List<RelocObjects> notTrackedCandidates = new List<RelocObjects>(); //Hierarchy of types string[] types = { "MESH", "IMAGE_MARKER", "FIDUCIAL_MARKER", "MAP", "OTHER" }; //TODO : GEOPOSE string[] types = { "MESH", "IMAGE_MARKER", "FIDUCIAL_MARKER", "MAP", "GEOPOSE", "OTHER" }; List<Guid> keysToRemove = new List<Guid>(); //We fill in the confidence level lists. foreach (KeyValuePair<Guid, RelocObjects> relocObject in temp) Loading @@ -178,7 +189,16 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface { notTrackedCandidates.Add(relocObject.Value); } }else { keysToRemove.Add(relocObject.Key); } } // Remove null trackables from temp foreach (Guid key in keysToRemove) { temp.Remove(key); } //uses the types[] array indexes as key, and UUIDs as values Loading Loading @@ -364,9 +384,12 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface ///Convert into world storage capabilities List<ETSI.ARF.OpenAPI.WorldStorage.Capability> capabilities = new List<ETSI.ARF.OpenAPI.WorldStorage.Capability>(); foreach (ETSI.ARF.OpenAPI.WorldAnalysis.Capability capability in currentCapabilities) { if(capability != null) { capabilities.Add(WorldAnalysisUnityHelper.ConvertWorldAnalysisCapability(capability)); } } /// Collect relocalization information ETSI.ARF.OpenAPI.WorldStorage.Response response = RelocalizationInformationRequest.GetRelocalizationInformation(m_worldStorageServer, uuids, modes, capabilities); Loading Loading @@ -544,7 +567,7 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface /// <returns></returns> private Guid SelectTrackableWithTypeAndDistance(List<RelocObjects> candidates, List<KeyValuePair<string, Guid>> typesSortedList, UnityEngine.Vector3 cameraTransformPos) { float bestDistance = 100.0f; //valeur par d�faut = grande distance (� changer) float bestDistance = 10000000.0f; //default value : long distance (to change ?) Guid selectedTrackableUUID = Guid.Empty; //if only one trackable is candidate Loading Loading @@ -602,7 +625,6 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface } } } return selectedTrackableUUID; } Loading Runtime/Scripts/WorldAnalysisARFoundationModuleARCoreAnchor.cs +7 −3 Original line number Diff line number Diff line Loading @@ -30,9 +30,13 @@ public class WorldAnalysisARFoundationModuleARCoreAnchor : WorldAnalysisARFounda public void Initialize() { XROrigin origin = UnityEngine.Object.FindAnyObjectByType<XROrigin>(); m_anchorManager = origin.gameObject.GetComponent<ARAnchorManager>(); if (m_anchorManager == null ) { m_anchorManager = origin.gameObject.AddComponent<ARAnchorManager>(); GameObject anchorPrefab = (GameObject)Resources.Load("ARFAnchorTrackingPrefab"); m_anchorManager.anchorPrefab = anchorPrefab; } m_anchorManager.anchorsChanged += OnTrackedCloudAnchorChanged; } Loading Runtime/Scripts/WorldAnalysisARFoundationModuleGeospatial.cs 0 → 100644 +185 −0 Original line number Diff line number Diff line #if UNITY_ANDROID && ETSIARF_ARCORE_EXTENSIONS using System; using System.Collections.Generic; using Google.XR.ARCoreExtensions; using Unity.XR.CoreUtils; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; using static WorldAnalysisARFoundationModule; public class WorldAnalysisARFoundationModuleGeospatial : WorldAnalysisARFoundationModule { /// <summary> /// Anchor manager /// </summary> private ARAnchorManager m_anchorManager; private AREarthManager m_arEarthManager; private Dictionary<string, TrackableInfo> m_trackedGeospatialAnchors = new Dictionary<string, TrackableInfo>(); private bool geospatialSupported = true; /// Correspondance between local trackable and etsi uuid /// </summary> private Dictionary<string, string> m_localIdToEtsiId = new Dictionary<string, string>(); /// <summary> /// Initialize ARCore geospatial anchors tracking module /// </summary> public void Initialize() { XROrigin origin = UnityEngine.Object.FindAnyObjectByType<XROrigin>(); m_anchorManager = origin.gameObject.GetComponent<ARAnchorManager>(); if (m_anchorManager == null) { m_anchorManager = origin.gameObject.AddComponent<ARAnchorManager>(); GameObject anchorPrefab = (GameObject)Resources.Load("ARFAnchorTrackingPrefab"); m_anchorManager.anchorPrefab = anchorPrefab; } m_arEarthManager = origin.gameObject.AddComponent<AREarthManager>(); m_anchorManager.anchorsChanged += OnTrackedGeospatialAnchorChanged; } /// <summary> /// /// </summary> /// <param name="uuid"></param> /// <returns></returns> public TrackableInfo GetPoseTrackable(Guid uuid) { if (m_trackedGeospatialAnchors.ContainsKey(uuid.ToString())) { return m_trackedGeospatialAnchors[uuid.ToString()]; } else { return null; } } /// <summary> /// /// </summary> /// <param name="trackable"></param> /// <returns></returns> public bool AddTrackable(ETSI.ARF.OpenAPI.WorldStorage.Trackable trackable) { if (!geospatialSupported) return false; if (trackable.TrackableType != ETSI.ARF.OpenAPI.WorldStorage.TrackableType.GEOPOSE) { return false; } CreateGeosptialAnchor(trackable); return true; } public async void CreateGeosptialAnchor(ETSI.ARF.OpenAPI.WorldStorage.Trackable trackable) { if (geospatialSupported) { while (ARSession.state == ARSessionState.CheckingAvailability || ARSession.state == ARSessionState.None || ARSession.state == ARSessionState.SessionInitializing || m_arEarthManager.EarthState != EarthState.Enabled || m_arEarthManager.EarthTrackingState != TrackingState.Tracking) { await System.Threading.Tasks.Task.Delay(100); } if (m_arEarthManager.IsGeospatialModeSupported(GeospatialMode.Enabled) != FeatureSupported.Supported) { Debug.Log("Support : " + m_arEarthManager.IsGeospatialModeSupported(GeospatialMode.Enabled)); geospatialSupported = false; } else { double[] values = new double[trackable.TrackablePayload.Length / sizeof(double)]; for (int i = 0; i < values.Length; i++) { values[i] = BitConverter.ToDouble(trackable.TrackablePayload, i * sizeof(double)); } Quaternion rotation = Quaternion.Euler((float)values[3], (float)values[4], (float)values[5]); if (m_arEarthManager.EarthTrackingState == TrackingState.Tracking) { var anchor = m_anchorManager.AddAnchor(values[0], values[1], values[2], rotation); m_localIdToEtsiId.Add(anchor.trackableId.subId2.ToString("X16"), trackable.UUID.ToString()); } } } } /// <summary> /// /// </summary> /// <returns></returns> public ETSI.ARF.OpenAPI.WorldAnalysis.Capability GetSupportedCapability() //s'occuper de a (fonction doc) { if (!geospatialSupported) return null; ETSI.ARF.OpenAPI.WorldAnalysis.Capability capabilityGeospatialAnchor = new ETSI.ARF.OpenAPI.WorldAnalysis.Capability(); capabilityGeospatialAnchor.TrackableType = ETSI.ARF.OpenAPI.WorldAnalysis.TrackableType.GEOPOSE; ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructure encodingInformation = new ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructure(); encodingInformation.DataFormat = ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructureDataFormat.ARCORE; encodingInformation.Version = "1.01"; capabilityGeospatialAnchor.EncodingInformation = encodingInformation; capabilityGeospatialAnchor.Framerate = 30; // Not particularly specified on ARKit and ARCore capabilityGeospatialAnchor.Latency = 0; // Not particularly specified on ARKit and ARCore capabilityGeospatialAnchor.Accuracy = 1; // Not particularly specified on ARKit and ARCore return capabilityGeospatialAnchor; } /// <summary> /// /// </summary> /// <param name="eventArgs"></param> private void OnTrackedGeospatialAnchorChanged(ARAnchorsChangedEventArgs eventArgs) { foreach (var trackedGeospatialAnchor in eventArgs.updated) { Vector3 position = trackedGeospatialAnchor.transform.position; Quaternion rotation = trackedGeospatialAnchor.transform.rotation; TrackableInfo info = new TrackableInfo(); info.name = trackedGeospatialAnchor.name; string localId = trackedGeospatialAnchor.trackableId.subId1.ToString("X16");// there must be a better way : does it work every time? if (m_localIdToEtsiId.ContainsKey(localId)) { info.name = m_localIdToEtsiId[localId]; } else { Debug.Log("ARCore Geospatial Anchor No correspondance for Local Anchor " + localId); continue; } if (trackedGeospatialAnchor.trackingState == TrackingState.Tracking) { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK; info.confidence = 100; } else if (trackedGeospatialAnchor.trackingState == TrackingState.Limited) { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK; info.confidence = 50; } else { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.FAILURE; //ADD NOT_TRACKED ? info.confidence = 0; } info.timeStamp = unchecked((int)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); info.position = position; info.rotation = rotation; info.trackableType = ETSI.ARF.OpenAPI.WorldAnalysis.TrackableType.GEOPOSE; m_trackedGeospatialAnchors[info.name] = info; } } } #endif No newline at end of file Loading
Runtime/ARCoreExtensionsConfig.asset +1 −1 Original line number Diff line number Diff line Loading @@ -14,5 +14,5 @@ MonoBehaviour: m_EditorClassIdentifier: CloudAnchorMode: 1 SemanticMode: 0 GeospatialMode: 0 GeospatialMode: 2 StreetscapeGeometryMode: 0
Runtime/Resources/ARFAnchorTrackingPrefab.prefab +106 −0 Original line number Diff line number Diff line %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!1 &919512057412407595 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - component: {fileID: 5663275178603938767} - component: {fileID: 2250489381470411502} - component: {fileID: 5243785181569724411} - component: {fileID: 4959683567476516339} m_Layer: 0 m_Name: PurpleSphere m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &5663275178603938767 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} serializedVersion: 2 m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 20, y: 20, z: 20} m_ConstrainProportionsScale: 1 m_Children: [] m_Father: {fileID: 6911754431728604849} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &2250489381470411502 MeshFilter: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} --- !u!23 &5243785181569724411 MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 m_RayTraceProcedural: 0 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - {fileID: 2100000, guid: a64202207c2bc6042a40ad749c6eabf1, type: 2} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 m_StitchLightmapSeams: 1 m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} --- !u!135 &4959683567476516339 SphereCollider: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 919512057412407595} m_Material: {fileID: 0} m_IncludeLayers: serializedVersion: 2 m_Bits: 0 m_ExcludeLayers: serializedVersion: 2 m_Bits: 0 m_LayerOverridePriority: 0 m_IsTrigger: 0 m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 m_Radius: 0.5 m_Center: {x: 0, y: 0, z: 0} --- !u!1 &6911754431728604848 GameObject: m_ObjectHideFlags: 0 Loading Loading @@ -33,6 +138,7 @@ Transform: - {fileID: 6911754433267149346} - {fileID: 6911754433204531549} - {fileID: 5348077246929615354} - {fileID: 5663275178603938767} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &6911754432812775762 Loading
Runtime/Scripts/WorldAnalysisARFoundation.cs +28 −6 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ using System.Collections; using System.Linq; using ETSI.ARF.OpenAPI.WorldStorage; using ETSI.ARF.WorldStorage.REST; using Unity.XR.CoreUtils; //Implementation of the WorldAnalysis interface public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface Loading Loading @@ -50,6 +51,11 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface /// </summary> private bool isChekingAvailabilityRunning = false; /// <summary> /// Anchor manager /// </summary> private ARAnchorManager m_anchorManager; /// <summary> /// Informations regarding a subscription to a pose /// </summary> Loading Loading @@ -77,6 +83,9 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface m_trackableModules = new List<WorldAnalysisARFoundationModule>(); WorldAnalysisARFoundationModuleImage imageModule = new WorldAnalysisARFoundationModuleImage(); m_trackableModules.Add(imageModule); WorldAnalysisARFoundationModuleGeospatial geospatialModule = new WorldAnalysisARFoundationModuleGeospatial(); m_trackableModules.Add(geospatialModule); #if UNITY_IOS WorldAnalysisARFoundationModuleMesh meshModule = new WorldAnalysisARFoundationModuleMesh(); m_trackableModules.Add(meshModule); Loading Loading @@ -158,7 +167,9 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface List<RelocObjects> notTrackedCandidates = new List<RelocObjects>(); //Hierarchy of types string[] types = { "MESH", "IMAGE_MARKER", "FIDUCIAL_MARKER", "MAP", "OTHER" }; //TODO : GEOPOSE string[] types = { "MESH", "IMAGE_MARKER", "FIDUCIAL_MARKER", "MAP", "GEOPOSE", "OTHER" }; List<Guid> keysToRemove = new List<Guid>(); //We fill in the confidence level lists. foreach (KeyValuePair<Guid, RelocObjects> relocObject in temp) Loading @@ -178,7 +189,16 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface { notTrackedCandidates.Add(relocObject.Value); } }else { keysToRemove.Add(relocObject.Key); } } // Remove null trackables from temp foreach (Guid key in keysToRemove) { temp.Remove(key); } //uses the types[] array indexes as key, and UUIDs as values Loading Loading @@ -364,9 +384,12 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface ///Convert into world storage capabilities List<ETSI.ARF.OpenAPI.WorldStorage.Capability> capabilities = new List<ETSI.ARF.OpenAPI.WorldStorage.Capability>(); foreach (ETSI.ARF.OpenAPI.WorldAnalysis.Capability capability in currentCapabilities) { if(capability != null) { capabilities.Add(WorldAnalysisUnityHelper.ConvertWorldAnalysisCapability(capability)); } } /// Collect relocalization information ETSI.ARF.OpenAPI.WorldStorage.Response response = RelocalizationInformationRequest.GetRelocalizationInformation(m_worldStorageServer, uuids, modes, capabilities); Loading Loading @@ -544,7 +567,7 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface /// <returns></returns> private Guid SelectTrackableWithTypeAndDistance(List<RelocObjects> candidates, List<KeyValuePair<string, Guid>> typesSortedList, UnityEngine.Vector3 cameraTransformPos) { float bestDistance = 100.0f; //valeur par d�faut = grande distance (� changer) float bestDistance = 10000000.0f; //default value : long distance (to change ?) Guid selectedTrackableUUID = Guid.Empty; //if only one trackable is candidate Loading Loading @@ -602,7 +625,6 @@ public class WorldAnalysisARFoundation : MonoBehaviour, WorldAnalysisInterface } } } return selectedTrackableUUID; } Loading
Runtime/Scripts/WorldAnalysisARFoundationModuleARCoreAnchor.cs +7 −3 Original line number Diff line number Diff line Loading @@ -30,9 +30,13 @@ public class WorldAnalysisARFoundationModuleARCoreAnchor : WorldAnalysisARFounda public void Initialize() { XROrigin origin = UnityEngine.Object.FindAnyObjectByType<XROrigin>(); m_anchorManager = origin.gameObject.GetComponent<ARAnchorManager>(); if (m_anchorManager == null ) { m_anchorManager = origin.gameObject.AddComponent<ARAnchorManager>(); GameObject anchorPrefab = (GameObject)Resources.Load("ARFAnchorTrackingPrefab"); m_anchorManager.anchorPrefab = anchorPrefab; } m_anchorManager.anchorsChanged += OnTrackedCloudAnchorChanged; } Loading
Runtime/Scripts/WorldAnalysisARFoundationModuleGeospatial.cs 0 → 100644 +185 −0 Original line number Diff line number Diff line #if UNITY_ANDROID && ETSIARF_ARCORE_EXTENSIONS using System; using System.Collections.Generic; using Google.XR.ARCoreExtensions; using Unity.XR.CoreUtils; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; using static WorldAnalysisARFoundationModule; public class WorldAnalysisARFoundationModuleGeospatial : WorldAnalysisARFoundationModule { /// <summary> /// Anchor manager /// </summary> private ARAnchorManager m_anchorManager; private AREarthManager m_arEarthManager; private Dictionary<string, TrackableInfo> m_trackedGeospatialAnchors = new Dictionary<string, TrackableInfo>(); private bool geospatialSupported = true; /// Correspondance between local trackable and etsi uuid /// </summary> private Dictionary<string, string> m_localIdToEtsiId = new Dictionary<string, string>(); /// <summary> /// Initialize ARCore geospatial anchors tracking module /// </summary> public void Initialize() { XROrigin origin = UnityEngine.Object.FindAnyObjectByType<XROrigin>(); m_anchorManager = origin.gameObject.GetComponent<ARAnchorManager>(); if (m_anchorManager == null) { m_anchorManager = origin.gameObject.AddComponent<ARAnchorManager>(); GameObject anchorPrefab = (GameObject)Resources.Load("ARFAnchorTrackingPrefab"); m_anchorManager.anchorPrefab = anchorPrefab; } m_arEarthManager = origin.gameObject.AddComponent<AREarthManager>(); m_anchorManager.anchorsChanged += OnTrackedGeospatialAnchorChanged; } /// <summary> /// /// </summary> /// <param name="uuid"></param> /// <returns></returns> public TrackableInfo GetPoseTrackable(Guid uuid) { if (m_trackedGeospatialAnchors.ContainsKey(uuid.ToString())) { return m_trackedGeospatialAnchors[uuid.ToString()]; } else { return null; } } /// <summary> /// /// </summary> /// <param name="trackable"></param> /// <returns></returns> public bool AddTrackable(ETSI.ARF.OpenAPI.WorldStorage.Trackable trackable) { if (!geospatialSupported) return false; if (trackable.TrackableType != ETSI.ARF.OpenAPI.WorldStorage.TrackableType.GEOPOSE) { return false; } CreateGeosptialAnchor(trackable); return true; } public async void CreateGeosptialAnchor(ETSI.ARF.OpenAPI.WorldStorage.Trackable trackable) { if (geospatialSupported) { while (ARSession.state == ARSessionState.CheckingAvailability || ARSession.state == ARSessionState.None || ARSession.state == ARSessionState.SessionInitializing || m_arEarthManager.EarthState != EarthState.Enabled || m_arEarthManager.EarthTrackingState != TrackingState.Tracking) { await System.Threading.Tasks.Task.Delay(100); } if (m_arEarthManager.IsGeospatialModeSupported(GeospatialMode.Enabled) != FeatureSupported.Supported) { Debug.Log("Support : " + m_arEarthManager.IsGeospatialModeSupported(GeospatialMode.Enabled)); geospatialSupported = false; } else { double[] values = new double[trackable.TrackablePayload.Length / sizeof(double)]; for (int i = 0; i < values.Length; i++) { values[i] = BitConverter.ToDouble(trackable.TrackablePayload, i * sizeof(double)); } Quaternion rotation = Quaternion.Euler((float)values[3], (float)values[4], (float)values[5]); if (m_arEarthManager.EarthTrackingState == TrackingState.Tracking) { var anchor = m_anchorManager.AddAnchor(values[0], values[1], values[2], rotation); m_localIdToEtsiId.Add(anchor.trackableId.subId2.ToString("X16"), trackable.UUID.ToString()); } } } } /// <summary> /// /// </summary> /// <returns></returns> public ETSI.ARF.OpenAPI.WorldAnalysis.Capability GetSupportedCapability() //s'occuper de a (fonction doc) { if (!geospatialSupported) return null; ETSI.ARF.OpenAPI.WorldAnalysis.Capability capabilityGeospatialAnchor = new ETSI.ARF.OpenAPI.WorldAnalysis.Capability(); capabilityGeospatialAnchor.TrackableType = ETSI.ARF.OpenAPI.WorldAnalysis.TrackableType.GEOPOSE; ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructure encodingInformation = new ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructure(); encodingInformation.DataFormat = ETSI.ARF.OpenAPI.WorldAnalysis.EncodingInformationStructureDataFormat.ARCORE; encodingInformation.Version = "1.01"; capabilityGeospatialAnchor.EncodingInformation = encodingInformation; capabilityGeospatialAnchor.Framerate = 30; // Not particularly specified on ARKit and ARCore capabilityGeospatialAnchor.Latency = 0; // Not particularly specified on ARKit and ARCore capabilityGeospatialAnchor.Accuracy = 1; // Not particularly specified on ARKit and ARCore return capabilityGeospatialAnchor; } /// <summary> /// /// </summary> /// <param name="eventArgs"></param> private void OnTrackedGeospatialAnchorChanged(ARAnchorsChangedEventArgs eventArgs) { foreach (var trackedGeospatialAnchor in eventArgs.updated) { Vector3 position = trackedGeospatialAnchor.transform.position; Quaternion rotation = trackedGeospatialAnchor.transform.rotation; TrackableInfo info = new TrackableInfo(); info.name = trackedGeospatialAnchor.name; string localId = trackedGeospatialAnchor.trackableId.subId1.ToString("X16");// there must be a better way : does it work every time? if (m_localIdToEtsiId.ContainsKey(localId)) { info.name = m_localIdToEtsiId[localId]; } else { Debug.Log("ARCore Geospatial Anchor No correspondance for Local Anchor " + localId); continue; } if (trackedGeospatialAnchor.trackingState == TrackingState.Tracking) { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK; info.confidence = 100; } else if (trackedGeospatialAnchor.trackingState == TrackingState.Limited) { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK; info.confidence = 50; } else { info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.FAILURE; //ADD NOT_TRACKED ? info.confidence = 0; } info.timeStamp = unchecked((int)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); info.position = position; info.rotation = rotation; info.trackableType = ETSI.ARF.OpenAPI.WorldAnalysis.TrackableType.GEOPOSE; m_trackedGeospatialAnchors[info.name] = info; } } } #endif No newline at end of file