- slice_mesh now supports interpolating custom Float32 data arrays.

- get_skinned_vertex_positions now uses Ref<ArrayMesh> instead of a pointer.
This commit is contained in:
2026-09-27 17:36:49 -04:00
parent e35adc23b2
commit 6e508ccde2
2 changed files with 83 additions and 20 deletions
+77 -14
View File
@@ -24,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");
@@ -38,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);
@@ -50,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);
@@ -59,6 +61,7 @@ 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);
@@ -82,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();
@@ -92,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 int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
const bool has_normal = surface_normal_array.size() >= num_vertices; surface_has_normal[surface] = has_normal; const bool has_normal = surface_normal_array.size() >= num_vertices; surface_has_normal[surface] = has_normal;
const bool has_tangent = surface_tangent_array.size() >= num_vertices * 4; surface_has_tangent[surface] = has_tangent; 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_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_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_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_bone = original_mesh_format_mask & Mesh::ARRAY_FORMAT_BONES; surface_has_bone[surface] = has_bone;
const bool has_weight = surface_weight_array.size() >= num_vertices * 4; surface_has_weight[surface] = has_weight; 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 uint32_t bone_array_size = surface_bone_array.size(); const uint8_t num_custom0_per_vertex = has_custom0 ? (
surface_bone_array_size[surface] = bone_array_size; ((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 = surface_bone_array_size[surface] / num_vertices; 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++)
@@ -126,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++)
@@ -151,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++)
@@ -316,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);
@@ -430,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;
@@ -442,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);
} }
@@ -461,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);
} }
@@ -490,9 +539,13 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
SurfaceTool *surface_tool_first_half = memnew(SurfaceTool); SurfaceTool *surface_tool_first_half = memnew(SurfaceTool);
SurfaceTool *surface_tool_other_half = memnew(SurfaceTool); SurfaceTool *surface_tool_other_half = memnew(SurfaceTool);
surface_tool_first_half->begin(Mesh::PRIMITIVE_TRIANGLES); surface_tool_first_half->begin(Mesh::PRIMITIVE_TRIANGLES);
surface_tool_other_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;
@@ -529,6 +582,16 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
surface_tool_other_half->set_uv2(uv); surface_tool_other_half->set_uv2(uv);
} }
if (surface_has_custom0[vertex.surface])
{
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]) if (surface_has_colour[vertex.surface])
{ {
const Color &colour = first_half_colours[vertex.surface][vertex.index]; const Color &colour = first_half_colours[vertex.surface][vertex.index];
@@ -589,15 +652,15 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
surface_tool_first_half->generate_normals(); surface_tool_first_half->generate_normals();
surface_tool_other_half->generate_normals(); surface_tool_other_half->generate_normals();
// surface_tool_first_half->generate_tangents(); surface_tool_first_half->generate_tangents();
// surface_tool_other_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_first_half = surface_tool_first_half->commit(out_first_half);
out_other_half = surface_tool_other_half->commit(out_other_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]);
out_other_half->surface_set_material(out_other_half->get_surface_count()-1, cap_materials[uv_plane]);
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms"); PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms");
} }
@@ -606,7 +669,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
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)
+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);