AkAcousticPortal.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 "Components/TextRenderComponent.h"
  17. #include "GameFramework/Volume.h"
  18. #include "ObstructionAndOcclusionService/AkPortalObstructionAndOcclusionService.h"
  19. #include "AkGameplayTypes.h"
  20. #if WITH_EDITOR
  21. #include "AkSettings.h"
  22. #endif
  23. #include "AkAcousticPortal.generated.h"
  24. class UAkRoomComponent;
  25. class UAkLateReverbComponent;
  26. UCLASS(ClassGroup = Audiokinetic, hidecategories = (Advanced, Attachment, Volume), BlueprintType, meta = (BlueprintSpawnableComponent))
  27. class AKAUDIO_API UAkPortalComponent : public USceneComponent
  28. {
  29. GENERATED_BODY()
  30. public:
  31. UAkPortalComponent(const class FObjectInitializer& ObjectInitializer);
  32. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
  33. void OpenPortal();
  34. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
  35. void ClosePortal();
  36. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
  37. AkAcousticPortalState GetCurrentState() const;
  38. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
  39. UPrimitiveComponent* GetPrimitiveParent() const;
  40. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
  41. bool PortalPlacementValid() const { return GetFrontRoom() != GetBackRoom(); }
  42. /** If true, the room connections for this portal can change during runtime when this portal moves. For worlds containing many rooms, this can be expensive. Note that this portal's room connections may still change, even when bDynamic = false, when dynamic rooms are moved (i.e. when rooms move who have bDynamic = true). */
  43. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent", meta = (DisplayName = "Is Dynamic"))
  44. bool bDynamic = false;
  45. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AkPortalComponent")
  46. AkAcousticPortalState InitialState = AkAcousticPortalState::Open;
  47. /** Time interval between obstruction checks (direct line of sight between listener and portal opening). Set to 0 to disable obstruction checks. We recommend disabling it if you want to use full Spatial Audio diffraction. */
  48. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent|Obstruction")
  49. float ObstructionRefreshInterval = .0f;
  50. /** Collision channel for obstruction checks (between listener and portal opening). */
  51. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent|Obstruction")
  52. TEnumAsByte<ECollisionChannel> ObstructionCollisionChannel = ECollisionChannel::ECC_Visibility;
  53. void ResetPortalState();
  54. FVector GetExtent() const;
  55. AkRoomID GetFrontRoom() const;
  56. AkRoomID GetBackRoom() const;
  57. AkPortalID GetPortalID() const { return AkPortalID(this); }
  58. /** Update the room connections for the portal, given the portals current transform.
  59. Return true if the room connections have changed.
  60. */
  61. bool UpdateConnectedRooms();
  62. const UAkRoomComponent* GetFrontRoomComponent() const { return FrontRoom; }
  63. const UAkRoomComponent* GetBackRoomComponent() const { return BackRoom; }
  64. virtual void BeginPlay() override;
  65. #if WITH_EDITOR
  66. virtual void BeginDestroy() override;
  67. virtual void InitializeComponent() override;
  68. virtual void OnComponentCreated() override;
  69. virtual void PostLoad() override;
  70. virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
  71. void UpdateTextRotations() const;
  72. #endif // WITH_EDITOR
  73. virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) override;
  74. virtual void OnRegister() override;
  75. virtual void OnUnregister() override;
  76. virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) override;
  77. virtual bool MoveComponentImpl(
  78. const FVector & Delta,
  79. const FQuat & NewRotation,
  80. bool bSweep,
  81. FHitResult * Hit,
  82. EMoveComponentFlags MoveFlags,
  83. ETeleportType Teleport) override;
  84. private:
  85. class UPrimitiveComponent* Parent;
  86. void InitializeParent();
  87. void SetSpatialAudioPortal();
  88. template <typename tComponent>
  89. void FindConnectedComponents(FAkEnvironmentIndex& RoomQuery, tComponent*& out_pFront, tComponent*& out_pBack);
  90. AkAcousticPortalState PortalState;
  91. #if WITH_EDITOR
  92. static const float RoomsRefreshIntervalEditor;
  93. #endif
  94. static const float RoomsRefreshIntervalGame;
  95. static const float RoomsRefreshDistanceThreshold;
  96. static const float RoomsRefreshMinRotationThreshold_Degrees;
  97. float RoomsRefreshIntervalSeconds = 0.5f;
  98. float LastRoomsUpdate = 0.0f;
  99. FVector PreviousLocation;
  100. FRotator PreviousRotation;
  101. bool PortalNeedUpdated = false;
  102. UAkRoomComponent* FrontRoom;
  103. UAkRoomComponent* BackRoom;
  104. AkPortalObstructionAndOcclusionService ObstructionService;
  105. #if WITH_EDITOR
  106. void HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap);
  107. class UDrawPortalComponent* DrawPortalComponent = nullptr;
  108. void RegisterVisEnabledCallback();
  109. void InitializeDrawComponent();
  110. void DestroyDrawComponent();
  111. FDelegateHandle ShowPortalsChangedHandle;
  112. bool AreTextVisualizersInitialized() const;
  113. void InitTextVisualizers();
  114. void DestroyTextVisualizers();
  115. void UpdateRoomNames();
  116. void UpdateTextVisibility();
  117. // Updates the location, rotation and visibility of the text visualizers
  118. void UpdateTextLocRotVis();
  119. bool bWasSelected = false;
  120. #endif
  121. #if WITH_EDITORONLY_DATA
  122. UPROPERTY(SkipSerialization, NonTransactional)
  123. mutable UTextRenderComponent* FrontRoomText = nullptr;
  124. UPROPERTY(SkipSerialization, NonTransactional)
  125. mutable UTextRenderComponent* BackRoomText = nullptr;
  126. #endif
  127. };
  128. UCLASS(ClassGroup = Audiokinetic, hidecategories = (Advanced, Attachment, Volume), BlueprintType)
  129. class AKAUDIO_API AAkAcousticPortal : public AVolume
  130. {
  131. GENERATED_BODY()
  132. public:
  133. AAkAcousticPortal(const class FObjectInitializer& ObjectInitializer);
  134. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
  135. void OpenPortal();
  136. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
  137. void ClosePortal();
  138. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
  139. AkAcousticPortalState GetCurrentState() const;
  140. AkRoomID GetFrontRoom() const;
  141. AkRoomID GetBackRoom() const;
  142. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Portal", meta = (ShowOnlyInnerProperties))
  143. UAkPortalComponent* Portal = nullptr;
  144. virtual void PostRegisterAllComponents() override;
  145. virtual void PostLoad() override;
  146. virtual void Serialize(FArchive& Ar) override;
  147. #if WITH_EDITOR
  148. void FitRaycast();
  149. void FitPortal();
  150. virtual void PostEditMove(bool bFinished) override;
  151. virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
  152. bool GetBestHits(FVector& Start0, FVector& End0, FVector& Start1, FVector& End1)
  153. {
  154. if (BestFitValid)
  155. {
  156. Start0 = BestFit[0];
  157. End0 = BestFit[1];
  158. Start1 = BestFit[2];
  159. End1 = BestFit[3];
  160. return true;
  161. }
  162. return false;
  163. }
  164. float GetDetectionRadius() const { return DetectionRadius; }
  165. bool GetFitToGeometry() const { return FitToGeometry; }
  166. bool GetIsDragging() const { return IsDragging; }
  167. virtual FName GetCustomIconName() const override
  168. {
  169. static const FName IconName("ClassIcon.AkAcousticPortal");
  170. return IconName;
  171. }
  172. #endif
  173. protected:
  174. static const int kNumRaycasts = 128;
  175. #if WITH_EDITORONLY_DATA
  176. void ClearBestFit();
  177. /**
  178. Automatically fit the Ak Acoustic Portal to surrounding geometry. The fitting operation is performed after enabling this property, or after moving the actor to a new location.
  179. To find portals in surrounding geometry, rays emanating spherically outwards are cast from the origin of the actor in an attempt to detect sets of parallel surfaces.
  180. The "best" detected parallel surfaces are indicated with yellow outline when dragging the actor to a new location.
  181. */
  182. UPROPERTY(EditAnywhere, Category = "Fit to Geometry")
  183. bool FitToGeometry = false;
  184. /**
  185. Sets the collision channel for the ray traces performed to fit the portal to the surrounding geometry. When set to 'Use Integration Settings Default', the value will be taken from the DefaultFitToGeometryCollisionChannel in the Wwise Integration Settings.
  186. */
  187. UPROPERTY(EditAnywhere, Category = "Fit to Geometry")
  188. TEnumAsByte<EAkCollisionChannel> CollisionChannel = { EAkCollisionChannel::EAKCC_UseIntegrationSettingsDefault };
  189. #if WITH_EDITOR
  190. /**
  191. Converts between EAkCollisionChannel and ECollisionChannel. Returns Wwise Integration Settings default if CollisionChannel == UseIntegrationSettingsDefault. Otherwise, casts CollisionChannel to ECollisionChannel.
  192. */
  193. UFUNCTION(BlueprintCallable, Category = "Fit to Geometry")
  194. ECollisionChannel GetCollisionChannel();
  195. #endif
  196. /**
  197. Limits the effective portal opening size that can be detected when fitting the portal to surrounding geometry.
  198. Increase this value to find larger openings; decrease it if large portals are erroneously detected, for example ones that span whole rooms.
  199. The slider range can be expanded by entering a text value into this field.
  200. */
  201. UPROPERTY(EditAnywhere, Category = "Fit to Geometry", meta = (ClampMin = 1.0f, ClampMax = 100000.0f, UIMin = 100.0f, UIMax = 5000.0f))
  202. float DetectionRadius = 500.0f;
  203. FVector SavedRaycastOrigin;
  204. bool bUseSavedRaycastOrigin = false;
  205. FVector BestFit[4];
  206. bool BestFitValid = false;
  207. bool IsDragging = false;
  208. #endif
  209. private:
  210. /** As of Wwise 2020.1, the InitialState is contained in the AkPortalComponent */
  211. UPROPERTY()
  212. AkAcousticPortalState InitialState;
  213. UPROPERTY(Transient)
  214. bool bRequiresStateMigration = false;
  215. bool bRequiresTransformMigration = false;
  216. };