AkEnvironmentIndex.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #pragma once
  16. #include "Math/GenericOctree.h"
  17. #include "WwiseDefines.h"
  18. #include "Components/SceneComponent.h"
  19. #include "EngineDefines.h"
  20. class UAkEnvironmentOctree;
  21. #if UE_4_26_OR_LATER
  22. #define AK_OCTREE_TYPE TOctree2
  23. #define AK_OCTREE_ELEMENT_ID FOctreeElementId2
  24. #else
  25. #define AK_OCTREE_TYPE TOctree
  26. #define AK_OCTREE_ELEMENT_ID FOctreeElementId
  27. #endif
  28. struct FAkEnvironmentOctreeElement
  29. {
  30. USceneComponent* Component;
  31. FBoxCenterAndExtent BoundingBox;
  32. FAkEnvironmentOctreeElement(USceneComponent* in_Component)
  33. {
  34. Component = in_Component;
  35. BoundingBox = FBoxCenterAndExtent(Component->Bounds.GetBox().GetCenter(), Component->Bounds.GetBox().GetExtent());
  36. }
  37. };
  38. struct FAkEnvironmentOctreeSemantics
  39. {
  40. typedef AK_OCTREE_TYPE<FAkEnvironmentOctreeElement, FAkEnvironmentOctreeSemantics> FOctree;
  41. enum { MaxElementsPerLeaf = 16 };
  42. enum { MinInclusiveElementsPerNode = 7 };
  43. enum { MaxNodeDepth = 12 };
  44. typedef TInlineAllocator<MaxElementsPerLeaf> ElementAllocator;
  45. FORCEINLINE static FBoxCenterAndExtent GetBoundingBox(const FAkEnvironmentOctreeElement& Element)
  46. {
  47. return Element.BoundingBox;
  48. }
  49. FORCEINLINE static bool AreElementsEqual(const FAkEnvironmentOctreeElement& A, const FAkEnvironmentOctreeElement& B)
  50. {
  51. return (A.Component == B.Component);
  52. }
  53. static void SetElementId(FOctree& OctreeOwner, const FAkEnvironmentOctreeElement& Element, AK_OCTREE_ELEMENT_ID Id);
  54. };
  55. class UAkEnvironmentOctree : public AK_OCTREE_TYPE<FAkEnvironmentOctreeElement, FAkEnvironmentOctreeSemantics>
  56. {
  57. public:
  58. UAkEnvironmentOctree() : AK_OCTREE_TYPE<FAkEnvironmentOctreeElement, FAkEnvironmentOctreeSemantics>(FVector::ZeroVector, HALF_WORLD_MAX) {}
  59. TMap<uint32, AK_OCTREE_ELEMENT_ID> ObjectToOctreeId;
  60. };
  61. /** A spatial indexing data structure used to accelerate geometric queries.
  62. Used for fast look up of UAkRoomComponents for Spatial Audio Rooms, and for UAkLateReverbComponents for auxiliary sends in Wwise.
  63. */
  64. class FAkEnvironmentIndex
  65. {
  66. public:
  67. /**
  68. Query a world and location for an environmental rooms or late reverb components.
  69. Returns an array of components that overlap Location, sorted by decreasing priority.
  70. */
  71. template <typename EnvironmentType>
  72. TArray<EnvironmentType*> Query(const FVector& Location, const UWorld* World)
  73. {
  74. TArray<EnvironmentType*> Result;
  75. TUniquePtr<UAkEnvironmentOctree>* Octree = Map.Find(World);
  76. if (Octree != nullptr)
  77. {
  78. #if UE_4_26_OR_LATER
  79. FBoxCenterAndExtent BoxBounds(Location, FVector::ZeroVector);
  80. (*Octree)->FindElementsWithBoundsTest(BoxBounds, [&Result, Location](const FAkEnvironmentOctreeElement& Element)
  81. {
  82. EnvironmentType* Env = Cast<EnvironmentType>(Element.Component);
  83. if (Env &&
  84. Env->bEnable &&
  85. Env->HasEffectOnLocation(Location))
  86. {
  87. Result.Add(Env);
  88. }
  89. });
  90. #else
  91. for (UAkEnvironmentOctree::TConstElementBoxIterator<> It(**Octree, FBoxCenterAndExtent(Location, FVector(ForceInitToZero)));
  92. It.HasPendingElements();
  93. It.Advance())
  94. {
  95. const FAkEnvironmentOctreeElement& Element = It.GetCurrentElement();
  96. EnvironmentType* Env = Cast<EnvironmentType>(Element.Component);
  97. if (Env &&
  98. Env->bEnable &&
  99. Env->HasEffectOnLocation(Location))
  100. {
  101. Result.Add(Env);
  102. }
  103. }
  104. #endif
  105. }
  106. // Sort the found Volumes
  107. if (Result.Num() > 1)
  108. {
  109. Result.Sort([](const EnvironmentType& A, const EnvironmentType& B)
  110. {
  111. return A.Priority > B.Priority;
  112. });
  113. }
  114. return Result;
  115. }
  116. /**
  117. Add a Component to the spatial index.
  118. */
  119. void Add(USceneComponent* EnvironmentToAdd);
  120. /**
  121. * Remove a Component from the spatial index.
  122. */
  123. bool Remove(USceneComponent* EnvironmentToRemove);
  124. /**
  125. * Update the bounds of a component that is already indexed. Must be called if the transform of the component changes.
  126. */
  127. void Update(USceneComponent* EnvironmentToUpdate);
  128. /**
  129. * Clear all components in the given World.
  130. */
  131. void Clear(const UWorld* WorldToClear);
  132. /**
  133. * Is the index empty for the given World.
  134. */
  135. bool IsEmpty(const UWorld* World);
  136. private:
  137. TMap<UWorld*, TUniquePtr<UAkEnvironmentOctree> > Map;
  138. };