AkGeometryComponent.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 "Platforms/AkUEPlatform.h"
  17. #include "AkAcousticTexture.h"
  18. #include "Components/SceneComponent.h"
  19. #include "PhysicalMaterials/PhysicalMaterial.h"
  20. #include "AkAcousticTextureSetComponent.h"
  21. #include "AkGeometryData.h"
  22. #include "AkGeometryComponent.generated.h"
  23. class UAkSettings;
  24. #if UE_5_0_OR_LATER
  25. class UMaterialInterface;
  26. #endif
  27. DECLARE_DELEGATE(FOnRefreshDetails);
  28. UENUM()
  29. enum class AkMeshType : uint8
  30. {
  31. StaticMesh,
  32. CollisionMesh UMETA(DisplayName = "Simple Collision")
  33. };
  34. USTRUCT(BlueprintType)
  35. struct FAkGeometrySurfaceOverride
  36. {
  37. GENERATED_BODY()
  38. /** The Acoustic Texture represents the sound absorption on the surface of the geometry when a sound bounces off of it.
  39. * If left to None, the mesh's physical material will be used to fetch an acoustic texture.
  40. */
  41. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry")
  42. UAkAcousticTexture* AcousticTexture = nullptr;
  43. /** Enable Transmission Loss Override */
  44. UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName = "Enable Transmission Loss Override", Category = "Geometry")
  45. bool bEnableOcclusionOverride = false;
  46. /** Transmission loss value to set when modeling sound transmission through geometry. Transmission is modeled only when there is no direct line of sight from the emitter to the listener.
  47. * If there is more than one surface between the emitter and the listener, the maximum of each surface's transmission loss value is used. If the emitter and listener are in different rooms, the room's transmission loss value is taken into account.
  48. * Valid range : (0.0, 1.0)
  49. */
  50. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", DisplayName = "Transmission Loss", meta = (EditCondition = "bEnableOcclusionOverride", ClampMin = "0.0", ClampMax = "1.0"))
  51. float OcclusionValue = 1.f;
  52. void SetSurfaceArea(float area) { SurfaceArea = area; }
  53. FAkGeometrySurfaceOverride()
  54. {
  55. AcousticTexture = nullptr;
  56. bEnableOcclusionOverride = false;
  57. OcclusionValue = 1.f;
  58. }
  59. private:
  60. UPROPERTY()
  61. float SurfaceArea = 0.0f;
  62. };
  63. UCLASS(ClassGroup = Audiokinetic, BlueprintType, hidecategories = (Transform, Rendering, Mobility, LOD, Component, Activation, Tags), meta = (BlueprintSpawnableComponent))
  64. class AKAUDIO_API UAkGeometryComponent : public UAkAcousticTextureSetComponent
  65. {
  66. GENERATED_BODY()
  67. public:
  68. UAkGeometryComponent(const class FObjectInitializer& ObjectInitializer);
  69. /** Convert the mesh into a local representation suited for Wwise:
  70. * a set of vertices, triangles, surfaces, acoustic textures and transmission loss values. */
  71. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkGeometry")
  72. void ConvertMesh();
  73. /** Add or update a geometry in Spatial Audio by sending the converted mesh, as well as the rest of the AkGeometryParams to Wwise.
  74. * It is necessary to create at least one geometry instance for each geometry set that is to be used for diffraction and reflection simulation. See UpdateGeometry(). */
  75. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkGeometry")
  76. void SendGeometry();
  77. /** Add or update an instance of the geometry by sending the transform of this component to Wwise.
  78. * A geometry instance is a unique instance of a geometry set with a specified transform (position, rotation and scale).
  79. * It is necessary to create at least one geometry instance for each geometry set that is to be used for diffraction and reflection simulation. */
  80. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkGeometry")
  81. void UpdateGeometry();
  82. /** Remove the geometry and the corresponding instance from Wwise. */
  83. UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkGeometry")
  84. void RemoveGeometry();
  85. virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
  86. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Geometry")
  87. AkMeshType MeshType = AkMeshType::CollisionMesh;
  88. /** The Static Mesh's LOD to use */
  89. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", meta = (ClampMin = "0.0"))
  90. int LOD = 0;
  91. /** The local distance in Unreal units between two vertices to be welded together.
  92. * Any two vertices closer than this threshold will be treated as the same unique vertex and assigned the same position.
  93. * Increasing this threshold decreases the number of gaps between triangles, resulting in a more continuous mesh and less sound leaking though, as well as eliminating triangles that are too small to be significant.
  94. * Increasing this threshold also helps Spatial Audio's edge-finding algorithm to find more valid diffraction edges.
  95. */
  96. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", meta = (ClampMin = "0.0"))
  97. float WeldingThreshold = .0f;
  98. /** Override the acoustic properties of this mesh per material.*/
  99. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", DisplayName = "Acoustic Properties Override")
  100. TMap<UMaterialInterface*, FAkGeometrySurfaceOverride> StaticMeshSurfaceOverride;
  101. /** Override the acoustic properties of the collision mesh.*/
  102. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", DisplayName = "Acoustic Properties Override")
  103. FAkGeometrySurfaceOverride CollisionMeshSurfaceOverride;
  104. /** Enable or disable geometric diffraction for this mesh. Check this box to have Wwise Spatial Audio generate diffraction edges on the geometry. The diffraction edges will be visible in the Wwise game object viewer when connected to the game. */
  105. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry")
  106. bool bEnableDiffraction = false;
  107. /** Enable or disable geometric diffraction on boundary edges for this Geometry. Boundary edges are edges that are connected to only one triangle. Depending on the specific shape of the geometry, boundary edges may or may not be useful and it is beneficial to reduce the total number of diffraction edges to process. */
  108. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry", meta = (EditCondition = "bEnableDiffraction"))
  109. bool bEnableDiffractionOnBoundaryEdges = false;
  110. /** (Optional) Associate this Surface Reflector Set with a Room.
  111. * Associating a spatial audio geometry with a particular room will limit the scope in which the geometry is visible/accessible. Leave it to None and this geometry will have a global scope.
  112. * It is recommended to associate geometry with a room when the geometry is (1) fully contained within the room (ie. not visible to other rooms except by portals), and (2) the room does not share geometry with other rooms. Doing so reduces the search space for ray casting performed by reflection and diffraction calculations.
  113. * Take note that once one or more geometry sets are associated with a room, that room will no longer be able to access geometry that is in the global scope.
  114. */
  115. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Geometry")
  116. AActor* AssociatedRoom = nullptr;
  117. float GetSurfaceAreaSquaredMeters(const int& surfaceIndex) const;
  118. void UpdateStaticMeshOverride();
  119. #if WITH_EDITORONLY_DATA
  120. void SetOnRefreshDetails(const FOnRefreshDetails& in_delegate) { OnRefreshDetails = in_delegate; }
  121. void ClearOnRefreshDetails() { OnRefreshDetails.Unbind(); }
  122. const FOnRefreshDetails* GetOnRefreshDetails() { return &OnRefreshDetails; }
  123. bool bMeshMaterialChanged = false;
  124. #endif
  125. #if WITH_EDITOR
  126. virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
  127. virtual void PostEditUndo() override;
  128. virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
  129. #endif
  130. virtual void OnRegister() override;
  131. virtual void OnUnregister() override;
  132. virtual void BeginPlay() override;
  133. virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
  134. virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) override;
  135. virtual bool MoveComponentImpl(
  136. const FVector & Delta,
  137. const FQuat & NewRotation,
  138. bool bSweep,
  139. FHitResult * Hit,
  140. EMoveComponentFlags MoveFlags,
  141. ETeleportType Teleport) override;
  142. virtual void Serialize(FArchive& Ar) override;
  143. void GetTexturesAndSurfaceAreas(TArray<FAkAcousticTextureParams>& textures, TArray<float>& surfaceAreas) const override;
  144. /** Indicates whether this component was added dynamically by a sibling room component in order to send geometry to Wwise. */
  145. bool bWasAddedByRoom = false;
  146. private:
  147. UPrimitiveComponent* Parent = nullptr;
  148. void InitializeParent();
  149. void CalculateSurfaceArea(UStaticMeshComponent* StaticMeshComponent);
  150. void ConvertStaticMesh(UStaticMeshComponent* StaticMeshComponent, const UAkSettings* AkSettings);
  151. void ConvertCollisionMesh(UPrimitiveComponent* PrimitiveComponent, const UAkSettings* AkSettings);
  152. void UpdateMeshAndArchetype(UStaticMeshComponent* StaticMeshComponent);
  153. void _UpdateStaticMeshOverride(UStaticMeshComponent* StaticMeshComponent);
  154. UPROPERTY()
  155. FAkGeometryData GeometryData;
  156. UPROPERTY()
  157. TMap<int, double> SurfaceAreas;
  158. TMap<UMaterialInterface*, FAkGeometrySurfaceOverride> PreviousStaticMeshSurfaceOverride;
  159. void BeginPlayInternal();
  160. #if WITH_EDITOR
  161. virtual void HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap) override;
  162. bool bRequiresDeferredBeginPlay = false;
  163. void RegisterAllTextureParamCallbacks() override;
  164. bool ContainsTexture(const FGuid& textureID) override;
  165. #endif
  166. #if WITH_EDITORONLY_DATA
  167. FOnRefreshDetails OnRefreshDetails;
  168. FDelegateHandle OnMeshMaterialChangedHandle;
  169. #endif
  170. };