|
|
@@ -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 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++)
|
|
|
@@ -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,6 +522,9 @@ 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (clip_edges.size() > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z;
|
|
|
|
MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z;
|
|
|
|
const Basis &mesh_instance_basis = original_mesh_instance->get_basis();
|
|
|
|
const Basis &mesh_instance_basis = original_mesh_instance->get_basis();
|
|
|
|
const Vector3 &local_plane_normal = local_plane.get_normal();
|
|
|
|
const Vector3 &local_plane_normal = local_plane.get_normal();
|
|
|
@@ -496,8 +537,15 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
uv_plane = MeshSlicePlaneOrientation::X;
|
|
|
|
uv_plane = MeshSlicePlaneOrientation::X;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (clip_edges.size() > 0)
|
|
|
|
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])
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cap_section_tangents.append(first_half_tangents[vertex.surface][(vertex.index * 4) + i] * -1.0f);
|
|
|
|
const Color &colour = first_half_colours[vertex.surface][vertex.index];
|
|
|
|
cap_section_flipped_tangents.append(first_half_tangents[vertex.surface][(vertex.index * 4) + i]);
|
|
|
|
surface_tool_first_half->set_color(colour);
|
|
|
|
|
|
|
|
surface_tool_other_half->set_color(colour);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (surface_has_bone[vertex.surface])
|
|
|
|
if (surface_has_bone[vertex.surface] && surface_has_weight[vertex.surface])
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < surface_num_bones_per_vertex[vertex.surface]; i++)
|
|
|
|
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_bones.append(first_half_bones[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];
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
polygon_vertex_base += polygon_vertex_counter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
surface_tool_first_half->generate_normals();
|
|
|
|
|
|
|
|
surface_tool_other_half->generate_normals();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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, "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);
|
|
|
|
|
|
|
|
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, "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,21 +869,10 @@ 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();
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
{
|
|
|
|