mirror of
https://github.com/Relintai/mesh_data_resource.git
synced 2024-11-14 10:17:26 +01:00
Work on uv unwrapping.
This commit is contained in:
parent
aace67c49c
commit
e031ed36b5
@ -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);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
|
||||
void recompute_aabb();
|
||||
|
||||
bool uv_unwrap();
|
||||
bool uv_unwrap(float p_texel_size = 0.1);
|
||||
|
||||
MeshDataResource();
|
||||
~MeshDataResource();
|
||||
|
Loading…
Reference in New Issue
Block a user