Files
UnrealEngine/Engine/Source/Developer/NaniteBuilder/Private/ClusterDAG.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

143 lines
3.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Cluster.h"
#include "Math/Bounds.h"
#include "NaniteRayTracingScene.h"
#include "Rendering/NaniteResources.h"
// Log CRCs to test for deterministic building
#if 0
#define LOG_CRC( Array ) UE_LOG( LogStaticMesh, Log, TEXT(#Array " CRC %u"), FCrc::MemCrc32( Array.GetData(), Array.Num() * Array.GetTypeSize() ) )
#else
#define LOG_CRC( Array )
#endif
namespace Nanite
{
struct FClusterGroup
{
FSphere3f Bounds;
FSphere3f LODBounds;
float ParentLODError = 0.0f;
int32 MipLevel = 0;
uint32 MeshIndex = MAX_uint32;
uint32 AssemblyPartIndex = MAX_uint32;
bool bTrimmed = false;
bool bRoot = false;
FPageRangeKey PageRangeKey;
TArray< FClusterRef > Children;
};
struct FAssemblyPartData
{
uint32 FirstInstance = MAX_uint32;
uint32 NumInstances = 0;
};
struct FAssemblyInstanceData
{
FMatrix44f Transform;
FSphere3f LODBounds; // TODO Index the referencing group instead of copying its properties.
float ParentLODError;
uint32 RootClusterIndex;
uint32 RootGroupIndex;
uint32 FirstBoneInfluence;
uint32 NumBoneInfluences;
};
class FClusterDAG
{
public:
FClusterDAG() {}
void AddMesh(
const FConstMeshBuildVertexView& Verts,
TArrayView< const uint32 > Indexes,
TArrayView< const int32 > MaterialIndexes,
const FBounds3f& VertexBounds,
const FVertexFormat& VertexFormat );
void AddEmptyMesh() { MeshInput.AddDefaulted(); }
void ReduceMesh( uint32 MeshIndex );
void FindCut(
TArray< FClusterRef >& SelectedClusters,
TSet< uint32 >& SelectedGroups,
uint32 TargetNumTris,
float TargetError,
uint32 TargetOvershoot ) const;
TArray< FCluster > Clusters;
TArray< FClusterGroup > Groups;
TArray< FAssemblyPartData > AssemblyPartData;
TArray< FAssemblyInstanceData > AssemblyInstanceData;
TArray< FVector2f > AssemblyBoneInfluences;
TArray< TArray< FClusterRef >, TInlineAllocator<1> > MeshInput;
#if RAY_TRACE_VOXELS
// TODO Always creates
FRayTracingScene RayTracingScene;
#endif
FBounds3f TotalBounds;
float SurfaceArea = 0.0f;
struct FSettings
{
uint32 NumRays = 1;
int32 VoxelLevel = 0;
uint32 ExtraVoxelLevels = 0;
float RayBackUp = 0.0f;
float MaxEdgeLengthFactor = 0.0f;
ENaniteShapePreservation ShapePreservation = ENaniteShapePreservation::None;
bool bLerpUVs : 1 = true;
bool bSeparable : 1 = false;
bool bVoxelNDF : 1 = true;
bool bVoxelOpacity : 1 = false;
};
FSettings Settings;
bool bHasSkinning : 1 = false;
bool bHasTangents : 1 = false;
bool bHasColors : 1 = false;
uint8 MaxTexCoords = 0;
uint8 MaxBoneInfluences = 0;
private:
uint32 FindAdjacentClusters( TArray< TMap< uint32, uint32 > >& OutAdjacency, TArrayView< const FClusterRef > LevelClusters, uint32 NumExternalEdges );
void GroupTriangleClusters( TArrayView< const FClusterRef > LevelClusters, uint32 NumExternalEdges );
void GroupVoxelClusters( TArrayView< const FClusterRef > LevelClusters );
public: //TEMP
void ReduceGroup(
std::atomic< int32 >& NumClusters,
uint32 MaxClusterSize,
uint32 NumParents,
int32 GroupIndex,
uint32 MeshIndex );
};
FORCEINLINE FCluster& FClusterRef::GetCluster( FClusterDAG& DAG ) const
{
return DAG.Clusters[ ClusterIndex ];
}
FORCEINLINE const FCluster& FClusterRef::GetCluster( const FClusterDAG& DAG ) const
{
return DAG.Clusters[ ClusterIndex ];
}
FORCEINLINE const FMatrix44f& FClusterRef::GetTransform( const FClusterDAG& DAG ) const
{
return DAG.AssemblyInstanceData[ InstanceIndex ].Transform;
}
} // namespace Nanite