// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "CoreMinimal.h" #include "GeometryBase.h" #include "Math/Box.h" #include "Math/UnrealMathSSE.h" #include "Math/Vector2D.h" #include "Math/Vector4.h" #include "MeshDescription.h" #include "MeshTypes.h" #include "UObject/NameTypes.h" #include "UObject/UnrealNames.h" PREDECLARE_USE_GEOMETRY_CLASS(FDynamicMesh3); template class TAttributesSet; /** * These attributes are used to store custom modeling tools data on a MeshDescription */ namespace ExtendedMeshAttribute { extern MESHCONVERSION_API const FName PolyTriGroups; } /** * Utility class to construct MeshDescription instances. * NB: this will add a vertex-instance UV to the Description, if it has none. */ class FMeshDescriptionBuilder { public: MESHCONVERSION_API void SetMeshDescription(FMeshDescription* Description); /** Pre-allocate space in the mesh description */ MESHCONVERSION_API void ReserveNewVertices(int32 Count); /** Append vertex and return new vertex ID */ MESHCONVERSION_API FVertexID AppendVertex(const FVector& Position); /** Append vertex with a specific ID and return it */ MESHCONVERSION_API FVertexID AppendVertexWithId(int32 NewVertexID, const FVector& Position); /** Return position of vertex */ MESHCONVERSION_API FVector GetPosition(const FVertexID& VertexID); /** Return position of vertex parent of instance */ MESHCONVERSION_API FVector GetPosition(const FVertexInstanceID& InstanceID); /** Set the position of a vertex */ MESHCONVERSION_API void SetPosition(const FVertexID& VertexID, const FVector& NewPosition); /** Set the number of UV layers */ MESHCONVERSION_API void SetNumUVLayers(int32 NumUVLayers); /** Pre-allocate space in the mesh description for UVs in the indicated UVLayer */ MESHCONVERSION_API void ReserveNewUVs(int32 Count, int UVLayerIndex); /** Append a UV 'vertex' and return a new UV ID*/ MESHCONVERSION_API FUVID AppendUV(const FVector2D& UVvalue, int32 UVLayerIndex); /** Append new vertex instance and return ID */ MESHCONVERSION_API FVertexInstanceID AppendInstance(const FVertexID& VertexID); /** * Set the UV of a vertex instance. * Note: this generally shouldn't be called directly because it alters the instance UVs but not the shared UVs * When setting UVs use AppendUVTriangle */ MESHCONVERSION_API void SetInstanceUV(const FVertexInstanceID& InstanceID, const FVector2D& InstanceUV, int32 UVLayerIndex = 0); /** Set the Normal of a vertex instance*/ MESHCONVERSION_API void SetInstanceNormal(const FVertexInstanceID& InstanceID, const FVector& Normal); /** Set the full tangent space of a vertex instance, this is stored as a vec3 normal, vec3 tangent, and a bitangent sign */ MESHCONVERSION_API void SetInstanceTangentSpace(const FVertexInstanceID& InstanceID, const FVector& Normal, const FVector& Tangent, float Sign); /** Set the Color of a vertex instance*/ MESHCONVERSION_API void SetInstanceColor(const FVertexInstanceID& InstanceID, const FVector4f& Color); /** Enable per-triangle integer attribute named PolyTriGroups */ MESHCONVERSION_API void EnablePolyGroups(); /** Set the PolyTriGroups attribute value to a specific GroupID for a Triangle */ MESHCONVERSION_API void SetPolyGroupID(const FTriangleID& TriangleID, int GroupID); /** Append a UV triangle to the specified UV layer. This will use both shared and per-instance UV storage*/ MESHCONVERSION_API void AppendUVTriangle(const FTriangleID& TriangleID, const FUVID UVverterxID0, const FUVID UVvertexID1, const FUVID UVvertexID2, int32 UVLayerIndex); /** Append a triangle to the mesh with the given PolygonGroup ID */ MESHCONVERSION_API FTriangleID AppendTriangle(const FVertexID& Vertex0, const FVertexID& Vertex1, const FVertexID& Vertex2, const FPolygonGroupID& PolygonGroup); /** Append a triangle to the mesh with the given PolygonGroup ID */ MESHCONVERSION_API FTriangleID AppendTriangle(const FVertexID* Triangle, const FPolygonGroupID& PolygonGroup); /** * Append a triangle to the mesh using the given vertex instances and PolygonGroup ID */ MESHCONVERSION_API FTriangleID AppendTriangle(const FVertexInstanceID& Instance0, const FVertexInstanceID& Instance1, const FVertexInstanceID& Instance2, const FPolygonGroupID& PolygonGroup); /** * Append an arbitrary polygon to the mesh with the given PolygonGroup ID * Unique Vertex instances will be created for each polygon-vertex. */ MESHCONVERSION_API FPolygonID AppendPolygon(const TArray& Vertices, const FPolygonGroupID& PolygonGroup); /** * Create a new MeshDescription PolygonGroup and return it's ID. * PolygonGroups are not the same as Polygroups, they essentially represent * Mesh Sections, which then reference Material Slots, etc */ MESHCONVERSION_API FPolygonGroupID AppendPolygonGroup(FName MaterialSlotName = NAME_None); /** * Set the specified value for the named attribute / vertex index combination. * If a vertex attribute with the given name doesn't exist, it is created. */ template void SetVertexAttributeValue(FName AttributeName, FVertexID VertexID, const T& Value) { TAttributesSet& VertexAttributes = MeshDescription->VertexAttributes(); if (!VertexAttributes.GetAttributesRef(AttributeName).IsValid()) { VertexAttributes.RegisterAttribute(AttributeName); } VertexAttributes.GetAttributesRef(AttributeName).Set(VertexID, Value); } /** Set MeshAttribute::Edge::IsHard to true for all edges */ MESHCONVERSION_API void SetAllEdgesHardness(bool bHard); /** Translate the MeshDescription vertex positions */ MESHCONVERSION_API void Translate(const FVector& Translation); /** Return the current bounding box of the mesh */ MESHCONVERSION_API FBox ComputeBoundingBox() const; /** Disable the construction of secondary data structures in the mesh description */ MESHCONVERSION_API void SuspendMeshDescriptionIndexing(); /** Enable the construction of secondary data structures in the mesh description */ MESHCONVERSION_API void ResumeMeshDescriptionIndexing(); protected: FMeshDescription* MeshDescription; TVertexAttributesRef VertexPositions; TVertexInstanceAttributesRef InstanceUVs; TVertexInstanceAttributesRef InstanceNormals; TVertexInstanceAttributesRef InstanceTangents; TVertexInstanceAttributesRef InstanceBiTangentSign; TVertexInstanceAttributesRef InstanceColors; TArray> UVCoordinateLayers; TArray TempBuffer; TArray TempUVBuffer; TPolygonAttributesRef PolyGroups; TPolygonGroupAttributesRef GroupMaterialSlotNames; };