253 lines
8.1 KiB
C++
253 lines
8.1 KiB
C++
/*******************************************************************************
|
|
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 "AkAcousticTextureSetComponent.h"
|
|
#include "AkAudioDevice.h"
|
|
#include "AkRoomComponent.h"
|
|
#include "AkReverbDescriptor.h"
|
|
#include "AkComponentHelpers.h"
|
|
#include "AkLateReverbComponent.h"
|
|
#include "AkSpatialAudioHelper.h"
|
|
|
|
UAkAcousticTextureSetComponent::UAkAcousticTextureSetComponent(const class FObjectInitializer& ObjectInitializer) :
|
|
Super(ObjectInitializer)
|
|
{
|
|
PrimaryComponentTick.bCanEverTick = true;
|
|
bTickInEditor = true;
|
|
#if WITH_EDITOR
|
|
if (AkSpatialAudioHelper::GetObjectReplacedEvent())
|
|
{
|
|
AkSpatialAudioHelper::GetObjectReplacedEvent()->AddUObject(this, &UAkAcousticTextureSetComponent::HandleObjectsReplaced);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::OnRegister()
|
|
{
|
|
Super::OnRegister();
|
|
#if WITH_EDITOR
|
|
RegisterAllTextureParamCallbacks();
|
|
RegisterReverbRTPCChangedCallback();
|
|
#endif
|
|
// In the case where a blueprint class has a texture set component and a late reverb component as siblings, We can't know which will be registered first.
|
|
// We need to check for the sibling in each OnRegister function and associate the texture set component to the late reverb when they are both registered.
|
|
if (USceneComponent* parent = GetAttachParent())
|
|
{
|
|
if (UAkLateReverbComponent* reverbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*parent))
|
|
{
|
|
reverbComp->AssociateAkTextureSetComponent(this);
|
|
}
|
|
}
|
|
DampingEstimationNeedsUpdate = true;
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::OnUnregister()
|
|
{
|
|
#if WITH_EDITOR
|
|
UnregisterTextureParamChangeCallbacks();
|
|
UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
|
|
if (AkSettings != nullptr)
|
|
{
|
|
if (RTPCChangedHandle.IsValid())
|
|
AkSettings->OnReverbRTPCChanged.Remove(RTPCChangedHandle);
|
|
}
|
|
#endif
|
|
Super::OnUnregister();
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
DampingEstimationNeedsUpdate = true;
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
{
|
|
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
|
|
if (SecondsSinceDampingUpdate < PARAM_ESTIMATION_UPDATE_PERIOD)
|
|
{
|
|
SecondsSinceDampingUpdate += DeltaTime;
|
|
}
|
|
if (DampingEstimationNeedsUpdate && SecondsSinceDampingUpdate >= PARAM_ESTIMATION_UPDATE_PERIOD)
|
|
{
|
|
RecalculateHFDamping();
|
|
DampingEstimationNeedsUpdate = false;
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::SetReverbDescriptor(FAkReverbDescriptor* reverbDescriptor)
|
|
{
|
|
ReverbDescriptor = reverbDescriptor;
|
|
#if WITH_EDITOR
|
|
UnregisterTextureParamChangeCallbacks();
|
|
if (reverbDescriptor != nullptr)
|
|
RegisterAllTextureParamCallbacks();
|
|
#endif
|
|
if (reverbDescriptor != nullptr)
|
|
DampingEstimationNeedsUpdate = true;
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::RecalculateHFDamping()
|
|
{
|
|
if (ReverbDescriptor != nullptr && ReverbDescriptor->ShouldEstimateDamping())
|
|
{
|
|
ReverbDescriptor->CalculateHFDamping(this);
|
|
SecondsSinceDampingUpdate = 0.0f;
|
|
}
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void UAkAcousticTextureSetComponent::BeginDestroy()
|
|
{
|
|
Super::BeginDestroy();
|
|
if (AkSpatialAudioHelper::GetObjectReplacedEvent())
|
|
{
|
|
AkSpatialAudioHelper::GetObjectReplacedEvent()->RemoveAll(this);
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap)
|
|
{
|
|
if (ReplacementMap.Contains(this))
|
|
{
|
|
UAkAcousticTextureSetComponent* NewTextureSetComponent = Cast<UAkAcousticTextureSetComponent>(ReplacementMap[this]);
|
|
if (USceneComponent* Parent = NewTextureSetComponent->GetAttachParent())
|
|
{
|
|
if (UAkLateReverbComponent* ReverbComp = AkComponentHelpers::GetChildComponentOfType<UAkLateReverbComponent>(*Parent))
|
|
{
|
|
ReverbComp->AssociateAkTextureSetComponent(NewTextureSetComponent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::RegisterReverbRTPCChangedCallback()
|
|
{
|
|
UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
|
|
if (AkSettings != nullptr)
|
|
{
|
|
if (RTPCChangedHandle.IsValid())
|
|
AkSettings->OnReverbRTPCChanged.Remove(RTPCChangedHandle);
|
|
RTPCChangedHandle = AkSettings->OnReverbRTPCChanged.AddLambda([this]()
|
|
{
|
|
DampingEstimationNeedsUpdate = true;
|
|
});
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::RegisterTextureParamChangeCallback(FGuid textureID)
|
|
{
|
|
UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
|
|
if (AkSettings != nullptr)
|
|
{
|
|
if (TextureDelegateHandles.Find(textureID) != nullptr)
|
|
{
|
|
if (TextureDelegateHandles[textureID].IsValid())
|
|
{
|
|
AkSettings->OnTextureParamsChanged.Remove(TextureDelegateHandles[textureID]);
|
|
}
|
|
TextureDelegateHandles.Remove(textureID);
|
|
}
|
|
TextureDelegateHandles.Add(textureID, AkSettings->OnTextureParamsChanged.AddLambda([&](const FGuid& textureID)
|
|
{
|
|
if (ContainsTexture(textureID) && ReverbDescriptor != nullptr)
|
|
DampingEstimationNeedsUpdate = ReverbDescriptor->ShouldEstimateDamping();
|
|
}));
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::UnregisterTextureParamChangeCallbacks()
|
|
{
|
|
UAkSettings* AkSettings = GetMutableDefault<UAkSettings>();
|
|
if (AkSettings != nullptr)
|
|
{
|
|
for (auto it = TextureDelegateHandles.CreateIterator(); it; ++it)
|
|
{
|
|
if (it->Value.IsValid())
|
|
AkSettings->OnTextureParamsChanged.Remove(it->Value);
|
|
}
|
|
TextureDelegateHandles.Empty();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bool UAkAcousticTextureSetComponent::ShouldSendGeometry() const
|
|
{
|
|
UWorld* CurrentWorld = GetWorld();
|
|
if (CurrentWorld && !IsRunningCommandlet())
|
|
{
|
|
return CurrentWorld->WorldType == EWorldType::Game || CurrentWorld->WorldType == EWorldType::PIE;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::SendGeometryToWwise(const AkGeometryParams& params)
|
|
{
|
|
if (ShouldSendGeometry())
|
|
{
|
|
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
|
|
if (AkAudioDevice != nullptr && AkAudioDevice->SetGeometry(GetGeometrySetID(), params) == AK_Success)
|
|
GeometryHasBeenSent = true;
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::SendGeometryInstanceToWwise(const FRotator& rotation, const FVector& location, const FVector& scale, const AkRoomID roomID)
|
|
{
|
|
if (ShouldSendGeometry() && GeometryHasBeenSent)
|
|
{
|
|
AkVector front, up;
|
|
AkVector64 position;
|
|
FAkAudioDevice::FVectorToAKVector(rotation.RotateVector(FVector::ForwardVector), front);
|
|
FAkAudioDevice::FVectorToAKVector(rotation.RotateVector(FVector::UpVector), up);
|
|
FAkAudioDevice::FVectorToAKVector64(location, position);
|
|
|
|
AkGeometryInstanceParams params;
|
|
params.PositionAndOrientation.Set(position, front, up);
|
|
FAkAudioDevice::FVectorToAKVector(scale, params.Scale);
|
|
params.GeometrySetID = GetGeometrySetID();
|
|
params.RoomID = roomID;
|
|
|
|
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
|
|
if (AkAudioDevice != nullptr && AkAudioDevice->SetGeometryInstance(GetGeometrySetID(), params) == AK_Success)
|
|
GeometryInstanceHasBeenSent = true;
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::RemoveGeometryFromWwise()
|
|
{
|
|
if (ShouldSendGeometry() && GeometryHasBeenSent)
|
|
{
|
|
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
|
|
if (AkAudioDevice != nullptr && AkAudioDevice->RemoveGeometrySet(GetGeometrySetID()) == AK_Success)
|
|
{
|
|
GeometryHasBeenSent = false;
|
|
GeometryInstanceHasBeenSent = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAkAcousticTextureSetComponent::RemoveGeometryInstanceFromWwise()
|
|
{
|
|
if (ShouldSendGeometry() && GeometryInstanceHasBeenSent)
|
|
{
|
|
FAkAudioDevice* AkAudioDevice = FAkAudioDevice::Get();
|
|
if (AkAudioDevice != nullptr && AkAudioDevice->RemoveGeometrySet(GetGeometrySetID()) == AK_Success)
|
|
GeometryInstanceHasBeenSent = false;
|
|
}
|
|
}
|