123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881 |
- /*******************************************************************************
- The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
- Technology released in source code form as part of the game integration package.
- The content of this file may not be used without valid licenses to the
- AUDIOKINETIC Wwise Technology.
- Note that the use of the game engine is subject to the Unreal(R) Engine End User
- License Agreement at https://www.unrealengine.com/en-US/eula/unreal
-
- License Usage
-
- Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
- this file in accordance with the end user license agreement provided with the
- software or, alternatively, in accordance with the terms contained
- in a written agreement between you and Audiokinetic Inc.
- Copyright (c) 2023 Audiokinetic Inc.
- *******************************************************************************/
- #include "SAcousticSurfacesController.h"
- #include "AkSurfaceReflectorSetComponent.h"
- #include "DetailCategoryBuilder.h"
- #include "DetailLayoutBuilder.h"
- #include "EditorModeManager.h"
- #include "EditorModes.h"
- #include "Engine/Selection.h"
- #include "Editor/TransBuffer.h"
- #include "EditorSupportDelegates.h"
- #include "PropertyCustomizationHelpers.h"
- #include "SlateCore/Public/Widgets/SBoxPanel.h"
- #include "Widgets/Input/SButton.h"
- #include "Widgets/Input/SCheckBox.h"
- #include "Widgets/Input/SNumericEntryBox.h"
- #include "Widgets/Input/SSlider.h"
- #include "Widgets/Layout/SBox.h"
- #include "Widgets/SOverlay.h"
- #include "Widgets/Text/STextBlock.h"
- #if AK_SUPPORT_WAAPI
- #include "AkWaapiClient.h"
- #include "AkWaapiUtils.h"
- #include "Async/Async.h"
- #endif
- #define LOCTEXT_NAMESPACE "AkAudio"
- namespace AkAcousticSurfacesUI
- {
- static FText OverrideButtonText = FText::FromString(FString("Override"));
- static int OverrideButtonPadding = 5;
- static int LabelWidth = 102;
- }
- class SOverrideControls : public SCompoundWidget
- {
- public:
- SLATE_BEGIN_ARGS(SOverrideControls) {}
- /** Called when the button is clicked */
- SLATE_EVENT(FOnClicked, OnButtonClicked)
- SLATE_END_ARGS()
- void Construct(const FArguments& InArgs)
- {
- OnButtonClicked = InArgs._OnButtonClicked;
- ChildSlot
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Label
- .AutoWidth()
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(FText::FromString(FString(TEXT("Multiple Values"))))
- ]
- + SHorizontalBox::Slot() // Button
- .AutoWidth()
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .Padding(AkAcousticSurfacesUI::OverrideButtonPadding, 0)
- [
- SNew(SButton)
- .Text(AkAcousticSurfacesUI::OverrideButtonText)
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .OnClicked(this, &SOverrideControls::CallClicked)
- ]
- ];
- }
- private:
- FOnClicked OnButtonClicked;
- FReply CallClicked() { return OnButtonClicked.Execute(); }
- };
- // ==================================================
- // SAcousticSurfacesLabels
- // ==================================================
- void SAcousticSurfacesLabels::Construct(const FArguments& InArgs, TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized)
- {
- ComponentsBeingCustomized = ObjectsBeingCustomized;
- ChildSlot
- [
- SNew(SVerticalBox)
- + SVerticalBox::Slot() // Acoustic Surface Parameters
- .FillHeight(1.0f)
- [
- SNew(SVerticalBox)
- + SVerticalBox::Slot() // Texture
- .FillHeight(0.33f)
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Label
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SBox)
- .WidthOverride(AkAcousticSurfacesUI::LabelWidth)
- [
- SNew(STextBlock)
- .ToolTipText(FText::FromString("The Audiokinetic Texture associated with the selected faces."))
- .Text(FText::FromString(FString(TEXT("AkAcousticTexture"))))
- .Font(IDetailLayoutBuilder::GetDetailFont())
- ]
- ]
- ]
- + SVerticalBox::Slot() // Occlusion
- .FillHeight(0.33f)
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return TransmissionLossEnableSurfaceVisibility(); })
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Label
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SBox)
- .WidthOverride(AkAcousticSurfacesUI::LabelWidth)
- [
- SNew(STextBlock)
- .ToolTipText(FText::FromString("Indicates how much sound is transmitted through the surface."))
- .Text(FText::FromString(FString(TEXT("Transmission Loss"))))
- .Font(IDetailLayoutBuilder::GetDetailFont())
- ]
- ]
- ]
- ]
- + SVerticalBox::Slot() // EnableSurface
- .FillHeight(0.33f)
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Label
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SBox)
- .WidthOverride(AkAcousticSurfacesUI::LabelWidth)
- [
- SNew(STextBlock)
- .ToolTipText(FText::FromString("Indicates whether the selected faces are sent to the Spatial Audio engine."))
- .Text(FText::FromString(FString(TEXT("Enable Surface"))))
- .Font(IDetailLayoutBuilder::GetDetailFont())
- ]
- ]
- ]
- ]
- ];
- }
- EVisibility SAcousticSurfacesLabels::TransmissionLossEnableSurfaceVisibility()
- {
- for (TWeakObjectPtr<UObject> ObjectBeingCustomized : ComponentsBeingCustomized)
- {
- UAkSurfaceReflectorSetComponent* reflectorSetComponent = Cast<UAkSurfaceReflectorSetComponent>(ObjectBeingCustomized.Get());
- if (reflectorSetComponent && reflectorSetComponent->bEnableSurfaceReflectors)
- {
- return EVisibility::Visible;
- }
- }
- return EVisibility::Collapsed;
- }
- // ==================================================
- // SAcousticSurfacesController
- // ==================================================
- void SAcousticSurfacesController::Construct(const FArguments& InArgs, TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized, const TSharedPtr<IDetailLayoutBuilder>& InLayoutBuilder)
- {
- ensure(ObjectsBeingCustomized.Num() > 0);
- LayoutBuilder = InLayoutBuilder;
- FCoreUObjectDelegates::FOnObjectPropertyChanged::FDelegate OnPropertyChangedDelegate = FCoreUObjectDelegates::FOnObjectPropertyChanged::FDelegate::CreateRaw(this, &SAcousticSurfacesController::OnPropertyChanged);
- OnPropertyChangedHandle = FCoreUObjectDelegates::OnObjectPropertyChanged.Add(OnPropertyChangedDelegate);
- GLevelEditorModeTools().OnEditorModeIDChanged().AddRaw(this, &SAcousticSurfacesController::OnEditorModeChanged);
- ComponentsToEdit = ObjectsBeingCustomized;
- if (GLevelEditorModeTools().IsModeActive(FEditorModeID(TEXT("EM_Geometry"))))
- {
- // In geometry edit mode, we only want to apply to all faces when no individual faces are selected.
- bool individualSelection = false;
- // Loop through all selected components to check if any indivdual faces are selected.
- // If no individual faces are selected, we'll just apply the changes to every face on each component.
- for (TWeakObjectPtr<UObject> ObjectBeingCustomized : ComponentsToEdit)
- {
- UAkSurfaceReflectorSetComponent* reflectorSetComponent = Cast<UAkSurfaceReflectorSetComponent>(ObjectBeingCustomized.Get());
- if (reflectorSetComponent)
- {
- TSet<int> FacesToEdit = reflectorSetComponent->GetSelectedFaceIndices();
- if (FacesToEdit.Num() > 0)
- {
- individualSelection = true;
- break;
- }
- }
- }
- ApplyToAllFaces = !individualSelection;
- }
- else
- {
- ApplyToAllFaces = true;
- }
- InitReflectorSetsFacesToEdit();
- UpdateCurrentValues();
- #if AK_SUPPORT_WAAPI
- RegisterTextureDeletedCallback();
- #endif
- BuildSlate();
- }
- SAcousticSurfacesController::~SAcousticSurfacesController()
- {
- #if AK_SUPPORT_WAAPI
- RemoveTextureDeletedCallback();
- #endif
- FCoreUObjectDelegates::OnObjectPropertyChanged.Remove(OnPropertyChangedHandle);
- GLevelEditorModeTools().OnEditorModeIDChanged().RemoveAll(this);
- }
- void SAcousticSurfacesController::InitReflectorSetsFacesToEdit()
- {
- NumFacesSelected = 0;
- for (TWeakObjectPtr<UObject> ObjectBeingCustomized : ComponentsToEdit)
- {
- UAkSurfaceReflectorSetComponent* reflectorSetComponent = Cast<UAkSurfaceReflectorSetComponent>(ObjectBeingCustomized.Get());
- if (reflectorSetComponent)
- {
- TSet<int> FacesToEdit;
- if (ApplyToAllFaces)
- {
- for (int i = 0; i < reflectorSetComponent->AcousticPolys.Num(); ++i)
- FacesToEdit.Add(i);
- }
- else
- {
- FacesToEdit = reflectorSetComponent->GetSelectedFaceIndices();
- }
- NumFacesSelected += FacesToEdit.Num();
- if (FacesToEdit.Num() > 0)
- ReflectorSetsFacesToEdit.Add(reflectorSetComponent, FacesToEdit);
- }
- }
- UpdateCurrentValues();
- }
- FAkSurfacePoly& SAcousticSurfacesController::GetAcousticSurfaceChecked(UAkSurfaceReflectorSetComponent* reflectorSet, int faceIndex)
- {
- ensure(faceIndex <= reflectorSet->AcousticPolys.Num());
- return reflectorSet->AcousticPolys[faceIndex];
- }
- void SAcousticSurfacesController::RefreshEditor(bool reinitVisualizers /*= false*/) const
- {
- if (!LayoutBuilder.IsValid())
- {
- return;
- }
- FEditorSupportDelegates::RedrawAllViewports.Broadcast();
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- if (reinitVisualizers)
- {
- ReflectorSetComponent->CacheAcousticProperties();
- ReflectorSetComponent->UpdatePolys();
- }
- else
- {
- ReflectorSetComponent->SurfacePropertiesChanged();
- }
- }
- }
- IDetailLayoutBuilder* Layout = nullptr;
- if (auto LockedLayoutBuilder = LayoutBuilder.Pin())
- {
- Layout = LockedLayoutBuilder.Get();
- }
- if (LIKELY(Layout))
- {
- Layout->ForceRefreshDetails();
- }
- }
- void SAcousticSurfacesController::BeginModify(FText TransactionText)
- {
- if (GEditor && GEditor->Trans)
- {
- UTransBuffer* TransBuffer = CastChecked<UTransBuffer>(GEditor->Trans);
- if (TransBuffer != nullptr)
- TransBuffer->Begin(*FString("AkSurfaceReflectorSet Acoustic Surfaces"), TransactionText);
- }
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- ReflectorSetComponent->Modify();
- }
- }
- void SAcousticSurfacesController::EndModify()
- {
- if (GEditor && GEditor->Trans)
- {
- UTransBuffer* TransBuffer = CastChecked<UTransBuffer>(GEditor->Trans);
- if (TransBuffer != nullptr)
- TransBuffer->End();
- }
- }
- void SAcousticSurfacesController::OnPropertyChanged(UObject* ObjectBeingModified, FPropertyChangedEvent& PropertyChangedEvent)
- {
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ObjectBeingModified == ReflectorSetComponent)
- {
- const FName memberPropertyName = (PropertyChangedEvent.MemberProperty != nullptr) ? PropertyChangedEvent.MemberProperty->GetFName() : NAME_None;
- if (memberPropertyName == GET_MEMBER_NAME_CHECKED(UAkSurfaceReflectorSetComponent, AcousticPolys))
- {
- UpdateCurrentValues();
- }
- return;
- }
- }
- }
- void SAcousticSurfacesController::OnEditorModeChanged(const FEditorModeID& InEditorModeID, bool bIsEnteringMode)
- {
- if (InEditorModeID == FEditorModeID(TEXT("EM_Geometry")))
- {
- if (bIsEnteringMode)
- {
- ApplyToAllFaces = false;
- InitReflectorSetsFacesToEdit();
- Invalidate(EInvalidateWidgetReason::Paint);
- }
- else
- {
- ApplyToAllFaces = true;
- InitReflectorSetsFacesToEdit();
- Invalidate(EInvalidateWidgetReason::Paint);
- }
- }
- }
- FText SAcousticSurfacesController::GetSelectionText() const
- {
- FString selectionInfo = "(All faces)";
- if (!ApplyToAllFaces && NumFacesSelected > 0)
- {
- selectionInfo = "(" + FString::FromInt(NumFacesSelected) + " faces selected)";
- }
- return FText::FromString(selectionInfo);
- }
- FText SAcousticSurfacesController::GetSelectionTextTooltip() const
- {
- if (!ApplyToAllFaces && NumFacesSelected > 0)
- {
- return FText::FromString(FString("Changes will apply to all selected faces."));
- }
- return FText::FromString(FString("Changes will apply to all faces. Use ") + GEOMETRY_EDIT_DISPLAY_NAME + " to select individual faces. You can enable " GEOMETRY_EDIT_DISPLAY_NAME " by clicking 'Enable Edit Surfaces'.");
- }
- void SAcousticSurfacesController::UpdateCurrentValues()
- {
- CurrentTexture = GetCollectiveTexture(TexturesDiffer);
- CurrentOcclusion = GetCollectiveOcclusion(OcclusionsDiffer);
- CurrentEnablement = GetCollectiveEnableSurface(EnablementsDiffer);
- }
- void SAcousticSurfacesController::OnTextureAssetChanged(const FAssetData& InAssetData)
- {
- BeginModify(FText::FromString(FString("Set Textures")));
- CurrentTexture = Cast<UAkAcousticTexture>(InAssetData.GetAsset());
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = elem.Value;
- for (const int& i : FacesToEdit)
- {
- GetAcousticSurfaceChecked(ReflectorSetComponent, i).Texture = CurrentTexture;
- }
- }
- }
- RefreshEditor();
- EndModify();
- }
- FString SAcousticSurfacesController::GetSelectedTextureAssetPath() const
- {
- if (CurrentTexture == nullptr)
- {
- return "";
- }
-
- FSoftObjectPath path(CurrentTexture);
- return path.GetAssetPathString();
- }
- EVisibility SAcousticSurfacesController::TransmissionLossEnableSurfaceVisibility()
- {
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr && ReflectorSetComponent->bEnableSurfaceReflectors)
- return EVisibility::Visible;
- }
- return EVisibility::Collapsed;
- }
- EVisibility SAcousticSurfacesController::OverrideTextureControlsVisibility()
- {
- if (TexturesDiffer)
- return EVisibility::Visible;
- return EVisibility::Collapsed;
- }
- FReply SAcousticSurfacesController::OnOverrideTextureButtonClicked()
- {
- BeginModify(FText::FromString(FString("Override Textures")));
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = elem.Value;
- for (const int& i : FacesToEdit)
- {
- GetAcousticSurfaceChecked(ReflectorSetComponent, i).Texture = nullptr;
- }
- }
- }
- RefreshEditor();
- EndModify();
- return FReply::Handled();
- }
- UAkAcousticTexture* SAcousticSurfacesController::GetCollectiveTexture(bool& ValuesDiffer)
- {
- ValuesDiffer = false;
- if (ReflectorSetsFacesToEdit.Num() == 0)
- return nullptr;
- auto it = ReflectorSetsFacesToEdit.CreateIterator();
- ensure(it.Key() != nullptr);
- int firstIndex = *(it.Value().begin());
- UAkAcousticTexture* texture = it.Key()->AcousticPolys[firstIndex].Texture;
- for (; it; ++it)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = it.Key();
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = it.Value();
- for (const int& i : FacesToEdit)
- {
- if (GetAcousticSurfaceChecked(ReflectorSetComponent, i).Texture != texture)
- {
- ValuesDiffer = true;
- texture = nullptr;
- break;
- }
- }
- }
- }
- return texture;
- }
- EVisibility SAcousticSurfacesController::OverrideOcclusionControlsVisibility()
- {
- return OcclusionsDiffer ? EVisibility::Visible : EVisibility::Collapsed;
- }
- FReply SAcousticSurfacesController::OnOverrideOcclusionButtonClicked()
- {
- BeginModify(FText::FromString(FString("Override Transmission Loss Values")));
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = elem.Value;
- for (const int& i : FacesToEdit)
- {
- GetAcousticSurfaceChecked(ReflectorSetComponent, i).Occlusion = 0.0f;
- }
- }
- }
- RefreshEditor();
- EndModify();
- return FReply::Handled();
- }
- float SAcousticSurfacesController::GetCollectiveOcclusion(bool& ValuesDiffer)
- {
- ValuesDiffer = false;
- if (ReflectorSetsFacesToEdit.Num() == 0)
- return 0.0f;
- auto it = ReflectorSetsFacesToEdit.CreateIterator();
- ensure(it.Key() != nullptr);
- int firstIndex = *(it.Value().begin());
- float occlusion = it.Key()->AcousticPolys[firstIndex].Occlusion;
- for (; it; ++it)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = it.Key();
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = it.Value();
- for (const int& i : FacesToEdit)
- {
- if (GetAcousticSurfaceChecked(ReflectorSetComponent, i).Occlusion != occlusion)
- {
- ValuesDiffer = true;
- occlusion = 0.0f;
- break;
- }
- }
- }
- }
- return occlusion;
- }
- TOptional<float> SAcousticSurfacesController::GetOcclusionSliderValue() const
- {
- return CurrentOcclusion;
- }
- void SAcousticSurfacesController::OnOcclusionSliderChanged(float NewValue, ETextCommit::Type Commit)
- {
- // TODO: Remove this when fixed.
- // There is a bug in UE5.1 when modifying numerical properties and pressing Enter.
- // This is the case for the occlusion(transmission loss) value of acoustic surfaces.
- // This function is getting called a second time with a wrong occlusion value.
- // When that happens, LayoutBuilder is invalid, so we check it to make sure the value is valid as well.
- if (!LayoutBuilder.IsValid())
- {
- return;
- }
- // Only apply valid values
- if (NewValue >= 0.0f && NewValue <= 1.0f)
- {
- BeginModify(FText::FromString(FString("Set Transmission Loss Values")));
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = elem.Value;
- for (const int& i : FacesToEdit)
- {
- GetAcousticSurfaceChecked(ReflectorSetComponent, i).Occlusion = NewValue;
- }
- }
- }
- RefreshEditor();
- EndModify();
- }
- }
- bool SAcousticSurfacesController::GetCollectiveEnableSurface(bool& ValuesDiffer)
- {
- ValuesDiffer = false;
- if (ReflectorSetsFacesToEdit.Num() == 0)
- return false;
- auto it = ReflectorSetsFacesToEdit.CreateIterator();
- ensure(it.Key() != nullptr);
- int firstIndex = *(it.Value().begin());
- bool enableSurface = it.Key()->AcousticPolys[firstIndex].EnableSurface;
- for (; it; ++it)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = it.Key();
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = it.Value();
- for (const int& i : FacesToEdit)
- {
- if (GetAcousticSurfaceChecked(ReflectorSetComponent, i).EnableSurface != enableSurface)
- {
- ValuesDiffer = true;
- enableSurface = false;
- break;
- }
- }
- }
- }
- return enableSurface;
- }
- ECheckBoxState SAcousticSurfacesController::GetEnableSurfaceCheckBoxState() const
- {
- return EnablementsDiffer ? ECheckBoxState::Undetermined
- : (CurrentEnablement ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
- }
- void SAcousticSurfacesController::OnEnableCheckboxChanged(ECheckBoxState NewState)
- {
- BeginModify(FText::FromString(FString("Set Enable Surfaces")));
- for (auto elem : ReflectorSetsFacesToEdit)
- {
- UAkSurfaceReflectorSetComponent* ReflectorSetComponent = elem.Key;
- if (ReflectorSetComponent != nullptr)
- {
- TSet<int> FacesToEdit = elem.Value;
- if (NewState != ECheckBoxState::Undetermined)
- {
- bool enable = NewState == ECheckBoxState::Checked;
- for (const int& i : FacesToEdit)
- {
- GetAcousticSurfaceChecked(ReflectorSetComponent, i).EnableSurface = enable;
- }
- }
- }
- }
- RefreshEditor(true);
- EndModify();
- }
- #if AK_SUPPORT_WAAPI
- void SAcousticSurfacesController::RegisterTextureDeletedCallback()
- {
- FAkWaapiClient* waapiClient = FAkWaapiClient::Get();
- if (waapiClient != nullptr && waapiClient->IsConnected())
- {
- auto textureDeletedCallback = WampEventCallback::CreateLambda([this](uint64_t id, TSharedPtr<FJsonObject> jsonObject)
- {
- const TSharedPtr<FJsonObject> itemObj = jsonObject->GetObjectField(WwiseWaapiHelper::OBJECT);
- if (itemObj != nullptr)
- {
- const FString itemIdString = itemObj->GetStringField(WwiseWaapiHelper::ID);
- FGuid itemID = FGuid::NewGuid();
- FGuid::ParseExact(itemIdString, EGuidFormats::DigitsWithHyphensInBraces, itemID);
- if (CurrentTexture != nullptr && itemID == CurrentTexture->AcousticTextureInfo.WwiseGuid)
- {
- AsyncTask(ENamedThreads::GameThread, [this, itemID]
- {
- CurrentTexture = nullptr;
- });
- }
- }
- });
- TSharedRef<FJsonObject> options = MakeShareable(new FJsonObject());
- options->SetArrayField(WwiseWaapiHelper::RETURN, TArray<TSharedPtr<FJsonValue>> { MakeShareable(new FJsonValueString(WwiseWaapiHelper::ID)) });
- TSharedPtr<FJsonObject> outJsonResult;
- if (!waapiClient->Subscribe(ak::wwise::core::object::preDeleted, options, textureDeletedCallback, TextureDeleteSubscriptionID, outJsonResult))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("AkSettings: WAAPI: Acoustic texture object preDeleted subscription failed."));
- }
- }
- }
- void SAcousticSurfacesController::RemoveTextureDeletedCallback()
- {
- FAkWaapiClient* waapiClient = FAkWaapiClient::Get();
- if (waapiClient != nullptr && waapiClient->IsConnected() && TextureDeleteSubscriptionID != 0)
- {
- TSharedPtr<FJsonObject> unsubscribeResult;
- waapiClient->Unsubscribe(TextureDeleteSubscriptionID, unsubscribeResult);
- }
- }
- #endif
- void SAcousticSurfacesController::BuildSlate()
- {
- FSlateFontInfo SelectionInfoFont = FAkAppStyle::Get().GetFontStyle("TinyText");
- if (LayoutBuilder.IsValid())
- {
- if (auto LockedDetailBuilder = LayoutBuilder.Pin())
- {
- SelectionInfoFont = LockedDetailBuilder->GetDetailFontItalic();
- }
- }
- ChildSlot
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Acoustic Surface Parameters
- .AutoWidth()
- [
- SNew(SVerticalBox)
- + SVerticalBox::Slot() // Texture
- .FillHeight(0.33f)
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Control
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SOverlay)
- + SOverlay::Slot()
- [
- SNew(SObjectPropertyEntryBox)
- .AllowedClass(UAkAcousticTexture::StaticClass())
- .OnObjectChanged(this, &SAcousticSurfacesController::OnTextureAssetChanged)
- .ObjectPath(this, &SAcousticSurfacesController::GetSelectedTextureAssetPath)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- .Visibility_Lambda([this]() { return (OverrideTextureControlsVisibility() == EVisibility::Collapsed) ? EVisibility::Visible : EVisibility::Collapsed; })
- ]
- + SOverlay::Slot() // Multiple values controls
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return OverrideTextureControlsVisibility(); })
- [
- SNew(SOverrideControls)
- .OnButtonClicked(this, &SAcousticSurfacesController::OnOverrideTextureButtonClicked)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- ]
- ]
- ]
- ]
- + SVerticalBox::Slot() // Occlusion
- .FillHeight(0.33f)
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return TransmissionLossEnableSurfaceVisibility(); })
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Control
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SOverlay)
- + SOverlay::Slot()
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return (OverrideOcclusionControlsVisibility() == EVisibility::Collapsed) ? EVisibility::Visible : EVisibility::Collapsed; })
- [
- SNew(SNumericEntryBox<float>)
- .MinValue(0.0f)
- .MaxValue(1.0f)
- .MinSliderValue(0.0f)
- .MaxSliderValue(1.0f)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- .Value(this, &SAcousticSurfacesController::GetOcclusionSliderValue)
- .OnValueCommitted(this, &SAcousticSurfacesController::OnOcclusionSliderChanged)
- ]
- ]
- + SOverlay::Slot() // Multiple values controls
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return OverrideOcclusionControlsVisibility(); })
- [
- SNew(SOverrideControls)
- .OnButtonClicked(this, &SAcousticSurfacesController::OnOverrideOcclusionButtonClicked)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- ]
- ]
- ]
- ]
- ]
- + SVerticalBox::Slot() // EnableSurface
- .FillHeight(0.33f)
- [
- SNew(SHorizontalBox)
- + SHorizontalBox::Slot() // Control
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- .AutoWidth()
- [
- SNew(SCheckBox)
- .IsChecked(ECheckBoxState::Undetermined)
- .OnCheckStateChanged(this, &SAcousticSurfacesController::OnEnableCheckboxChanged)
- .IsChecked(this, &SAcousticSurfacesController::GetEnableSurfaceCheckBoxState)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- ]
- ]
- ]
- + SHorizontalBox::Slot() // Selection Info
- .AutoWidth()
- [
- SNew(SVerticalBox)
- + SVerticalBox::Slot() // Texture
- .FillHeight(0.33f)
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(this, &SAcousticSurfacesController::GetSelectionText)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- .Font(SelectionInfoFont)
- ]
- + SVerticalBox::Slot() // Occlusion
- .FillHeight(0.33f)
- [
- SNew(SBox)
- .Visibility_Lambda([this]() { return TransmissionLossEnableSurfaceVisibility(); })
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(this, &SAcousticSurfacesController::GetSelectionText)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- .Font(SelectionInfoFont)
- ]
- ]
- + SVerticalBox::Slot() // EnableSurface
- .FillHeight(0.33f)
- .HAlign(HAlign_Left)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(this, &SAcousticSurfacesController::GetSelectionText)
- .ToolTipText(this, &SAcousticSurfacesController::GetSelectionTextTooltip)
- .Font(SelectionInfoFont)
- ]
- ]
- ];
- }
- #undef LOCTEXT_NAMESPACE
|