diff options
Diffstat (limited to 'thirdparty/xatlas/xatlas.h')
-rw-r--r-- | thirdparty/xatlas/xatlas.h | 170 |
1 files changed, 78 insertions, 92 deletions
diff --git a/thirdparty/xatlas/xatlas.h b/thirdparty/xatlas/xatlas.h index cc47f4837e..fc40d9d49c 100644 --- a/thirdparty/xatlas/xatlas.h +++ b/thirdparty/xatlas/xatlas.h @@ -31,35 +31,30 @@ Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com> #pragma once #ifndef XATLAS_H #define XATLAS_H +#include <stddef.h> #include <stdint.h> namespace xatlas { -struct ChartType -{ - enum Enum - { - Planar, - Ortho, - LSCM, - Piecewise, - Invalid - }; +enum class ChartType { + Planar, + Ortho, + LSCM, + Piecewise, + Invalid }; // A group of connected faces, belonging to a single atlas. -struct Chart -{ +struct Chart { uint32_t *faceArray; uint32_t atlasIndex; // Sub-atlas index. uint32_t faceCount; - ChartType::Enum type; + ChartType type; uint32_t material; }; // Output vertex. -struct Vertex -{ +struct Vertex { int32_t atlasIndex; // Sub-atlas index. -1 if the vertex doesn't exist in any atlas. int32_t chartIndex; // -1 if the vertex doesn't exist in any chart. float uv[2]; // Not normalized - values are in Atlas width and height range. @@ -67,8 +62,7 @@ struct Vertex }; // Output mesh. -struct Mesh -{ +struct Mesh { Chart *chartArray; uint32_t *indexArray; Vertex *vertexArray; @@ -83,16 +77,15 @@ static const uint32_t kImageIsBilinearBit = 0x40000000; static const uint32_t kImageIsPaddingBit = 0x20000000; // Empty on creation. Populated after charts are packed. -struct Atlas -{ +struct Atlas { uint32_t *image; Mesh *meshes; // The output meshes, corresponding to each AddMesh call. + float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length. uint32_t width; // Atlas width in texels. uint32_t height; // Atlas height in texels. uint32_t atlasCount; // Number of sub-atlases. Equal to 0 unless PackOptions resolution is changed from default (0). uint32_t chartCount; // Total number of charts in all meshes. uint32_t meshCount; // Number of output meshes. Equal to the number of times AddMesh was called. - float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length. float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution. }; @@ -101,73 +94,76 @@ Atlas *Create(); void Destroy(Atlas *atlas); -struct IndexFormat -{ - enum Enum - { - UInt16, - UInt32 - }; +enum class IndexFormat { + UInt16, + UInt32 }; // Input mesh declaration. -struct MeshDecl -{ +struct MeshDecl { const void *vertexPositionData = nullptr; const void *vertexNormalData = nullptr; // optional const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator. const void *indexData = nullptr; // optional - - // Optional. indexCount / 3 (triangle count) in length. + + // Optional. Must be faceCount in length. // Don't atlas faces set to true. Ignored faces still exist in the output meshes, Vertex uv is set to (0, 0) and Vertex atlasIndex to -1. const bool *faceIgnoreData = nullptr; + // Optional. Must be faceCount in length. + // Only faces with the same material will be assigned to the same chart. + const uint32_t *faceMaterialData = nullptr; + + // Optional. Must be faceCount in length. + // Polygon / n-gon support. Faces are assumed to be triangles if this is null. + const uint8_t *faceVertexCount = nullptr; + uint32_t vertexCount = 0; uint32_t vertexPositionStride = 0; uint32_t vertexNormalStride = 0; // optional uint32_t vertexUvStride = 0; // optional uint32_t indexCount = 0; int32_t indexOffset = 0; // optional. Add this offset to all indices. - IndexFormat::Enum indexFormat = IndexFormat::UInt16; + uint32_t faceCount = 0; // Optional if faceVertexCount is null. Otherwise assumed to be indexCount / 3. + IndexFormat indexFormat = IndexFormat::UInt16; // Vertex positions within epsilon distance of each other are considered colocal. float epsilon = 1.192092896e-07F; }; -struct AddMeshError -{ - enum Enum - { - Success, // No error. - Error, // Unspecified error. - IndexOutOfRange, // An index is >= MeshDecl vertexCount. - InvalidIndexCount // Not evenly divisible by 3 - expecting triangles. - }; +enum class AddMeshError { + Success, // No error. + Error, // Unspecified error. + IndexOutOfRange, // An index is >= MeshDecl vertexCount. + InvalidFaceVertexCount, // Must be >= 3. + InvalidIndexCount // Not evenly divisible by 3 - expecting triangles. }; // Add a mesh to the atlas. MeshDecl data is copied, so it can be freed after AddMesh returns. -AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint = 0); +AddMeshError AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint = 0); // Wait for AddMesh async processing to finish. ComputeCharts / Generate call this internally. void AddMeshJoin(Atlas *atlas); -struct UvMeshDecl -{ +struct UvMeshDecl { const void *vertexUvData = nullptr; const void *indexData = nullptr; // optional - const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length. + const uint32_t *faceMaterialData = nullptr; // Optional. Overlapping UVs should be assigned a different material. Must be indexCount / 3 in length. uint32_t vertexCount = 0; uint32_t vertexStride = 0; uint32_t indexCount = 0; int32_t indexOffset = 0; // optional. Add this offset to all indices. - IndexFormat::Enum indexFormat = IndexFormat::UInt16; - bool rotateCharts = true; + IndexFormat indexFormat = IndexFormat::UInt16; }; -AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl); +AddMeshError AddUvMesh(Atlas *atlas, const UvMeshDecl &decl); + +// Custom parameterization function. texcoords initial values are an orthogonal parameterization. +typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount); + +struct ChartOptions { + ParameterizeFunc paramFunc = nullptr; -struct ChartOptions -{ float maxChartArea = 0.0f; // Don't grow charts to be larger than this. 0 means no limit. float maxBoundaryLength = 0.0f; // Don't grow charts to have a longer boundary than this. 0 means no limit. @@ -180,26 +176,31 @@ struct ChartOptions float maxCost = 2.0f; // If total of all metrics * weights > maxCost, don't grow chart. Lower values result in more charts. uint32_t maxIterations = 1; // Number of iterations of the chart growing and seeding phases. Higher values result in better charts. + + bool useInputMeshUvs = false; // Use MeshDecl::vertexUvData for charts. + bool fixWinding = false; // Enforce consistent texture coordinate winding. }; // Call after all AddMesh calls. Can be called multiple times to recompute charts with different options. void ComputeCharts(Atlas *atlas, ChartOptions options = ChartOptions()); -// Custom parameterization function. texcoords initial values are an orthogonal parameterization. -typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount); +struct PackOptions { + // Charts larger than this will be scaled down. 0 means no limit. + uint32_t maxChartSize = 0; -struct ParameterizeOptions -{ - ParameterizeFunc func = nullptr; - bool closeHoles = true; // If the custom parameterization function works with multiple boundaries, this can be set to false to improve performance. - bool fixTJunctions = true; // If meshes don't have T-junctions, this can be set to false to improve performance. -}; + // Number of pixels to pad charts with. + uint32_t padding = 0; + + // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take up approximately 32x32 texels in the atlas. + // If 0, an estimated value will be calculated to approximately match the given resolution. + // If resolution is also 0, the estimated value will approximately match a 1024x1024 atlas. + float texelsPerUnit = 0.0f; -// Call after ComputeCharts. Can be called multiple times to re-parameterize charts with a different ParameterizeFunc. -void ParameterizeCharts(Atlas *atlas, ParameterizeOptions options = ParameterizeOptions()); + // If 0, generate a single atlas with texelsPerUnit determining the final resolution. + // If not 0, and texelsPerUnit is not 0, generate one or more atlases with that exact resolution. + // If not 0, and texelsPerUnit is 0, texelsPerUnit is estimated to approximately match the resolution. + uint32_t resolution = 0; -struct PackOptions -{ // Leave space around charts for texels that would be sampled by bilinear filtering. bool bilinear = true; @@ -212,44 +213,29 @@ struct PackOptions // Create Atlas::image bool createImage = false; - // Charts larger than this will be scaled down. 0 means no limit. - uint32_t maxChartSize = 0; - - // Number of pixels to pad charts with. - uint32_t padding = 0; + // Rotate charts to the axis of their convex hull. + bool rotateChartsToAxis = true; - // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take up approximately 32x32 texels in the atlas. - // If 0, an estimated value will be calculated to approximately match the given resolution. - // If resolution is also 0, the estimated value will approximately match a 1024x1024 atlas. - float texelsPerUnit = 0.0f; - - // If 0, generate a single atlas with texelsPerUnit determining the final resolution. - // If not 0, and texelsPerUnit is not 0, generate one or more atlases with that exact resolution. - // If not 0, and texelsPerUnit is 0, texelsPerUnit is estimated to approximately match the resolution. - uint32_t resolution = 0; + // Rotate charts to improve packing. + bool rotateCharts = true; }; -// Call after ParameterizeCharts. Can be called multiple times to re-pack charts with different options. +// Call after ComputeCharts. Can be called multiple times to re-pack charts with different options. void PackCharts(Atlas *atlas, PackOptions packOptions = PackOptions()); -// Equivalent to calling ComputeCharts, ParameterizeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options. -void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), ParameterizeOptions parameterizeOptions = ParameterizeOptions(), PackOptions packOptions = PackOptions()); +// Equivalent to calling ComputeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options. +void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), PackOptions packOptions = PackOptions()); // Progress tracking. -struct ProgressCategory -{ - enum Enum - { - AddMesh, - ComputeCharts, - ParameterizeCharts, - PackCharts, - BuildOutputMeshes - }; +enum class ProgressCategory { + AddMesh, + ComputeCharts, + PackCharts, + BuildOutputMeshes }; // May be called from any thread. Return false to cancel. -typedef bool (*ProgressFunc)(ProgressCategory::Enum category, int progress, void *userData); +typedef bool (*ProgressFunc)(ProgressCategory category, int progress, void *userData); void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc = nullptr, void *progressUserData = nullptr); @@ -263,8 +249,8 @@ typedef int (*PrintFunc)(const char *, ...); void SetPrint(PrintFunc print, bool verbose); // Helper functions for error messages. -const char *StringForEnum(AddMeshError::Enum error); -const char *StringForEnum(ProgressCategory::Enum category); +const char *StringForEnum(AddMeshError error); +const char *StringForEnum(ProgressCategory category); } // namespace xatlas |