|
@@ -31,35 +31,30 @@ Copyright NVIDIA Corporation 2006 -- Ignacio Castano <[email protected]>
|
|
#pragma once
|
|
#pragma once
|
|
#ifndef XATLAS_H
|
|
#ifndef XATLAS_H
|
|
#define XATLAS_H
|
|
#define XATLAS_H
|
|
|
|
+#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
namespace xatlas {
|
|
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.
|
|
// A group of connected faces, belonging to a single atlas.
|
|
-struct Chart
|
|
|
|
-{
|
|
|
|
|
|
+struct Chart {
|
|
uint32_t *faceArray;
|
|
uint32_t *faceArray;
|
|
uint32_t atlasIndex; // Sub-atlas index.
|
|
uint32_t atlasIndex; // Sub-atlas index.
|
|
uint32_t faceCount;
|
|
uint32_t faceCount;
|
|
- ChartType::Enum type;
|
|
|
|
|
|
+ ChartType type;
|
|
uint32_t material;
|
|
uint32_t material;
|
|
};
|
|
};
|
|
|
|
|
|
// Output vertex.
|
|
// Output vertex.
|
|
-struct Vertex
|
|
|
|
-{
|
|
|
|
|
|
+struct Vertex {
|
|
int32_t atlasIndex; // Sub-atlas index. -1 if the vertex doesn't exist in any atlas.
|
|
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.
|
|
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.
|
|
float uv[2]; // Not normalized - values are in Atlas width and height range.
|
|
@@ -67,8 +62,7 @@ struct Vertex
|
|
};
|
|
};
|
|
|
|
|
|
// Output mesh.
|
|
// Output mesh.
|
|
-struct Mesh
|
|
|
|
-{
|
|
|
|
|
|
+struct Mesh {
|
|
Chart *chartArray;
|
|
Chart *chartArray;
|
|
uint32_t *indexArray;
|
|
uint32_t *indexArray;
|
|
Vertex *vertexArray;
|
|
Vertex *vertexArray;
|
|
@@ -83,16 +77,15 @@ static const uint32_t kImageIsBilinearBit = 0x40000000;
|
|
static const uint32_t kImageIsPaddingBit = 0x20000000;
|
|
static const uint32_t kImageIsPaddingBit = 0x20000000;
|
|
|
|
|
|
// Empty on creation. Populated after charts are packed.
|
|
// Empty on creation. Populated after charts are packed.
|
|
-struct Atlas
|
|
|
|
-{
|
|
|
|
|
|
+struct Atlas {
|
|
uint32_t *image;
|
|
uint32_t *image;
|
|
Mesh *meshes; // The output meshes, corresponding to each AddMesh call.
|
|
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 width; // Atlas width in texels.
|
|
uint32_t height; // Atlas height 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 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 chartCount; // Total number of charts in all meshes.
|
|
uint32_t meshCount; // Number of output meshes. Equal to the number of times AddMesh was called.
|
|
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.
|
|
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);
|
|
void Destroy(Atlas *atlas);
|
|
|
|
|
|
-struct IndexFormat
|
|
|
|
-{
|
|
|
|
- enum Enum
|
|
|
|
- {
|
|
|
|
- UInt16,
|
|
|
|
- UInt32
|
|
|
|
- };
|
|
|
|
|
|
+enum class IndexFormat {
|
|
|
|
+ UInt16,
|
|
|
|
+ UInt32
|
|
};
|
|
};
|
|
|
|
|
|
// Input mesh declaration.
|
|
// Input mesh declaration.
|
|
-struct MeshDecl
|
|
|
|
-{
|
|
|
|
|
|
+struct MeshDecl {
|
|
const void *vertexPositionData = nullptr;
|
|
const void *vertexPositionData = nullptr;
|
|
const void *vertexNormalData = nullptr; // optional
|
|
const void *vertexNormalData = nullptr; // optional
|
|
const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator.
|
|
const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator.
|
|
const void *indexData = nullptr; // optional
|
|
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.
|
|
// 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;
|
|
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 vertexCount = 0;
|
|
uint32_t vertexPositionStride = 0;
|
|
uint32_t vertexPositionStride = 0;
|
|
uint32_t vertexNormalStride = 0; // optional
|
|
uint32_t vertexNormalStride = 0; // optional
|
|
uint32_t vertexUvStride = 0; // optional
|
|
uint32_t vertexUvStride = 0; // optional
|
|
uint32_t indexCount = 0;
|
|
uint32_t indexCount = 0;
|
|
int32_t indexOffset = 0; // optional. Add this offset to all indices.
|
|
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.
|
|
// Vertex positions within epsilon distance of each other are considered colocal.
|
|
float epsilon = 1.192092896e-07F;
|
|
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.
|
|
// 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.
|
|
// Wait for AddMesh async processing to finish. ComputeCharts / Generate call this internally.
|
|
void AddMeshJoin(Atlas *atlas);
|
|
void AddMeshJoin(Atlas *atlas);
|
|
|
|
|
|
-struct UvMeshDecl
|
|
|
|
-{
|
|
|
|
|
|
+struct UvMeshDecl {
|
|
const void *vertexUvData = nullptr;
|
|
const void *vertexUvData = nullptr;
|
|
const void *indexData = nullptr; // optional
|
|
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 vertexCount = 0;
|
|
uint32_t vertexStride = 0;
|
|
uint32_t vertexStride = 0;
|
|
uint32_t indexCount = 0;
|
|
uint32_t indexCount = 0;
|
|
int32_t indexOffset = 0; // optional. Add this offset to all indices.
|
|
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 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.
|
|
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.
|
|
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.
|
|
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.
|
|
// Call after all AddMesh calls. Can be called multiple times to recompute charts with different options.
|
|
void ComputeCharts(Atlas *atlas, ChartOptions options = ChartOptions());
|
|
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.
|
|
// Leave space around charts for texels that would be sampled by bilinear filtering.
|
|
bool bilinear = true;
|
|
bool bilinear = true;
|
|
|
|
|
|
@@ -212,44 +213,29 @@ struct PackOptions
|
|
// Create Atlas::image
|
|
// Create Atlas::image
|
|
bool createImage = false;
|
|
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());
|
|
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.
|
|
// 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.
|
|
// 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);
|
|
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);
|
|
void SetPrint(PrintFunc print, bool verbose);
|
|
|
|
|
|
// Helper functions for error messages.
|
|
// 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
|
|
} // namespace xatlas
|
|
|
|
|