6cbdeedf57
Did some hacks to it to avoid it from failing on bad geometry.
160 lines
4 KiB
C++
160 lines
4 KiB
C++
// 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
|