Work on uv unwrapping.

This commit is contained in:
Relintai 2021-09-13 18:45:20 +02:00
parent aace67c49c
commit e031ed36b5
2 changed files with 132 additions and 29 deletions

View File

@ -22,9 +22,12 @@ SOFTWARE.
#include "mesh_data_resource.h"
#include "core/variant.h"
#include "core/version.h"
#ifdef XATLAS_PRESENT
#include "scene/resources/surface_tool.h"
#include "core/local_vector.h"
#include "thirdparty/xatlas/xatlas.h"
#endif
@ -141,20 +144,61 @@ void MeshDataResource::recompute_aabb() {
_aabb = aabb;
}
bool MeshDataResource::uv_unwrap() {
#ifdef XATLAS_PRESENT
// set up input mesh
//xatlas::MeshDecl input_mesh;
struct MeshDataResourceUnwrapSurface {
Vector<SurfaceTool::Vertex> vertices;
uint32_t format;
};
/*
input_mesh.indexData = p_indices;
input_mesh.indexCount = p_index_count;
bool MeshDataResource::uv_unwrap(float p_texel_size) {
if (_arrays.size() != ArrayMesh::ARRAY_MAX) {
return false;
}
PoolVector3Array pool_vertices = _arrays[Mesh::ARRAY_VERTEX];
if (pool_vertices.size() == 0) {
return false;
}
PoolVector3Array pool_normals = _arrays[Mesh::ARRAY_NORMAL];
ERR_FAIL_COND_V_MSG(pool_vertices.size() != pool_normals.size(), false, "Normals are required for lightmap unwrap.");
PoolIntArray pool_indices = _arrays[Mesh::ARRAY_INDEX];
MeshDataResourceUnwrapSurface mdrsurface;
mdrsurface.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(_arrays);
LocalVector<Vector3> vertices;
LocalVector<Vector3> normals;
LocalVector<int> indices;
vertices.resize(pool_vertices.size());
normals.resize(pool_normals.size());
for (int i = 0; i < pool_vertices.size(); ++i) {
vertices[i] = pool_vertices[i];
normals[i] = pool_normals[i];
}
indices.resize(pool_indices.size());
for (int i = 0; i < pool_indices.size(); ++i) {
indices[i] = pool_indices[i];
}
// set up input mesh
xatlas::MeshDecl input_mesh;
input_mesh.indexData = indices.ptr();
input_mesh.indexCount = indices.size();
input_mesh.indexFormat = xatlas::IndexFormat::UInt32;
input_mesh.vertexCount = p_vertex_count;
input_mesh.vertexPositionData = p_vertices;
input_mesh.vertexCount = vertices.size();
input_mesh.vertexPositionData = vertices.ptr();
input_mesh.vertexPositionStride = sizeof(float) * 3;
input_mesh.vertexNormalData = p_normals;
input_mesh.vertexNormalData = normals.ptr();
input_mesh.vertexNormalStride = sizeof(uint32_t) * 3;
input_mesh.vertexUvData = nullptr;
input_mesh.vertexUvStride = 0;
@ -175,11 +219,11 @@ bool MeshDataResource::uv_unwrap() {
xatlas::Generate(atlas, chart_options, pack_options);
*r_size_hint_x = atlas->width;
*r_size_hint_y = atlas->height;
int size_x = atlas->width;
int size_y = atlas->height;
float w = *r_size_hint_x;
float h = *r_size_hint_y;
float w = 1;
float h = 1;
if (w == 0 || h == 0) {
xatlas::Destroy(atlas);
@ -188,34 +232,93 @@ bool MeshDataResource::uv_unwrap() {
const xatlas::Mesh &output = atlas->meshes[0];
*r_vertex = (int *)malloc(sizeof(int) * output.vertexCount);
ERR_FAIL_NULL_V_MSG(*r_vertex, false, "Out of memory.");
*r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2);
ERR_FAIL_NULL_V_MSG(*r_uv, false, "Out of memory.");
*r_index = (int *)malloc(sizeof(int) * output.indexCount);
ERR_FAIL_NULL_V_MSG(*r_index, false, "Out of memory.");
int *r_vertex = (int *)malloc(sizeof(int) * output.vertexCount);
ERR_FAIL_NULL_V_MSG(r_vertex, false, "Out of memory.");
float *r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2);
ERR_FAIL_NULL_V_MSG(r_uv, false, "Out of memory.");
int *r_index = (int *)malloc(sizeof(int) * output.indexCount);
ERR_FAIL_NULL_V_MSG(r_index, false, "Out of memory.");
float max_x = 0;
float max_y = 0;
for (uint32_t i = 0; i < output.vertexCount; i++) {
(*r_vertex)[i] = output.vertexArray[i].xref;
(*r_uv)[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
(*r_uv)[i * 2 + 1] = output.vertexArray[i].uv[1] / h;
r_vertex[i] = output.vertexArray[i].xref;
r_uv[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
r_uv[i * 2 + 1] = output.vertexArray[i].uv[1] / h;
max_x = MAX(max_x, output.vertexArray[i].uv[0]);
max_y = MAX(max_y, output.vertexArray[i].uv[1]);
}
*r_vertex_count = output.vertexCount;
int r_vertex_count = output.vertexCount;
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;
int r_index_count = output.indexCount;
/*
print_verbose("Mesh: Gen indices: " + itos(gen_index_count));
//go through all indices
for (int i = 0; i < gen_index_count; i += 3) {
ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], (int)uv_indices.size(), ERR_BUG);
ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], (int)uv_indices.size(), ERR_BUG);
ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], (int)uv_indices.size(), ERR_BUG);
ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first;
for (int j = 0; j < 3; j++) {
SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) {
surfaces_tools[surface]->add_color(v.color);
}
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
surfaces_tools[surface]->add_uv(v.uv);
}
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
surfaces_tools[surface]->add_normal(v.normal);
}
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
Plane t;
t.normal = v.tangent;
t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
surfaces_tools[surface]->add_tangent(t);
}
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) {
surfaces_tools[surface]->add_bones(v.bones);
}
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
surfaces_tools[surface]->add_weights(v.weights);
}
Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
surfaces_tools[surface]->add_uv2(uv2);
surfaces_tools[surface]->add_vertex(v.vertex);
}
}
//generate surfaces
for (unsigned int i = 0; i < surfaces_tools.size(); i++) {
surfaces_tools[i]->index();
surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format);
}
*/
//xatlas::Destroy(atlas);
xatlas::Destroy(atlas);
::free(r_vertex);
::free(r_index);
::free(r_uv);
return true;
#ifdef XATLAS_PRESENT
#else
return false;
#endif
@ -251,5 +354,5 @@ void MeshDataResource::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collision_shape_count"), &MeshDataResource::get_collision_shape_count);
ClassDB::bind_method(D_METHOD("recompute_aabb"), &MeshDataResource::recompute_aabb);
ClassDB::bind_method(D_METHOD("uv_unwrap"), &MeshDataResource::uv_unwrap);
ClassDB::bind_method(D_METHOD("uv_unwrap", "texel_size"), &MeshDataResource::uv_unwrap, 0.1);
}

View File

@ -84,7 +84,7 @@ public:
void recompute_aabb();
bool uv_unwrap();
bool uv_unwrap(float p_texel_size = 0.1);
MeshDataResource();
~MeshDataResource();