mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Update xatlas to b7d7bb.
This commit is contained in:
parent
68081b3f6e
commit
d81d29dcbf
4 changed files with 6348 additions and 5791 deletions
|
|
@ -39,57 +39,37 @@ extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const flo
|
||||||
bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) {
|
bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) {
|
||||||
|
|
||||||
//set up input mesh
|
//set up input mesh
|
||||||
xatlas::InputMesh input_mesh;
|
xatlas::MeshDecl input_mesh;
|
||||||
input_mesh.indexData = malloc(sizeof(int) * p_index_count);
|
input_mesh.indexData = p_indices;
|
||||||
input_mesh.indexCount = p_index_count;
|
input_mesh.indexCount = p_index_count;
|
||||||
input_mesh.indexFormat = xatlas::IndexFormat::Float; //really xatlas?
|
input_mesh.indexFormat = xatlas::IndexFormat::UInt32;
|
||||||
input_mesh.faceMaterialData = (uint16_t *)malloc(sizeof(uint16_t) * p_index_count);
|
|
||||||
|
|
||||||
for (int i = 0; i < p_index_count; i++) {
|
|
||||||
int *index = (int *)input_mesh.indexData;
|
|
||||||
index[i] = p_indices[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < p_index_count / 3; i++) {
|
|
||||||
uint16_t *mat_index = (uint16_t *)input_mesh.faceMaterialData;
|
|
||||||
mat_index[i] = p_face_materials[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
input_mesh.vertexCount = p_vertex_count;
|
input_mesh.vertexCount = p_vertex_count;
|
||||||
input_mesh.vertexPositionData = malloc(sizeof(float) * p_vertex_count * 3);
|
input_mesh.vertexPositionData = p_vertices;
|
||||||
input_mesh.vertexPositionStride = sizeof(float) * 3;
|
input_mesh.vertexPositionStride = sizeof(float) * 3;
|
||||||
input_mesh.vertexNormalData = malloc(sizeof(float) * p_vertex_count * 3);
|
input_mesh.vertexNormalData = p_normals;
|
||||||
input_mesh.vertexNormalStride = sizeof(float) * 3;
|
input_mesh.vertexNormalStride = sizeof(uint32_t) * 3;
|
||||||
|
|
||||||
//material is a better hint than this i guess?
|
|
||||||
input_mesh.vertexUvData = NULL;
|
input_mesh.vertexUvData = NULL;
|
||||||
input_mesh.vertexUvStride = 0;
|
input_mesh.vertexUvStride = 0;
|
||||||
|
|
||||||
for (int i = 0; i < p_vertex_count * 3; i++) {
|
xatlas::ChartOptions chart_options;
|
||||||
float *vertex_ptr = (float *)input_mesh.vertexPositionData;
|
xatlas::PackOptions pack_options;
|
||||||
float *normal_ptr = (float *)input_mesh.vertexNormalData;
|
|
||||||
|
|
||||||
vertex_ptr[i] = p_vertices[i];
|
pack_options.maxChartSize = 4096;
|
||||||
normal_ptr[i] = p_normals[i];
|
pack_options.bruteForce = true;
|
||||||
}
|
pack_options.texelsPerUnit = 1.0 / p_texel_size;
|
||||||
|
|
||||||
xatlas::CharterOptions chart_options;
|
|
||||||
xatlas::PackerOptions pack_options;
|
|
||||||
|
|
||||||
pack_options.method = xatlas::PackMethod::TexelArea;
|
|
||||||
pack_options.texelArea = 1.0 / p_texel_size;
|
|
||||||
pack_options.quality = 3;
|
|
||||||
|
|
||||||
xatlas::Atlas *atlas = xatlas::Create();
|
xatlas::Atlas *atlas = xatlas::Create();
|
||||||
printf("adding mesh..\n");
|
printf("Adding mesh..\n");
|
||||||
xatlas::AddMeshError err = xatlas::AddMesh(atlas, input_mesh);
|
xatlas::AddMeshError::Enum err = xatlas::AddMesh(atlas, input_mesh, 1);
|
||||||
ERR_EXPLAINC(xatlas::StringForEnum(err.code));
|
ERR_EXPLAINC(xatlas::StringForEnum(err));
|
||||||
ERR_FAIL_COND_V(err.code != xatlas::AddMeshErrorCode::Success, false);
|
ERR_FAIL_COND_V(err != xatlas::AddMeshError::Enum::Success, false);
|
||||||
|
|
||||||
printf("generate..\n");
|
printf("Generate..\n");
|
||||||
xatlas::Generate(atlas, chart_options, pack_options);
|
xatlas::Generate(atlas, chart_options, NULL, pack_options);
|
||||||
|
|
||||||
*r_size_hint_x = xatlas::GetWidth(atlas);
|
*r_size_hint_x = atlas->width;
|
||||||
*r_size_hint_y = xatlas::GetHeight(atlas);
|
*r_size_hint_y = atlas->height;
|
||||||
|
|
||||||
float w = *r_size_hint_x;
|
float w = *r_size_hint_x;
|
||||||
float h = *r_size_hint_y;
|
float h = *r_size_hint_y;
|
||||||
|
|
@ -98,39 +78,33 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
|
||||||
return false; //could not bake
|
return false; //could not bake
|
||||||
}
|
}
|
||||||
|
|
||||||
const xatlas::OutputMesh *const *output_meshes = xatlas::GetOutputMeshes(atlas);
|
const xatlas::Mesh &output = atlas->meshes[0];
|
||||||
|
|
||||||
const xatlas::OutputMesh *output = output_meshes[0];
|
*r_vertex = (int *)malloc(sizeof(int) * output.vertexCount);
|
||||||
|
*r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2);
|
||||||
*r_vertex = (int *)malloc(sizeof(int) * output->vertexCount);
|
*r_index = (int *)malloc(sizeof(int) * output.indexCount);
|
||||||
*r_uv = (float *)malloc(sizeof(float) * output->vertexCount * 2);
|
|
||||||
*r_index = (int *)malloc(sizeof(int) * output->indexCount);
|
|
||||||
|
|
||||||
float max_x = 0;
|
float max_x = 0;
|
||||||
float max_y = 0;
|
float max_y = 0;
|
||||||
for (uint32_t i = 0; i < output->vertexCount; i++) {
|
for (uint32_t i = 0; i < output.vertexCount; i++) {
|
||||||
(*r_vertex)[i] = output->vertexArray[i].xref;
|
(*r_vertex)[i] = output.vertexArray[i].xref;
|
||||||
(*r_uv)[i * 2 + 0] = output->vertexArray[i].uv[0] / w;
|
(*r_uv)[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
|
||||||
(*r_uv)[i * 2 + 1] = output->vertexArray[i].uv[1] / h;
|
(*r_uv)[i * 2 + 1] = output.vertexArray[i].uv[1] / h;
|
||||||
max_x = MAX(max_x, output->vertexArray[i].uv[0]);
|
max_x = MAX(max_x, output.vertexArray[i].uv[0]);
|
||||||
max_y = MAX(max_y, output->vertexArray[i].uv[1]);
|
max_y = MAX(max_y, output.vertexArray[i].uv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("final texsize: %f,%f - max %f,%f\n", w, h, max_x, max_y);
|
printf("Final texture size: %f,%f - max %f,%f\n", w, h, max_x, max_y);
|
||||||
*r_vertex_count = output->vertexCount;
|
*r_vertex_count = output.vertexCount;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < output->indexCount; i++) {
|
for (uint32_t i = 0; i < output.indexCount; i++) {
|
||||||
(*r_index)[i] = output->indexArray[i];
|
(*r_index)[i] = output.indexArray[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_index_count = output->indexCount;
|
*r_index_count = output.indexCount;
|
||||||
|
|
||||||
//xatlas::Destroy(atlas);
|
//xatlas::Destroy(atlas);
|
||||||
free((void *)input_mesh.indexData);
|
printf("Done\n");
|
||||||
free((void *)input_mesh.vertexPositionData);
|
|
||||||
free((void *)input_mesh.vertexNormalData);
|
|
||||||
free((void *)input_mesh.faceMaterialData);
|
|
||||||
printf("done");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
|
|
@ -511,7 +511,7 @@ folder.
|
||||||
## xatlas
|
## xatlas
|
||||||
|
|
||||||
- Upstream: https://github.com/jpcy/xatlas
|
- Upstream: https://github.com/jpcy/xatlas
|
||||||
- Version: git (b8ec29b, 2018)
|
- Version: git (b7d7bb, 2019)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
|
||||||
11367
thirdparty/xatlas/xatlas.cpp
vendored
11367
thirdparty/xatlas/xatlas.cpp
vendored
File diff suppressed because it is too large
Load diff
342
thirdparty/xatlas/xatlas.h
vendored
342
thirdparty/xatlas/xatlas.h
vendored
|
|
@ -1,176 +1,254 @@
|
||||||
// This code is in the public domain -- castanyo@yahoo.es
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018-2019 Jonathan Young
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
thekla_atlas
|
||||||
|
MIT License
|
||||||
|
https://github.com/Thekla/thekla_atlas
|
||||||
|
Copyright (c) 2013 Thekla, Inc
|
||||||
|
Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com>
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef XATLAS_H
|
#ifndef XATLAS_H
|
||||||
#define XATLAS_H
|
#define XATLAS_H
|
||||||
#include <float.h> // FLT_MAX
|
#include <stdint.h>
|
||||||
// -- GODOT start --
|
|
||||||
#include <limits.h> // INT_MAX, UINT_MAX
|
|
||||||
// -- GODOT end --
|
|
||||||
|
|
||||||
namespace xatlas {
|
namespace xatlas {
|
||||||
|
|
||||||
typedef void (*PrintFunc)(const char *, ...);
|
struct ChartFlags
|
||||||
|
|
||||||
struct Atlas;
|
|
||||||
|
|
||||||
struct CharterOptions
|
|
||||||
{
|
{
|
||||||
float proxyFitMetricWeight;
|
enum
|
||||||
float roundnessMetricWeight;
|
|
||||||
float straightnessMetricWeight;
|
|
||||||
float normalSeamMetricWeight;
|
|
||||||
float textureSeamMetricWeight;
|
|
||||||
float maxChartArea;
|
|
||||||
float maxBoundaryLength;
|
|
||||||
|
|
||||||
CharterOptions()
|
|
||||||
{
|
{
|
||||||
// These are the default values we use on The Witness.
|
Invalid = 1 << 0
|
||||||
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
|
// A group of connected faces, belonging to a single atlas.
|
||||||
|
struct Chart
|
||||||
{
|
{
|
||||||
PackMethod::Enum method;
|
uint32_t atlasIndex; // Sub-atlas index.
|
||||||
|
uint32_t flags;
|
||||||
// 0 - brute force
|
uint32_t *indexArray;
|
||||||
// 1 - 4096 attempts
|
uint32_t indexCount;
|
||||||
// 2 - 2048
|
uint32_t material;
|
||||||
// 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
|
// Output vertex.
|
||||||
|
struct Vertex
|
||||||
{
|
{
|
||||||
enum Enum
|
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.
|
||||||
Success,
|
float uv[2]; // Not normalized - values are in Atlas width and height range.
|
||||||
AlreadyAddedEdge, // index0 and index1 are the edge indices
|
uint32_t xref; // Index of input vertex from which this output vertex originated.
|
||||||
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
|
// Output mesh.
|
||||||
|
struct Mesh
|
||||||
{
|
{
|
||||||
AddMeshErrorCode::Enum code;
|
Chart *chartArray;
|
||||||
uint32_t face;
|
uint32_t chartCount;
|
||||||
uint32_t index0, index1;
|
uint32_t *indexArray;
|
||||||
|
uint32_t indexCount;
|
||||||
|
Vertex *vertexArray;
|
||||||
|
uint32_t vertexCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint32_t kImageChartIndexMask = 0x3FFFFFFF;
|
||||||
|
static const uint32_t kImageHasChartIndexBit = 0x40000000;
|
||||||
|
static const uint32_t kImageIsPaddingBit = 0x80000000;
|
||||||
|
|
||||||
|
// Empty on creation. Populated after charts are packed.
|
||||||
|
struct Atlas
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution.
|
||||||
|
uint32_t *image;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an empty atlas.
|
||||||
|
Atlas *Create();
|
||||||
|
|
||||||
|
void Destroy(Atlas *atlas);
|
||||||
|
|
||||||
struct IndexFormat
|
struct IndexFormat
|
||||||
{
|
{
|
||||||
enum Enum
|
enum Enum
|
||||||
{
|
{
|
||||||
HalfFloat,
|
UInt16,
|
||||||
Float
|
UInt32
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputMesh
|
// Input mesh declaration.
|
||||||
|
struct MeshDecl
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount = 0;
|
||||||
const void *vertexPositionData;
|
const void *vertexPositionData = nullptr;
|
||||||
uint32_t vertexPositionStride;
|
uint32_t vertexPositionStride = 0;
|
||||||
const void *vertexNormalData; // optional
|
const void *vertexNormalData = nullptr; // optional
|
||||||
uint32_t vertexNormalStride; // optional
|
uint32_t vertexNormalStride = 0; // optional
|
||||||
|
const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator.
|
||||||
|
uint32_t vertexUvStride = 0; // optional
|
||||||
|
uint32_t indexCount = 0;
|
||||||
|
const void *indexData = nullptr; // optional
|
||||||
|
int32_t indexOffset = 0; // optional. Add this offset to all indices.
|
||||||
|
IndexFormat::Enum indexFormat = IndexFormat::UInt16;
|
||||||
|
|
||||||
// optional
|
// Optional. indexCount / 3 (triangle count) in length.
|
||||||
// The input UVs are provided as a hint to the chart generator.
|
// 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 void *vertexUvData;
|
const bool *faceIgnoreData = nullptr;
|
||||||
uint32_t vertexUvStride;
|
|
||||||
|
|
||||||
uint32_t indexCount;
|
// Vertex positions within epsilon distance of each other are considered colocal.
|
||||||
const void *indexData;
|
float epsilon = 1.192092896e-07F;
|
||||||
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
|
struct AddMeshError
|
||||||
{
|
{
|
||||||
uint32_t *indexArray;
|
enum Enum
|
||||||
uint32_t indexCount;
|
{
|
||||||
|
Success, // No error.
|
||||||
|
Error, // Unspecified error.
|
||||||
|
IndexOutOfRange, // An index is >= MeshDecl vertexCount.
|
||||||
|
InvalidIndexCount // Not evenly divisible by 3 - expecting triangles.
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutputVertex
|
// 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);
|
||||||
|
|
||||||
|
// Wait for AddMesh async processing to finish. ComputeCharts / Generate call this internally.
|
||||||
|
void AddMeshJoin(Atlas *atlas);
|
||||||
|
|
||||||
|
struct UvMeshDecl
|
||||||
{
|
{
|
||||||
float uv[2];
|
uint32_t vertexCount = 0;
|
||||||
uint32_t xref; // Index of input vertex from which this output vertex originated.
|
uint32_t vertexStride = 0;
|
||||||
|
const void *vertexUvData = nullptr;
|
||||||
|
uint32_t indexCount = 0;
|
||||||
|
const void *indexData = nullptr; // optional
|
||||||
|
int32_t indexOffset = 0; // optional. Add this offset to all indices.
|
||||||
|
IndexFormat::Enum indexFormat = IndexFormat::UInt16;
|
||||||
|
const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length.
|
||||||
|
bool rotateCharts = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutputMesh
|
AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl);
|
||||||
|
|
||||||
|
struct ChartOptions
|
||||||
{
|
{
|
||||||
OutputChart *chartArray;
|
float maxChartArea = 0.0f; // Don't grow charts to be larger than this. 0 means no limit.
|
||||||
uint32_t chartCount;
|
float maxBoundaryLength = 0.0f; // Don't grow charts to have a longer boundary than this. 0 means no limit.
|
||||||
uint32_t *indexArray;
|
|
||||||
uint32_t indexCount;
|
// Weights determine chart growth. Higher weights mean higher cost for that metric.
|
||||||
OutputVertex *vertexArray;
|
float proxyFitMetricWeight = 2.0f; // Angle between face and average chart normal.
|
||||||
uint32_t vertexCount;
|
float roundnessMetricWeight = 0.01f;
|
||||||
|
float straightnessMetricWeight = 6.0f;
|
||||||
|
float normalSeamMetricWeight = 4.0f; // If > 1000, normal seams are fully respected.
|
||||||
|
float textureSeamMetricWeight = 0.5f;
|
||||||
|
|
||||||
|
float maxThreshold = 2.0f; // If total of all metrics * weights > maxThreshold, don't grow chart. Lower values result in more charts.
|
||||||
|
uint32_t growFaceCount = 32; // Grow this many faces at a time.
|
||||||
|
uint32_t maxIterations = 1; // Number of iterations of the chart growing and seeding phases. Higher values result in better charts.
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetPrint(PrintFunc print);
|
// Call after all AddMesh calls. Can be called multiple times to recompute charts with different options.
|
||||||
Atlas *Create();
|
void ComputeCharts(Atlas *atlas, ChartOptions chartOptions = ChartOptions());
|
||||||
void Destroy(Atlas *atlas);
|
|
||||||
// useColocalVertices - generates fewer charts (good), but is more sensitive to bad geometry.
|
// Custom parameterization function. texcoords initial values are an orthogonal parameterization.
|
||||||
AddMeshError AddMesh(Atlas *atlas, const InputMesh &mesh, bool useColocalVertices = true);
|
typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount);
|
||||||
void Generate(Atlas *atlas, CharterOptions charterOptions = CharterOptions(), PackerOptions packerOptions = PackerOptions());
|
|
||||||
uint32_t GetWidth(const Atlas *atlas);
|
// Call after ComputeCharts. Can be called multiple times to re-parameterize charts with a different ParameterizeFunc.
|
||||||
uint32_t GetHeight(const Atlas *atlas);
|
void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func = nullptr);
|
||||||
uint32_t GetNumCharts(const Atlas *atlas);
|
|
||||||
const OutputMesh * const *GetOutputMeshes(const Atlas *atlas);
|
struct PackOptions
|
||||||
const char *StringForEnum(AddMeshErrorCode::Enum error);
|
{
|
||||||
|
// Slower, but gives the best result. If false, use random chart placement.
|
||||||
|
bool bruteForce = false;
|
||||||
|
|
||||||
|
// Create Atlas::image
|
||||||
|
bool createImage = false;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Charts larger than this will be scaled down.
|
||||||
|
uint32_t maxChartSize = 1024;
|
||||||
|
|
||||||
|
// Align charts to 4x4 blocks. Also improves packing speed, since there are fewer possible chart locations to consider.
|
||||||
|
bool blockAlign = false;
|
||||||
|
|
||||||
|
// Number of pixels to pad charts with.
|
||||||
|
uint32_t padding = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call after ParameterizeCharts. 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(), ParameterizeFunc paramFunc = nullptr, PackOptions packOptions = PackOptions());
|
||||||
|
|
||||||
|
// Progress tracking.
|
||||||
|
struct ProgressCategory
|
||||||
|
{
|
||||||
|
enum Enum
|
||||||
|
{
|
||||||
|
AddMesh,
|
||||||
|
ComputeCharts,
|
||||||
|
ParameterizeCharts,
|
||||||
|
PackCharts,
|
||||||
|
BuildOutputMeshes
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// May be called from any thread. Return false to cancel.
|
||||||
|
typedef bool (*ProgressFunc)(ProgressCategory::Enum category, int progress, void *userData);
|
||||||
|
|
||||||
|
void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc = nullptr, void *progressUserData = nullptr);
|
||||||
|
|
||||||
|
// Custom memory allocation.
|
||||||
|
typedef void *(*ReallocFunc)(void *, size_t);
|
||||||
|
void SetRealloc(ReallocFunc reallocFunc);
|
||||||
|
|
||||||
|
// Custom print function.
|
||||||
|
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);
|
||||||
|
|
||||||
} // namespace xatlas
|
} // namespace xatlas
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue