CelticCraft/Plugins/VoxelFree/Source/Voxel/Private/VoxelRender/Meshers/VoxelMesher.h

148 lines
No EOL
4.4 KiB
C++

// Copyright 2020 Phyronnaz
#pragma once
#include "CoreMinimal.h"
#include "VoxelIntBox.h"
#include "VoxelMinimal.h"
struct FVoxelRendererSettings;
struct FVoxelChunkMesh;
class FVoxelData;
class FVoxelDataLockInfo;
#if ENABLE_MESHER_STATS
struct FVoxelScopedMesherTime
{
const uint64 StartCycle = FPlatformTime::Cycles64();
uint64& Cycles;
FORCEINLINE explicit FVoxelScopedMesherTime(uint64& Cycles)
: Cycles(Cycles)
{
}
FORCEINLINE ~FVoxelScopedMesherTime()
{
Cycles += FPlatformTime::Cycles64() - StartCycle;
}
};
#define MESHER_TIME_SCOPE(Time) FVoxelScopedMesherTime LocalScope(Times.Time);
#define MESHER_TIME(Time, X) { FVoxelScopedMesherTime LocalScope(Times.Time); X; }
#define MESHER_TIME_RETURN(Time, X) [&]() { FVoxelScopedMesherTime LocalScope(Times.Time); return X; }()
#define MESHER_TIME_SCOPE_VALUES(Count) FVoxelScopedMesherTime LocalScope(Times._Values); Times._ValuesAccesses += Count;
#define MESHER_TIME_VALUES(Count, X) { FVoxelScopedMesherTime LocalScope(Times._Values); Times._ValuesAccesses += Count; X; }
#define MESHER_TIME_RETURN_VALUES(Count, X) [&]() { FVoxelScopedMesherTime LocalScope(Times._Values); Times._ValuesAccesses += Count; return X; }()
#define MESHER_TIME_SCOPE_MATERIALS(Count) FVoxelScopedMesherTime LocalScope(Times._Materials); Times._MaterialsAccesses += Count;
#define MESHER_TIME_MATERIALS(Count, X) { FVoxelScopedMesherTime LocalScope(Times._Materials); Times._MaterialsAccesses += Count; X; }
#define MESHER_TIME_RETURN_MATERIALS(Count, X) [&]() { FVoxelScopedMesherTime LocalScope(Times._Materials); Times._MaterialsAccesses += Count; return X; }()
#else
#define MESHER_TIME_SCOPE(Time)
#define MESHER_TIME(Time, X) X
#define MESHER_TIME_RETURN(Time, X) X
#define MESHER_TIME_SCOPE_VALUES(Count)
#define MESHER_TIME_VALUES(Count, X) X
#define MESHER_TIME_RETURN_VALUES(Count, X) X
#define MESHER_TIME_SCOPE_MATERIALS(Count)
#define MESHER_TIME_MATERIALS(Count, X) X
#define MESHER_TIME_RETURN_MATERIALS(Count, X) X
#endif
// All times are in cycles
struct FVoxelMesherTimes
{
uint64 _Values = 0;
uint64 _Materials = 0;
uint64 _ValuesAccesses = 0;
uint64 _MaterialsAccesses = 0;
uint64 Normals = 0;
uint64 UVs = 0;
uint64 CreateChunk = 0;
uint64 FinishCreatingChunk = 0;
uint64 DistanceField = 0;
};
class FVoxelMesherBase
{
public:
const int32 LOD;
const int32 Step;
const int32 Size;
const FIntVector ChunkPosition;
const FVoxelRendererSettings& Settings;
const FVoxelData& Data;
const bool bIsTransitions;
FVoxelMesherBase(
int32 LOD,
const FIntVector& ChunkPosition,
const FVoxelRendererSettings& Settings,
bool bIsTransitions);
virtual ~FVoxelMesherBase();
virtual TVoxelSharedPtr<FVoxelChunkMesh> CreateFullChunk() = 0;
virtual void CreateGeometry(TArray<uint32>& Indices, TArray<FVector>& Vertices) = 0;
TVoxelSharedPtr<FVoxelChunkMesh> CreateEmptyChunk() const;
protected:
virtual FVoxelIntBox GetBoundsToCheckIsEmptyOn() const = 0;
virtual FVoxelIntBox GetBoundsToLock() const = 0;
void UnlockData();
private:
TUniquePtr<FVoxelDataLockInfo> LockInfo;
void LockData();
bool IsEmpty() const;
void FinishCreatingChunk(FVoxelChunkMesh& Chunk) const;
friend class FVoxelMesher;
friend class FVoxelTransitionsMesher;
};
class FVoxelMesher : public FVoxelMesherBase
{
public:
FVoxelMesher(
int32 LOD,
const FIntVector& ChunkPosition,
const FVoxelRendererSettings& Settings);
virtual TVoxelSharedPtr<FVoxelChunkMesh> CreateFullChunk() override final;
virtual void CreateGeometry(TArray<uint32>& Indices, TArray<FVector>& Vertices) override final;
protected:
// Need to call UnlockData
virtual TVoxelSharedPtr<FVoxelChunkMesh> CreateFullChunkImpl(FVoxelMesherTimes& Times) = 0;
// Need to call UnlockData
virtual void CreateGeometryImpl(FVoxelMesherTimes& Times, TArray<uint32>& Indices, TArray<FVector>& Vertices) = 0;
};
class FVoxelTransitionsMesher : public FVoxelMesherBase
{
public:
const uint8 TransitionsMask;
const int32 HalfLOD;
const int32 HalfStep;
FVoxelTransitionsMesher(
int32 LOD,
const FIntVector& ChunkPosition,
const FVoxelRendererSettings& Settings,
uint8 TransitionsMask);
virtual TVoxelSharedPtr<FVoxelChunkMesh> CreateFullChunk() override final;
virtual void CreateGeometry(TArray<uint32>& Indices, TArray<FVector>& Vertices) override final;
protected:
// Need to call UnlockData
virtual TVoxelSharedPtr<FVoxelChunkMesh> CreateFullChunkImpl(FVoxelMesherTimes& Times) = 0;
};