zworld-em/Source/zworld/NiagaraArrayBatchSubsystem.h

290 lines
8.6 KiB
C
Raw Normal View History

2025-05-30 19:06:39 +08:00
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UnLuaInterface.h"
#include "Subsystems/WorldSubsystem.h"
#include "NiagaraComponent.h"
#include "NiagaraArrayBatchSubsystem.generated.h"
class UNiagaraDataChannelHandler_Islands;
class UNiagaraSystem;
class UNiagaraComponent;
template<typename T>
struct FNiagaraBatchData
{
FNiagaraBatchData(uint32 InDataUid, T InData)
: DataUid(InDataUid)
, Data(InData)
{
}
uint32 DataUid;
T Data;
};
UENUM(BlueprintType)
enum class ENiagaraBatchDataType : uint8
{
Vector,
Float,
Int32,
Color,
Quat,
Bool,
Vector2D,
};
USTRUCT(BlueprintType)
struct FNiagaraBatchProperty
{
GENERATED_BODY()
ENiagaraBatchDataType Type;
FName Name;
};
struct FNiagaraArrayBatchData
{
friend class UNiagaraArrayBatchSubsystem;
friend struct FNABParticleData;
friend struct FNABIsland;
private:
void ConsumeData();
private:
TWeakObjectPtr<UNiagaraComponent> NiagaraComponent;
TMap<FName, TArray<FNiagaraBatchData<FVector>>> VectorData;
TMap<FName, TArray<FNiagaraBatchData<float>>> FloatData;
TMap<FName, TArray<FNiagaraBatchData<int32>>> IntData;
TMap<FName, TArray<FNiagaraBatchData<FLinearColor>>> ColorData;
TMap<FName, TArray<FNiagaraBatchData<FQuat>>> QuatData;
TMap<FName, TArray<FNiagaraBatchData<bool>>> BoolData;
TMap<FName, TArray<FNiagaraBatchData<FVector2D>>> Vector2DData;
bool bDirty = false;
};
USTRUCT()
struct FNABIsland
{
GENERATED_BODY()
// UE_NONCOPYABLE(FNABIsland)
friend class UNiagaraArrayBatchSubsystem;
public:
FNABIsland() {};
~FNABIsland();
void Init(const FVector& Extent);
void Tick();
FORCEINLINE bool Contains(FVector Point) const
{
return Bounds.ComputeSquaredDistanceFromBoxToPoint(Point) <= 0.f;
}
void OnAcquired(UObject* WorldContext, FVector Location);
void OnReleased();
bool IsBeingUsed() const;
FORCEINLINE bool IsDirty() const
{
return Data.bDirty;
}
private:
/** Current bounds of this island. The bounds of any handler systems are modified to match these bounds. */
UPROPERTY()
FBoxSphereBounds Bounds = FBoxSphereBounds(EForceInit::ForceInit);
/** Niagara components spawned for this island. */
UPROPERTY()
TWeakObjectPtr<UNiagaraComponent> NiagaraComponent = nullptr;
UPROPERTY()
UNiagaraSystem* NiagaraSystem = nullptr;
/** The underlying storage for this island. */
FNiagaraArrayBatchData Data;
uint32 DataUid = 0;
TWeakObjectPtr<class UNiagaraArrayBatchSubsystem> Subsystem = nullptr;
};
USTRUCT()
struct FNABIslandInfo
{
GENERATED_BODY()
void Tick(float DeltaTime);
/** All currently active Islands for this channel. */
UPROPERTY()
TArray<int32> ActiveIslands;
/** All currently free Islands for this channel. */
UPROPERTY()
TArray<int32> FreeIslands;
/** Pool of all islands. */
UPROPERTY()
TArray<FNABIsland> IslandPool;
UPROPERTY()
FVector Extent = FVector(5000.f, 5000.f, 2000.f);
};
USTRUCT(BlueprintType)
struct FNABParticleData
{
GENERATED_BODY()
uint32 ParticleID;
int32 IslandIndex;
FNiagaraArrayBatchData* DataPtr;
TArray<FNiagaraBatchProperty> Propertys;
public:
FNABParticleData() : FNABParticleData(0)
{
}
FNABParticleData(uint32 ParticleID) : ParticleID(ParticleID), IslandIndex(0), DataPtr(nullptr)
{
}
FNABParticleData(uint32 ParticleID, int32 IslandIndex, FNiagaraArrayBatchData* DataPtr)
: ParticleID(ParticleID), IslandIndex(IslandIndex), DataPtr(DataPtr)
{
}
int64 GetUUID();
TArray<FNiagaraBatchProperty>& GetPropertys();
FNABParticleData& WriteVector(FName Name, const FVector& Value);
FNABParticleData& WriteQuat(FName Name, const FQuat& Value);
FNABParticleData& WriteColor(FName Name, const FLinearColor& Value);
FNABParticleData& WriteInt(FName Name, int32 Value);
FNABParticleData& WriteFloat(FName Name, float Value);
FNABParticleData& WriteBool(FName Name, bool Value);
};
/**
*
*/
UCLASS()
class ZWORLD_API UNiagaraArrayBatchSubsystem : public UTickableWorldSubsystem, public IUnLuaInterface
{
GENERATED_BODY()
virtual FString GetModuleName_Implementation() const override
{
return TEXT("BluePrints.Managers.NiagaraArrayBatchSubsystem_C");
}
virtual TStatId GetStatId() const override
{
RETURN_QUICK_DECLARE_CYCLE_STAT(UNiagaraArrayBatchSubsystem, STATGROUP_Tickables);
}
public:
static const FName ParticleIDName;
static const FName PositionParamName;
static const FName RotationParamName;
static const FName TextureParamName;
static const FName ColorParamName;
static const FName DeadTimeName;
UFUNCTION(BlueprintCallable)
FNABParticleData WriteNABParticle(UNiagaraSystem* NiagaraAsset, const FVector& Location);
UFUNCTION(BlueprintCallable)
void RemoveNABParticle(UNiagaraSystem* NiagaraAsset, int64 DataUid, const TArray<FNiagaraBatchProperty>& Propertys);
UFUNCTION(BlueprintCallable)
void WriteNABVector(FNABParticleData& Data, FName Name, const FVector& Value);
UFUNCTION(BlueprintCallable)
void WriteNABQuat(FNABParticleData& Data, FName Name, const FQuat& Value);
UFUNCTION(BlueprintCallable)
void WriteNABColor(FNABParticleData& Data, FName Name, const FLinearColor& Value);
UFUNCTION(BlueprintCallable)
void WriteNABInt(FNABParticleData& Data, FName Name, int32 Value);
UFUNCTION(BlueprintCallable)
void WriteNABFloat(FNABParticleData& Data, FName Name, float Value);
UFUNCTION(BlueprintCallable)
void WriteNABBool(FNABParticleData& Data, FName Name, bool Value);
UFUNCTION(BlueprintCallable)
int64 WriteVector(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector& Value);
UFUNCTION(BlueprintCallable)
int64 WriteFloat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, float Value);
UFUNCTION(BlueprintCallable)
int64 WriteInt(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, int32 Value);
UFUNCTION(BlueprintCallable)
int64 WriteColor(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FLinearColor& Value);
UFUNCTION(BlueprintCallable)
int64 WriteQuat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FQuat& Value);
UFUNCTION(BlueprintCallable)
int64 WriteBool(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, bool Value);
UFUNCTION(BlueprintCallable)
int64 WriteVector2D(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector2D& Value);
UFUNCTION(BlueprintCallable)
void OverrideVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FVector& Value);
UFUNCTION(BlueprintCallable)
void OverrideFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, float Value);
UFUNCTION(BlueprintCallable)
void OverrideInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, int32 Value);
UFUNCTION(BlueprintCallable)
void OverrideColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FLinearColor& Value);
UFUNCTION(BlueprintCallable)
void OverrideQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FQuat& Value);
UFUNCTION(BlueprintCallable)
void OverrideBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, bool Value);
UFUNCTION(BlueprintCallable)
void RemoveVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void RemoveVector2D(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid);
UFUNCTION(BlueprintCallable)
void SetNiagaraHidden(const FString& NiagaraFullName, bool bHide, FName HideTag);
protected:
virtual void Tick(float DeltaTime) override;
/** Gets the correct island for the given location. */
FNABIsland* FindOrCreateIsland(UNiagaraSystem* NiagaraSystem, const FVector& Location, int32& IslandIndex);
/** Initializes and adds a new island to the ActiveIslands list. Either retrieving from the free pool of existing inactive islands or creating a new one. */
int32 ActivateNewIsland(UNiagaraSystem* NiagaraSystem, FNABIslandInfo& FNABIslandInfo, FVector Location);
UFUNCTION(BlueprintImplementableEvent)
TMap<FString, FVector> GetNiagaraIslandExtents();
protected:
UPROPERTY()
TMap<TWeakObjectPtr<UNiagaraSystem>, FNABIslandInfo> NiagaraIslandInfoMap;
UPROPERTY()
TMap<FString, FVector> NiagaraIslandExtentsMap;
bool bLoadedIslandExtents = false;
};