zworld-em/Source/zworld/NiagaraArrayBatchSubsystem.cpp
2025-05-30 19:06:39 +08:00

1021 lines
27 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "NiagaraArrayBatchSubsystem.h"
#include "NiagaraComponent.h"
#include "NiagaraDataInterfaceArrayFunctionLibrary.h"
#include "NiagaraFunctionLibrary.h"
DECLARE_LOG_CATEGORY_EXTERN(LogZBS, Log, All);
DEFINE_LOG_CATEGORY(LogZBS);
const FName UNiagaraArrayBatchSubsystem::ParticleIDName = TEXT("User.SpawnList");
const FName UNiagaraArrayBatchSubsystem::PositionParamName = TEXT("User.Positions");
const FName UNiagaraArrayBatchSubsystem::RotationParamName = TEXT("User.Rotations");
const FName UNiagaraArrayBatchSubsystem::ColorParamName = TEXT("User.Colors");
const FName UNiagaraArrayBatchSubsystem::TextureParamName = TEXT("User.TextureIndices");
const FName UNiagaraArrayBatchSubsystem::DeadTimeName = TEXT("User.DeadTimes");
template<typename T>
FORCEINLINE TArray<T> ConvertBatchDataToArray(const TArray<FNiagaraBatchData<T>>& InArray)
{
TArray<T> Result;
Result.Reserve(InArray.Num());
for (const auto& Data : InArray)
{
Result.Add(Data.Data);
}
return Result;
}
FNABIsland::~FNABIsland()
{
if (NiagaraComponent.IsValid())
{
NiagaraComponent->ReleaseToPool();
}
NiagaraComponent = nullptr;
}
void FNABIsland::Init(const FVector& Extent)
{
Bounds.Origin = FVector::ZeroVector;
Bounds.BoxExtent = Extent;
}
void FNABIsland::Tick()
{
if (Data.bDirty)
{
if (!IsBeingUsed())
{
FBox HandlerSystemBounds(-Bounds.BoxExtent, Bounds.BoxExtent);
if (NiagaraSystem)
{
FFXSystemSpawnParameters SpawnParams;
SpawnParams.bAutoActivate = false;//We must activate AFTER adding this component to our handle system array.
SpawnParams.bAutoDestroy = false;
SpawnParams.Location = Bounds.Origin;
SpawnParams.PoolingMethod = EPSCPoolMethod::ManualRelease;
SpawnParams.bPreCullCheck = false;
SpawnParams.SystemTemplate = NiagaraSystem;
SpawnParams.WorldContextObject = Subsystem.Get();
if (UNiagaraComponent* NewComp = UNiagaraFunctionLibrary::SpawnSystemAtLocationWithParams(SpawnParams))
{
NiagaraComponent = NewComp;
Data.NiagaraComponent = NewComp;
NewComp->SetSystemFixedBounds(HandlerSystemBounds);
NewComp->Activate();
}
}
else
{
UE_LOG(LogZBS, Error, TEXT("NiagaraSystem is null, unable to spawn system at location"));
}
}
Data.ConsumeData();
}
}
void FNABIsland::OnAcquired(UObject* WorldContext, FVector Location)
{
FVector ActualMaxSize = Bounds.BoxExtent;
FVector BoxSize = Bounds.BoxExtent * 2;
FVector BoxN = Location / BoxSize;
BoxN.X = FMath::RoundToNegativeInfinity(BoxN.X);
BoxN.Y = FMath::RoundToNegativeInfinity(BoxN.Y);
BoxN.Z = FMath::RoundToNegativeInfinity(BoxN.Z);
Bounds.Origin = BoxN * BoxSize + Bounds.BoxExtent;
Bounds.BoxExtent = ActualMaxSize;
Subsystem = Cast<UNiagaraArrayBatchSubsystem>(WorldContext);
// FBox HandlerSystemBounds(-Bounds.BoxExtent, Bounds.BoxExtent);
// if(NiagaraSystem)
// {
// FFXSystemSpawnParameters SpawnParams;
// SpawnParams.bAutoActivate = false;//We must activate AFTER adding this component to our handle system array.
// SpawnParams.bAutoDestroy = false;
// SpawnParams.Location = Bounds.Origin;
// SpawnParams.PoolingMethod = EPSCPoolMethod::ManualRelease;
// SpawnParams.bPreCullCheck = false;
// SpawnParams.SystemTemplate = NiagaraSystem;
// SpawnParams.WorldContextObject = WorldContext;
// if(UNiagaraComponent* NewComp = UNiagaraFunctionLibrary::SpawnSystemAtLocationWithParams(SpawnParams))
// {
// NiagaraComponent = NewComp;
// Data.NiagaraComponent = NewComp;
// NewComp->SetSystemFixedBounds(HandlerSystemBounds);
// NewComp->Activate();
// }
// }
}
void FNABIsland::OnReleased()
{
if (NiagaraComponent.IsValid())
{
NiagaraComponent->ReleaseToPool();
}
NiagaraComponent = nullptr;
}
bool FNABIsland::IsBeingUsed() const
{
if (!NiagaraComponent.IsValid())
{
return false;
}
return NiagaraComponent->IsActive();
}
void FNABIslandInfo::Tick(float DeltaTime)
{
for (auto Iter = ActiveIslands.CreateIterator(); Iter; ++Iter)
{
FNABIsland& Island = IslandPool[*Iter];
if (!Island.IsBeingUsed() && !Island.IsDirty())
{
Island.OnReleased();
FreeIslands.Add(*Iter);
Iter.RemoveCurrent();
}
else
{
Island.Tick();
}
}
}
void FNiagaraArrayBatchData::ConsumeData()
{
QUICK_SCOPE_CYCLE_COUNTER(NiagaraArrayBatchData_ConsumeData);
bDirty = false;
if (!NiagaraComponent.IsValid())
{
return;
}
for (const auto& Data : VectorData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : FloatData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayFloat(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : IntData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayInt32(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : ColorData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayColor(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : QuatData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayQuat(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : BoolData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayBool(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
for (const auto& Data : Vector2DData)
{
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector2D(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value));
}
}
void UNiagaraArrayBatchSubsystem::Tick(float DeltaTime)
{
QUICK_SCOPE_CYCLE_COUNTER(NiagaraArrayBatchSubsystem_Tick);
Super::Tick(DeltaTime);
for (auto Iter = NiagaraIslandInfoMap.CreateIterator(); Iter; ++Iter)
{
if (!Iter->Key.IsValid())
{
Iter.RemoveCurrent();
continue;
}
Iter->Value.Tick(DeltaTime);
}
}
FNABIsland* UNiagaraArrayBatchSubsystem::FindOrCreateIsland(UNiagaraSystem* NiagaraSystem, const FVector& Location, int32& IslandIndex)
{
//Find the first island that could contain this point.
//For now we do a linear search of active islands.
//Assuming that overall active island count will be low.
//If this is not the case then we'll want to add an acceleration structure to speed up this search.
if (!bLoadedIslandExtents)
{
bLoadedIslandExtents = true;
NiagaraIslandExtentsMap = GetNiagaraIslandExtents();
}
auto& NABIslandInfo = NiagaraIslandInfoMap.FindOrAdd(NiagaraSystem);
if (FVector* Ret = NiagaraIslandExtentsMap.Find(NiagaraSystem->GetPackage()->GetPathName()))
{
NABIslandInfo.Extent = *Ret;
}
FNABIsland* IslandToUse = nullptr;
for (int32 i : NABIslandInfo.ActiveIslands)
{
FNABIsland& Island = NABIslandInfo.IslandPool[i];
if (Island.Contains(Location))
{
IslandToUse = &Island;
IslandIndex = i;
}
}
if (IslandToUse)
{
return IslandToUse;
}
//Failing that, get a init a new island from the pool.
int32 NewIslandIndex = ActivateNewIsland(NiagaraSystem, NABIslandInfo, Location);
if (ensure(NewIslandIndex != INDEX_NONE))
{
IslandToUse = &NABIslandInfo.IslandPool[NewIslandIndex];
IslandIndex = NewIslandIndex;
}
if (IslandToUse)
{
IslandToUse->OnAcquired(this, Location);
}
return IslandToUse;
}
int32 UNiagaraArrayBatchSubsystem::ActivateNewIsland(UNiagaraSystem* NiagaraSystem, FNABIslandInfo& FNABIslandInfo, FVector Location)
{
int32 NewIndex = INDEX_NONE;
FNABIsland* NewIsland = nullptr;
if (FNABIslandInfo.FreeIslands.Num() > 0)
{
NewIndex = FNABIslandInfo.FreeIslands.Pop(false);
NewIsland = &FNABIslandInfo.IslandPool[NewIndex];
}
if (NewIsland == nullptr)
{
NewIndex = FNABIslandInfo.IslandPool.Num();
NewIsland = &FNABIslandInfo.IslandPool.AddDefaulted_GetRef();
}
if (NewIndex != INDEX_NONE)
{
check(NewIsland);
FNABIslandInfo.ActiveIslands.Add(NewIndex);
NewIsland->NiagaraSystem = NiagaraSystem;
NewIsland->Init(FNABIslandInfo.Extent);
}
return NewIndex;
}
int64 FNABParticleData::GetUUID()
{
return static_cast<int64>(IslandIndex) << 32 | ParticleID;
}
TArray<FNiagaraBatchProperty>& FNABParticleData::GetPropertys()
{
return Propertys;
}
FNABParticleData& FNABParticleData::WriteVector(FName Name, const FVector& Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Vector, Name });
DataPtr->VectorData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData& FNABParticleData::WriteQuat(FName Name, const FQuat& Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Quat, Name });
DataPtr->QuatData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData& FNABParticleData::WriteColor(FName Name, const FLinearColor& Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Color, Name });
DataPtr->ColorData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData& FNABParticleData::WriteInt(FName Name, int32 Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Int32, Name });
DataPtr->IntData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData& FNABParticleData::WriteFloat(FName Name, float Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Float, Name });
DataPtr->FloatData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData& FNABParticleData::WriteBool(FName Name, bool Value)
{
if (DataPtr)
{
Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Bool, Name });
DataPtr->BoolData.FindOrAdd(Name).Add({ ParticleID, Value });
DataPtr->bDirty = true;
}
return *this;
}
FNABParticleData UNiagaraArrayBatchSubsystem::WriteNABParticle(UNiagaraSystem* NiagaraAsset, const FVector& Location)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
return FNABParticleData{ DataUid , IslandIndex , &Data }.WriteInt(ParticleIDName, DataUid);
}
template<typename T>
void RemoveProperty(TMap<FName, TArray<FNiagaraBatchData<T>>>& Data, FName Name, int64 DataUid)
{
Data.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<T>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveNABParticle(UNiagaraSystem* NiagaraAsset, int64 DataUid, const TArray<FNiagaraBatchProperty>& Propertys)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
for (auto& Property : Propertys)
{
ENiagaraBatchDataType Type = Property.Type;
FName Name = Property.Name;
switch (Type)
{
case ENiagaraBatchDataType::Vector:
RemoveProperty<FVector>(Data.VectorData, Name, DataUid);
break;
case ENiagaraBatchDataType::Float:
RemoveProperty<float>(Data.FloatData, Name, DataUid);
break;
case ENiagaraBatchDataType::Int32:
RemoveProperty<int32>(Data.IntData, Name, DataUid);
break;
case ENiagaraBatchDataType::Color:
RemoveProperty<FLinearColor>(Data.ColorData, Name, DataUid);
break;
case ENiagaraBatchDataType::Quat:
RemoveProperty<FQuat>(Data.QuatData, Name, DataUid);
break;
case ENiagaraBatchDataType::Bool:
RemoveProperty<bool>(Data.BoolData, Name, DataUid);
break;
case ENiagaraBatchDataType::Vector2D:
RemoveProperty<FVector2D>(Data.Vector2DData, Name, DataUid);
break;
default:
ensureMsgf(false, TEXT("%s Failed to remove property %d %s"), *NiagaraAsset->GetName(), Type, *Name.ToString());
}
}
}
void UNiagaraArrayBatchSubsystem::WriteNABVector(FNABParticleData& Data, FName Name, const FVector& Value)
{
Data.WriteVector(Name, Value);
}
void UNiagaraArrayBatchSubsystem::WriteNABQuat(FNABParticleData& Data, FName Name, const FQuat& Value)
{
Data.WriteQuat(Name, Value);
}
void UNiagaraArrayBatchSubsystem::WriteNABColor(FNABParticleData& Data, FName Name, const FLinearColor& Value)
{
Data.WriteColor(Name, Value);
}
void UNiagaraArrayBatchSubsystem::WriteNABInt(FNABParticleData& Data, FName Name, int32 Value)
{
Data.WriteInt(Name, Value);
}
void UNiagaraArrayBatchSubsystem::WriteNABFloat(FNABParticleData& Data, FName Name, float Value)
{
Data.WriteFloat(Name, Value);
}
void UNiagaraArrayBatchSubsystem::WriteNABBool(FNABParticleData& Data, FName Name, bool Value)
{
Data.WriteBool(Name, Value);
}
int64 UNiagaraArrayBatchSubsystem::WriteVector(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector& Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.VectorData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteFloat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
float Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.FloatData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteInt(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
int32 Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.IntData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteColor(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
const FLinearColor& Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.ColorData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteQuat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
const FQuat& Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.QuatData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteBool(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
bool Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.BoolData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
int64 UNiagaraArrayBatchSubsystem::WriteVector2D(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name,
const FVector2D& Value)
{
if (!NiagaraAsset)
{
return 0;
}
int32 IslandIndex;
auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex);
if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName()))
{
return 0;
}
auto DataUid = ++Island->DataUid;
FNiagaraArrayBatchData& Data = Island->Data;
Data.Vector2DData.FindOrAdd(Name).Add({ DataUid, Value });
Data.bDirty = true;
return static_cast<int64>(IslandIndex) << 32 | DataUid;
}
void UNiagaraArrayBatchSubsystem::OverrideVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid,
const FVector& Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.VectorData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<FVector>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::OverrideFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, float Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.FloatData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<float>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);;
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::OverrideInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, int32 Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.IntData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<int32>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);;
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::OverrideColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid,
const FLinearColor& Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.ColorData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<FLinearColor>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);;
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::OverrideQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid,
const FQuat& Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.QuatData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<FQuat>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);;
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::OverrideBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, bool Value)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.BoolData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData<bool>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);;
})->Data = Value;
}
void UNiagaraArrayBatchSubsystem::RemoveVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.VectorData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<FVector>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.FloatData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<float>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.IntData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<int32>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.ColorData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<FLinearColor>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (DataUid == 0)
{
return;
}
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.QuatData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<FQuat>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.BoolData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<bool>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::RemoveVector2D(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid)
{
if (!NiagaraAsset)
{
return;
}
int32 IslandIndex = DataUid >> 32;
auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset);
if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName()))
{
return;
}
if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex))
{
return;
}
auto& Island = IslandInfo->IslandPool[IslandIndex];
FNiagaraArrayBatchData& Data = Island.Data;
Data.bDirty = true;
Data.Vector2DData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData<FVector2D>& InData)
{
return InData.DataUid == static_cast<uint32>(DataUid);
});
}
void UNiagaraArrayBatchSubsystem::SetNiagaraHidden(const FString& NiagaraFullName, bool bHide, FName HideTag)
{
for (auto& Pair : NiagaraIslandInfoMap)
{
if (!Pair.Key.IsValid())
{
continue;
}
if (Pair.Key->GetPathName() == NiagaraFullName)
{
for (auto& Island : Pair.Value.IslandPool)
{
if (!Island.NiagaraComponent.IsValid())
{
continue;
}
//TArray<USceneComponent*> HiddenComponents;
//URuntimeCommonFunctionLibrary::SetSceneComponentHiddenInGame(Island.NiagaraComponent.Get(), bHide, false, HideTag, HiddenComponents);
}
break;
}
}
}