Files
Illusion-UE5/hwanyoung2/Plugins/FMODStudio/Source/FMODStudio/Public/FMODUtils.h
2025-04-09 02:35:22 +09:00

202 lines
6.0 KiB
C++

// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2025.
#pragma once
#include "fmod_studio.hpp"
#include "fmod.hpp"
#include "Runtime/Launch/Resources/Version.h"
#include "Engine/Engine.h"
#include "FMODStudioModule.h"
#define verifyfmod(fn) \
{ \
FMOD_RESULT _result = (fn); \
if (_result != FMOD_OK) \
{ \
FMODUtils::LogError(_result, #fn); \
} \
}
namespace FMODUtils
{
// Unreal defines 1 unit == 1cm, so convert to metres for Studio automatically
#define FMOD_VECTOR_SCALE_DEFAULT 0.01f
// Just call into module
inline void LogError(FMOD_RESULT result, const char *function)
{
IFMODStudioModule::Get().LogError(result, function);
}
inline void Assign(FMOD_VECTOR &Dest, const FVector &Src)
{
Dest.x = Src.X;
Dest.y = Src.Y;
Dest.z = Src.Z;
}
inline FMOD_VECTOR ConvertWorldVector(const FVector &Src)
{
static FMatrix UE4toFMOD(FVector(0.0f, 0.0f, FMOD_VECTOR_SCALE_DEFAULT), FVector(FMOD_VECTOR_SCALE_DEFAULT, 0.0f, 0.0f),
FVector(0.0f, FMOD_VECTOR_SCALE_DEFAULT, 0.0f), FVector::ZeroVector);
FMOD_VECTOR Dest;
Assign(Dest, UE4toFMOD.TransformPosition(Src));
return Dest;
}
inline FMOD_VECTOR ConvertUnitVector(const FVector &Src)
{
static FMatrix UE4toFMOD(FVector(0.0f, 0.0f, 1.0f), FVector(1.0f, 0.0f, 0.0f), FVector(0.0f, 1.0f, 0.0f), FVector::ZeroVector);
FMOD_VECTOR Dest;
Assign(Dest, UE4toFMOD.TransformVector(Src));
return Dest;
}
inline void Assign(FMOD_3D_ATTRIBUTES &Dest, const FTransform &Src)
{
Dest.position = ConvertWorldVector(Src.GetTranslation());
Dest.forward = ConvertUnitVector(Src.GetUnitAxis(EAxis::X));
Dest.up = ConvertUnitVector(Src.GetUnitAxis(EAxis::Z));
}
inline float DistanceToUEScale(float FMODDistance)
{
return FMODDistance / FMOD_VECTOR_SCALE_DEFAULT;
}
inline bool IsWorldAudible(UWorld *World, bool AllowInEditor)
{
if (GEngine && IFMODStudioModule::Get().UseSound())
{
if (!IsValid(World))
{
return true;
}
if (World->bAllowAudioPlayback && World->GetNetMode() != NM_DedicatedServer)
{
EWorldType::Type previewEnum;
previewEnum = EWorldType::EditorPreview;
if (World->IsGameWorld() || World->WorldType == previewEnum || (AllowInEditor && World->WorldType == EWorldType::Editor))
{
return true;
}
}
}
return false;
}
inline FMOD::Studio::ID ConvertGuid(const FGuid &UnrealGuid)
{
// Unreal doesn't follow the usual windows GUID format, instead it parses
// them as 4 integers
FMOD::Studio::ID StudioGuid;
FMemory::Memcpy(&StudioGuid, &UnrealGuid, sizeof(StudioGuid));
Swap(StudioGuid.Data2, StudioGuid.Data3);
Swap(StudioGuid.Data4[0], StudioGuid.Data4[3]);
Swap(StudioGuid.Data4[1], StudioGuid.Data4[2]);
Swap(StudioGuid.Data4[4], StudioGuid.Data4[7]);
Swap(StudioGuid.Data4[5], StudioGuid.Data4[6]);
return StudioGuid;
}
inline FGuid ConvertGuid(const FMOD::Studio::ID &StudioGuid)
{
// Unreal doesn't follow the usual windows GUID format, instead it parses
// them as 4 integers
FMOD::Studio::ID CopiedGuid;
FMemory::Memcpy(&CopiedGuid, &StudioGuid, sizeof(StudioGuid));
Swap(CopiedGuid.Data2, CopiedGuid.Data3);
Swap(CopiedGuid.Data4[0], CopiedGuid.Data4[3]);
Swap(CopiedGuid.Data4[1], CopiedGuid.Data4[2]);
Swap(CopiedGuid.Data4[4], CopiedGuid.Data4[7]);
Swap(CopiedGuid.Data4[5], CopiedGuid.Data4[6]);
FGuid UnrealGuid;
FMemory::Memcpy(&UnrealGuid, &CopiedGuid, sizeof(CopiedGuid));
return UnrealGuid;
}
template <class StudioType>
inline FGuid GetID(StudioType *Instance)
{
FMOD::Studio::ID StudioID = { 0 };
verifyfmod(Instance->getID(&StudioID));
return FMODUtils::ConvertGuid(StudioID);
}
template <class StudioType>
inline FString GetPath(StudioType *Instance)
{
int ActualSize = 128; // Start with expected enough space
TArray<char> RawBuffer;
FMOD_RESULT Result;
do
{
RawBuffer.SetNum(ActualSize);
Result = Instance->getPath(RawBuffer.GetData(), ActualSize, &ActualSize);
} while (Result == FMOD_ERR_TRUNCATED);
if (Result == FMOD_OK)
{
return FString(UTF8_TO_TCHAR(RawBuffer.GetData()));
}
else
{
return FString();
}
}
inline FString LookupNameFromGuid(FMOD::Studio::System *StudioSystem, const FMOD::Studio::ID &Guid)
{
int ActualSize = 128; // Start with expected enough space
TArray<char> RawBuffer;
FMOD_RESULT Result;
do
{
RawBuffer.SetNum(ActualSize);
Result = StudioSystem->lookupPath(&Guid, RawBuffer.GetData(), ActualSize, &ActualSize);
} while (Result == FMOD_ERR_TRUNCATED);
if (Result == FMOD_OK)
{
return FString(UTF8_TO_TCHAR(RawBuffer.GetData()));
}
else
{
return FString();
}
}
inline FString LookupNameFromGuid(FMOD::Studio::System *StudioSystem, const FGuid &Guid)
{
return LookupNameFromGuid(StudioSystem, ConvertGuid(Guid));
}
inline FString ParameterTypeToString(FMOD_STUDIO_PARAMETER_TYPE Type)
{
switch (Type)
{
case FMOD_STUDIO_PARAMETER_GAME_CONTROLLED:
return FString("Game Controlled");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE:
return FString("Distance (Auto)");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE:
return FString("Event Cone Angle (Auto)");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION:
return FString("Event Orientation (Auto)");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION:
return FString("Direction (Auto)");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION:
return FString("Elevation (Auto)");
case FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION:
return FString("Listener Orientation (Auto)");
}
return FString();
}
}