Initial seam storage and uv unwrapping setup.

This commit is contained in:
Relintai 2021-09-13 14:06:47 +02:00
parent 4830687056
commit aace67c49c
3 changed files with 108 additions and 1 deletions

3
SCsub
View File

@ -13,6 +13,9 @@ if os.path.isdir('../props'):
if os.path.isdir('../mesh_utils'):
module_env.Append(CPPDEFINES=['MESH_UTILS_PRESENT'])
if env["module_xatlas_unwrap_enabled"]:
module_env.Append(CPPDEFINES=['XATLAS_PRESENT'])
module_env.add_source_files(env.modules_sources,"register_types.cpp")
module_env.add_source_files(env.modules_sources,"mesh_data_resource.cpp")

View File

@ -24,6 +24,10 @@ SOFTWARE.
#include "core/version.h"
#ifdef XATLAS_PRESENT
#include "thirdparty/xatlas/xatlas.h"
#endif
#if VERSION_MAJOR >= 4
#define PoolVector Vector
#endif
@ -98,6 +102,14 @@ void MeshDataResource::set_collision_shapes(const Vector<Variant> &p_arrays) {
}
}
PoolIntArray MeshDataResource::get_seams() {
return _seams;
}
void MeshDataResource::set_seams(const PoolIntArray &array) {
_seams = array;
}
void MeshDataResource::recompute_aabb() {
if (_arrays.size() == 0) {
return;
@ -106,7 +118,7 @@ void MeshDataResource::recompute_aabb() {
Variant arr = _arrays[Mesh::ARRAY_VERTEX];
PoolVector<Vector3> vertices = arr;
int len = vertices.size();
if (len == 0) {
return;
}
@ -129,6 +141,86 @@ void MeshDataResource::recompute_aabb() {
_aabb = aabb;
}
bool MeshDataResource::uv_unwrap() {
#ifdef XATLAS_PRESENT
// set up input mesh
//xatlas::MeshDecl input_mesh;
/*
input_mesh.indexData = p_indices;
input_mesh.indexCount = p_index_count;
input_mesh.indexFormat = xatlas::IndexFormat::UInt32;
input_mesh.vertexCount = p_vertex_count;
input_mesh.vertexPositionData = p_vertices;
input_mesh.vertexPositionStride = sizeof(float) * 3;
input_mesh.vertexNormalData = p_normals;
input_mesh.vertexNormalStride = sizeof(uint32_t) * 3;
input_mesh.vertexUvData = nullptr;
input_mesh.vertexUvStride = 0;
xatlas::ChartOptions chart_options;
chart_options.fixWinding = true;
xatlas::PackOptions pack_options;
pack_options.padding = 1;
pack_options.maxChartSize = 4094; // Lightmap atlassing needs 2 for padding between meshes, so 4096-2
pack_options.blockAlign = true;
pack_options.texelsPerUnit = 1.0 / p_texel_size;
xatlas::Atlas *atlas = xatlas::Create();
xatlas::AddMeshError err = xatlas::AddMesh(atlas, input_mesh, 1);
ERR_FAIL_COND_V_MSG(err != xatlas::AddMeshError::Success, false, xatlas::StringForEnum(err));
xatlas::Generate(atlas, chart_options, pack_options);
*r_size_hint_x = atlas->width;
*r_size_hint_y = atlas->height;
float w = *r_size_hint_x;
float h = *r_size_hint_y;
if (w == 0 || h == 0) {
xatlas::Destroy(atlas);
return false; //could not bake because there is no area
}
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.");
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;
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;
for (uint32_t i = 0; i < output.indexCount; i++) {
(*r_index)[i] = output.indexArray[i];
}
*r_index_count = output.indexCount;
*/
//xatlas::Destroy(atlas);
return true;
#else
return false;
#endif
}
MeshDataResource::MeshDataResource() {
}
@ -150,9 +242,14 @@ void MeshDataResource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_shapes", "array"), &MeshDataResource::set_collision_shapes);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "collision_shapes"), "set_collision_shapes", "get_collision_shapes");
ClassDB::bind_method(D_METHOD("get_seams"), &MeshDataResource::get_seams);
ClassDB::bind_method(D_METHOD("set_seams", "array"), &MeshDataResource::set_seams);
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "seams"), "set_seams", "get_seams");
ClassDB::bind_method(D_METHOD("add_collision_shape", "shape"), &MeshDataResource::add_collision_shape);
ClassDB::bind_method(D_METHOD("get_collision_shape", "index"), &MeshDataResource::get_collision_shape);
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);
}

View File

@ -24,6 +24,7 @@ SOFTWARE.
#define MESH_DATA_REOURCE_H
#include "core/version.h"
#include "core/variant.h"
#if VERSION_MAJOR > 3
#include "core/io/resource.h"
@ -78,8 +79,13 @@ public:
Vector<Variant> get_collision_shapes();
void set_collision_shapes(const Vector<Variant> &p_arrays);
PoolIntArray get_seams();
void set_seams(const PoolIntArray &array);
void recompute_aabb();
bool uv_unwrap();
MeshDataResource();
~MeshDataResource();
@ -96,6 +102,7 @@ private:
Array _arrays;
AABB _aabb;
Vector<MDRData> _collision_shapes;
PoolIntArray _seams;
};
VARIANT_ENUM_CAST(MeshDataResource::ColliderType);