Compare commits

...
5 Commits
Author SHA1 Message Date
ActualHorse 6e508ccde2 - slice_mesh now supports interpolating custom Float32 data arrays.
- get_skinned_vertex_positions now uses Ref<ArrayMesh> instead of a pointer.
2026-09-27 17:36:49 -04:00
ActualHorse e35adc23b2 Removed fix_polygon_winding's ability to delete edges, since it caused problems
with polygons that have only three vertices and also that isn't really its job
to do anyway.
2026-09-26 14:04:32 -04:00
ActualHorse b5fe9f7c8d HurtboxBase now sends hit updates on a timer instead of on a new frame. 2026-09-26 01:42:38 -04:00
ActualHorse 64421d8ff7 Added a macro to easily call functions on a timer. 2026-09-26 01:34:33 -04:00
ActualHorse b6315f3076 Sliced mesh caps now generate proper normals, thanks to SurfaceTool. 2026-09-26 01:34:01 -04:00
4 changed files with 163 additions and 124 deletions
+2 -2
View File
@@ -52,7 +52,7 @@ void HurtboxBase::_ready()
this->set_process(false); this->set_process(false);
this->remaining_life = this->lifetime; this->remaining_life = this->lifetime;
CALL_NEXT_FRAME(callable_mp(this, &HurtboxBase::_send_next_in_queue)); this->_send_next_in_queue();
} }
void HurtboxBase::_physics_process(double delta) void HurtboxBase::_physics_process(double delta)
@@ -146,6 +146,6 @@ void HurtboxBase::_send_next_in_queue()
} }
else else
{ {
CALL_NEXT_FRAME(callable_mp(this, &HurtboxBase::_send_next_in_queue)); CALL_ON_TIMEOUT(1.0f / 8.0f, callable_mp(this, &HurtboxBase::_send_next_in_queue));
} }
} }
+156 -119
View File
@@ -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;
@@ -23,7 +24,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms"); PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms");
const Mesh *original_mesh = original_mesh_instance->get_mesh().ptr(); const Ref<ArrayMesh> original_mesh = original_mesh_instance->get_mesh();
const uint8_t num_surfaces = original_mesh->get_surface_count(); const uint8_t num_surfaces = original_mesh->get_surface_count();
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms"); PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms");
@@ -37,6 +38,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
std::vector<bool> surface_has_colour; surface_has_colour.resize(num_surfaces); std::vector<bool> surface_has_colour; surface_has_colour.resize(num_surfaces);
std::vector<bool> surface_has_bone; surface_has_bone.resize(num_surfaces); std::vector<bool> surface_has_bone; surface_has_bone.resize(num_surfaces);
std::vector<bool> surface_has_weight; surface_has_weight.resize(num_surfaces); std::vector<bool> surface_has_weight; surface_has_weight.resize(num_surfaces);
std::vector<bool> surface_has_custom0; surface_has_custom0.resize(num_surfaces);
std::vector<uint32_t> surface_bone_array_size; surface_bone_array_size.resize(num_surfaces); std::vector<uint32_t> surface_bone_array_size; surface_bone_array_size.resize(num_surfaces);
std::vector<uint8_t> surface_num_bones_per_vertex; surface_num_bones_per_vertex.resize(num_surfaces); std::vector<uint8_t> surface_num_bones_per_vertex; surface_num_bones_per_vertex.resize(num_surfaces);
@@ -49,6 +51,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
std::vector<PackedColorArray> first_half_colours; first_half_colours.resize(num_surfaces); std::vector<PackedColorArray> first_half_colours; first_half_colours.resize(num_surfaces);
std::vector<PackedInt32Array> first_half_bones; first_half_bones.resize(num_surfaces); std::vector<PackedInt32Array> first_half_bones; first_half_bones.resize(num_surfaces);
std::vector<PackedFloat32Array> first_half_weights; first_half_weights.resize(num_surfaces); std::vector<PackedFloat32Array> first_half_weights; first_half_weights.resize(num_surfaces);
std::vector<PackedFloat32Array> first_half_custom0; first_half_custom0.resize(num_surfaces);
std::vector<PackedVector3Array> other_half_vertices; other_half_vertices.resize(num_surfaces); std::vector<PackedVector3Array> other_half_vertices; other_half_vertices.resize(num_surfaces);
std::vector<PackedVector3Array> other_half_normals; other_half_normals.resize(num_surfaces); std::vector<PackedVector3Array> other_half_normals; other_half_normals.resize(num_surfaces);
@@ -58,22 +61,11 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
std::vector<PackedColorArray> other_half_colours; other_half_colours.resize(num_surfaces); std::vector<PackedColorArray> other_half_colours; other_half_colours.resize(num_surfaces);
std::vector<PackedInt32Array> other_half_bones; other_half_bones.resize(num_surfaces); std::vector<PackedInt32Array> other_half_bones; other_half_bones.resize(num_surfaces);
std::vector<PackedFloat32Array> other_half_weights; other_half_weights.resize(num_surfaces); std::vector<PackedFloat32Array> other_half_weights; other_half_weights.resize(num_surfaces);
std::vector<PackedFloat32Array> other_half_custom0; other_half_custom0.resize(num_surfaces);
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;
@@ -93,6 +85,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
const PackedColorArray &surface_colour_array = surface_arrays[ArrayMesh::ARRAY_COLOR]; const PackedColorArray &surface_colour_array = surface_arrays[ArrayMesh::ARRAY_COLOR];
const PackedInt32Array &surface_bone_array = surface_arrays[ArrayMesh::ARRAY_BONES]; const PackedInt32Array &surface_bone_array = surface_arrays[ArrayMesh::ARRAY_BONES];
const PackedFloat32Array &surface_weight_array = surface_arrays[ArrayMesh::ARRAY_WEIGHTS]; const PackedFloat32Array &surface_weight_array = surface_arrays[ArrayMesh::ARRAY_WEIGHTS];
const PackedFloat32Array &surface_custom0_array = surface_arrays[ArrayMesh::ARRAY_CUSTOM0];
const Vector3 *surface_vertex_array_ptr = surface_vertex_array.ptr(); const Vector3 *surface_vertex_array_ptr = surface_vertex_array.ptr();
const uint32_t num_vertices = surface_vertex_array.size(); const uint32_t num_vertices = surface_vertex_array.size();
@@ -103,18 +96,23 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
std::map<uint32_t, uint32_t> base_to_sliced_vert_index; std::map<uint32_t, uint32_t> base_to_sliced_vert_index;
std::map<uint32_t, uint32_t> base_to_other_sliced_vert_index; std::map<uint32_t, uint32_t> base_to_other_sliced_vert_index;
const bool has_normal = surface_normal_array.size() >= num_vertices; surface_has_normal[surface] = has_normal; const int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
const bool has_tangent = surface_tangent_array.size() >= num_vertices * 4; surface_has_tangent[surface] = has_tangent;
const bool has_uv = surface_uv_array.size() >= num_vertices; surface_has_uv[surface] = has_uv;
const bool has_uv2 = surface_uv2_array.size() >= num_vertices; surface_has_uv2[surface] = has_uv2;
const bool has_colour = surface_colour_array.size() >= num_vertices; surface_has_colour[surface] = has_colour;
const bool has_bone = surface_bone_array.size() >= num_vertices * 4; surface_has_bone[surface] = has_bone;
const bool has_weight = surface_weight_array.size() >= num_vertices * 4; surface_has_weight[surface] = has_weight;
const uint32_t bone_array_size = surface_bone_array.size(); const bool has_normal = surface_normal_array.size() >= num_vertices; surface_has_normal[surface] = has_normal;
surface_bone_array_size[surface] = bone_array_size; const bool has_tangent = surface_tangent_array.size() >= num_vertices * 4; surface_has_tangent[surface] = has_tangent;
const bool has_uv = surface_uv_array.size() >= num_vertices; surface_has_uv[surface] = has_uv;
const bool has_uv2 = surface_uv2_array.size() >= num_vertices; surface_has_uv2[surface] = has_uv2;
const bool has_colour = surface_colour_array.size() >= num_vertices; surface_has_colour[surface] = has_colour;
const bool has_bone = original_mesh_format_mask & Mesh::ARRAY_FORMAT_BONES; surface_has_bone[surface] = has_bone;
const bool has_weight = original_mesh_format_mask & Mesh::ARRAY_FORMAT_WEIGHTS; surface_has_weight[surface] = has_weight;
const bool has_custom0 = original_mesh_format_mask & Mesh::ARRAY_FORMAT_CUSTOM0; surface_has_custom0[surface] = has_custom0;
const uint8_t num_bones_per_vertex = surface_bone_array_size[surface] / num_vertices; const uint8_t num_custom0_per_vertex = has_custom0 ? (
((original_mesh_format_mask & (Mesh::ARRAY_FORMAT_CUSTOM_MASK << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT)) ==
(Mesh::ARRAY_CUSTOM_RGBA_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT)) ? 4 : 2 ) : 0;
const uint8_t num_bones_per_vertex = (has_bone && has_weight) ? (
(original_mesh_format_mask & Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4 ) : 0;
surface_num_bones_per_vertex[surface] = num_bones_per_vertex; surface_num_bones_per_vertex[surface] = num_bones_per_vertex;
for (uint32_t vertex = 0; vertex < num_vertices; vertex++) for (uint32_t vertex = 0; vertex < num_vertices; vertex++)
@@ -137,6 +135,13 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]); first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]);
first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]); first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]);
} }
if (has_custom0)
{
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
{
first_half_custom0[surface].append(surface_custom0_array.ptr()[(vertex * num_custom0_per_vertex) + i]);
}
}
if (has_bone) if (has_bone)
{ {
for (uint8_t i = 0; i < num_bones_per_vertex; i++) for (uint8_t i = 0; i < num_bones_per_vertex; i++)
@@ -162,6 +167,13 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]); other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]);
other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]); other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]);
} }
if (has_custom0)
{
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
{
other_half_custom0[surface].append(surface_custom0_array.ptr()[(vertex * num_custom0_per_vertex) + i]);
}
}
if (has_bone) if (has_bone)
{ {
for (uint8_t i = 0; i < num_bones_per_vertex; i++) for (uint8_t i = 0; i < num_bones_per_vertex; i++)
@@ -327,6 +339,19 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
other_half_uv2s[surface].append(interp_uv2); other_half_uv2s[surface].append(interp_uv2);
} }
if (has_custom0)
{
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
{
const float &interp_custom0 = UtilityFunctions::lerpf(
surface_custom0_array.ptr()[(base_v[this_vert] * num_custom0_per_vertex) + i],
surface_custom0_array.ptr()[(base_v[next_vert] * num_custom0_per_vertex) + i],
alpha);
first_half_custom0[surface].append(interp_custom0);
other_half_custom0[surface].append(interp_custom0);
}
}
if (has_colour) if (has_colour)
{ {
const Color &interp_colour = surface_colour_array.ptr()[base_v[this_vert]].lerp(surface_colour_array.ptr()[base_v[next_vert]], alpha); const Color &interp_colour = surface_colour_array.ptr()[base_v[this_vert]].lerp(surface_colour_array.ptr()[base_v[next_vert]], alpha);
@@ -441,6 +466,17 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
} }
} }
int64_t array_format_bit_mask = Mesh::ARRAY_FORMAT_VERTEX;
if (has_normal) array_format_bit_mask |= Mesh::ARRAY_FORMAT_NORMAL;
if (has_tangent) array_format_bit_mask |= Mesh::ARRAY_FORMAT_TANGENT;
if (has_uv) array_format_bit_mask |= Mesh::ARRAY_FORMAT_TEX_UV;
if (has_uv2) array_format_bit_mask |= Mesh::ARRAY_FORMAT_TEX_UV2;
if (has_colour) array_format_bit_mask |= Mesh::ARRAY_FORMAT_COLOR;
if (has_bone) array_format_bit_mask |= Mesh::ARRAY_FORMAT_BONES;
if (has_weight) array_format_bit_mask |= Mesh::ARRAY_FORMAT_WEIGHTS;
if (has_custom0) array_format_bit_mask |= (Mesh::ARRAY_FORMAT_CUSTOM0 | (Mesh::ARRAY_CUSTOM_RG_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT));
BitField<Mesh::ArrayFormat> array_format(array_format_bit_mask);
if (first_half_vertices[surface].size() > 0 && first_half_indices[surface].size() > 0) if (first_half_vertices[surface].size() > 0 && first_half_indices[surface].size() > 0)
{ {
Array first_half_section; Array first_half_section;
@@ -453,10 +489,11 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
if (has_colour) first_half_section[ArrayMesh::ARRAY_COLOR] = first_half_colours[surface]; if (has_colour) first_half_section[ArrayMesh::ARRAY_COLOR] = first_half_colours[surface];
if (has_bone) first_half_section[ArrayMesh::ARRAY_BONES] = first_half_bones[surface]; if (has_bone) first_half_section[ArrayMesh::ARRAY_BONES] = first_half_bones[surface];
if (has_weight) first_half_section[ArrayMesh::ARRAY_WEIGHTS] = first_half_weights[surface]; if (has_weight) first_half_section[ArrayMesh::ARRAY_WEIGHTS] = first_half_weights[surface];
if (has_custom0) first_half_section[ArrayMesh::ARRAY_CUSTOM0] = first_half_custom0[surface];
first_half_section[ArrayMesh::ARRAY_INDEX] = first_half_indices[surface]; first_half_section[ArrayMesh::ARRAY_INDEX] = first_half_indices[surface];
const uint16_t next_surface = out_first_half->get_surface_count(); const uint16_t next_surface = out_first_half->get_surface_count();
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section); out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section, Array(), Dictionary(), array_format_bit_mask);
out_first_half->surface_set_material(next_surface, original_material); out_first_half->surface_set_material(next_surface, original_material);
} }
@@ -472,10 +509,11 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
if (has_colour) other_half_section[ArrayMesh::ARRAY_COLOR] = other_half_colours[surface]; if (has_colour) other_half_section[ArrayMesh::ARRAY_COLOR] = other_half_colours[surface];
if (has_bone) other_half_section[ArrayMesh::ARRAY_BONES] = other_half_bones[surface]; if (has_bone) other_half_section[ArrayMesh::ARRAY_BONES] = other_half_bones[surface];
if (has_weight) other_half_section[ArrayMesh::ARRAY_WEIGHTS] = other_half_weights[surface]; if (has_weight) other_half_section[ArrayMesh::ARRAY_WEIGHTS] = other_half_weights[surface];
if (has_custom0) other_half_section[ArrayMesh::ARRAY_CUSTOM0] = other_half_custom0[surface];
other_half_section[ArrayMesh::ARRAY_INDEX] = other_half_indices[surface]; other_half_section[ArrayMesh::ARRAY_INDEX] = other_half_indices[surface];
const uint16_t next_surface = out_other_half->get_surface_count(); const uint16_t next_surface = out_other_half->get_surface_count();
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section); out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section, Array(), Dictionary(), array_format_bit_mask);
out_other_half->surface_set_material(next_surface, original_material); out_other_half->surface_set_material(next_surface, original_material);
} }
@@ -484,20 +522,30 @@ 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);
surface_tool_first_half->set_custom_format(0, SurfaceTool::CUSTOM_RG_FLOAT);
surface_tool_other_half->set_custom_format(0, SurfaceTool::CUSTOM_RG_FLOAT);
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 +555,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 +566,64 @@ 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_custom0[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 &custom_uv3 = Color(
first_half_custom0[vertex.surface][(vertex.index * 2)],
first_half_custom0[vertex.surface][(vertex.index * 2) + 1],
0.0f, 0.0f);
surface_tool_first_half->set_custom(0, custom_uv3);
surface_tool_other_half->set_custom(0, custom_uv3);
}
if (surface_has_colour[vertex.surface])
{
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,60 +633,43 @@ 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);
} }
}
}
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms"); polygon_vertex_base += polygon_vertex_counter;
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]);
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; surface_tool_first_half->generate_normals();
cap_other_mesh_section.resize(ArrayMesh::ARRAY_MAX); surface_tool_other_half->generate_normals();
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"); surface_tool_first_half->generate_tangents();
surface_tool_other_half->generate_tangents();
surface_tool_first_half->set_material(cap_materials[uv_plane]);
surface_tool_other_half->set_material(cap_materials[uv_plane]);
out_first_half = surface_tool_first_half->commit(out_first_half);
out_other_half = surface_tool_other_half->commit(out_other_half);
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;
} }
SkinnedVertices MeshEditingLibrary::get_skinned_vertex_positions(const uint8_t surface, const Mesh *mesh, const Skeleton3D *skeleton, std::vector<Transform3D> &vertex_transforms) SkinnedVertices MeshEditingLibrary::get_skinned_vertex_positions(const uint8_t surface, const Ref<ArrayMesh> mesh, const Skeleton3D *skeleton, std::vector<Transform3D> &vertex_transforms)
{ {
const uint8_t num_surfaces = mesh->get_surface_count(); const uint8_t num_surfaces = mesh->get_surface_count();
if (surface > num_surfaces) if (surface > num_surfaces)
@@ -821,20 +869,9 @@ void MeshEditingLibrary::fix_polygon_winding(MeshEditPolygon2D &polygon)
const int32_t b_index = i; const int32_t b_index = i;
const int32_t c_index = (i + 1) % polygon.vertices.size(); const int32_t c_index = (i + 1) % polygon.vertices.size();
const float ab_dist_squared = (polygon.vertices[b_index].position - polygon.vertices[a_index].position).length_squared();
const Vector2 ab_edge = (polygon.vertices[b_index].position - polygon.vertices[a_index].position).normalized(); const Vector2 ab_edge = (polygon.vertices[b_index].position - polygon.vertices[a_index].position).normalized();
const float bc_dist_squared = (polygon.vertices[c_index].position - polygon.vertices[b_index].position).length_squared();
const Vector2 bc_edge = (polygon.vertices[c_index].position - polygon.vertices[b_index].position).normalized(); const Vector2 bc_edge = (polygon.vertices[c_index].position - polygon.vertices[b_index].position).normalized();
total_angle += UtilityFunctions::asin(ab_edge.x * bc_edge.y - ab_edge.y * bc_edge.x);
if (ab_dist_squared < TINY_NUMBER || bc_dist_squared < TINY_NUMBER || (ab_edge - bc_edge).length_squared() < TEENY_TINY_NUMBER)
{
polygon.vertices.erase(polygon.vertices.begin() + i);
}
else
{
total_angle += UtilityFunctions::asin(ab_edge.x * bc_edge.y - ab_edge.y * bc_edge.x);
}
} }
if (total_angle < 0.0f) if (total_angle < 0.0f)
+1 -1
View File
@@ -83,7 +83,7 @@ protected:
private: private:
static const Vector2 calculate_planar_uv(const Vector3 &vertex, const Vector3 &mesh_bounds, const MeshSlicePlaneOrientation &axis); static const Vector2 calculate_planar_uv(const Vector3 &vertex, const Vector3 &mesh_bounds, const MeshSlicePlaneOrientation &axis);
static SkinnedVertices get_skinned_vertex_positions(const uint8_t surface, const Mesh *mesh, const Skeleton3D *skeleton = nullptr, std::vector<Transform3D> &bone_transforms = std::vector<Transform3D>()); static SkinnedVertices get_skinned_vertex_positions(const uint8_t surface, const Ref<ArrayMesh> mesh, const Skeleton3D *skeleton = nullptr, std::vector<Transform3D> &bone_transforms = std::vector<Transform3D>());
static const Transform3D project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane); static const Transform3D project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane);
static void build_2d_polygons_from_edges(std::vector<MeshEditPolygon2D> &out_polygons, const std::vector<MeshEditEdge2D> &in_edges, std::vector<MeshEditPolygon2D> &error_polygons); static void build_2d_polygons_from_edges(std::vector<MeshEditPolygon2D> &out_polygons, const std::vector<MeshEditEdge2D> &in_edges, std::vector<MeshEditPolygon2D> &error_polygons);
+3 -1
View File
@@ -34,8 +34,10 @@
/** /**
* Deferred function helpers * Deferred function helpers
*/ */
#define CALL_ON_TIMEOUT(T,C) \
this->get_tree()->create_timer(T)->connect("timeout", C)
#define CALL_NEXT_FRAME(C) \ #define CALL_NEXT_FRAME(C) \
this->get_tree()->create_timer(SMALL_NUMBER)->connect("timeout", C) CALL_ON_TIMEOUT(SMALL_NUMBER,C)
/** /**