|
|
@@ -18,18 +18,25 @@
|
|
|
|
using namespace godot;
|
|
|
|
using namespace godot;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const AABB &original_aabb, const Plane &local_plane, Ref<ArrayMesh> out_first_half, Ref<ArrayMesh> out_other_half, const MeshEditCapUV cap_option, const TypedArray<Material> &cap_materials)
|
|
|
|
Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceInput> input)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
Ref<MeshEditSliceOutput> out; out.instantiate();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ref<ArrayMesh> first_half; first_half.instantiate();
|
|
|
|
|
|
|
|
Ref<ArrayMesh> other_half; other_half.instantiate();
|
|
|
|
|
|
|
|
|
|
|
|
const Time *time = Time::get_singleton();
|
|
|
|
const Time *time = Time::get_singleton();
|
|
|
|
|
|
|
|
|
|
|
|
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 Ref<ArrayMesh> original_mesh = original_mesh_instance->get_mesh();
|
|
|
|
const Ref<ArrayMesh> original_mesh = input->sliceable_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");
|
|
|
|
|
|
|
|
|
|
|
|
PackedVector3Array impact_points;
|
|
|
|
std::vector<Array> surface_arrays_list; surface_arrays_list.resize(num_surfaces);
|
|
|
|
|
|
|
|
std::vector<SkinnedVertices> skinned_vertex_positions; skinned_vertex_positions.resize(num_surfaces);
|
|
|
|
|
|
|
|
std::vector<std::vector<Transform3D>> skinned_vertex_transforms; skinned_vertex_transforms.resize(num_surfaces);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<bool> surface_has_normal; surface_has_normal.resize(num_surfaces);
|
|
|
|
std::vector<bool> surface_has_normal; surface_has_normal.resize(num_surfaces);
|
|
|
|
std::vector<bool> surface_has_tangent; surface_has_tangent.resize(num_surfaces);
|
|
|
|
std::vector<bool> surface_has_tangent; surface_has_tangent.resize(num_surfaces);
|
|
|
@@ -40,8 +47,8 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
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<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<uint8_t> num_bones_per_vertex; num_bones_per_vertex.resize(num_surfaces);
|
|
|
|
std::vector<uint8_t> surface_num_bones_per_vertex; surface_num_bones_per_vertex.resize(num_surfaces);
|
|
|
|
std::vector<uint8_t> num_custom0_per_vertex; num_custom0_per_vertex.resize(num_surfaces);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<PackedVector3Array> first_half_vertices; first_half_vertices.resize(num_surfaces);
|
|
|
|
std::vector<PackedVector3Array> first_half_vertices; first_half_vertices.resize(num_surfaces);
|
|
|
|
std::vector<PackedVector3Array> first_half_normals; first_half_normals.resize(num_surfaces);
|
|
|
|
std::vector<PackedVector3Array> first_half_normals; first_half_normals.resize(num_surfaces);
|
|
|
@@ -66,15 +73,22 @@ 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);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<Transform3D>> skinned_vertex_transforms;
|
|
|
|
std::vector<std::vector<float>> vertex_distances; vertex_distances.resize(num_surfaces);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::map<uint32_t, uint32_t>> base_to_first_sliced_vert_indices; base_to_first_sliced_vert_indices.resize(num_surfaces);
|
|
|
|
|
|
|
|
std::vector<std::map<uint32_t, uint32_t>> base_to_other_sliced_vert_indices; base_to_other_sliced_vert_indices.resize(num_surfaces);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t first_half_split_map = 0x00000000;
|
|
|
|
|
|
|
|
uint32_t other_half_split_map = 0x00000000;
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<MeshEditEdge3D> clip_edges;
|
|
|
|
std::vector<MeshEditEdge3D> clip_edges;
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
|
|
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Ref<Material> original_material = original_mesh->surface_get_material(surface);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<Transform3D> surface_skinned_vertex_transforms;
|
|
|
|
std::vector<Transform3D> surface_skinned_vertex_transforms;
|
|
|
|
const SkinnedVertices &surface_skinned_vertex_positions = MeshEditingLibrary::get_skinned_vertex_positions(surface, original_mesh, original_skeleton, surface_skinned_vertex_transforms);
|
|
|
|
const SkinnedVertices &surface_skinned_vertex_positions = MeshEditingLibrary::get_skinned_vertex_positions(surface, original_mesh, input->sliceable_skeleton, surface_skinned_vertex_transforms);
|
|
|
|
|
|
|
|
skinned_vertex_positions[surface] = surface_skinned_vertex_positions;
|
|
|
|
|
|
|
|
skinned_vertex_transforms[surface] = surface_skinned_vertex_transforms;
|
|
|
|
|
|
|
|
|
|
|
|
const Array &surface_arrays = original_mesh->surface_get_arrays(surface);
|
|
|
|
const Array &surface_arrays = original_mesh->surface_get_arrays(surface);
|
|
|
|
const PackedVector3Array &surface_vertex_array = surface_arrays[ArrayMesh::ARRAY_VERTEX];
|
|
|
|
const PackedVector3Array &surface_vertex_array = surface_arrays[ArrayMesh::ARRAY_VERTEX];
|
|
|
@@ -86,15 +100,16 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
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 PackedFloat32Array &surface_custom0_array = surface_arrays[ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
|
|
|
surface_arrays_list[surface] = surface_arrays;
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<float> vertex_distance;
|
|
|
|
std::map<uint32_t, uint32_t> &base_to_first_sliced_vert_index = base_to_first_sliced_vert_indices[surface];
|
|
|
|
vertex_distance.resize(num_vertices);
|
|
|
|
std::map<uint32_t, uint32_t> &base_to_other_sliced_vert_index = base_to_other_sliced_vert_indices[surface];
|
|
|
|
|
|
|
|
|
|
|
|
std::map<uint32_t, uint32_t> base_to_sliced_vert_index;
|
|
|
|
std::vector<float> &vertex_distance = vertex_distances[surface];
|
|
|
|
std::map<uint32_t, uint32_t> base_to_other_sliced_vert_index;
|
|
|
|
vertex_distance.resize(num_vertices);
|
|
|
|
|
|
|
|
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
|
|
|
|
|
|
|
|
|
|
|
@@ -107,21 +122,22 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
const bool has_weight = original_mesh_format_mask & Mesh::ARRAY_FORMAT_WEIGHTS; 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 bool has_custom0 = original_mesh_format_mask & Mesh::ARRAY_FORMAT_CUSTOM0; surface_has_custom0[surface] = has_custom0;
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t num_custom0_per_vertex = has_custom0 ? (
|
|
|
|
const uint8_t surface_num_bones_per_vertex = (has_bone && has_weight) ? (
|
|
|
|
|
|
|
|
(original_mesh_format_mask & Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 8 : 4 ) : 0;
|
|
|
|
|
|
|
|
num_bones_per_vertex[surface] = surface_num_bones_per_vertex;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t surface_num_custom0_per_vertex = has_custom0 ? (
|
|
|
|
((original_mesh_format_mask & (Mesh::ARRAY_FORMAT_CUSTOM_MASK << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT)) ==
|
|
|
|
((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;
|
|
|
|
(Mesh::ARRAY_CUSTOM_RGBA_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT)) ? 4 : 2 ) : 0;
|
|
|
|
|
|
|
|
num_custom0_per_vertex[surface] = surface_num_custom0_per_vertex;
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t vertex = 0; vertex < num_vertices; vertex++)
|
|
|
|
for (uint32_t vertex = 0; vertex < num_vertices; vertex++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
vertex_distance[vertex] = local_plane.distance_to(surface_skinned_vertex_positions[vertex]);
|
|
|
|
vertex_distance[vertex] = input->local_plane.distance_to(surface_skinned_vertex_positions[vertex]);
|
|
|
|
|
|
|
|
|
|
|
|
if (vertex_distance[vertex] >= 0.0f)
|
|
|
|
if (vertex_distance[vertex] >= 0.0f)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
base_to_sliced_vert_index[vertex] = first_half_vertices[surface].size();
|
|
|
|
base_to_first_sliced_vert_index[vertex] = first_half_vertices[surface].size();
|
|
|
|
|
|
|
|
|
|
|
|
first_half_vertices[surface].append(surface_vertex_array_ptr[vertex]);
|
|
|
|
first_half_vertices[surface].append(surface_vertex_array_ptr[vertex]);
|
|
|
|
if (has_normal) { first_half_normals[surface].append(surface_normal_array.ptr()[vertex]); }
|
|
|
|
if (has_normal) { first_half_normals[surface].append(surface_normal_array.ptr()[vertex]); }
|
|
|
@@ -137,17 +153,21 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (has_custom0)
|
|
|
|
if (has_custom0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
|
|
|
|
float hit_grid[] = { 0.0f, 0.0f };
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < surface_num_custom0_per_vertex; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
first_half_custom0[surface].append(surface_custom0_array.ptr()[(vertex * num_custom0_per_vertex) + i]);
|
|
|
|
const float value = surface_custom0_array.ptr()[(vertex * surface_num_custom0_per_vertex) + i];
|
|
|
|
|
|
|
|
first_half_custom0[surface].append(value);
|
|
|
|
|
|
|
|
hit_grid[i] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
first_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (has_bone)
|
|
|
|
if (has_bone)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < num_bones_per_vertex; i++)
|
|
|
|
for (uint8_t i = 0; i < surface_num_bones_per_vertex; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
first_half_bones[surface].append(surface_bone_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
first_half_bones[surface].append(surface_bone_array.ptr()[(vertex * surface_num_bones_per_vertex) + i]);
|
|
|
|
first_half_weights[surface].append(surface_weight_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
first_half_weights[surface].append(surface_weight_array.ptr()[(vertex * surface_num_bones_per_vertex) + i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -169,25 +189,62 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (has_custom0)
|
|
|
|
if (has_custom0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
|
|
|
|
float hit_grid[] = { 0.0f, 0.0f };
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < surface_num_custom0_per_vertex; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
other_half_custom0[surface].append(surface_custom0_array.ptr()[(vertex * num_custom0_per_vertex) + i]);
|
|
|
|
const float value = surface_custom0_array.ptr()[(vertex * surface_num_custom0_per_vertex) + i];
|
|
|
|
|
|
|
|
other_half_custom0[surface].append(value);
|
|
|
|
|
|
|
|
hit_grid[i] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
other_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (has_bone)
|
|
|
|
if (has_bone)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < num_bones_per_vertex; i++)
|
|
|
|
for (uint8_t i = 0; i < surface_num_bones_per_vertex; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
other_half_bones[surface].append(surface_bone_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
other_half_bones[surface].append(surface_bone_array.ptr()[(vertex * surface_num_bones_per_vertex) + i]);
|
|
|
|
other_half_weights[surface].append(surface_weight_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
other_half_weights[surface].append(surface_weight_array.ptr()[(vertex * surface_num_bones_per_vertex) + i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const PackedInt32Array &surface_index_array = surface_arrays[ArrayMesh::ARRAY_INDEX];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Surface ", surface, " sorted by plane distance at ", time->get_ticks_msec(), "ms");
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Surface ", surface, " sorted by plane distance at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out->hit_map = first_half_split_map & other_half_split_map;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Ref<Material> original_material = original_mesh->surface_get_material(surface);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const PackedVector3Array &surface_vertex_array = surface_arrays_list[surface][ArrayMesh::ARRAY_VERTEX];
|
|
|
|
|
|
|
|
const PackedVector3Array &surface_normal_array = surface_arrays_list[surface][ArrayMesh::ARRAY_NORMAL];
|
|
|
|
|
|
|
|
const PackedFloat32Array &surface_tangent_array = surface_arrays_list[surface][ArrayMesh::ARRAY_TANGENT];
|
|
|
|
|
|
|
|
const PackedVector2Array &surface_uv_array = surface_arrays_list[surface][ArrayMesh::ARRAY_TEX_UV];
|
|
|
|
|
|
|
|
const PackedVector2Array &surface_uv2_array = surface_arrays_list[surface][ArrayMesh::ARRAY_TEX_UV2];
|
|
|
|
|
|
|
|
const PackedColorArray &surface_colour_array = surface_arrays_list[surface][ArrayMesh::ARRAY_COLOR];
|
|
|
|
|
|
|
|
const PackedInt32Array &surface_bone_array = surface_arrays_list[surface][ArrayMesh::ARRAY_BONES];
|
|
|
|
|
|
|
|
const PackedFloat32Array &surface_weight_array = surface_arrays_list[surface][ArrayMesh::ARRAY_WEIGHTS];
|
|
|
|
|
|
|
|
const PackedFloat32Array &surface_custom0_array = surface_arrays_list[surface][ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
|
|
|
const PackedInt32Array &surface_index_array = surface_arrays_list[surface][ArrayMesh::ARRAY_INDEX];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SkinnedVertices &surface_skinned_vertex_positions = skinned_vertex_positions[surface];
|
|
|
|
|
|
|
|
std::vector<Transform3D> &surface_skinned_vertex_transforms = skinned_vertex_transforms[surface];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const std::vector<float> &vertex_distance = vertex_distances[surface];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool has_normal = surface_has_normal[surface];
|
|
|
|
|
|
|
|
const bool has_tangent = surface_has_tangent[surface];
|
|
|
|
|
|
|
|
const bool has_uv = surface_has_uv[surface];
|
|
|
|
|
|
|
|
const bool has_uv2 = surface_has_uv2[surface];
|
|
|
|
|
|
|
|
const bool has_colour = surface_has_colour[surface];
|
|
|
|
|
|
|
|
const bool has_bone = surface_has_bone[surface];
|
|
|
|
|
|
|
|
const bool has_weight = surface_has_weight[surface];
|
|
|
|
|
|
|
|
const bool has_custom0 = surface_has_custom0[surface];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t &surface_num_bones_per_vertex = num_bones_per_vertex[surface];
|
|
|
|
|
|
|
|
const uint8_t &surface_num_custom0_per_vertex = num_custom0_per_vertex[surface];
|
|
|
|
|
|
|
|
|
|
|
|
if (!(first_half_vertices[surface].size() > 0 && other_half_vertices[surface].size() > 0))
|
|
|
|
if (!(first_half_vertices[surface].size() > 0 && other_half_vertices[surface].size() > 0))
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -209,19 +266,19 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
std::map<uint32_t, uint32_t>::iterator sliced_v[3];
|
|
|
|
std::map<uint32_t, uint32_t>::iterator sliced_v[3];
|
|
|
|
std::map<uint32_t, uint32_t>::iterator sliced_other_v[3];
|
|
|
|
std::map<uint32_t, uint32_t>::iterator sliced_other_v[3];
|
|
|
|
|
|
|
|
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_sliced_end = base_to_sliced_vert_index.end();
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_first_sliced_end = base_to_first_sliced_vert_indices[surface].end();
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_other_sliced_end = base_to_other_sliced_vert_index.end();
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_other_sliced_end = base_to_other_sliced_vert_indices[surface].end();
|
|
|
|
for (uint32_t i = 0; i < 3; i++)
|
|
|
|
for (uint32_t i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
base_v[i] = surface_index_array.ptr()[triangle_index + i];
|
|
|
|
base_v[i] = surface_index_array.ptr()[triangle_index + i];
|
|
|
|
sliced_v[i] = base_to_sliced_vert_index.find(base_v[i]);
|
|
|
|
sliced_v[i] = base_to_first_sliced_vert_indices[surface].find(base_v[i]);
|
|
|
|
sliced_other_v[i] = base_to_other_sliced_vert_index.find(base_v[i]);
|
|
|
|
sliced_other_v[i] = base_to_other_sliced_vert_indices[surface].find(base_v[i]);
|
|
|
|
|
|
|
|
|
|
|
|
// All vertex indices must be represented by one of the two slice index maps.
|
|
|
|
// All vertex indices must be represented by one of the two slice index maps.
|
|
|
|
assert((sliced_v[i] != base_to_sliced_vert_index.end()) != (sliced_other_v[i] != base_to_other_sliced_vert_index.end()));
|
|
|
|
assert((sliced_v[i] != base_to_first_sliced_vert_indices[surface].end()) != (sliced_other_v[i] != base_to_other_sliced_vert_indices[surface].end()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sliced_v[0] != base_to_sliced_end && sliced_v[1] != base_to_sliced_end && sliced_v[2] != base_to_sliced_end)
|
|
|
|
if (sliced_v[0] != base_to_first_sliced_end && sliced_v[1] != base_to_first_sliced_end && sliced_v[2] != base_to_first_sliced_end)
|
|
|
|
{ // If the triangle is entirely in the first slice, send all the vertices to the first slice.
|
|
|
|
{ // If the triangle is entirely in the first slice, send all the vertices to the first slice.
|
|
|
|
first_half_indices[surface].append(sliced_v[0]->second);
|
|
|
|
first_half_indices[surface].append(sliced_v[0]->second);
|
|
|
|
first_half_indices[surface].append(sliced_v[1]->second);
|
|
|
|
first_half_indices[surface].append(sliced_v[1]->second);
|
|
|
@@ -252,7 +309,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t this_vert = 0; this_vert < 3; this_vert++)
|
|
|
|
for (uint32_t this_vert = 0; this_vert < 3; this_vert++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (sliced_v[this_vert] != base_to_sliced_end)
|
|
|
|
if (sliced_v[this_vert] != base_to_first_sliced_end)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
final_verts[num_final_verts] = sliced_v[this_vert]->second;
|
|
|
|
final_verts[num_final_verts] = sliced_v[this_vert]->second;
|
|
|
|
num_final_verts++;
|
|
|
|
num_final_verts++;
|
|
|
@@ -264,7 +321,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t next_vert = (this_vert + 1) % 3;
|
|
|
|
uint32_t next_vert = (this_vert + 1) % 3;
|
|
|
|
if ((sliced_v[this_vert] == base_to_sliced_end) != (sliced_v[next_vert] == base_to_sliced_end))
|
|
|
|
if ((sliced_v[this_vert] == base_to_first_sliced_end) != (sliced_v[next_vert] == base_to_first_sliced_end))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const float alpha = UtilityFunctions::clampf(-plane_distance[this_vert] / (plane_distance[next_vert] - plane_distance[this_vert]), 0.0f, 1.0f);
|
|
|
|
const float alpha = UtilityFunctions::clampf(-plane_distance[this_vert] / (plane_distance[next_vert] - plane_distance[this_vert]), 0.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
|
@@ -341,11 +398,11 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
|
|
if (has_custom0)
|
|
|
|
if (has_custom0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < num_custom0_per_vertex; i++)
|
|
|
|
for (uint8_t i = 0; i < surface_num_custom0_per_vertex; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const float &interp_custom0 = UtilityFunctions::lerpf(
|
|
|
|
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[this_vert] * surface_num_custom0_per_vertex) + i],
|
|
|
|
surface_custom0_array.ptr()[(base_v[next_vert] * num_custom0_per_vertex) + i],
|
|
|
|
surface_custom0_array.ptr()[(base_v[next_vert] * surface_num_custom0_per_vertex) + i],
|
|
|
|
alpha);
|
|
|
|
alpha);
|
|
|
|
first_half_custom0[surface].append(interp_custom0);
|
|
|
|
first_half_custom0[surface].append(interp_custom0);
|
|
|
|
other_half_custom0[surface].append(interp_custom0);
|
|
|
|
other_half_custom0[surface].append(interp_custom0);
|
|
|
@@ -366,10 +423,10 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
|
|
// First pack all active bones and weights into a list of pairs
|
|
|
|
// First pack all active bones and weights into a list of pairs
|
|
|
|
uint8_t vertex_bone = 0;
|
|
|
|
uint8_t vertex_bone = 0;
|
|
|
|
for (vertex_bone = 0; vertex_bone < num_bones_per_vertex; vertex_bone++)
|
|
|
|
for (vertex_bone = 0; vertex_bone < surface_num_bones_per_vertex; vertex_bone++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const int32_t bone = surface_bone_array[(base_v[this_vert] * num_bones_per_vertex) + vertex_bone];
|
|
|
|
const int32_t bone = surface_bone_array[(base_v[this_vert] * surface_num_bones_per_vertex) + vertex_bone];
|
|
|
|
const float weight = surface_weight_array[(base_v[this_vert] * num_bones_per_vertex) + vertex_bone];
|
|
|
|
const float weight = surface_weight_array[(base_v[this_vert] * surface_num_bones_per_vertex) + vertex_bone];
|
|
|
|
if (weight > TINY_NUMBER) { positive_side_bones_and_weights[bone] = weight; }
|
|
|
|
if (weight > TINY_NUMBER) { positive_side_bones_and_weights[bone] = weight; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -378,10 +435,10 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
// Delete any matches from the first half, leaving only unique bones to add later.
|
|
|
|
// Delete any matches from the first half, leaving only unique bones to add later.
|
|
|
|
std::map<int32_t, float> negative_side_bones_and_weights;
|
|
|
|
std::map<int32_t, float> negative_side_bones_and_weights;
|
|
|
|
std::vector<std::pair<int32_t, float>> bone_weight_pairs;
|
|
|
|
std::vector<std::pair<int32_t, float>> bone_weight_pairs;
|
|
|
|
for (uint32_t other_bone_index = 0; other_bone_index < num_bones_per_vertex; other_bone_index++)
|
|
|
|
for (uint32_t other_bone_index = 0; other_bone_index < surface_num_bones_per_vertex; other_bone_index++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const uint32_t other_bone = surface_bone_array[(base_v[next_vert] * num_bones_per_vertex) + other_bone_index];
|
|
|
|
const uint32_t other_bone = surface_bone_array[(base_v[next_vert] * surface_num_bones_per_vertex) + other_bone_index];
|
|
|
|
const float other_weight = surface_weight_array[(base_v[next_vert] * num_bones_per_vertex) + other_bone_index];
|
|
|
|
const float other_weight = surface_weight_array[(base_v[next_vert] * surface_num_bones_per_vertex) + other_bone_index];
|
|
|
|
|
|
|
|
|
|
|
|
if (negative_side_bones_and_weights.find(other_bone) != negative_side_bones_and_weights.end())
|
|
|
|
if (negative_side_bones_and_weights.find(other_bone) != negative_side_bones_and_weights.end())
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -419,7 +476,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
[=](std::pair<int32_t, float> &a, std::pair<int32_t, float> &b) { return a.second > b.second; });
|
|
|
|
[=](std::pair<int32_t, float> &a, std::pair<int32_t, float> &b) { return a.second > b.second; });
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, add all our new interpolated bones and weights to the arrays
|
|
|
|
// Finally, add all our new interpolated bones and weights to the arrays
|
|
|
|
for (vertex_bone = 0; vertex_bone < num_bones_per_vertex; vertex_bone++)
|
|
|
|
for (vertex_bone = 0; vertex_bone < surface_num_bones_per_vertex; vertex_bone++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (vertex_bone < bone_weight_pairs.size())
|
|
|
|
if (vertex_bone < bone_weight_pairs.size())
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -492,9 +549,9 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
if (has_custom0) first_half_section[ArrayMesh::ARRAY_CUSTOM0] = first_half_custom0[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 = first_half->get_surface_count();
|
|
|
|
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
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);
|
|
|
|
first_half->surface_set_material(next_surface, original_material);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (other_half_vertices[surface].size() > 0 && other_half_indices[surface].size() > 0)
|
|
|
|
if (other_half_vertices[surface].size() > 0 && other_half_indices[surface].size() > 0)
|
|
|
@@ -512,9 +569,9 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
if (has_custom0) other_half_section[ArrayMesh::ARRAY_CUSTOM0] = other_half_custom0[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 = other_half->get_surface_count();
|
|
|
|
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
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);
|
|
|
|
other_half->surface_set_material(next_surface, original_material);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
skinned_vertex_transforms.emplace_back(surface_skinned_vertex_transforms);
|
|
|
|
skinned_vertex_transforms.emplace_back(surface_skinned_vertex_transforms);
|
|
|
@@ -526,8 +583,8 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
if (clip_edges.size() > 0)
|
|
|
|
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 = input->sliceable_mesh_instance->get_basis();
|
|
|
|
const Vector3 &local_plane_normal = local_plane.get_normal();
|
|
|
|
const Vector3 &local_plane_normal = input->local_plane.get_normal();
|
|
|
|
if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(0.0f, 1.0f, 0.0f)))) > 0.5f)
|
|
|
|
if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(0.0f, 1.0f, 0.0f)))) > 0.5f)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uv_plane = MeshSlicePlaneOrientation::Y;
|
|
|
|
uv_plane = MeshSlicePlaneOrientation::Y;
|
|
|
@@ -549,11 +606,11 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
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;
|
|
|
|
const Transform3D &plane_inverse_transform = MeshEditingLibrary::project_edges(edges_2d, clip_edges, local_plane);
|
|
|
|
const Transform3D &plane_inverse_transform = MeshEditingLibrary::project_edges(edges_2d, clip_edges, input->local_plane);
|
|
|
|
MeshEditingLibrary::build_2d_polygons_from_edges(polygon_set, edges_2d, error_polygons);
|
|
|
|
MeshEditingLibrary::build_2d_polygons_from_edges(polygon_set, edges_2d, error_polygons);
|
|
|
|
MeshEditingLibrary::draw_debug_polygons(original_mesh_instance, error_polygons, plane_inverse_transform, Color(1.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
MeshEditingLibrary::draw_debug_polygons(input->sliceable_mesh_instance, error_polygons, plane_inverse_transform, Color(1.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
|
|
const Vector3 &mesh_bounds = original_aabb.get_size();
|
|
|
|
const Vector3 &mesh_bounds = input->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;
|
|
|
|
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++)
|
|
|
@@ -604,10 +661,10 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
PackedInt32Array bones; bones.resize(4);
|
|
|
|
PackedInt32Array bones; bones.resize(4);
|
|
|
|
PackedFloat32Array weights; weights.resize(4);
|
|
|
|
PackedFloat32Array weights; weights.resize(4);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < surface_num_bones_per_vertex[vertex.surface] && i < 4; i++)
|
|
|
|
for (uint8_t i = 0; i < num_bones_per_vertex[vertex.surface] && i < 4; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
bones[i] = first_half_bones[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
bones[i] = first_half_bones[vertex.surface][(vertex.index * num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
weights[i] = first_half_weights[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
weights[i] = first_half_weights[vertex.surface][(vertex.index * num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
surface_tool_first_half->set_bones(bones);
|
|
|
|
surface_tool_first_half->set_bones(bones);
|
|
|
@@ -627,7 +684,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
|
|
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
|
|
|
impact_points.append(polygon_centroid);
|
|
|
|
out->impact_points.append(polygon_centroid);
|
|
|
|
|
|
|
|
|
|
|
|
earcut_polygon.push_back(sub_polygon);
|
|
|
|
earcut_polygon.push_back(sub_polygon);
|
|
|
|
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
|
|
|
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
|
|
@@ -655,18 +712,21 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
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_first_half->set_material(input->cap_materials[uv_plane]);
|
|
|
|
surface_tool_other_half->set_material(cap_materials[uv_plane]);
|
|
|
|
surface_tool_other_half->set_material(input->cap_materials[uv_plane]);
|
|
|
|
|
|
|
|
|
|
|
|
out_first_half = surface_tool_first_half->commit(out_first_half);
|
|
|
|
first_half = surface_tool_first_half->commit(first_half);
|
|
|
|
out_other_half = surface_tool_other_half->commit(out_other_half);
|
|
|
|
other_half = surface_tool_other_half->commit(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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
out->main_half = first_half;
|
|
|
|
|
|
|
|
out->secondary_half = other_half;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SkinnedVertices MeshEditingLibrary::get_skinned_vertex_positions(const uint8_t surface, const Ref<ArrayMesh> 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)
|
|
|
|