1021 lines
27 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|