virtualx-engine/thirdparty/xatlas/xatlas.h

161 lines
4 KiB
C++
Raw Normal View History

// This code is in the public domain -- castanyo@yahoo.es
#pragma once
#ifndef XATLAS_H
#define XATLAS_H
#include <float.h> // FLT_MAX
#include <limits.h>
#include <stdint.h>
namespace xatlas {
typedef void (*PrintFunc)(const char *, ...);
struct Atlas;
struct CharterOptions {
float proxyFitMetricWeight;
float roundnessMetricWeight;
float straightnessMetricWeight;
float normalSeamMetricWeight;
float textureSeamMetricWeight;
float maxChartArea;
float maxBoundaryLength;
CharterOptions() {
// These are the default values we use on The Witness.
proxyFitMetricWeight = 2.0f;
roundnessMetricWeight = 0.01f;
straightnessMetricWeight = 6.0f;
normalSeamMetricWeight = 4.0f;
textureSeamMetricWeight = 0.5f;
/*
proxyFitMetricWeight = 1.0f;
roundnessMetricWeight = 0.1f;
straightnessMetricWeight = 0.25f;
normalSeamMetricWeight = 1.0f;
textureSeamMetricWeight = 0.1f;
*/
maxChartArea = FLT_MAX;
maxBoundaryLength = FLT_MAX;
}
};
struct PackMethod {
enum Enum {
TexelArea, // texel_area determines resolution
ApproximateResolution, // guess texel_area to approximately match desired resolution
ExactResolution // run the packer multiple times to exactly match the desired resolution (slow)
};
};
struct PackerOptions {
PackMethod::Enum method;
// 0 - brute force
// 1 - 4096 attempts
// 2 - 2048
// 3 - 1024
// 4 - 512
// other - 256
// Avoid brute force packing, since it can be unusably slow in some situations.
int quality;
float texelArea; // This is not really texel area, but 1 / texel width?
uint32_t resolution;
bool blockAlign; // Align charts to 4x4 blocks.
bool conservative; // Pack charts with extra padding.
int padding;
PackerOptions() {
method = PackMethod::ApproximateResolution;
quality = 1;
texelArea = 8;
resolution = 512;
blockAlign = false;
conservative = false;
padding = 0;
}
};
struct AddMeshErrorCode {
enum Enum {
Success,
AlreadyAddedEdge, // index0 and index1 are the edge indices
DegenerateColocalEdge, // index0 and index1 are the edge indices
DegenerateEdge, // index0 and index1 are the edge indices
DuplicateEdge, // index0 and index1 are the edge indices
IndexOutOfRange, // index0 is the index
InvalidIndexCount, // not evenly divisible by 3 - expecting triangles
ZeroAreaFace,
ZeroLengthEdge // index0 and index1 are the edge indices
};
};
struct AddMeshError {
AddMeshErrorCode::Enum code;
uint32_t face;
uint32_t index0, index1;
};
struct IndexFormat {
enum Enum {
HalfFloat,
Float
};
};
struct InputMesh {
uint32_t vertexCount;
const void *vertexPositionData;
uint32_t vertexPositionStride;
const void *vertexNormalData; // optional
uint32_t vertexNormalStride; // optional
// optional
// The input UVs are provided as a hint to the chart generator.
const void *vertexUvData;
uint32_t vertexUvStride;
uint32_t indexCount;
const void *indexData;
IndexFormat::Enum indexFormat;
// optional. indexCount / 3 in length.
// Charter also uses material boundaries as a hint to cut charts.
const uint16_t *faceMaterialData;
};
struct OutputChart {
uint32_t *indexArray;
uint32_t indexCount;
};
struct OutputVertex {
float uv[2];
uint32_t xref; // Index of input vertex from which this output vertex originated.
};
struct OutputMesh {
OutputChart *chartArray;
uint32_t chartCount;
uint32_t *indexArray;
uint32_t indexCount;
OutputVertex *vertexArray;
uint32_t vertexCount;
};
void SetPrint(PrintFunc print);
Atlas *Create();
void Destroy(Atlas *atlas);
// useColocalVertices - generates fewer charts (good), but is more sensitive to bad geometry.
AddMeshError AddMesh(Atlas *atlas, const InputMesh &mesh, bool useColocalVertices = true);
void Generate(Atlas *atlas, CharterOptions charterOptions = CharterOptions(), PackerOptions packerOptions = PackerOptions());
uint32_t GetWidth(const Atlas *atlas);
uint32_t GetHeight(const Atlas *atlas);
uint32_t GetNumCharts(const Atlas *atlas);
const OutputMesh *const *GetOutputMeshes(const Atlas *atlas);
const char *StringForEnum(AddMeshErrorCode::Enum error);
} // namespace xatlas
#endif // XATLAS_H