Files
UnrealEngine/Engine/Plugins/Editor/ProxyLODPlugin/Source/ProxyLOD/Public/ProxyLODVolume.h
2025-05-18 13:04:45 +08:00

129 lines
4.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Math/Vector.h"
struct FMeshMergeData;
struct FInstancedMeshMergeData;
struct FMeshDescription;
class PROXYLODMESHREDUCTION_API IProxyLODVolume
{
public:
/** Helper class to extract dimensions in voxel size units of OpenVDB volume */
struct PROXYLODMESHREDUCTION_API FVector3i
{
int32 X;
int32 Y;
int32 Z;
FVector3i(int32 InX, int32 InY, int32 InZ)
: X(InX), Y(InY), Z(InZ)
{
}
FORCEINLINE int32 operator[](int32 Index) const
{
return Index == 0 ? X : (Index == 1 ? Y : (Index == 2 ? Z : 0));
}
int32 MinIndex() const;
};
/** Create OpenVDB volume from input geometry */
static TUniquePtr<IProxyLODVolume> CreateSDFVolumeFromMeshArray(const TArray<FMeshMergeData>& Geometry, float Step);
static TUniquePtr<IProxyLODVolume> CreateSDFVolumeFromMeshArray(const TArray<FInstancedMeshMergeData>& Geometry, float Step);
virtual ~IProxyLODVolume() {}
/** Get size of voxel cell */
virtual double GetVoxelSize() const = 0;
/** Get dimensions of bounding box of OpenVDB volume in multiple of size of voxel cell */
virtual FVector3i GetBBoxSize() const = 0;
/** Close any gap in OpenVDB volume which radius is less than given one in given maximum iteration */
virtual void CloseGaps(const double GapRadius, const int32 MaxDilations) = 0;
/** Extract iso distance 0 from OpenVDB volume as a RawMesh */
virtual void ConvertToRawMesh(FMeshDescription& OutRawMesh) const = 0;
/** Expand exterior and interior narrow band of OpenVDB volume by given amount */
virtual void ExpandNarrowBand(float ExteriorWidth, float InteriorWidth) = 0;
/**
* Returns distance between given point and iso distance 0 of OpenVDB volume.
* Note: Returned value is clamped between -'dimension of interior narrow band' and +'dimension of exterior narrow band'
*/
virtual float QueryDistance(const FVector& Point) const = 0;
};
class PROXYLODMESHREDUCTION_API IVoxelBasedCSG
{
public :
static TUniquePtr<IVoxelBasedCSG> CreateCSGTool(float VoxelSize);
virtual ~IVoxelBasedCSG() {}
class FPlacedMesh
{
public:
FPlacedMesh()
: Mesh(nullptr)
{}
explicit FPlacedMesh(const FMeshDescription* MeshIn, const FTransform& TransformIn = FTransform::Identity)
: Mesh(MeshIn), Transform(TransformIn)
{}
FPlacedMesh(const FPlacedMesh& other)
: Mesh(other.Mesh)
, Transform(other.Transform)
{}
FPlacedMesh& operator=(const FPlacedMesh& other)
{
Mesh = other.Mesh;
Transform = other.Transform;
return *this;
}
const FMeshDescription* Mesh;
FTransform Transform;
};
// the interrupter interface.
struct FInterrupter
{
FInterrupter() = default;
virtual ~FInterrupter() = default;
// templated openvdb code requires these functions.
virtual void start(const char* name = nullptr) { (void)name; }
virtual void end() {};
virtual bool wasInterrupted(int percent = -1) { (void)percent; return false; }
};
virtual double GetVoxelSize() const = 0;
virtual void SetVoxelSize(double VolexSize) = 0;
// Will destroy UVs and other attributes Returns the average location of the input meshes
virtual FVector ComputeUnion(const TArray<IVoxelBasedCSG::FPlacedMesh>& MeshArray, FMeshDescription& ResultMesh, double Adaptivity = 0.1, double IsoSurfcae = 0.) const = 0;
virtual FVector ComputeDifference(const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, double Adaptivity, double IsoSurface) const = 0;
virtual FVector ComputeIntersection(const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, double Adaptivity, double IsoSurface) const = 0;
virtual FVector ComputeUnion(const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, double Adaptivity, double IsoSurface) const = 0;
// interruptible versions. return true on success.
virtual bool ComputeUnion(IVoxelBasedCSG::FInterrupter& Interrupter, const TArray<IVoxelBasedCSG::FPlacedMesh>& MeshArray, FMeshDescription& ResultMesh, FVector& AverageTranslation, double Adaptivity, double IsoSurfcae) const = 0;
virtual bool ComputeDifference(IVoxelBasedCSG::FInterrupter& Interrupter, const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, FVector& AverageTranslation, double Adaptivity, double IsoSurface) const = 0;
virtual bool ComputeIntersection(IVoxelBasedCSG::FInterrupter& Interrupter, const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, FVector& AverageTranslation, double Adaptivity, double IsoSurface) const = 0;
virtual bool ComputeUnion(IVoxelBasedCSG::FInterrupter& Interrupter, const FPlacedMesh& PlacedMeshA, const FPlacedMesh& PlacedMeshB, FMeshDescription& ResultMesh, FVector& AverageTranslation, double Adaptivity, double IsoSurface) const = 0;
};