Sliced mesh caps now generate proper normals, thanks to SurfaceTool.
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "godot_cpp/classes/immediate_mesh.hpp"
|
#include "godot_cpp/classes/immediate_mesh.hpp"
|
||||||
|
#include "godot_cpp/classes/surface_tool.hpp"
|
||||||
#include "godot_cpp/classes/time.hpp"
|
#include "godot_cpp/classes/time.hpp"
|
||||||
#include "godot_cpp/variant/utility_functions.hpp"
|
#include "godot_cpp/variant/utility_functions.hpp"
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
@@ -62,18 +63,6 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
std::vector<PackedInt32Array> first_half_indices; first_half_indices.resize(num_surfaces);
|
std::vector<PackedInt32Array> first_half_indices; first_half_indices.resize(num_surfaces);
|
||||||
std::vector<PackedInt32Array> other_half_indices; other_half_indices.resize(num_surfaces);
|
std::vector<PackedInt32Array> 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<std::vector<Transform3D>> skinned_vertex_transforms;
|
std::vector<std::vector<Transform3D>> skinned_vertex_transforms;
|
||||||
std::vector<MeshEditEdge3D> clip_edges;
|
std::vector<MeshEditEdge3D> 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");
|
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)
|
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<MeshEditEdge2D> edges_2d;
|
std::vector<MeshEditEdge2D> edges_2d;
|
||||||
std::vector<MeshEditPolygon2D> polygon_set;
|
std::vector<MeshEditPolygon2D> polygon_set;
|
||||||
std::vector<MeshEditPolygon2D> error_polygons;
|
std::vector<MeshEditPolygon2D> error_polygons;
|
||||||
@@ -507,6 +502,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
|
|
||||||
const Vector3 &mesh_bounds = original_aabb.get_size();
|
const Vector3 &mesh_bounds = original_aabb.get_size();
|
||||||
const uint32_t num_polygons = polygon_set.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++)
|
for (uint32_t polygon_index = 0; polygon_index < num_polygons; polygon_index++)
|
||||||
{
|
{
|
||||||
using Point = std::array<float,2>;
|
using Point = std::array<float,2>;
|
||||||
@@ -517,48 +513,54 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
|
|
||||||
Vector3 polygon_centroid;
|
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)
|
for (const MeshEditVert2D &vertex : polygon_set[polygon_index].vertices)
|
||||||
{
|
{
|
||||||
const Vector3 &position = first_half_vertices[vertex.surface][vertex.index];
|
const Vector3 &position = first_half_vertices[vertex.surface][vertex.index];
|
||||||
|
|
||||||
const Transform3D &skinned_vertex_transform = skinned_vertex_transforms[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);
|
const Vector2 &uv = MeshEditingLibrary::calculate_planar_uv(position, mesh_bounds, uv_plane);
|
||||||
if (surface_has_normal[vertex.surface])
|
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);
|
surface_tool_first_half->set_uv2(uv);
|
||||||
cap_section_flipped_normals.append(local_plane_transformed_normal * -1.0f);
|
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_colour[vertex.surface])
|
||||||
if (surface_has_uv2[vertex.surface]) { cap_section_uv2s.append(first_half_uv2s[vertex.surface][vertex.index]); }
|
|
||||||
if (surface_has_tangent[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);
|
bones[i] = first_half_bones[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i];
|
||||||
cap_section_flipped_tangents.append(first_half_tangents[vertex.surface][(vertex.index * 4) + i]);
|
weights[i] = first_half_weights[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + 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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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});
|
sub_polygon.push_back({vertex.position.x, vertex.position.y});
|
||||||
polygon_centroid += position;
|
polygon_centroid += position;
|
||||||
|
|
||||||
|
polygon_vertex_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
||||||
@@ -568,56 +570,39 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
||||||
for (uint32_t i = 0; (i+2) < indices.size(); i += 3)
|
for (uint32_t i = 0; (i+2) < indices.size(); i += 3)
|
||||||
{
|
{
|
||||||
cap_section_indices.append(indices[i+1] + polygon_vertex_base);
|
const uint32_t index1 = indices[i+1] + polygon_vertex_base;
|
||||||
cap_section_indices.append(indices[i] + polygon_vertex_base);
|
const uint32_t index2 = indices[i] + polygon_vertex_base;
|
||||||
cap_section_indices.append(indices[i+2] + 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");
|
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);
|
||||||
|
|
||||||
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);
|
|
||||||
out_first_half->surface_set_material(out_first_half->get_surface_count()-1, cap_materials[uv_plane]);
|
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]);
|
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;
|
return impact_points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user