AkAcousticTextureSetComponent.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. #include "AkAcousticTextureSetComponent.h"
  16. #include "AkAudioDevice.h"
  17. #include "AkRoomComponent.h"
  18. #include "AkReverbDescriptor.h"
  19. #include "AkComponentHelpers.h"
  20. #include "AkLateReverbComponent.h"
  21. #include "AkSpatialAudioHelper.h"
  22. UAkAcousticTextureSetComponent::UAkAcousticTextureSetComponent(const class FObjectInitializer& ObjectInitializer) :
  23. Super(ObjectInitializer)
  24. {
  25. PrimaryComponentTick.bCanEverTick = true;
  26. bTickInEditor = true;
  27. #if WITH_EDITOR
  28. if (AkSpatialAudioHelper::GetObjectReplacedEvent())
  29. {
  30. AkSpatialAudioHelper::GetObjectReplacedEvent()->AddUObject(this, &UAkAcousticTextureSetComponent::HandleObjectsReplaced);
  31. }
  32. #endif
  33. }
  34. void UAkAcousticTextureSetComponent::OnRegister()
  35. {
  36. Super::OnRegister();
  37. #if WITH_EDITOR
  38. RegisterAllTextureParamCallbacks();
  39. RegisterReverbRTPCChangedCallback();
  40. #endif
  41. // In the case where a blueprint class has a texture set component and a late reverb component as siblings, We can't know which will be registered first.
  42. // We need to check for the sibling in each OnRegister function and associate the texture set component to the late reverb when they are both registered.
  43. if (USceneComponent* parent = GetAttachParent())
  44. {
  45. if (UAkLateReverbComponent* reverbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*parent))
  46. {
  47. reverbComp->AssociateAkTextureSetComponent(this);
  48. }
  49. }
  50. DampingEstimationNeedsUpdate = true;
  51. }
  52. void UAkAcousticTextureSetComponent::OnUnregister()
  53. {
  54. #if WITH_EDITOR
  55. UnregisterTextureParamChangeCallbacks();
  56. UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
  57. if (AkSettings != nullptr)
  58. {
  59. if (RTPCChangedHandle.IsValid())
  60. AkSettings->OnReverbRTPCChanged.Remove(RTPCChangedHandle);
  61. }
  62. #endif
  63. Super::OnUnregister();
  64. }
  65. void UAkAcousticTextureSetComponent::BeginPlay()
  66. {
  67. Super::BeginPlay();
  68. DampingEstimationNeedsUpdate = true;
  69. }
  70. void UAkAcousticTextureSetComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
  71. {
  72. Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
  73. if (SecondsSinceDampingUpdate < PARAM_ESTIMATION_UPDATE_PERIOD)
  74. {
  75. SecondsSinceDampingUpdate += DeltaTime;
  76. }
  77. if (DampingEstimationNeedsUpdate && SecondsSinceDampingUpdate >= PARAM_ESTIMATION_UPDATE_PERIOD)
  78. {
  79. RecalculateHFDamping();
  80. if (USceneComponent* parent = GetAttachParent())
  81. {
  82. if (UAkLateReverbComponent* ReverbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*parent))
  83. {
  84. ReverbComp->TextureSetUpdated(); // We notify the late reverb component so it can recompute the Decay value.
  85. }
  86. }
  87. DampingEstimationNeedsUpdate = false;
  88. }
  89. }
  90. void UAkAcousticTextureSetComponent::SetReverbDescriptor(FAkReverbDescriptor* reverbDescriptor)
  91. {
  92. ReverbDescriptor = reverbDescriptor;
  93. #if WITH_EDITOR
  94. UnregisterTextureParamChangeCallbacks();
  95. if (reverbDescriptor != nullptr)
  96. RegisterAllTextureParamCallbacks();
  97. #endif
  98. if (reverbDescriptor != nullptr)
  99. DampingEstimationNeedsUpdate = true;
  100. }
  101. void UAkAcousticTextureSetComponent::RecalculateHFDamping()
  102. {
  103. if (ReverbDescriptor != nullptr && ReverbDescriptor->ShouldEstimateDamping())
  104. {
  105. ReverbDescriptor->CalculateHFDamping(this);
  106. SecondsSinceDampingUpdate = 0.0f;
  107. }
  108. }
  109. #if WITH_EDITOR
  110. void UAkAcousticTextureSetComponent::BeginDestroy()
  111. {
  112. Super::BeginDestroy();
  113. if (AkSpatialAudioHelper::GetObjectReplacedEvent())
  114. {
  115. AkSpatialAudioHelper::GetObjectReplacedEvent()->RemoveAll(this);
  116. }
  117. }
  118. void UAkAcousticTextureSetComponent::HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap)
  119. {
  120. if (ReplacementMap.Contains(this))
  121. {
  122. UAkAcousticTextureSetComponent* NewTextureSetComponent = Cast<UAkAcousticTextureSetComponent>(ReplacementMap[this]);
  123. if (USceneComponent* Parent = NewTextureSetComponent->GetAttachParent())
  124. {
  125. if (UAkLateReverbComponent* ReverbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*Parent))
  126. {
  127. ReverbComp->AssociateAkTextureSetComponent(NewTextureSetComponent);
  128. }
  129. }
  130. }
  131. }
  132. void UAkAcousticTextureSetComponent::RegisterReverbRTPCChangedCallback()
  133. {
  134. UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
  135. if (AkSettings != nullptr)
  136. {
  137. if (RTPCChangedHandle.IsValid())
  138. AkSettings->OnReverbRTPCChanged.Remove(RTPCChangedHandle);
  139. RTPCChangedHandle = AkSettings->OnReverbRTPCChanged.AddLambda([this]()
  140. {
  141. DampingEstimationNeedsUpdate = true;
  142. });
  143. }
  144. }
  145. void UAkAcousticTextureSetComponent::RegisterTextureParamChangeCallback(FGuid textureID)
  146. {
  147. UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
  148. if (AkSettings != nullptr)
  149. {
  150. if (TextureDelegateHandles.Find(textureID) != nullptr)
  151. {
  152. if (TextureDelegateHandles[textureID].IsValid())
  153. {
  154. AkSettings->OnTextureParamsChanged.Remove(TextureDelegateHandles[textureID]);
  155. }
  156. TextureDelegateHandles.Remove(textureID);
  157. }
  158. TextureDelegateHandles.Add(textureID, AkSettings->OnTextureParamsChanged.AddLambda([&](const FGuid& textureID)
  159. {
  160. if (ContainsTexture(textureID) && ReverbDescriptor != nullptr)
  161. DampingEstimationNeedsUpdate = ReverbDescriptor->ShouldEstimateDamping();
  162. }));
  163. }
  164. }
  165. void UAkAcousticTextureSetComponent::UnregisterTextureParamChangeCallbacks()
  166. {
  167. UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
  168. if (AkSettings != nullptr)
  169. {
  170. for (auto it = TextureDelegateHandles.CreateIterator(); it; ++it)
  171. {
  172. if (it->Value.IsValid())
  173. AkSettings->OnTextureParamsChanged.Remove(it->Value);
  174. }
  175. TextureDelegateHandles.Empty();
  176. }
  177. }
  178. #endif
  179. bool UAkAcousticTextureSetComponent::ShouldSendGeometry() const
  180. {
  181. UWorld* CurrentWorld = GetWorld();
  182. if (CurrentWorld && !IsRunningCommandlet())
  183. {
  184. return CurrentWorld->WorldType == EWorldType::Game || CurrentWorld->WorldType == EWorldType::PIE;
  185. }
  186. return false;
  187. }
  188. void UAkAcousticTextureSetComponent::SendGeometryToWwise(const AkGeometryParams& params)
  189. {
  190. if (ShouldSendGeometry())
  191. {
  192. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  193. if (AkAudioDevice != nullptr && AkAudioDevice->SetGeometry(GetGeometrySetID(), params) == AK_Success)
  194. GeometryHasBeenSent = true;
  195. }
  196. }
  197. void UAkAcousticTextureSetComponent::SendGeometryInstanceToWwise(const FRotator& rotation, const FVector& location, const FVector& scale, const AkRoomID roomID, bool useForReflectionAndDiffraction)
  198. {
  199. if (ShouldSendGeometry() && GeometryHasBeenSent)
  200. {
  201. AkVector front, up;
  202. AkVector64 position;
  203. FAkAudioDevice::FVectorToAKVector(rotation.RotateVector(FVector::ForwardVector), front);
  204. FAkAudioDevice::FVectorToAKVector(rotation.RotateVector(FVector::UpVector), up);
  205. FAkAudioDevice::FVectorToAKVector64(location, position);
  206. AkGeometryInstanceParams params;
  207. params.PositionAndOrientation.Set(position, front, up);
  208. FAkAudioDevice::FVectorToAKVector(scale, params.Scale);
  209. params.GeometrySetID = GetGeometrySetID();
  210. params.RoomID = roomID;
  211. #if WWISE_2023_1_OR_LATER
  212. params.UseForReflectionAndDiffraction = useForReflectionAndDiffraction;
  213. #endif
  214. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  215. if (AkAudioDevice != nullptr && AkAudioDevice->SetGeometryInstance(GetGeometrySetID(), params) == AK_Success)
  216. GeometryInstanceHasBeenSent = true;
  217. }
  218. }
  219. void UAkAcousticTextureSetComponent::RemoveGeometryFromWwise()
  220. {
  221. if (ShouldSendGeometry() && GeometryHasBeenSent)
  222. {
  223. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  224. if (AkAudioDevice != nullptr && AkAudioDevice->RemoveGeometrySet(GetGeometrySetID()) == AK_Success)
  225. {
  226. GeometryHasBeenSent = false;
  227. GeometryInstanceHasBeenSent = false;
  228. }
  229. }
  230. }
  231. void UAkAcousticTextureSetComponent::RemoveGeometryInstanceFromWwise()
  232. {
  233. if (ShouldSendGeometry() && GeometryInstanceHasBeenSent)
  234. {
  235. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  236. if (AkAudioDevice != nullptr && AkAudioDevice->RemoveGeometrySet(GetGeometrySetID()) == AK_Success)
  237. GeometryInstanceHasBeenSent = false;
  238. }
  239. }