diff --git a/src/liborng/nodes/mesh_editing_library.cpp b/src/liborng/nodes/mesh_editing_library.cpp index 1108482..3084868 100644 --- a/src/liborng/nodes/mesh_editing_library.cpp +++ b/src/liborng/nodes/mesh_editing_library.cpp @@ -12,6 +12,7 @@ #include #include "godot_cpp/classes/immediate_mesh.hpp" +#include "godot_cpp/classes/surface_tool.hpp" #include "godot_cpp/classes/time.hpp" #include "godot_cpp/variant/utility_functions.hpp" using namespace godot; @@ -62,18 +63,6 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_ std::vector first_half_indices; first_half_indices.resize(num_surfaces); std::vector other_half_indices; other_half_indices.resize(num_surfaces); - PackedVector3Array cap_section_vertices; - PackedVector3Array cap_section_normals; - PackedVector3Array cap_section_flipped_normals; - PackedFloat32Array cap_section_tangents; - PackedFloat32Array cap_section_flipped_tangents; - PackedVector2Array cap_section_uvs; - PackedVector2Array cap_section_uv2s; - PackedColorArray cap_section_colours; - PackedInt32Array cap_section_bones; - PackedFloat32Array cap_section_weights; - PackedInt32Array cap_section_indices; - std::vector> skinned_vertex_transforms; std::vector clip_edges; @@ -484,20 +473,26 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_ PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Surface ", surface, " split edges at ", time->get_ticks_msec(), "ms"); } - MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z; - const Basis &mesh_instance_basis = original_mesh_instance->get_basis(); - const Vector3 &local_plane_normal = local_plane.get_normal(); - if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(0.0f, 1.0f, 0.0f)))) > 0.5f) - { - uv_plane = MeshSlicePlaneOrientation::Y; - } - else if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(1.0f, 0.0f, 0.0f)))) > 0.5f) - { - uv_plane = MeshSlicePlaneOrientation::X; - } if (clip_edges.size() > 0) { + MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z; + const Basis &mesh_instance_basis = original_mesh_instance->get_basis(); + const Vector3 &local_plane_normal = local_plane.get_normal(); + if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(0.0f, 1.0f, 0.0f)))) > 0.5f) + { + uv_plane = MeshSlicePlaneOrientation::Y; + } + else if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(1.0f, 0.0f, 0.0f)))) > 0.5f) + { + uv_plane = MeshSlicePlaneOrientation::X; + } + + SurfaceTool *surface_tool_first_half = memnew(SurfaceTool); + SurfaceTool *surface_tool_other_half = memnew(SurfaceTool); + surface_tool_first_half->begin(Mesh::PRIMITIVE_TRIANGLES); + surface_tool_other_half->begin(Mesh::PRIMITIVE_TRIANGLES); + std::vector edges_2d; std::vector polygon_set; std::vector error_polygons; @@ -507,6 +502,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_ const Vector3 &mesh_bounds = original_aabb.get_size(); const uint32_t num_polygons = polygon_set.size(); + uint32_t polygon_vertex_base = 0; for (uint32_t polygon_index = 0; polygon_index < num_polygons; polygon_index++) { using Point = std::array; @@ -517,48 +513,54 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_ Vector3 polygon_centroid; - const uint32_t polygon_vertex_base = cap_section_vertices.size(); + uint32_t polygon_vertex_counter = 0; for (const MeshEditVert2D &vertex : polygon_set[polygon_index].vertices) { const Vector3 &position = first_half_vertices[vertex.surface][vertex.index]; const Transform3D &skinned_vertex_transform = skinned_vertex_transforms[vertex.surface][vertex.index]; - const Vector3 &local_plane_transformed_normal = skinned_vertex_transform.xform(local_plane_normal).normalized(); - cap_section_vertices.append(position); - if (surface_has_normal[vertex.surface]) + const Vector2 &uv = MeshEditingLibrary::calculate_planar_uv(position, mesh_bounds, uv_plane); + surface_tool_first_half->set_uv(uv); + surface_tool_other_half->set_uv(uv); + if (surface_has_uv2[vertex.surface]) { - cap_section_normals.append(local_plane_transformed_normal); - cap_section_flipped_normals.append(local_plane_transformed_normal * -1.0f); + surface_tool_first_half->set_uv2(uv); + surface_tool_other_half->set_uv2(uv); } - if (surface_has_colour[vertex.surface]) { cap_section_colours.append(first_half_colours[vertex.surface][vertex.index]); } - if (surface_has_uv[vertex.surface]) { cap_section_uvs.append(MeshEditingLibrary::calculate_planar_uv(position, mesh_bounds, uv_plane)); } - if (surface_has_uv2[vertex.surface]) { cap_section_uv2s.append(first_half_uv2s[vertex.surface][vertex.index]); } - if (surface_has_tangent[vertex.surface]) + + if (surface_has_colour[vertex.surface]) { - for (uint8_t i = 0; i < 4; i++) + const Color &colour = first_half_colours[vertex.surface][vertex.index]; + surface_tool_first_half->set_color(colour); + surface_tool_other_half->set_color(colour); + } + + if (surface_has_bone[vertex.surface] && surface_has_weight[vertex.surface]) + { + PackedInt32Array bones; bones.resize(4); + PackedFloat32Array weights; weights.resize(4); + + for (uint8_t i = 0; i < surface_num_bones_per_vertex[vertex.surface] && i < 4; i++) { - cap_section_tangents.append(first_half_tangents[vertex.surface][(vertex.index * 4) + i] * -1.0f); - cap_section_flipped_tangents.append(first_half_tangents[vertex.surface][(vertex.index * 4) + i]); - } - } - if (surface_has_bone[vertex.surface]) - { - for (uint8_t i = 0; i < surface_num_bones_per_vertex[vertex.surface]; i++) - { - cap_section_bones.append(first_half_bones[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i]); - } - } - if (surface_has_weight[vertex.surface]) - { - for (uint8_t i = 0; i < surface_num_bones_per_vertex[vertex.surface]; i++) - { - cap_section_weights.append(first_half_weights[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i]); + bones[i] = first_half_bones[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i]; + weights[i] = first_half_weights[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i]; } + + surface_tool_first_half->set_bones(bones); + surface_tool_first_half->set_weights(weights); + + surface_tool_other_half->set_bones(bones); + surface_tool_other_half->set_weights(weights); } + surface_tool_first_half->add_vertex(position); + surface_tool_other_half->add_vertex(position); + sub_polygon.push_back({vertex.position.x, vertex.position.y}); polygon_centroid += position; + + polygon_vertex_counter++; } polygon_centroid /= polygon_set[polygon_index].vertices.size(); @@ -568,56 +570,39 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_ std::vector indices = mapbox::earcut(earcut_polygon); for (uint32_t i = 0; (i+2) < indices.size(); i += 3) { - cap_section_indices.append(indices[i+1] + polygon_vertex_base); - cap_section_indices.append(indices[i] + polygon_vertex_base); - cap_section_indices.append(indices[i+2] + polygon_vertex_base); + const uint32_t index1 = indices[i+1] + polygon_vertex_base; + const uint32_t index2 = indices[i] + polygon_vertex_base; + const uint32_t index3 = indices[i+2] + polygon_vertex_base; + + surface_tool_first_half->add_index(index1); + surface_tool_first_half->add_index(index2); + surface_tool_first_half->add_index(index3); + + surface_tool_other_half->add_index(index1); + surface_tool_other_half->add_index(index3); + surface_tool_other_half->add_index(index2); } + + polygon_vertex_base += polygon_vertex_counter; } - } - - PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms"); - - if (cap_section_vertices.size() > 0 && cap_section_indices.size() > 0) - { - Array cap_mesh_section; - cap_mesh_section.resize(ArrayMesh::ARRAY_MAX); - cap_mesh_section[ArrayMesh::ARRAY_VERTEX] = cap_section_vertices; - cap_mesh_section[ArrayMesh::ARRAY_INDEX] = cap_section_indices; - if (cap_section_normals.size()) cap_mesh_section[ArrayMesh::ARRAY_NORMAL] = cap_section_normals; - // if (cap_section_tangents.size()) cap_mesh_section[ArrayMesh::ARRAY_TANGENT] = cap_section_tangents; - if (cap_section_colours.size()) cap_mesh_section[ArrayMesh::ARRAY_COLOR] = cap_section_colours; - if (cap_section_uvs.size()) cap_mesh_section[ArrayMesh::ARRAY_TEX_UV] = cap_section_uvs; - if (cap_section_uv2s.size()) cap_mesh_section[ArrayMesh::ARRAY_TEX_UV2] = cap_section_uv2s; - if (cap_section_bones.size()) cap_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones; - if (cap_section_weights.size()) cap_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights; - out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_mesh_section); + + surface_tool_first_half->generate_normals(); + surface_tool_other_half->generate_normals(); + + // surface_tool_first_half->generate_tangents(); + // surface_tool_other_half->generate_tangents(); + + out_first_half = surface_tool_first_half->commit(out_first_half); + out_other_half = surface_tool_other_half->commit(out_other_half); + out_first_half->surface_set_material(out_first_half->get_surface_count()-1, cap_materials[uv_plane]); - - const uint32_t num_cap_triangles = cap_section_indices.size(); - for (uint32_t i = 0; i < num_cap_triangles; i += 3) - { - const int32_t old_index = cap_section_indices[i]; - cap_section_indices[i] = cap_section_indices[i+1]; - cap_section_indices[i+1] = old_index; - } - - Array cap_other_mesh_section; - cap_other_mesh_section.resize(ArrayMesh::ARRAY_MAX); - cap_other_mesh_section[ArrayMesh::ARRAY_VERTEX] = cap_section_vertices; - cap_other_mesh_section[ArrayMesh::ARRAY_INDEX] = cap_section_indices; - if (cap_section_normals.size()) cap_other_mesh_section[ArrayMesh::ARRAY_NORMAL] = cap_section_flipped_normals; - // if (cap_section_tangents.size()) cap_other_mesh_section[ArrayMesh::ARRAY_TANGENT] = cap_section_flipped_tangents; - if (cap_section_colours.size()) cap_other_mesh_section[ArrayMesh::ARRAY_COLOR] = cap_section_colours; - if (cap_section_uvs.size()) cap_other_mesh_section[ArrayMesh::ARRAY_TEX_UV] = cap_section_uvs; - if (cap_section_uv2s.size()) cap_other_mesh_section[ArrayMesh::ARRAY_TEX_UV2] = cap_section_uv2s; - if (cap_section_bones.size()) cap_other_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones; - if (cap_section_weights.size()) cap_other_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights; - out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_other_mesh_section); out_other_half->surface_set_material(out_other_half->get_surface_count()-1, cap_materials[uv_plane]); - PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Generated final cap surface at ", time->get_ticks_msec(), "ms"); + PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms"); } + PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Generated final cap surface at ", time->get_ticks_msec(), "ms"); + return impact_points; }