AkRoomComponent.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  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. /*=============================================================================
  16. AkRoomComponent.cpp:
  17. =============================================================================*/
  18. #include "AkRoomComponent.h"
  19. #include "AkComponentHelpers.h"
  20. #include "AkAcousticPortal.h"
  21. #include "AkAudioDevice.h"
  22. #include "AkGeometryComponent.h"
  23. #include "AkLateReverbComponent.h"
  24. #include "AkSurfaceReflectorSetComponent.h"
  25. #include "Components/BrushComponent.h"
  26. #include "GameFramework/Volume.h"
  27. #include "Model.h"
  28. #include "EngineUtils.h"
  29. #include "AkAudioEvent.h"
  30. #include "AkSettingsPerUser.h"
  31. #include "Wwise/API/WwiseSpatialAudioAPI.h"
  32. #if WITH_EDITOR
  33. #include "AkDrawRoomComponent.h"
  34. #include "AkSpatialAudioHelper.h"
  35. #endif
  36. #define MOVEMENT_STOP_TIMEOUT 0.1f
  37. /*------------------------------------------------------------------------------------
  38. UAkRoomComponent
  39. ------------------------------------------------------------------------------------*/
  40. UAkRoomComponent::UAkRoomComponent(const class FObjectInitializer& ObjectInitializer) :
  41. Super(ObjectInitializer)
  42. {
  43. Parent = NULL;
  44. WallOcclusion = 1.0f;
  45. bEnable = true;
  46. bUseAttachParentBound = true;
  47. AutoPost = false;
  48. PrimaryComponentTick.bCanEverTick = true;
  49. PrimaryComponentTick.bStartWithTickEnabled = true;
  50. bTickInEditor = true;
  51. #if WITH_EDITOR
  52. if (AkSpatialAudioHelper::GetObjectReplacedEvent())
  53. {
  54. AkSpatialAudioHelper::GetObjectReplacedEvent()->AddUObject(this, &UAkRoomComponent::HandleObjectsReplaced);
  55. }
  56. bWantsInitializeComponent = true;
  57. bWantsOnUpdateTransform = true;
  58. #else
  59. bWantsOnUpdateTransform = false;
  60. #endif
  61. }
  62. void UAkRoomComponent::SetDynamic(bool bInDynamic)
  63. {
  64. bDynamic = bInDynamic;
  65. #if WITH_EDITOR
  66. bWantsOnUpdateTransform = true;
  67. // If we're PIE, or somehow otherwise in a game world in editor, simulate the bDynamic behaviour.
  68. UWorld* world = GetWorld();
  69. if (world != nullptr && (world->WorldType == EWorldType::Type::Game || world->WorldType == EWorldType::Type::PIE))
  70. {
  71. bWantsOnUpdateTransform = bDynamic;
  72. }
  73. #else
  74. bWantsOnUpdateTransform = bDynamic;
  75. #endif
  76. }
  77. FName UAkRoomComponent::GetName() const
  78. {
  79. return Parent->GetFName();
  80. }
  81. bool UAkRoomComponent::HasEffectOnLocation(const FVector& Location) const
  82. {
  83. // Need to add a small radius, because on the Mac, EncompassesPoint returns false if
  84. // Location is exactly equal to the Volume's location
  85. static float RADIUS = 0.01f;
  86. return RoomIsActive() && EncompassesPoint(Location, RADIUS);
  87. }
  88. bool UAkRoomComponent::RoomIsActive() const
  89. {
  90. return IsValid(Parent) && bEnable && !IsRunningCommandlet();
  91. }
  92. void UAkRoomComponent::OnRegister()
  93. {
  94. Super::OnRegister();
  95. #if WITH_EDITOR
  96. bWantsOnUpdateTransform = true;
  97. // If we're PIE, or somehow otherwise in a game world in editor, simulate the bDynamic behaviour.
  98. UWorld* world = GetWorld();
  99. if (world != nullptr && (world->WorldType == EWorldType::Type::Game || world->WorldType == EWorldType::Type::PIE))
  100. {
  101. bWantsOnUpdateTransform = bDynamic;
  102. }
  103. #else
  104. bWantsOnUpdateTransform = bDynamic;
  105. #endif
  106. SetRelativeTransform(FTransform::Identity);
  107. InitializeParent();
  108. // We want to add / update the room both in BeginPlay and OnRegister. BeginPlay for aux bus and reverb level assignment, OnRegister for portal room assignment and visualization
  109. if (!IsRegisteredWithWwise)
  110. AddSpatialAudioRoom();
  111. else
  112. UpdateSpatialAudioRoom();
  113. #if WITH_EDITOR
  114. if (GetDefault<UAkSettingsPerUser>()->VisualizeRoomsAndPortals)
  115. {
  116. InitializeDrawComponent();
  117. }
  118. #endif
  119. }
  120. void UAkRoomComponent::OnUnregister()
  121. {
  122. Super::OnUnregister();
  123. RemoveSpatialAudioRoom();
  124. }
  125. #if WITH_EDITOR
  126. void UAkRoomComponent::OnComponentCreated()
  127. {
  128. Super::OnComponentCreated();
  129. RegisterVisEnabledCallback();
  130. }
  131. void UAkRoomComponent::InitializeComponent()
  132. {
  133. Super::InitializeComponent();
  134. RegisterVisEnabledCallback();
  135. }
  136. void UAkRoomComponent::PostLoad()
  137. {
  138. Super::PostLoad();
  139. RegisterVisEnabledCallback();
  140. }
  141. void UAkRoomComponent::OnComponentDestroyed(bool bDestroyingHierarchy)
  142. {
  143. UAkSettingsPerUser* AkSettingsPerUser = GetMutableDefault<UAkSettingsPerUser>();
  144. AkSettingsPerUser->OnShowRoomsPortalsChanged.Remove(ShowRoomsChangedHandle);
  145. ShowRoomsChangedHandle.Reset();
  146. ConnectedPortals.Empty();
  147. DestroyDrawComponent();
  148. }
  149. #endif // WITH_EDITOR
  150. void UAkRoomComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
  151. {
  152. #if WITH_EDITOR
  153. if (bRequiresDeferredBeginPlay)
  154. {
  155. BeginPlayInternal();
  156. bRequiresDeferredBeginPlay = false;
  157. }
  158. #endif
  159. // In PIE, only update in tick if bDynamic is true (simulate the behaviour in the no-editor game build).
  160. bool bUpdate = true;
  161. #if WITH_EDITOR
  162. if (AkComponentHelpers::IsInGameWorld(this))
  163. bUpdate = bDynamic;
  164. #endif
  165. if (bUpdate)
  166. {
  167. if (Moving)
  168. {
  169. SecondsSinceMovement += DeltaTime;
  170. if (SecondsSinceMovement >= MOVEMENT_STOP_TIMEOUT)
  171. {
  172. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  173. if (AkAudioDevice != nullptr)
  174. {
  175. AkAudioDevice->ReindexRoom(this);
  176. AkAudioDevice->PortalsNeedRoomUpdate(GetWorld());
  177. }
  178. Moving = false;
  179. }
  180. }
  181. if ((bEnable && !IsRegisteredWithWwise) || (!bEnable && IsRegisteredWithWwise))
  182. {
  183. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  184. if (AkAudioDevice != nullptr)
  185. {
  186. if (IsRegisteredWithWwise)
  187. RemoveSpatialAudioRoom();
  188. else
  189. AddSpatialAudioRoom();
  190. }
  191. }
  192. }
  193. }
  194. #if WITH_EDITOR
  195. void UAkRoomComponent::BeginDestroy()
  196. {
  197. Super::BeginDestroy();
  198. if (AkSpatialAudioHelper::GetObjectReplacedEvent())
  199. {
  200. AkSpatialAudioHelper::GetObjectReplacedEvent()->RemoveAll(this);
  201. }
  202. }
  203. void UAkRoomComponent::HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap)
  204. {
  205. if (ReplacementMap.Contains(Parent))
  206. {
  207. InitializeParent();
  208. if (!IsRegisteredWithWwise)
  209. AddSpatialAudioRoom();
  210. else
  211. UpdateSpatialAudioRoom();
  212. }
  213. if (ReplacementMap.Contains(GeometryComponent))
  214. {
  215. GeometryComponent = AkComponentHelpers::GetChildComponentOfType<UAkAcousticTextureSetComponent>(*Parent);
  216. if (GeometryComponent == nullptr || GeometryComponent->HasAnyFlags(RF_Transient) || GeometryComponent->IsBeingDestroyed())
  217. {
  218. GeometryComponent = NewObject<UAkGeometryComponent>(Parent, TEXT("GeometryComponent"));
  219. UAkGeometryComponent* GeomComp = Cast<UAkGeometryComponent>(GeometryComponent);
  220. GeomComp->MeshType = AkMeshType::CollisionMesh;
  221. GeomComp->bWasAddedByRoom = true;
  222. GeometryComponent->AttachToComponent(Parent, FAttachmentTransformRules::KeepRelativeTransform);
  223. GeometryComponent->RegisterComponent();
  224. if (!RoomIsActive())
  225. GeomComp->RemoveGeometry();
  226. }
  227. SendGeometry();
  228. UpdateSpatialAudioRoom();
  229. }
  230. }
  231. void UAkRoomComponent::RegisterVisEnabledCallback()
  232. {
  233. if (!ShowRoomsChangedHandle.IsValid())
  234. {
  235. UAkSettingsPerUser* AkSettingsPerUser = GetMutableDefault<UAkSettingsPerUser>();
  236. ShowRoomsChangedHandle = AkSettingsPerUser->OnShowRoomsPortalsChanged.AddLambda([this, AkSettingsPerUser]()
  237. {
  238. if (AkSettingsPerUser->VisualizeRoomsAndPortals)
  239. {
  240. InitializeDrawComponent();
  241. }
  242. else
  243. {
  244. DestroyDrawComponent();
  245. }
  246. });
  247. }
  248. }
  249. void UAkRoomComponent::InitializeDrawComponent()
  250. {
  251. if (AActor* Owner = GetOwner())
  252. {
  253. if (DrawRoomComponent == nullptr)
  254. {
  255. DrawRoomComponent = NewObject<UDrawRoomComponent>(Owner, NAME_None, RF_Transactional | RF_TextExportTransient);
  256. DrawRoomComponent->SetupAttachment(this);
  257. DrawRoomComponent->SetIsVisualizationComponent(true);
  258. DrawRoomComponent->CreationMethod = CreationMethod;
  259. DrawRoomComponent->RegisterComponentWithWorld(GetWorld());
  260. DrawRoomComponent->MarkRenderStateDirty();
  261. }
  262. }
  263. }
  264. void UAkRoomComponent::DestroyDrawComponent()
  265. {
  266. if (DrawRoomComponent != nullptr)
  267. {
  268. DrawRoomComponent->DestroyComponent();
  269. DrawRoomComponent = nullptr;
  270. }
  271. }
  272. #endif
  273. void UAkRoomComponent::OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport)
  274. {
  275. Moving = true;
  276. SecondsSinceMovement = 0.0f;
  277. }
  278. bool UAkRoomComponent::MoveComponentImpl(
  279. const FVector & Delta,
  280. const FQuat & NewRotation,
  281. bool bSweep,
  282. FHitResult * Hit,
  283. EMoveComponentFlags MoveFlags,
  284. ETeleportType Teleport)
  285. {
  286. if (AkComponentHelpers::DoesMovementRecenterChild(this, Parent, Delta))
  287. Super::MoveComponentImpl(Delta, NewRotation, bSweep, Hit, MoveFlags, Teleport);
  288. return false;
  289. }
  290. void UAkRoomComponent::InitializeParent()
  291. {
  292. USceneComponent* SceneParent = GetAttachParent();
  293. if (SceneParent != nullptr)
  294. {
  295. Parent = Cast<UPrimitiveComponent>(SceneParent);
  296. if (!Parent)
  297. {
  298. bEnable = false;
  299. AkComponentHelpers::LogAttachmentError(this, SceneParent, "UPrimitiveComponent");
  300. return;
  301. }
  302. UBodySetup* bodySetup = Parent->GetBodySetup();
  303. if (bodySetup == nullptr || !AkComponentHelpers::HasSimpleCollisionGeometry(bodySetup))
  304. {
  305. if (UBrushComponent* brush = Cast<UBrushComponent>(Parent))
  306. brush->BuildSimpleBrushCollision();
  307. else
  308. AkComponentHelpers::LogSimpleGeometryWarning(Parent, this);
  309. }
  310. }
  311. }
  312. FString UAkRoomComponent::GetRoomName()
  313. {
  314. FString nameStr = UObject::GetName();
  315. AActor* roomOwner = GetOwner();
  316. if (roomOwner != nullptr)
  317. {
  318. #if WITH_EDITOR
  319. nameStr = roomOwner->GetActorLabel();
  320. #else
  321. nameStr = roomOwner->GetName();
  322. #endif
  323. if (Parent != nullptr)
  324. {
  325. TInlineComponentArray<UAkRoomComponent*> RoomComponents;
  326. roomOwner->GetComponents(RoomComponents);
  327. if (RoomComponents.Num() > 1)
  328. nameStr.Append(FString("_").Append(Parent->GetName()));
  329. }
  330. }
  331. return nameStr;
  332. }
  333. void UAkRoomComponent::GetRoomParams(AkRoomParams& outParams)
  334. {
  335. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  336. if (!AkAudioDevice)
  337. return;
  338. if (IsValid(Parent))
  339. {
  340. AkComponentHelpers::GetPrimitiveUpAndFront(*Parent, outParams.Up, outParams.Front);
  341. }
  342. outParams.TransmissionLoss = WallOcclusion;
  343. UAkLateReverbComponent* ReverbComp = GetReverbComponent();
  344. if (ReverbComp && ReverbComp->bEnable)
  345. {
  346. if (UNLIKELY(!ReverbComp->AuxBus && ReverbComp->AuxBusName.IsEmpty()))
  347. {
  348. outParams.ReverbAuxBus = AK_INVALID_AUX_ID;
  349. }
  350. else
  351. {
  352. outParams.ReverbAuxBus = ReverbComp->GetAuxBusId();
  353. }
  354. outParams.ReverbLevel = ReverbComp->SendLevel;
  355. }
  356. if (GeometryComponent != nullptr)
  357. outParams.GeometryInstanceID = GeometryComponent->GetGeometrySetID();
  358. outParams.RoomGameObj_AuxSendLevelToSelf = AuxSendLevel;
  359. outParams.RoomGameObj_KeepRegistered = AkAudioEvent == NULL ? false : true;
  360. const UAkSettings* AkSettings = GetDefault<UAkSettings>();
  361. if (AkSettings != nullptr && AkSettings->ReverbRTPCsInUse())
  362. outParams.RoomGameObj_KeepRegistered = true;
  363. }
  364. UPrimitiveComponent* UAkRoomComponent::GetPrimitiveParent() const
  365. {
  366. return Parent;
  367. }
  368. void UAkRoomComponent::SetReverbZone(const UAkRoomComponent* InParentRoom, float InTransitionRegionWidth)
  369. {
  370. if (GeometryComponent == nullptr)
  371. {
  372. UE_LOG(LogAkAudio, Error, TEXT("UAkRoomComponent::SetReverbZone: Reverb Zone Room component %s doesn't have an associated geometry."), *GetRoomName());
  373. return;
  374. }
  375. // If InParentRoom is null, assign the outdoor room as the parent room.
  376. ParentRoomID = AK::SpatialAudio::kOutdoorRoomID;
  377. if (InParentRoom != nullptr)
  378. {
  379. ParentRoomID = InParentRoom->GetRoomID();
  380. }
  381. if (InTransitionRegionWidth < 0.f)
  382. {
  383. UE_LOG(LogAkAudio, Warning, TEXT("UAkGameplayStatics::SetReverbZone: Transition region width for Reverb Zone %s is a negative number. It has been clamped to 0."), *GetRoomName());
  384. InTransitionRegionWidth = 0.f;
  385. }
  386. auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
  387. if (LIKELY(SpatialAudio))
  388. {
  389. SpatialAudio->SetReverbZone(GetRoomID(), ParentRoomID, InTransitionRegionWidth);
  390. bIsAReverbZoneInWwise = true;
  391. }
  392. }
  393. void UAkRoomComponent::RemoveReverbZone()
  394. {
  395. auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
  396. if (LIKELY(SpatialAudio))
  397. {
  398. SpatialAudio->RemoveReverbZone(GetRoomID());
  399. bIsAReverbZoneInWwise = false;
  400. }
  401. }
  402. void UAkRoomComponent::AddSpatialAudioRoom()
  403. {
  404. if (RoomIsActive())
  405. {
  406. SendGeometry();
  407. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  408. IWwiseSpatialAudioAPI* SpatialAudio = IWwiseSpatialAudioAPI::Get();
  409. if (AkAudioDevice && SpatialAudio)
  410. {
  411. AkRoomParams Params;
  412. GetRoomParams(Params);
  413. AkAudioDevice->AddRoom(this, Params);
  414. IsRegisteredWithWwise = true;
  415. if (GetOwner() != nullptr && IsRegisteredWithWwise && (GetWorld()->WorldType == EWorldType::Game || GetWorld()->WorldType == EWorldType::PIE))
  416. {
  417. UAkLateReverbComponent* pRvbComp = GetReverbComponent();
  418. if (pRvbComp != nullptr)
  419. pRvbComp->UpdateRTPCs(this);
  420. }
  421. }
  422. }
  423. }
  424. void UAkRoomComponent::UpdateSpatialAudioRoom()
  425. {
  426. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  427. IWwiseSpatialAudioAPI* SpatialAudio = IWwiseSpatialAudioAPI::Get();
  428. if (RoomIsActive() && AkAudioDevice && SpatialAudio && IsRegisteredWithWwise)
  429. {
  430. AkRoomParams Params;
  431. GetRoomParams(Params);
  432. AkAudioDevice->UpdateRoom(this, Params);
  433. if (GetOwner() != nullptr && (GetWorld()->WorldType == EWorldType::Game || GetWorld()->WorldType == EWorldType::PIE))
  434. {
  435. UAkLateReverbComponent* pRvbComp = GetReverbComponent();
  436. if (pRvbComp != nullptr)
  437. pRvbComp->UpdateRTPCs(this);
  438. }
  439. }
  440. }
  441. void UAkRoomComponent::RemoveSpatialAudioRoom()
  442. {
  443. if (Parent && !IsRunningCommandlet())
  444. {
  445. RemoveGeometry();
  446. FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
  447. if (AkAudioDevice)
  448. {
  449. if (GetOwner() != nullptr && (GetWorld()->WorldType == EWorldType::Game || GetWorld()->WorldType == EWorldType::PIE))
  450. {
  451. // stop all sounds posted on the room
  452. Stop();
  453. }
  454. AkAudioDevice->RemoveRoom(this);
  455. IsRegisteredWithWwise = false;
  456. }
  457. }
  458. }
  459. int32 UAkRoomComponent::PostAssociatedAkEvent(int32 CallbackMask, const FOnAkPostEventCallback& PostEventCallback)
  460. {
  461. if (LIKELY(IsValid(AkAudioEvent)))
  462. {
  463. return PostAkEvent(AkAudioEvent, CallbackMask, PostEventCallback);
  464. }
  465. UE_LOG(LogAkAudio, Error, TEXT("Failed to post invalid AkAudioEvent on Room component '%s'"), *GetRoomName());
  466. return AK_INVALID_PLAYING_ID;
  467. }
  468. AkPlayingID UAkRoomComponent::PostAkEventByNameWithDelegate(
  469. UAkAudioEvent* AkEvent,
  470. const FString& in_EventName,
  471. int32 CallbackMask, const FOnAkPostEventCallback& PostEventCallback)
  472. {
  473. AkPlayingID PlayingID = AK_INVALID_PLAYING_ID;
  474. auto AudioDevice = FAkAudioDevice::Get();
  475. if (AudioDevice)
  476. {
  477. const AkUInt32 ShortID = AudioDevice->GetShortID(AkEvent, in_EventName);
  478. PlayingID = AkEvent->PostOnGameObject(this, PostEventCallback, CallbackMask);
  479. }
  480. return PlayingID;
  481. }
  482. void UAkRoomComponent::BeginPlay()
  483. {
  484. Super::BeginPlay();
  485. #if WITH_EDITOR
  486. if (AkComponentHelpers::ShouldDeferBeginPlay(this))
  487. bRequiresDeferredBeginPlay = true;
  488. else
  489. BeginPlayInternal();
  490. #else
  491. BeginPlayInternal();
  492. PrimaryComponentTick.bCanEverTick = bDynamic;
  493. PrimaryComponentTick.bStartWithTickEnabled = bDynamic;
  494. #endif
  495. }
  496. void UAkRoomComponent::BeginPlayInternal()
  497. {
  498. GeometryComponent = AkComponentHelpers::GetChildComponentOfType<UAkAcousticTextureSetComponent>(*Parent);
  499. if (GeometryComponent == nullptr || GeometryComponent->HasAnyFlags(RF_Transient) || GeometryComponent->IsBeingDestroyed())
  500. {
  501. static const FName GeometryComponentName = TEXT("GeometryComponent");
  502. GeometryComponent = NewObject<UAkGeometryComponent>(Parent, GeometryComponentName);
  503. UAkGeometryComponent* geom = Cast<UAkGeometryComponent>(GeometryComponent);
  504. geom->MeshType = AkMeshType::CollisionMesh;
  505. geom->bWasAddedByRoom = true;
  506. GeometryComponent->AttachToComponent(Parent, FAttachmentTransformRules::KeepRelativeTransform);
  507. GeometryComponent->RegisterComponent();
  508. if (!RoomIsActive())
  509. geom->RemoveGeometry();
  510. }
  511. // We want to add / update the room both in BeginPlay and OnRegister. BeginPlay for aux bus and reverb level assignment, OnRegister for portal room assignment and visualization
  512. if (!IsRegisteredWithWwise)
  513. {
  514. AddSpatialAudioRoom();
  515. }
  516. else
  517. {
  518. SendGeometry();
  519. UpdateSpatialAudioRoom();
  520. }
  521. if (AutoPost)
  522. {
  523. PostAssociatedAkEvent(0, FOnAkPostEventCallback());
  524. }
  525. }
  526. void UAkRoomComponent::EndPlay(EEndPlayReason::Type EndPlayReason)
  527. {
  528. if (HasActiveEvents())
  529. {
  530. Stop();
  531. }
  532. Super::EndPlay(EndPlayReason);
  533. }
  534. void UAkRoomComponent::SetGeometryComponent(UAkAcousticTextureSetComponent* textureSetComponent)
  535. {
  536. if (GeometryComponent != nullptr)
  537. {
  538. RemoveGeometry();
  539. }
  540. GeometryComponent = textureSetComponent;
  541. if (RoomIsActive())
  542. {
  543. SendGeometry();
  544. UpdateSpatialAudioRoom();
  545. }
  546. }
  547. #if WITH_EDITOR
  548. void UAkRoomComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
  549. {
  550. Super::PostEditChangeProperty(PropertyChangedEvent);
  551. //Call add again to update the room parameters, if it has already been added.
  552. if (IsRegisteredWithWwise)
  553. UpdateSpatialAudioRoom();
  554. }
  555. void UAkRoomComponent::OnParentNameChanged()
  556. {
  557. for (auto& Portal : ConnectedPortals)
  558. {
  559. Portal.Value->UpdateRoomNames();
  560. }
  561. }
  562. #endif
  563. bool UAkRoomComponent::EncompassesPoint(FVector Point, float SphereRadius/*=0.f*/, float* OutDistanceToPoint/*=nullptr*/) const
  564. {
  565. if (IsValid(Parent))
  566. {
  567. return AkComponentHelpers::EncompassesPoint(*Parent, Point, SphereRadius, OutDistanceToPoint);
  568. }
  569. FString actorString = FString("NONE");
  570. if (GetOwner() != nullptr)
  571. actorString = GetOwner()->GetName();
  572. UE_LOG(LogAkAudio, Error, TEXT("UAkRoomComponent::EncompassesPoint : Error. In actor %s, AkRoomComponent %s has an invalid Parent."), *actorString, *UObject::GetName());
  573. return false;
  574. }
  575. void UAkRoomComponent::SendGeometry()
  576. {
  577. if (GeometryComponent)
  578. {
  579. UAkGeometryComponent* GeometryComp = Cast<UAkGeometryComponent>(GeometryComponent);
  580. if (GeometryComp && GeometryComp->bWasAddedByRoom)
  581. {
  582. if (!GeometryComp->GetGeometryHasBeenSent())
  583. GeometryComp->SendGeometry();
  584. if (!GeometryComp->GetGeometryInstanceHasBeenSent())
  585. GeometryComp->UpdateGeometry();
  586. }
  587. UAkSurfaceReflectorSetComponent* SurfaceReflector = Cast<UAkSurfaceReflectorSetComponent>(GeometryComponent);
  588. if (SurfaceReflector && !SurfaceReflector->bEnableSurfaceReflectors)
  589. {
  590. if (!SurfaceReflector->GetGeometryHasBeenSent())
  591. SurfaceReflector->SendSurfaceReflectorSet();
  592. if (!SurfaceReflector->GetGeometryInstanceHasBeenSent())
  593. SurfaceReflector->UpdateSurfaceReflectorSet();
  594. }
  595. }
  596. }
  597. void UAkRoomComponent::RemoveGeometry()
  598. {
  599. if (IsValid(GeometryComponent))
  600. {
  601. UAkGeometryComponent* GeometryComp = Cast<UAkGeometryComponent>(GeometryComponent);
  602. if (GeometryComp && GeometryComp->bWasAddedByRoom)
  603. {
  604. GeometryComp->RemoveGeometry();
  605. }
  606. UAkSurfaceReflectorSetComponent* SurfaceReflector = Cast<UAkSurfaceReflectorSetComponent>(GeometryComponent);
  607. if (SurfaceReflector && !SurfaceReflector->bEnableSurfaceReflectors)
  608. {
  609. SurfaceReflector->RemoveSurfaceReflectorSet();
  610. }
  611. }
  612. }
  613. UAkLateReverbComponent* UAkRoomComponent::GetReverbComponent()
  614. {
  615. UAkLateReverbComponent* pRvbComp = nullptr;
  616. if (Parent != nullptr)
  617. {
  618. pRvbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*Parent);
  619. }
  620. return pRvbComp;
  621. }
  622. void UAkRoomComponent::AddPortalConnection(UAkPortalComponent* in_pPortal)
  623. {
  624. ConnectedPortals.Add(in_pPortal->GetPortalID(), in_pPortal);
  625. }
  626. void UAkRoomComponent::RemovePortalConnection(AkPortalID in_portalID)
  627. {
  628. ConnectedPortals.Remove(in_portalID);
  629. }