NRWorldAnchor.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal.Experimental.Persistence
  10. {
  11. using UnityEngine;
  12. using System;
  13. /// <summary>
  14. /// The WorldAnchor component allows a GameObject's position to be locked in physical space. For
  15. /// example, a cube arranged on top of a physical desk with a WorldAnchor applied will remain
  16. /// fixed even as an observer walks around the room. This overrides all manipulation of the
  17. /// GameObject's position and orientation. To move the GameObject, first remove the WorldAnchor
  18. /// and manipulate the Transform normally. While it is generally recommended to use Destroy
  19. /// instead of DestroyImmediate, it's best to call DestroyImmediate on WorldAnchor objects. Doing
  20. /// so will let you manipulate the Transform of the GameObject including adding a new
  21. /// WorldAnchor. </summary>
  22. public class NRWorldAnchor : MonoBehaviour
  23. {
  24. /// <summary> Gets a value indicating whether this object is located. </summary>
  25. /// <value> True if this object is located, false if not. </value>
  26. public bool isLocated { get; private set; }
  27. /// <summary> Event queue for all listeners interested in OnTrackingChanged events. </summary>
  28. public event OnTrackingChangedDelegate OnTrackingChanged;
  29. /// <summary> Gets or sets the handle of the anchor native. </summary>
  30. /// <value> The anchor native handle. </value>
  31. public UInt64 AnchorNativeHandle
  32. {
  33. get;
  34. private set;
  35. }
  36. #if !UNITY_EDITOR
  37. private NativeMapping m_NativeInterface;
  38. #endif
  39. /// <summary> State of the tracking. </summary>
  40. private TrackingState m_TrackingState = TrackingState.Tracking;
  41. /// <summary> Get the tracking state of current trackable. </summary>
  42. /// <returns> The tracking state. </returns>
  43. public TrackingState GetTrackingState()
  44. {
  45. TrackingState currentState;
  46. #if !UNITY_EDITOR
  47. currentState = m_NativeInterface.GetTrackingState(AnchorNativeHandle);
  48. #else
  49. currentState = TrackingState.Tracking;
  50. #endif
  51. if (currentState != m_TrackingState)
  52. {
  53. OnTrackingChanged?.Invoke(this, currentState == TrackingState.Tracking);
  54. }
  55. m_TrackingState = currentState;
  56. return m_TrackingState;
  57. }
  58. #if UNITY_EDITOR
  59. /// <summary> The anchor position. </summary>
  60. Pose anchorPos;
  61. /// <summary> Starts this object. </summary>
  62. private void Start()
  63. {
  64. anchorPos = new Pose(UnityEngine.Random.insideUnitSphere, Quaternion.identity);
  65. }
  66. #endif
  67. /// <summary> Get the center pose of current trackable. </summary>
  68. /// <returns> The center pose. </returns>
  69. public virtual Pose GetCenterPose()
  70. {
  71. #if UNITY_EDITOR
  72. return ConversionUtility.ApiWorldToUnityWorld(anchorPos);
  73. #else
  74. return ConversionUtility.ApiWorldToUnityWorld(m_NativeInterface.GetAnchorPose(AnchorNativeHandle));
  75. #endif
  76. }
  77. /// <summary>
  78. /// Retrieve a native pointer to the Windows.Perception.Spatial.SpatialAnchor COM object. This
  79. /// function calls IUnknown::AddRef on the pointer before returning it. The pointer must be
  80. /// released by calling IUnknown::Release. </summary>
  81. /// <returns> The native spatial anchor pointer. </returns>
  82. public int GetNativeSpatialAnchorPtr()
  83. {
  84. #if UNITY_EDITOR
  85. return (int)AnchorNativeHandle;
  86. #else
  87. return NativeMapping.GetAnchorNativeID(AnchorNativeHandle);
  88. #endif
  89. }
  90. /// <summary>
  91. /// Assigns the Windows.Perception.Spatial.SpatialAnchor COM pointer maintained by this
  92. /// WorldAnchor. </summary>
  93. /// <param name="spatialAnchorPtr"> .</param>
  94. /// <param name="nativeinterface"> .</param>
  95. public void SetNativeSpatialAnchorPtr(UInt64 spatialAnchorPtr, NativeMapping nativeinterface)
  96. {
  97. AnchorNativeHandle = spatialAnchorPtr;
  98. #if !UNITY_EDITOR
  99. m_NativeInterface = nativeinterface;
  100. #endif
  101. }
  102. /// <summary>
  103. /// Update anchor's position while the state is Tracking. If not, anchor will be set to the
  104. /// position Vector3.one * 10000. </summary>
  105. internal void OnUpdateState()
  106. {
  107. if (GetTrackingState() == TrackingState.Tracking)
  108. {
  109. var pose = GetCenterPose();
  110. transform.position = pose.position;
  111. transform.rotation = pose.rotation;
  112. isLocated = true;
  113. }
  114. else
  115. {
  116. isLocated = false;
  117. transform.position = Vector3.one * 10000f;
  118. }
  119. }
  120. /// <summary> Event that is fired when this object's tracking state changes. </summary>
  121. /// <param name="worldAnchor"> .</param>
  122. /// <param name="located"> .</param>
  123. public delegate void OnTrackingChangedDelegate(NRWorldAnchor worldAnchor, bool located);
  124. }
  125. }