Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/Skinning/SkinningTransformProvider.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

184 lines
4.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "SpanAllocator.h"
#include "Containers/Map.h"
#include "SceneExtensions.h"
#include "RendererPrivateUtils.h"
#include "Matrix3x4.h"
#include "Delegates/DelegateCombinations.h"
#include "Delegates/Delegate.h"
#include "GameTime.h"
#define ENABLE_SKELETON_DEBUG_NAME (UE_BUILD_DEBUG | UE_BUILD_DEVELOPMENT)
struct FSkeletonBatch
{
#if ENABLE_SKELETON_DEBUG_NAME
FName SkeletonName = TEXT("Invalid");
#endif
FGuid SkeletonGuid;
uint32 MaxBoneTransforms = 0u;
uint32 UniqueAnimationCount = 0u;
};
struct FSkeletonBatchKey
{
#if ENABLE_SKELETON_DEBUG_NAME
FName SkeletonName = TEXT("Invalid");
#endif
FGuid SkeletonGuid;
FGuid TransformProviderId;
bool operator == (const FSkeletonBatchKey& InOther) const
{
return SkeletonGuid == InOther.SkeletonGuid && TransformProviderId == InOther.TransformProviderId;
}
bool operator != (const FSkeletonBatchKey& InOther) const
{
return !(*this == InOther);
}
friend inline SIZE_T GetTypeHash(const FSkeletonBatchKey& InKey)
{
return HashCombine(GetTypeHash(InKey.SkeletonGuid), GetTypeHash(InKey.TransformProviderId));
}
};
class FSkinningSceneExtensionProxy;
class FSkinningTransformProvider : public ISceneExtension
{
DECLARE_SCENE_EXTENSION(RENDERER_API, FSkinningTransformProvider);
public:
typedef FGuid FProviderId;
struct FProviderRange
{
FProviderId Id;
uint32 Count;
uint32 Offset;
};
struct FProviderIndirection
{
FProviderIndirection(uint32 InIndex, uint32 InTransformOffset, uint32 InHierarchyOffset)
: Index(InIndex)
, TransformOffset(InTransformOffset)
, HierarchyOffset(InHierarchyOffset)
{}
uint32 Index = 0;
uint32 TransformOffset = 0;
uint32 HierarchyOffset = 0;
};
struct FProviderContext
{
FProviderContext(
const TConstArrayView<FPrimitiveSceneInfo*> InPrimitives,
const TConstArrayView<FSkinningSceneExtensionProxy*> InProxies,
const TConstArrayView<FProviderIndirection> InIndirections,
const TConstArrayView<FSkeletonBatch> InSkeletonBatches,
float InDeltaTime,
FRDGBuilder& InGraphBuilder,
FRDGBufferRef InTransformBuffer,
FRDGBufferSRVRef InHierarchyBufferSRV
)
: Primitives(InPrimitives)
, Proxies(InProxies)
, Indirections(InIndirections)
, SkeletonBatches(InSkeletonBatches)
, GraphBuilder(InGraphBuilder)
, TransformBuffer(InTransformBuffer)
, HierarchyBufferSRV(InHierarchyBufferSRV)
, DeltaTime(InDeltaTime)
{
}
TConstArrayView<FPrimitiveSceneInfo*> Primitives;
TConstArrayView<FSkinningSceneExtensionProxy*> Proxies;
TConstArrayView<FProviderIndirection> Indirections;
TConstArrayView<FSkeletonBatch> SkeletonBatches;
FRDGBuilder& GraphBuilder;
FRDGBufferRef TransformBuffer;
FRDGBufferSRVRef HierarchyBufferSRV;
float DeltaTime = 0.0f;
};
DECLARE_DELEGATE_OneParam(FOnProvideTransforms, FProviderContext&);
public:
using ISceneExtension::ISceneExtension;
static bool ShouldCreateExtension(FScene& InScene);
RENDERER_API void RegisterProvider(const FProviderId& Id, const FOnProvideTransforms& Delegate, bool bUsesSkeletonBatches);
RENDERER_API void UnregisterProvider(const FProviderId& Id);
void Broadcast(const TConstArrayView<FProviderRange> Ranges, FProviderContext& Context);
inline bool HasProviders() const
{
return !Providers.IsEmpty();
}
inline TArray<FProviderId> GetProviderIds() const
{
TArray<FProviderId> Ids;
Ids.Reserve(Providers.Num());
for (const FTransformProvider& Provider : Providers)
{
Ids.Add(Provider.Id);
}
return Ids;
}
inline TArray<FProviderId> GetPrimitiveProviderIds() const
{
TArray<FProviderId> Ids;
Ids.Reserve(Providers.Num());
for (const FTransformProvider& Provider : Providers)
{
if (!Provider.bUsesSkeletonBatches)
{
Ids.Add(Provider.Id);
}
}
return Ids;
}
inline TArray<FProviderId> GetSkeletonProviderIds() const
{
TArray<FProviderId> Ids;
Ids.Reserve(Providers.Num());
for (const FTransformProvider& Provider : Providers)
{
if (Provider.bUsesSkeletonBatches)
{
Ids.Add(Provider.Id);
}
}
return Ids;
}
private:
struct FTransformProvider
{
FProviderId Id;
FOnProvideTransforms Delegate;
uint8 bUsesSkeletonBatches : 1 = false;
};
TArray<FTransformProvider> Providers;
};
RENDERER_API const FSkinningTransformProvider::FProviderId& GetRefPoseProviderId();
RENDERER_API const FSkinningTransformProvider::FProviderId& GetAnimRuntimeProviderId();