SAkGeometrySurfaceOverrideController.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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 "SAkGeometrySurfaceOverrideController.h"
  16. #include "DetailCategoryBuilder.h"
  17. #include "DetailLayoutBuilder.h"
  18. #include "PropertyCustomizationHelpers.h"
  19. #include "Editor/TransBuffer.h"
  20. #include "Widgets/Input/SCheckBox.h"
  21. #include "Widgets/Input/SNumericEntryBox.h"
  22. #include "Widgets/Layout/SBox.h"
  23. #include "AkGeometryComponent.h"
  24. #include "WwiseUEFeatures.h"
  25. namespace AkGeometryUI
  26. {
  27. static int LabelWidth = 146;
  28. }
  29. void SSurfacePropertiesLabels::Construct(const FArguments& InArgs, FAkGeometrySurfaceOverride* InSurfaceOverride)
  30. {
  31. SurfaceOverride = InSurfaceOverride;
  32. ChildSlot
  33. [
  34. SNew(SVerticalBox)
  35. + SVerticalBox::Slot() // Acoustic Surface Parameters
  36. .FillHeight(1.0f)
  37. [
  38. SNew(SVerticalBox)
  39. + SVerticalBox::Slot() // Texture
  40. .FillHeight(0.33f)
  41. [
  42. SNew(SHorizontalBox)
  43. + SHorizontalBox::Slot() // Label
  44. .HAlign(HAlign_Left)
  45. .VAlign(VAlign_Center)
  46. .AutoWidth()
  47. [
  48. SNew(SBox)
  49. .WidthOverride(AkGeometryUI::LabelWidth)
  50. [
  51. SNew(STextBlock)
  52. .ToolTipText(FText::FromString("The Audiokinetic Texture associated with the surface."))
  53. .Text(FText::FromString(FString(TEXT("AkAcousticTexture"))))
  54. .Font(IDetailLayoutBuilder::GetDetailFont())
  55. ]
  56. ]
  57. ]
  58. + SVerticalBox::Slot() // Transmission Loss
  59. .FillHeight(0.33f)
  60. [
  61. SNew(SHorizontalBox)
  62. + SHorizontalBox::Slot() // Label
  63. .HAlign(HAlign_Left)
  64. .VAlign(VAlign_Center)
  65. .AutoWidth()
  66. [
  67. SNew(SBox)
  68. .WidthOverride(AkGeometryUI::LabelWidth)
  69. [
  70. SNew(STextBlock)
  71. .ToolTipText(FText::FromString("Indicates whether the surface overrides the transmission loss value."))
  72. .Text(FText::FromString(FString(TEXT("Override Transmission Loss"))))
  73. .Font(IDetailLayoutBuilder::GetDetailFont())
  74. ]
  75. ]
  76. ]
  77. + SVerticalBox::Slot() // Enable Transmission Loss Override
  78. .FillHeight(0.33f)
  79. [
  80. SNew(SBox)
  81. [
  82. SNew(SHorizontalBox)
  83. + SHorizontalBox::Slot() // Label
  84. .HAlign(HAlign_Left)
  85. .VAlign(VAlign_Center)
  86. .AutoWidth()
  87. [
  88. SNew(SBox)
  89. .WidthOverride(AkGeometryUI::LabelWidth)
  90. .Visibility_Lambda([this]() { return TransmissionLossVisibility(); })
  91. [
  92. SNew(STextBlock)
  93. .ToolTipText(FText::FromString("Indicates how much sound is transmitted through the surface."))
  94. .Text(FText::FromString(FString(TEXT("Transmission Loss"))))
  95. .Font(IDetailLayoutBuilder::GetDetailFont())
  96. ]
  97. ]
  98. ]
  99. ]
  100. ]
  101. ];
  102. }
  103. EVisibility SSurfacePropertiesLabels::TransmissionLossVisibility() const
  104. {
  105. if (SurfaceOverride == nullptr)
  106. return EVisibility::Visible;
  107. return SurfaceOverride->bEnableOcclusionOverride ? EVisibility::Visible : EVisibility::Collapsed;
  108. }
  109. // ==================================================
  110. // SAkGeometrySurfaceController
  111. // ==================================================
  112. void SAkGeometrySurfaceController::Construct(const FArguments& InArgs, TWeakObjectPtr<UObject> ObjectBeingCustomized, const TSharedPtr<IDetailLayoutBuilder>& InLayoutBuilder)
  113. {
  114. LayoutBuilder = InLayoutBuilder;
  115. ComponentBeingCustomized = Cast<UAkGeometryComponent>(ObjectBeingCustomized);
  116. BuildSlate();
  117. }
  118. SAkGeometrySurfaceController::~SAkGeometrySurfaceController()
  119. {
  120. }
  121. void SAkGeometrySurfaceController::BeginModify(FText TransactionText)
  122. {
  123. if (GEditor && GEditor->Trans)
  124. {
  125. UTransBuffer* TransBuffer = CastChecked<UTransBuffer>(GEditor->Trans);
  126. if (TransBuffer != nullptr)
  127. TransBuffer->Begin(*FString("AkGeometry Acoustic Surfaces"), TransactionText);
  128. }
  129. if (ComponentBeingCustomized != nullptr)
  130. ComponentBeingCustomized->Modify();
  131. }
  132. void SAkGeometrySurfaceController::EndModify()
  133. {
  134. if (GEditor && GEditor->Trans)
  135. {
  136. UTransBuffer* TransBuffer = CastChecked<UTransBuffer>(GEditor->Trans);
  137. if (TransBuffer != nullptr)
  138. TransBuffer->End();
  139. }
  140. }
  141. FString SAkGeometrySurfaceController::GetSelectedTextureAssetPath() const
  142. {
  143. FAkGeometrySurfaceOverride* SurfaceProperties = GetSurfaceOverride();
  144. if (SurfaceProperties == nullptr)
  145. return "";
  146. FSoftObjectPath Path(SurfaceProperties->AcousticTexture);
  147. return Path.GetAssetPathString();
  148. }
  149. void SAkGeometrySurfaceController::OnTextureAssetChanged(const FAssetData& InAssetData)
  150. {
  151. BeginModify(FText::FromString(FString("Set AkGeometry Texture")));
  152. FAkGeometrySurfaceOverride* SurfaceProperties = GetSurfaceOverride();
  153. if (SurfaceProperties != nullptr)
  154. {
  155. SurfaceProperties->AcousticTexture = Cast<UAkAcousticTexture>(InAssetData.GetAsset());
  156. }
  157. EndModify();
  158. }
  159. TOptional<float> SAkGeometrySurfaceController::GetTransmissionLossValue() const
  160. {
  161. if (GetSurfaceOverride() != nullptr)
  162. return GetSurfaceOverride()->OcclusionValue;
  163. return 0.0f;
  164. }
  165. void SAkGeometrySurfaceController::OnTransmissionLossChanged(float NewValue, ETextCommit::Type Commit)
  166. {
  167. // Only apply valid values
  168. if (NewValue >= 0.0f && NewValue <= 1.0f)
  169. {
  170. if (GetSurfaceOverride() != nullptr)
  171. {
  172. BeginModify(FText::FromString(FString("AkGeometry: Set Transmission Loss Value")));
  173. GetSurfaceOverride()->OcclusionValue = NewValue;
  174. EndModify();
  175. }
  176. }
  177. }
  178. EVisibility SAkGeometrySurfaceController::TransmissionLossVisibility() const
  179. {
  180. if (GetSurfaceOverride() == nullptr)
  181. return EVisibility::Visible;
  182. return GetSurfaceOverride()->bEnableOcclusionOverride ? EVisibility::Visible : EVisibility::Collapsed;
  183. }
  184. ECheckBoxState SAkGeometrySurfaceController::GetEnableTransmissionLossOverrideCheckBoxState() const
  185. {
  186. if (GetSurfaceOverride() == nullptr)
  187. return ECheckBoxState::Undetermined;
  188. bool bEnabled = GetSurfaceOverride()->bEnableOcclusionOverride;
  189. return bEnabled ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
  190. }
  191. void SAkGeometrySurfaceController::OnEnableTransmissionLossOverrideChanged(ECheckBoxState NewState)
  192. {
  193. if (GetSurfaceOverride() != nullptr)
  194. {
  195. bool bEnable = NewState == ECheckBoxState::Checked;
  196. FString ModifyString = bEnable ? "AkGeometry: Enable Transmission Loss Override"
  197. : "AkGeometry: Disable Transmission Loss Override";
  198. BeginModify(FText::FromString(ModifyString));
  199. GetSurfaceOverride()->bEnableOcclusionOverride = bEnable;
  200. EndModify();
  201. }
  202. }
  203. void SAkGeometrySurfaceController::BuildSlate()
  204. {
  205. FSlateFontInfo selectionInfoFont = LayoutBuilder.IsValid() ? LayoutBuilder.Pin()->GetDetailFontItalic() : FAkAppStyle::Get().GetFontStyle("TinyText");
  206. ChildSlot
  207. [
  208. SNew(SHorizontalBox)
  209. + SHorizontalBox::Slot() // Controls
  210. .AutoWidth()
  211. [
  212. SNew(SVerticalBox)
  213. + SVerticalBox::Slot() // Texture
  214. .FillHeight(0.33f)
  215. [
  216. SNew(SHorizontalBox)
  217. + SHorizontalBox::Slot() // Control
  218. .HAlign(HAlign_Left)
  219. .VAlign(VAlign_Center)
  220. .AutoWidth()
  221. [
  222. SNew(SOverlay)
  223. + SOverlay::Slot()
  224. [
  225. SNew(SObjectPropertyEntryBox)
  226. .AllowedClass(UAkAcousticTexture::StaticClass())
  227. .OnObjectChanged(this, &SAkGeometrySurfaceController::OnTextureAssetChanged)
  228. .ObjectPath(this, &SAkGeometrySurfaceController::GetSelectedTextureAssetPath)
  229. .ToolTipText(FText::FromString("The Audiokinetic Texture associated with the surface."))
  230. ]
  231. ]
  232. ]
  233. + SVerticalBox::Slot() // Enable Transmission Loss Override
  234. .FillHeight(0.33f)
  235. [
  236. SNew(SHorizontalBox)
  237. + SHorizontalBox::Slot() // Control
  238. .HAlign(HAlign_Left)
  239. .VAlign(VAlign_Center)
  240. .AutoWidth()
  241. [
  242. SNew(SCheckBox)
  243. .OnCheckStateChanged(this, &SAkGeometrySurfaceController::OnEnableTransmissionLossOverrideChanged)
  244. .IsChecked(this, &SAkGeometrySurfaceController::GetEnableTransmissionLossOverrideCheckBoxState)
  245. .ToolTipText(FText::FromString("Indicates whether the surface overrides the transmission loss value."))
  246. ]
  247. ]
  248. + SVerticalBox::Slot() // Transmission Loss
  249. .FillHeight(0.33f)
  250. [
  251. SNew(SBox)
  252. [
  253. SNew(SHorizontalBox)
  254. + SHorizontalBox::Slot() // Control
  255. .HAlign(HAlign_Left)
  256. .VAlign(VAlign_Center)
  257. .AutoWidth()
  258. [
  259. SNew(SOverlay)
  260. + SOverlay::Slot()
  261. [
  262. SNew(SBox)
  263. .Visibility_Lambda([this]() { return TransmissionLossVisibility(); })
  264. [
  265. SNew(SNumericEntryBox<float>)
  266. .MinValue(0.0f)
  267. .MaxValue(1.0f)
  268. .MinSliderValue(0.0f)
  269. .MaxSliderValue(1.0f)
  270. .ToolTipText(FText::FromString("Indicates how much sound is transmitted through the surface."))
  271. .Value(this, &SAkGeometrySurfaceController::GetTransmissionLossValue)
  272. .OnValueCommitted(this, &SAkGeometrySurfaceController::OnTransmissionLossChanged)
  273. ]
  274. ]
  275. ]
  276. ]
  277. ]
  278. ]
  279. + SHorizontalBox::Slot() // Labels
  280. .AutoWidth()
  281. [
  282. SNew(SSurfacePropertiesLabels, GetSurfaceOverride())
  283. ]
  284. ];
  285. }
  286. FAkGeometrySurfaceOverride* SAkGeometryCollisionMeshSurfaceController::GetSurfaceOverride() const
  287. {
  288. if (ComponentBeingCustomized == nullptr)
  289. return nullptr;
  290. return &(ComponentBeingCustomized->CollisionMeshSurfaceOverride);
  291. }
  292. void SAkGeometryStaticMeshSurfaceController::Construct(const FArguments& InArgs, TWeakObjectPtr<UObject> ObjectBeingCustomized, const TSharedPtr<IDetailLayoutBuilder>& InLayoutBuilder, UMaterialInterface* InMaterialKey)
  293. {
  294. MaterialKey = InMaterialKey;
  295. SAkGeometrySurfaceController::Construct(InArgs, ObjectBeingCustomized, InLayoutBuilder);
  296. }
  297. FAkGeometrySurfaceOverride* SAkGeometryStaticMeshSurfaceController::GetSurfaceOverride() const
  298. {
  299. if (ComponentBeingCustomized == nullptr)
  300. return nullptr;
  301. return ComponentBeingCustomized->StaticMeshSurfaceOverride.Find(MaterialKey);
  302. }