SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.3 KiB

4 years ago
  1. using System.Collections.Generic;
  2. using UnityEngine.XR.ARSubsystems;
  3. #if UNITY_2019_3_OR_NEWER
  4. using LegacyMeshId = UnityEngine.XR.MeshId;
  5. #else
  6. using LegacyMeshId = UnityEngine.Experimental.XR.TrackableId;
  7. using MeshInfo = UnityEngine.Experimental.XR.MeshInfo;
  8. #endif
  9. namespace UnityEngine.XR.ARFoundation
  10. {
  11. internal class MeshInfoComparer : IComparer<MeshInfo>
  12. {
  13. /// <summary>
  14. /// Mesh infos are stored last first so that the dequeue operation is fast
  15. /// - < 0 <paramref name="infoA"/> will appear before infoB in the list
  16. /// - 0 <paramref name="infoA"/> has the same priority as <paramref name="infoB"/>
  17. /// - > 0 <paramref name="infoB"/> will appear before infoA in the list
  18. /// </summary>
  19. public int Compare(MeshInfo infoA, MeshInfo infoB)
  20. {
  21. // Prioritize 'added' over 'updated'
  22. if (infoA.ChangeState < infoB.ChangeState)
  23. {
  24. return 1;
  25. }
  26. else if (infoB.ChangeState < infoA.ChangeState)
  27. {
  28. return -1;
  29. }
  30. else
  31. {
  32. // If 'A' has a high priority, then we return a positive number
  33. // which puts A last in the list. This means we can dequeue
  34. // the next mesh to generate by taking the last element.
  35. return (infoA.PriorityHint - infoB.PriorityHint);
  36. }
  37. }
  38. }
  39. internal class MeshQueue
  40. {
  41. public void EnqueueUnique(MeshInfo meshInfo)
  42. {
  43. if (m_MeshSet.Contains(meshInfo.MeshId))
  44. {
  45. UpdateExisting(meshInfo);
  46. }
  47. else
  48. {
  49. InsertNew(meshInfo);
  50. }
  51. }
  52. public int count
  53. {
  54. get { return m_Queue.Count; }
  55. }
  56. public bool TryDequeue(IReadOnlyDictionary<LegacyMeshId, MeshInfo> generating, out MeshInfo meshInfo)
  57. {
  58. for (int i = m_Queue.Count - 1; i >= 0; --i)
  59. {
  60. meshInfo = m_Queue[i];
  61. if (!generating.ContainsKey(meshInfo.MeshId))
  62. {
  63. m_Queue.RemoveAt(i);
  64. m_MeshSet.Remove(meshInfo.MeshId);
  65. return true;
  66. }
  67. }
  68. meshInfo = default;
  69. return false;
  70. }
  71. public bool Remove(LegacyMeshId meshId)
  72. {
  73. // It is relatively rare to remove an existing mesh
  74. // (this means it was removed while awaiting generation).
  75. // So it most cases we should be able to early out.
  76. if (!m_MeshSet.Remove(meshId))
  77. return false;
  78. // Otherwise, perform a linear search and remove it.
  79. for (int i = 0; i < m_Queue.Count; ++i)
  80. {
  81. if (m_Queue[i].MeshId.Equals(meshId))
  82. {
  83. m_Queue.RemoveAt(i);
  84. break;
  85. }
  86. }
  87. return true;
  88. }
  89. void InsertNew(MeshInfo meshInfo)
  90. {
  91. int index = m_Queue.BinarySearch(meshInfo, s_MeshInfoComparer);
  92. if (index < 0)
  93. index = ~index;
  94. m_Queue.Insert(index, meshInfo);
  95. m_MeshSet.Add(meshInfo.MeshId);
  96. }
  97. void UpdateExisting(MeshInfo meshInfo)
  98. {
  99. for (int i = 0; i < m_Queue.Count; ++i)
  100. {
  101. var existing = m_Queue[i];
  102. if (existing.MeshId.Equals(meshInfo.MeshId))
  103. {
  104. // Only need to do anything if they are not equal
  105. if (existing.PriorityHint != meshInfo.PriorityHint)
  106. {
  107. existing.PriorityHint = meshInfo.PriorityHint;
  108. m_Queue[i] = existing;
  109. m_Queue.Sort(s_MeshInfoComparer);
  110. }
  111. break;
  112. }
  113. }
  114. }
  115. public void Clear()
  116. {
  117. m_Queue.Clear();
  118. m_MeshSet.Clear();
  119. }
  120. // This list is kept sorted according to MeshInfoComparer
  121. List<MeshInfo> m_Queue = new List<MeshInfo>();
  122. HashSet<LegacyMeshId> m_MeshSet = new HashSet<LegacyMeshId>();
  123. MeshInfoComparer s_MeshInfoComparer = new MeshInfoComparer();
  124. }
  125. }