|
|
|
@@ -9,8 +9,6 @@
|
|
|
|
|
#include "orng_macros.h"
|
|
|
|
|
#include "earcut.hpp"
|
|
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
#include "godot_cpp/classes/immediate_mesh.hpp"
|
|
|
|
|
#include "godot_cpp/classes/surface_tool.hpp"
|
|
|
|
|
#include "godot_cpp/classes/time.hpp"
|
|
|
|
@@ -18,220 +16,324 @@
|
|
|
|
|
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<MeshSliceState> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceInput> input)
|
|
|
|
|
{
|
|
|
|
|
const Time *time = Time::get_singleton();
|
|
|
|
|
Ref<MeshSliceState> fresh_state;
|
|
|
|
|
fresh_state.instantiate();
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
fresh_state->input = input;
|
|
|
|
|
|
|
|
|
|
const Ref<ArrayMesh> original_mesh = original_mesh_instance->get_mesh();
|
|
|
|
|
const uint8_t num_surfaces = original_mesh->get_surface_count();
|
|
|
|
|
fresh_state->output.instantiate();
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
fresh_state->first_half.instantiate();
|
|
|
|
|
fresh_state->other_half.instantiate();
|
|
|
|
|
|
|
|
|
|
PackedVector3Array impact_points;
|
|
|
|
|
|
|
|
|
|
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_uv; surface_has_uv.resize(num_surfaces);
|
|
|
|
|
std::vector<bool> surface_has_uv2; surface_has_uv2.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_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<uint8_t> surface_num_bones_per_vertex; surface_num_bones_per_vertex.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<PackedFloat32Array> first_half_tangents; first_half_tangents.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedVector2Array> first_half_uvs; first_half_uvs.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedVector2Array> first_half_uv2s; first_half_uv2s.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<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_normals; other_half_normals.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedFloat32Array> other_half_tangents; other_half_tangents.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedVector2Array> other_half_uvs; other_half_uvs.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedVector2Array> other_half_uv2s; other_half_uv2s.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<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> other_half_indices; other_half_indices.resize(num_surfaces);
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<Transform3D>> skinned_vertex_transforms;
|
|
|
|
|
std::vector<MeshEditEdge3D> clip_edges;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
const SkinnedVertices &surface_skinned_vertex_positions = MeshEditingLibrary::get_skinned_vertex_positions(surface, original_mesh, original_skeleton, surface_skinned_vertex_transforms);
|
|
|
|
|
return fresh_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MeshEditingLibrary::slice_mesh_init(Ref<MeshSliceState> state)
|
|
|
|
|
{
|
|
|
|
|
{ // Initialise the state here
|
|
|
|
|
// const Time *time = Time::get_singleton();
|
|
|
|
|
|
|
|
|
|
const Array &surface_arrays = original_mesh->surface_get_arrays(surface);
|
|
|
|
|
const PackedVector3Array &surface_vertex_array = surface_arrays[ArrayMesh::ARRAY_VERTEX];
|
|
|
|
|
const PackedVector3Array &surface_normal_array = surface_arrays[ArrayMesh::ARRAY_NORMAL];
|
|
|
|
|
const PackedFloat32Array &surface_tangent_array = surface_arrays[ArrayMesh::ARRAY_TANGENT];
|
|
|
|
|
const PackedVector2Array &surface_uv_array = surface_arrays[ArrayMesh::ARRAY_TEX_UV];
|
|
|
|
|
const PackedVector2Array &surface_uv2_array = surface_arrays[ArrayMesh::ARRAY_TEX_UV2];
|
|
|
|
|
const PackedColorArray &surface_colour_array = surface_arrays[ArrayMesh::ARRAY_COLOR];
|
|
|
|
|
const PackedInt32Array &surface_bone_array = surface_arrays[ArrayMesh::ARRAY_BONES];
|
|
|
|
|
const PackedFloat32Array &surface_weight_array = surface_arrays[ArrayMesh::ARRAY_WEIGHTS];
|
|
|
|
|
const PackedFloat32Array &surface_custom0_array = surface_arrays[ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
// PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
|
|
state->original_mesh = state->input->mesh_instance->get_mesh();
|
|
|
|
|
state->num_surfaces = state->original_mesh->get_surface_count();
|
|
|
|
|
|
|
|
|
|
// PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
|
|
state->surface_arrays_list.resize(state->num_surfaces);
|
|
|
|
|
state->skinned_vertex_positions.resize(state->num_surfaces);
|
|
|
|
|
state->skinned_vertex_transforms.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->has_normal.resize(state->num_surfaces);
|
|
|
|
|
state->has_tangent.resize(state->num_surfaces);
|
|
|
|
|
state->has_uv.resize(state->num_surfaces);
|
|
|
|
|
state->has_uv2.resize(state->num_surfaces);
|
|
|
|
|
state->has_colour.resize(state->num_surfaces);
|
|
|
|
|
state->has_bone.resize(state->num_surfaces);
|
|
|
|
|
state->has_weight.resize(state->num_surfaces);
|
|
|
|
|
state->has_custom0.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->num_bones_per_vertex.resize(state->num_surfaces);
|
|
|
|
|
state->num_custom0_per_vertex.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->first_half_vertices.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_normals.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_tangents.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_uvs.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_uv2s.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_colours.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_bones.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_weights.resize(state->num_surfaces);
|
|
|
|
|
state->first_half_custom0.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->other_half_vertices.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_normals.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_tangents.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_uvs.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_uv2s.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_colours.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_bones.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_weights.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_custom0.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->first_half_indices.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_indices.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->vertex_distances.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
state->base_to_first_sliced_vert_indices.resize(state->num_surfaces);
|
|
|
|
|
state->base_to_other_sliced_vert_indices.resize(state->num_surfaces);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (state->surface; state->surface < state->num_surfaces; state->surface++)
|
|
|
|
|
{
|
|
|
|
|
state->skinned_vertex_positions[state->surface] = MeshEditingLibrary::get_skinned_vertex_positions(state->surface, state->original_mesh, state->input->skeleton, state->skinned_vertex_transforms[state->surface]);
|
|
|
|
|
|
|
|
|
|
state->surface_arrays_list[state->surface] = state->original_mesh->surface_get_arrays(state->surface);
|
|
|
|
|
const PackedVector3Array &surface_vertex_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_VERTEX];
|
|
|
|
|
const PackedVector3Array &surface_normal_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_NORMAL];
|
|
|
|
|
const PackedFloat32Array &surface_tangent_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TANGENT];
|
|
|
|
|
const PackedVector2Array &surface_uv_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV];
|
|
|
|
|
const PackedVector2Array &surface_uv2_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV2];
|
|
|
|
|
const PackedColorArray &surface_colour_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_COLOR];
|
|
|
|
|
const PackedInt32Array &surface_bone_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_BONES];
|
|
|
|
|
const PackedFloat32Array &surface_weight_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_WEIGHTS];
|
|
|
|
|
const PackedFloat32Array &surface_custom0_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
|
|
|
|
|
const Vector3 *surface_vertex_array_ptr = surface_vertex_array.ptr();
|
|
|
|
|
const uint32_t num_vertices = surface_vertex_array.size();
|
|
|
|
|
|
|
|
|
|
std::vector<float> vertex_distance;
|
|
|
|
|
vertex_distance.resize(num_vertices);
|
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)state->original_mesh->surface_get_format(state->surface);
|
|
|
|
|
|
|
|
|
|
std::map<uint32_t, uint32_t> base_to_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; state->has_normal[state->surface] = has_normal;
|
|
|
|
|
const bool has_tangent = surface_tangent_array.size() >= num_vertices * 4; state->has_tangent[state->surface] = has_tangent;
|
|
|
|
|
const bool has_uv = surface_uv_array.size() >= num_vertices; state->has_uv[state->surface] = has_uv;
|
|
|
|
|
const bool has_uv2 = surface_uv2_array.size() >= num_vertices; state->has_uv2[state->surface] = has_uv2;
|
|
|
|
|
const bool has_colour = surface_colour_array.size() >= num_vertices; state->has_colour[state->surface] = has_colour;
|
|
|
|
|
const bool has_bone = original_mesh_format_mask & Mesh::ARRAY_FORMAT_BONES; state->has_bone[state->surface] = has_bone;
|
|
|
|
|
const bool has_weight = original_mesh_format_mask & Mesh::ARRAY_FORMAT_WEIGHTS; state->has_weight[state->surface] = has_weight;
|
|
|
|
|
const bool has_custom0 = original_mesh_format_mask & Mesh::ARRAY_FORMAT_CUSTOM0; state->has_custom0[state->surface] = has_custom0;
|
|
|
|
|
|
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
|
|
|
|
|
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;
|
|
|
|
|
state->num_bones_per_vertex[state->surface] = surface_num_bones_per_vertex;
|
|
|
|
|
|
|
|
|
|
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_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_custom0_per_vertex = has_custom0 ? (
|
|
|
|
|
const uint8_t surface_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;
|
|
|
|
|
state->num_custom0_per_vertex[state->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;
|
|
|
|
|
state->vertex_distances[state->surface].resize(num_vertices);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state->surface = 0;
|
|
|
|
|
state->element = 0;
|
|
|
|
|
state->current_stage = MeshEditSliceStage::SLICE_STAGE_PLANE_SPLIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MeshEditingLibrary::slice_mesh_plane_split(Ref<MeshSliceState> state)
|
|
|
|
|
{
|
|
|
|
|
for (state->surface; state->surface < state->num_surfaces; state->surface++)
|
|
|
|
|
{
|
|
|
|
|
const PackedVector3Array &surface_vertex_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_VERTEX];
|
|
|
|
|
const PackedVector3Array &surface_normal_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_NORMAL];
|
|
|
|
|
const PackedFloat32Array &surface_tangent_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TANGENT];
|
|
|
|
|
const PackedVector2Array &surface_uv_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV];
|
|
|
|
|
const PackedVector2Array &surface_uv2_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV2];
|
|
|
|
|
const PackedColorArray &surface_colour_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_COLOR];
|
|
|
|
|
const PackedInt32Array &surface_bone_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_BONES];
|
|
|
|
|
const PackedFloat32Array &surface_weight_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_WEIGHTS];
|
|
|
|
|
const PackedFloat32Array &surface_custom0_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
|
|
|
|
|
for (uint32_t vertex = 0; vertex < num_vertices; vertex++)
|
|
|
|
|
const bool &has_normal = state->has_normal[state->surface];
|
|
|
|
|
const bool &has_tangent = state->has_tangent[state->surface];
|
|
|
|
|
const bool &has_uv = state->has_uv[state->surface];
|
|
|
|
|
const bool &has_uv2 = state->has_uv2[state->surface];
|
|
|
|
|
const bool &has_colour = state->has_colour[state->surface];
|
|
|
|
|
const bool &has_bone = state->has_bone[state->surface];
|
|
|
|
|
const bool &has_weight = state->has_weight[state->surface];
|
|
|
|
|
const bool &has_custom0 = state->has_custom0[state->surface];
|
|
|
|
|
|
|
|
|
|
const Vector3 *surface_vertex_array_ptr = surface_vertex_array.ptr();
|
|
|
|
|
const uint32_t num_vertices = surface_vertex_array.size();
|
|
|
|
|
|
|
|
|
|
const uint8_t &surface_num_bones_per_vertex = state->num_bones_per_vertex[state->surface];
|
|
|
|
|
const uint8_t &surface_num_custom0_per_vertex = state->num_custom0_per_vertex[state->surface];
|
|
|
|
|
|
|
|
|
|
std::vector<float> &vertex_distances = state->vertex_distances[state->surface];
|
|
|
|
|
|
|
|
|
|
std::map<uint32_t, uint32_t> &base_to_first_sliced_vert_index = state->base_to_first_sliced_vert_indices[state->surface];
|
|
|
|
|
std::map<uint32_t, uint32_t> &base_to_other_sliced_vert_index = state->base_to_other_sliced_vert_indices[state->surface];
|
|
|
|
|
|
|
|
|
|
for (state->element; state->element < num_vertices; state->element++)
|
|
|
|
|
{
|
|
|
|
|
vertex_distance[vertex] = local_plane.distance_to(surface_skinned_vertex_positions[vertex]);
|
|
|
|
|
vertex_distances[state->element] = state->input->local_plane.distance_to(state->skinned_vertex_positions[state->surface][state->element]);
|
|
|
|
|
|
|
|
|
|
if (vertex_distance[vertex] >= 0.0f)
|
|
|
|
|
if (vertex_distances[state->element] >= 0.0f)
|
|
|
|
|
{
|
|
|
|
|
base_to_sliced_vert_index[vertex] = first_half_vertices[surface].size();
|
|
|
|
|
base_to_first_sliced_vert_index[state->element] = state->first_half_vertices[state->surface].size();
|
|
|
|
|
|
|
|
|
|
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_uv) { first_half_uvs[surface].append(surface_uv_array.ptr()[vertex]); }
|
|
|
|
|
if (has_uv2) { first_half_uv2s[surface].append(surface_uv2_array.ptr()[vertex]); }
|
|
|
|
|
if (has_colour) { first_half_colours[surface].append(surface_colour_array.ptr()[vertex]); }
|
|
|
|
|
state->first_half_vertices[state->surface].append(surface_vertex_array_ptr[state->element]);
|
|
|
|
|
if (has_normal) { state->first_half_normals[state->surface].append(surface_normal_array.ptr()[state->element]); }
|
|
|
|
|
if (has_uv) { state->first_half_uvs[state->surface].append(surface_uv_array.ptr()[state->element]); }
|
|
|
|
|
if (has_uv2) { state->first_half_uv2s[state->surface].append(surface_uv2_array.ptr()[state->element]); }
|
|
|
|
|
if (has_colour) { state->first_half_colours[state->surface].append(surface_colour_array.ptr()[state->element]); }
|
|
|
|
|
if (has_tangent)
|
|
|
|
|
{
|
|
|
|
|
first_half_tangents[surface].append(surface_tangent_array.ptr()[vertex * 4]);
|
|
|
|
|
first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 1]);
|
|
|
|
|
first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]);
|
|
|
|
|
first_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]);
|
|
|
|
|
state->first_half_tangents[state->surface].append(surface_tangent_array.ptr()[state->element * 4]);
|
|
|
|
|
state->first_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 1]);
|
|
|
|
|
state->first_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 2]);
|
|
|
|
|
state->first_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 3]);
|
|
|
|
|
}
|
|
|
|
|
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()[(state->element * surface_num_custom0_per_vertex) + i];
|
|
|
|
|
state->first_half_custom0[state->surface].append(value);
|
|
|
|
|
hit_grid[i] = value;
|
|
|
|
|
}
|
|
|
|
|
state->first_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
|
}
|
|
|
|
|
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_weights[surface].append(surface_weight_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
|
state->first_half_bones[state->surface].append(surface_bone_array.ptr()[(state->element * surface_num_bones_per_vertex) + i]);
|
|
|
|
|
state->first_half_weights[state->surface].append(surface_weight_array.ptr()[(state->element * surface_num_bones_per_vertex) + i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
base_to_other_sliced_vert_index[vertex] = other_half_vertices[surface].size();
|
|
|
|
|
base_to_other_sliced_vert_index[state->element] = state->other_half_vertices[state->surface].size();
|
|
|
|
|
|
|
|
|
|
other_half_vertices[surface].append(surface_vertex_array_ptr[vertex]);
|
|
|
|
|
if (has_normal) { other_half_normals[surface].append(surface_normal_array.ptr()[vertex]); }
|
|
|
|
|
if (has_uv) { other_half_uvs[surface].append(surface_uv_array.ptr()[vertex]); }
|
|
|
|
|
if (has_uv2) { other_half_uv2s[surface].append(surface_uv2_array.ptr()[vertex]); }
|
|
|
|
|
if (has_colour) { other_half_colours[surface].append(surface_colour_array.ptr()[vertex]); }
|
|
|
|
|
state->other_half_vertices[state->surface].append(surface_vertex_array_ptr[state->element]);
|
|
|
|
|
if (has_normal) { state->other_half_normals[state->surface].append(surface_normal_array.ptr()[state->element]); }
|
|
|
|
|
if (has_uv) { state->other_half_uvs[state->surface].append(surface_uv_array.ptr()[state->element]); }
|
|
|
|
|
if (has_uv2) { state->other_half_uv2s[state->surface].append(surface_uv2_array.ptr()[state->element]); }
|
|
|
|
|
if (has_colour) { state->other_half_colours[state->surface].append(surface_colour_array.ptr()[state->element]); }
|
|
|
|
|
if (has_tangent)
|
|
|
|
|
{
|
|
|
|
|
other_half_tangents[surface].append(surface_tangent_array.ptr()[vertex * 4]);
|
|
|
|
|
other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 1]);
|
|
|
|
|
other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 2]);
|
|
|
|
|
other_half_tangents[surface].append(surface_tangent_array.ptr()[(vertex * 4) + 3]);
|
|
|
|
|
state->other_half_tangents[state->surface].append(surface_tangent_array.ptr()[state->element * 4]);
|
|
|
|
|
state->other_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 1]);
|
|
|
|
|
state->other_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 2]);
|
|
|
|
|
state->other_half_tangents[state->surface].append(surface_tangent_array.ptr()[(state->element * 4) + 3]);
|
|
|
|
|
}
|
|
|
|
|
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()[(state->element * surface_num_custom0_per_vertex) + i];
|
|
|
|
|
state->other_half_custom0[state->surface].append(value);
|
|
|
|
|
hit_grid[i] = value;
|
|
|
|
|
}
|
|
|
|
|
state->other_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
|
}
|
|
|
|
|
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_weights[surface].append(surface_weight_array.ptr()[(vertex * num_bones_per_vertex) + i]);
|
|
|
|
|
state->other_half_bones[state->surface].append(surface_bone_array.ptr()[(state->element * surface_num_bones_per_vertex) + i]);
|
|
|
|
|
state->other_half_weights[state->surface].append(surface_weight_array.ptr()[(state->element * 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");
|
|
|
|
|
state->element = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state->output->hit_map = state->first_half_split_map & state->other_half_split_map;
|
|
|
|
|
|
|
|
|
|
state->surface = 0;
|
|
|
|
|
state->current_stage = MeshEditSliceStage::SLICE_STAGE_EDGE_SPLIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MeshEditingLibrary::slice_mesh_edge_split(Ref<MeshSliceState> state)
|
|
|
|
|
{
|
|
|
|
|
for (state->surface; state->surface < state->num_surfaces; state->surface++)
|
|
|
|
|
{
|
|
|
|
|
Ref<Material> original_material = state->original_mesh->surface_get_material(state->surface);
|
|
|
|
|
|
|
|
|
|
if (!(first_half_vertices[surface].size() > 0 && other_half_vertices[surface].size() > 0))
|
|
|
|
|
const PackedVector3Array &surface_vertex_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_VERTEX];
|
|
|
|
|
const PackedVector3Array &surface_normal_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_NORMAL];
|
|
|
|
|
const PackedFloat32Array &surface_tangent_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TANGENT];
|
|
|
|
|
const PackedVector2Array &surface_uv_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV];
|
|
|
|
|
const PackedVector2Array &surface_uv2_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_TEX_UV2];
|
|
|
|
|
const PackedColorArray &surface_colour_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_COLOR];
|
|
|
|
|
const PackedInt32Array &surface_bone_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_BONES];
|
|
|
|
|
const PackedFloat32Array &surface_weight_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_WEIGHTS];
|
|
|
|
|
const PackedFloat32Array &surface_custom0_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_CUSTOM0];
|
|
|
|
|
const PackedInt32Array &surface_index_array = state->surface_arrays_list[state->surface][ArrayMesh::ARRAY_INDEX];
|
|
|
|
|
|
|
|
|
|
SkinnedVertices &surface_skinned_vertex_positions = state->skinned_vertex_positions[state->surface];
|
|
|
|
|
std::vector<Transform3D> &surface_skinned_vertex_transforms = state->skinned_vertex_transforms[state->surface];
|
|
|
|
|
|
|
|
|
|
const std::vector<float> &vertex_distance = state->vertex_distances[state->surface];
|
|
|
|
|
|
|
|
|
|
const bool &has_normal = state->has_normal[state->surface];
|
|
|
|
|
const bool &has_tangent = state->has_tangent[state->surface];
|
|
|
|
|
const bool &has_uv = state->has_uv[state->surface];
|
|
|
|
|
const bool &has_uv2 = state->has_uv2[state->surface];
|
|
|
|
|
const bool &has_colour = state->has_colour[state->surface];
|
|
|
|
|
const bool &has_bone = state->has_bone[state->surface];
|
|
|
|
|
const bool &has_weight = state->has_weight[state->surface];
|
|
|
|
|
const bool &has_custom0 = state->has_custom0[state->surface];
|
|
|
|
|
|
|
|
|
|
const uint8_t &surface_num_bones_per_vertex = state->num_bones_per_vertex[state->surface];
|
|
|
|
|
const uint8_t &surface_num_custom0_per_vertex = state->num_custom0_per_vertex[state->surface];
|
|
|
|
|
|
|
|
|
|
if (!(state->first_half_vertices[state->surface].size() > 0 && state->other_half_vertices[state->surface].size() > 0))
|
|
|
|
|
{
|
|
|
|
|
if (first_half_vertices[surface].size() > 0)
|
|
|
|
|
if (state->first_half_vertices[state->surface].size() > 0)
|
|
|
|
|
{
|
|
|
|
|
first_half_indices[surface] = surface_index_array;
|
|
|
|
|
state->first_half_indices[state->surface] = surface_index_array;
|
|
|
|
|
}
|
|
|
|
|
else if (other_half_vertices[surface].size() > 0)
|
|
|
|
|
else if (state->other_half_vertices[state->surface].size() > 0)
|
|
|
|
|
{
|
|
|
|
|
other_half_indices[surface] = surface_index_array;
|
|
|
|
|
state->other_half_indices[state->surface] = surface_index_array;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const uint32_t num_triangles = surface_index_array.size();
|
|
|
|
|
for (uint32_t triangle_index = 0; triangle_index < num_triangles; triangle_index += 3)
|
|
|
|
|
for (state->element; state->element < num_triangles; state->element += 3)
|
|
|
|
|
{
|
|
|
|
|
uint32_t base_v[3];
|
|
|
|
|
std::map<uint32_t, uint32_t>::iterator sliced_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_other_sliced_end = base_to_other_sliced_vert_index.end();
|
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_first_sliced_end = state->base_to_first_sliced_vert_indices[state->surface].end();
|
|
|
|
|
const std::map<uint32_t, uint32_t>::iterator base_to_other_sliced_end = state->base_to_other_sliced_vert_indices[state->surface].end();
|
|
|
|
|
for (uint32_t i = 0; i < 3; i++)
|
|
|
|
|
{
|
|
|
|
|
base_v[i] = surface_index_array.ptr()[triangle_index + i];
|
|
|
|
|
sliced_v[i] = base_to_sliced_vert_index.find(base_v[i]);
|
|
|
|
|
sliced_other_v[i] = base_to_other_sliced_vert_index.find(base_v[i]);
|
|
|
|
|
base_v[i] = surface_index_array.ptr()[state->element + i];
|
|
|
|
|
sliced_v[i] = state->base_to_first_sliced_vert_indices[state->surface].find(base_v[i]);
|
|
|
|
|
sliced_other_v[i] = state->base_to_other_sliced_vert_indices[state->surface].find(base_v[i]);
|
|
|
|
|
|
|
|
|
|
// 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] != state->base_to_first_sliced_vert_indices[state->surface].end()) != (sliced_other_v[i] != state->base_to_other_sliced_vert_indices[state->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.
|
|
|
|
|
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[2]->second);
|
|
|
|
|
state->first_half_indices[state->surface].append(sliced_v[0]->second);
|
|
|
|
|
state->first_half_indices[state->surface].append(sliced_v[1]->second);
|
|
|
|
|
state->first_half_indices[state->surface].append(sliced_v[2]->second);
|
|
|
|
|
}
|
|
|
|
|
else if (sliced_other_v[0] != base_to_other_sliced_end && sliced_other_v[1] != base_to_other_sliced_end && sliced_other_v[2] != base_to_other_sliced_end)
|
|
|
|
|
{ // If the triangle is entirely in the second slice, send all the vertices to the second slice.
|
|
|
|
|
other_half_indices[surface].append(sliced_other_v[0]->second);
|
|
|
|
|
other_half_indices[surface].append(sliced_other_v[1]->second);
|
|
|
|
|
other_half_indices[surface].append(sliced_other_v[2]->second);
|
|
|
|
|
state->other_half_indices[state->surface].append(sliced_other_v[0]->second);
|
|
|
|
|
state->other_half_indices[state->surface].append(sliced_other_v[1]->second);
|
|
|
|
|
state->other_half_indices[state->surface].append(sliced_other_v[2]->second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ // If the triangle is split by the slice plane, then slice the overlapping edges.
|
|
|
|
@@ -252,7 +354,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
num_final_verts++;
|
|
|
|
@@ -264,22 +366,22 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 Vector3 &interp_vert = surface_vertex_array[base_v[this_vert]].lerp(
|
|
|
|
|
surface_vertex_array[base_v[next_vert]], alpha);
|
|
|
|
|
|
|
|
|
|
final_verts[num_final_verts++] = first_half_vertices[surface].size();
|
|
|
|
|
other_final_verts[num_other_final_verts++] = other_half_vertices[surface].size();
|
|
|
|
|
final_verts[num_final_verts++] = state->first_half_vertices[state->surface].size();
|
|
|
|
|
other_final_verts[num_other_final_verts++] = state->other_half_vertices[state->surface].size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Vector3 &skinned_interp_vert = surface_skinned_vertex_positions[base_v[this_vert]].lerp(
|
|
|
|
|
surface_skinned_vertex_positions[base_v[next_vert]], alpha);
|
|
|
|
|
MeshEditVert3D edge_vertex;
|
|
|
|
|
edge_vertex.surface = surface;
|
|
|
|
|
edge_vertex.index = first_half_vertices[surface].size();
|
|
|
|
|
edge_vertex.surface = state->surface;
|
|
|
|
|
edge_vertex.index = state->first_half_vertices[state->surface].size();
|
|
|
|
|
edge_vertex.position = skinned_interp_vert;
|
|
|
|
|
if (clipped_edges == 0)
|
|
|
|
|
{
|
|
|
|
@@ -292,14 +394,14 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
clipped_edges++;
|
|
|
|
|
assert(clipped_edges <= 2);
|
|
|
|
|
|
|
|
|
|
first_half_vertices[surface].append(interp_vert);
|
|
|
|
|
other_half_vertices[surface].append(interp_vert);
|
|
|
|
|
state->first_half_vertices[state->surface].append(interp_vert);
|
|
|
|
|
state->other_half_vertices[state->surface].append(interp_vert);
|
|
|
|
|
|
|
|
|
|
if (has_normal)
|
|
|
|
|
{
|
|
|
|
|
const Vector3 interp_normal = surface_normal_array.ptr()[base_v[this_vert]].slerp(surface_normal_array.ptr()[base_v[next_vert]], alpha);
|
|
|
|
|
first_half_normals[surface].append(interp_normal);
|
|
|
|
|
other_half_normals[surface].append(interp_normal);
|
|
|
|
|
state->first_half_normals[state->surface].append(interp_normal);
|
|
|
|
|
state->other_half_normals[state->surface].append(interp_normal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_tangent)
|
|
|
|
@@ -314,49 +416,49 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
const Vector3 &interp_tangent = this_tangent.slerp(next_tangent, alpha);
|
|
|
|
|
const uint8_t &interp_binormal = UtilityFunctions::roundi(UtilityFunctions::lerpf(this_binormal, next_binormal, alpha));
|
|
|
|
|
|
|
|
|
|
first_half_tangents[surface].append(interp_tangent.x);
|
|
|
|
|
first_half_tangents[surface].append(interp_tangent.y);
|
|
|
|
|
first_half_tangents[surface].append(interp_tangent.z);
|
|
|
|
|
first_half_tangents[surface].append(interp_binormal);
|
|
|
|
|
state->first_half_tangents[state->surface].append(interp_tangent.x);
|
|
|
|
|
state->first_half_tangents[state->surface].append(interp_tangent.y);
|
|
|
|
|
state->first_half_tangents[state->surface].append(interp_tangent.z);
|
|
|
|
|
state->first_half_tangents[state->surface].append(interp_binormal);
|
|
|
|
|
|
|
|
|
|
other_half_tangents[surface].append(interp_tangent.x);
|
|
|
|
|
other_half_tangents[surface].append(interp_tangent.y);
|
|
|
|
|
other_half_tangents[surface].append(interp_tangent.z);
|
|
|
|
|
other_half_tangents[surface].append(interp_binormal);
|
|
|
|
|
state->other_half_tangents[state->surface].append(interp_tangent.x);
|
|
|
|
|
state->other_half_tangents[state->surface].append(interp_tangent.y);
|
|
|
|
|
state->other_half_tangents[state->surface].append(interp_tangent.z);
|
|
|
|
|
state->other_half_tangents[state->surface].append(interp_binormal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_uv)
|
|
|
|
|
{
|
|
|
|
|
const Vector2 &interp_uv = surface_uv_array.ptr()[base_v[this_vert]].lerp(surface_uv_array.ptr()[base_v[next_vert]], alpha);
|
|
|
|
|
first_half_uvs[surface].append(interp_uv);
|
|
|
|
|
other_half_uvs[surface].append(interp_uv);
|
|
|
|
|
state->first_half_uvs[state->surface].append(interp_uv);
|
|
|
|
|
state->other_half_uvs[state->surface].append(interp_uv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_uv2)
|
|
|
|
|
{
|
|
|
|
|
const Vector2 &interp_uv2 = surface_uv2_array.ptr()[base_v[this_vert]].lerp(surface_uv2_array.ptr()[base_v[next_vert]], alpha);
|
|
|
|
|
first_half_uv2s[surface].append(interp_uv2);
|
|
|
|
|
other_half_uv2s[surface].append(interp_uv2);
|
|
|
|
|
state->first_half_uv2s[state->surface].append(interp_uv2);
|
|
|
|
|
state->other_half_uv2s[state->surface].append(interp_uv2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(
|
|
|
|
|
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],
|
|
|
|
|
surface_custom0_array.ptr()[(base_v[this_vert] * surface_num_custom0_per_vertex) + i],
|
|
|
|
|
surface_custom0_array.ptr()[(base_v[next_vert] * surface_num_custom0_per_vertex) + i],
|
|
|
|
|
alpha);
|
|
|
|
|
first_half_custom0[surface].append(interp_custom0);
|
|
|
|
|
other_half_custom0[surface].append(interp_custom0);
|
|
|
|
|
state->first_half_custom0[state->surface].append(interp_custom0);
|
|
|
|
|
state->other_half_custom0[state->surface].append(interp_custom0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
first_half_colours[surface].append(interp_colour);
|
|
|
|
|
other_half_colours[surface].append(interp_colour);
|
|
|
|
|
state->first_half_colours[state->surface].append(interp_colour);
|
|
|
|
|
state->other_half_colours[state->surface].append(interp_colour);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_bone && has_weight)
|
|
|
|
@@ -366,10 +468,10 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
// First pack all active bones and weights into a list of pairs
|
|
|
|
|
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 float weight = surface_weight_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] * surface_num_bones_per_vertex) + vertex_bone];
|
|
|
|
|
if (weight > TINY_NUMBER) { positive_side_bones_and_weights[bone] = weight; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -378,10 +480,10 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
// 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::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 float other_weight = surface_weight_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] * surface_num_bones_per_vertex) + other_bone_index];
|
|
|
|
|
|
|
|
|
|
if (negative_side_bones_and_weights.find(other_bone) != negative_side_bones_and_weights.end())
|
|
|
|
|
{
|
|
|
|
@@ -419,22 +521,22 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
[=](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
|
|
|
|
|
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())
|
|
|
|
|
{
|
|
|
|
|
const float normalised_weight = bone_weight_pairs[vertex_bone].second / normalisation_value;
|
|
|
|
|
first_half_bones[surface].append(bone_weight_pairs[vertex_bone].first);
|
|
|
|
|
first_half_weights[surface].append(normalised_weight);
|
|
|
|
|
other_half_bones[surface].append(bone_weight_pairs[vertex_bone].first);
|
|
|
|
|
other_half_weights[surface].append(normalised_weight);
|
|
|
|
|
state->first_half_bones[state->surface].append(bone_weight_pairs[vertex_bone].first);
|
|
|
|
|
state->first_half_weights[state->surface].append(normalised_weight);
|
|
|
|
|
state->other_half_bones[state->surface].append(bone_weight_pairs[vertex_bone].first);
|
|
|
|
|
state->other_half_weights[state->surface].append(normalised_weight);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
first_half_bones[surface].append(0);
|
|
|
|
|
first_half_weights[surface].append(0.0f);
|
|
|
|
|
other_half_bones[surface].append(0);
|
|
|
|
|
other_half_weights[surface].append(0.0f);
|
|
|
|
|
state->first_half_bones[state->surface].append(0);
|
|
|
|
|
state->first_half_weights[state->surface].append(0.0f);
|
|
|
|
|
state->other_half_bones[state->surface].append(0);
|
|
|
|
|
state->other_half_weights[state->surface].append(0.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -447,23 +549,25 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
|
|
|
|
|
// There should always be exactly two sliced edges per triangle
|
|
|
|
|
assert(clipped_edges == 2);
|
|
|
|
|
clip_edges.emplace_back(new_clip_edge);
|
|
|
|
|
state->clip_edges.emplace_back(new_clip_edge);
|
|
|
|
|
|
|
|
|
|
for (uint32_t vertex_index = 2; vertex_index < num_final_verts; vertex_index++)
|
|
|
|
|
{
|
|
|
|
|
first_half_indices[surface].append(final_verts[0]);
|
|
|
|
|
first_half_indices[surface].append(final_verts[vertex_index - 1]);
|
|
|
|
|
first_half_indices[surface].append(final_verts[vertex_index]);
|
|
|
|
|
state->first_half_indices[state->surface].append(final_verts[0]);
|
|
|
|
|
state->first_half_indices[state->surface].append(final_verts[vertex_index - 1]);
|
|
|
|
|
state->first_half_indices[state->surface].append(final_verts[vertex_index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t vertex_index = 2; vertex_index < num_other_final_verts; vertex_index++)
|
|
|
|
|
{
|
|
|
|
|
other_half_indices[surface].append(other_final_verts[0]);
|
|
|
|
|
other_half_indices[surface].append(other_final_verts[vertex_index - 1]);
|
|
|
|
|
other_half_indices[surface].append(other_final_verts[vertex_index]);
|
|
|
|
|
state->other_half_indices[state->surface].append(other_final_verts[0]);
|
|
|
|
|
state->other_half_indices[state->surface].append(other_final_verts[vertex_index - 1]);
|
|
|
|
|
state->other_half_indices[state->surface].append(other_final_verts[vertex_index]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state->element = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t array_format_bit_mask = Mesh::ARRAY_FORMAT_VERTEX;
|
|
|
|
@@ -477,57 +581,60 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
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 (state->first_half_vertices[state->surface].size() > 0 && state->first_half_indices[state->surface].size() > 0)
|
|
|
|
|
{
|
|
|
|
|
Array first_half_section;
|
|
|
|
|
first_half_section.resize(ArrayMesh::ARRAY_MAX);
|
|
|
|
|
first_half_section[ArrayMesh::ARRAY_VERTEX] = first_half_vertices[surface];
|
|
|
|
|
if (has_normal) first_half_section[ArrayMesh::ARRAY_NORMAL] = first_half_normals[surface];
|
|
|
|
|
if (has_tangent) first_half_section[ArrayMesh::ARRAY_TANGENT] = first_half_tangents[surface];
|
|
|
|
|
if (has_uv) first_half_section[ArrayMesh::ARRAY_TEX_UV] = first_half_uvs[surface];
|
|
|
|
|
if (has_uv2) first_half_section[ArrayMesh::ARRAY_TEX_UV2] = first_half_uv2s[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_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_VERTEX] = state->first_half_vertices[state->surface];
|
|
|
|
|
if (has_normal) first_half_section[ArrayMesh::ARRAY_NORMAL] = state->first_half_normals[state->surface];
|
|
|
|
|
if (has_tangent) first_half_section[ArrayMesh::ARRAY_TANGENT] = state->first_half_tangents[state->surface];
|
|
|
|
|
if (has_uv) first_half_section[ArrayMesh::ARRAY_TEX_UV] = state->first_half_uvs[state->surface];
|
|
|
|
|
if (has_uv2) first_half_section[ArrayMesh::ARRAY_TEX_UV2] = state->first_half_uv2s[state->surface];
|
|
|
|
|
if (has_colour) first_half_section[ArrayMesh::ARRAY_COLOR] = state->first_half_colours[state->surface];
|
|
|
|
|
if (has_bone) first_half_section[ArrayMesh::ARRAY_BONES] = state->first_half_bones[state->surface];
|
|
|
|
|
if (has_weight) first_half_section[ArrayMesh::ARRAY_WEIGHTS] = state->first_half_weights[state->surface];
|
|
|
|
|
if (has_custom0) first_half_section[ArrayMesh::ARRAY_CUSTOM0] = state->first_half_custom0[state->surface];
|
|
|
|
|
first_half_section[ArrayMesh::ARRAY_INDEX] = state->first_half_indices[state->surface];
|
|
|
|
|
|
|
|
|
|
const uint16_t next_surface = out_first_half->get_surface_count();
|
|
|
|
|
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);
|
|
|
|
|
const uint16_t next_surface = state->first_half->get_surface_count();
|
|
|
|
|
state->first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
|
state->first_half->surface_set_material(next_surface, original_material);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (other_half_vertices[surface].size() > 0 && other_half_indices[surface].size() > 0)
|
|
|
|
|
if (state->other_half_vertices[state->surface].size() > 0 && state->other_half_indices[state->surface].size() > 0)
|
|
|
|
|
{
|
|
|
|
|
Array other_half_section;
|
|
|
|
|
other_half_section.resize(ArrayMesh::ARRAY_MAX);
|
|
|
|
|
other_half_section[ArrayMesh::ARRAY_VERTEX] = other_half_vertices[surface];
|
|
|
|
|
if (has_normal) other_half_section[ArrayMesh::ARRAY_NORMAL] = other_half_normals[surface];
|
|
|
|
|
if (has_tangent) other_half_section[ArrayMesh::ARRAY_TANGENT] = other_half_tangents[surface];
|
|
|
|
|
if (has_uv) other_half_section[ArrayMesh::ARRAY_TEX_UV] = other_half_uvs[surface];
|
|
|
|
|
if (has_uv2) other_half_section[ArrayMesh::ARRAY_TEX_UV2] = other_half_uv2s[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_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_VERTEX] = state->other_half_vertices[state->surface];
|
|
|
|
|
if (has_normal) other_half_section[ArrayMesh::ARRAY_NORMAL] = state->other_half_normals[state->surface];
|
|
|
|
|
if (has_tangent) other_half_section[ArrayMesh::ARRAY_TANGENT] = state->other_half_tangents[state->surface];
|
|
|
|
|
if (has_uv) other_half_section[ArrayMesh::ARRAY_TEX_UV] = state->other_half_uvs[state->surface];
|
|
|
|
|
if (has_uv2) other_half_section[ArrayMesh::ARRAY_TEX_UV2] = state->other_half_uv2s[state->surface];
|
|
|
|
|
if (has_colour) other_half_section[ArrayMesh::ARRAY_COLOR] = state->other_half_colours[state->surface];
|
|
|
|
|
if (has_bone) other_half_section[ArrayMesh::ARRAY_BONES] = state->other_half_bones[state->surface];
|
|
|
|
|
if (has_weight) other_half_section[ArrayMesh::ARRAY_WEIGHTS] = state->other_half_weights[state->surface];
|
|
|
|
|
if (has_custom0) other_half_section[ArrayMesh::ARRAY_CUSTOM0] = state->other_half_custom0[state->surface];
|
|
|
|
|
other_half_section[ArrayMesh::ARRAY_INDEX] = state->other_half_indices[state->surface];
|
|
|
|
|
|
|
|
|
|
const uint16_t next_surface = out_other_half->get_surface_count();
|
|
|
|
|
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);
|
|
|
|
|
const uint16_t next_surface = state->other_half->get_surface_count();
|
|
|
|
|
state->other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
|
state->other_half->surface_set_material(next_surface, original_material);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
skinned_vertex_transforms.emplace_back(surface_skinned_vertex_transforms);
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
state->surface = 0;
|
|
|
|
|
state->current_stage = MeshEditSliceStage::SLICE_STAGE_APPLY_CAP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MeshEditingLibrary::slice_mesh_apply_cap(Ref<MeshSliceState> state)
|
|
|
|
|
{
|
|
|
|
|
if (state->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();
|
|
|
|
|
const Basis &mesh_instance_basis = state->input->mesh_instance->get_basis();
|
|
|
|
|
const Vector3 &local_plane_normal = state->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)
|
|
|
|
|
{
|
|
|
|
|
uv_plane = MeshSlicePlaneOrientation::Y;
|
|
|
|
@@ -549,14 +656,14 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
std::vector<MeshEditEdge2D> edges_2d;
|
|
|
|
|
std::vector<MeshEditPolygon2D> polygon_set;
|
|
|
|
|
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, state->clip_edges, state->input->local_plane);
|
|
|
|
|
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(state->input->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 = state->input->full_aabb.get_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 (state->element; state->element < num_polygons; state->element++)
|
|
|
|
|
{
|
|
|
|
|
using Point = std::array<float,2>;
|
|
|
|
|
using Polygon = std::vector<std::vector<Point>>;
|
|
|
|
@@ -567,47 +674,47 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
Vector3 polygon_centroid;
|
|
|
|
|
|
|
|
|
|
uint32_t polygon_vertex_counter = 0;
|
|
|
|
|
for (const MeshEditVert2D &vertex : polygon_set[polygon_index].vertices)
|
|
|
|
|
for (const MeshEditVert2D &vertex : polygon_set[state->element].vertices)
|
|
|
|
|
{
|
|
|
|
|
const Vector3 &position = first_half_vertices[vertex.surface][vertex.index];
|
|
|
|
|
const Vector3 &position = state->first_half_vertices[vertex.surface][vertex.index];
|
|
|
|
|
|
|
|
|
|
const Transform3D &skinned_vertex_transform = skinned_vertex_transforms[vertex.surface][vertex.index];
|
|
|
|
|
const Transform3D &skinned_vertex_transform = state->skinned_vertex_transforms[vertex.surface][vertex.index];
|
|
|
|
|
|
|
|
|
|
const Vector2 &uv = MeshEditingLibrary::calculate_planar_uv(position, mesh_bounds, uv_plane);
|
|
|
|
|
surface_tool_first_half->set_uv(uv);
|
|
|
|
|
surface_tool_other_half->set_uv(uv);
|
|
|
|
|
if (surface_has_uv2[vertex.surface])
|
|
|
|
|
if (state->has_uv2[vertex.surface])
|
|
|
|
|
{
|
|
|
|
|
surface_tool_first_half->set_uv2(uv);
|
|
|
|
|
surface_tool_other_half->set_uv2(uv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (surface_has_custom0[vertex.surface])
|
|
|
|
|
if (state->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],
|
|
|
|
|
state->first_half_custom0[vertex.surface][(vertex.index * 2)],
|
|
|
|
|
state->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 (state->has_colour[vertex.surface])
|
|
|
|
|
{
|
|
|
|
|
const Color &colour = first_half_colours[vertex.surface][vertex.index];
|
|
|
|
|
const Color &colour = state->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])
|
|
|
|
|
if (state->has_bone[vertex.surface] && state->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++)
|
|
|
|
|
for (uint8_t i = 0; i < state->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];
|
|
|
|
|
weights[i] = first_half_weights[vertex.surface][(vertex.index * surface_num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
|
bones[i] = state->first_half_bones[vertex.surface][(vertex.index * state->num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
|
weights[i] = state->first_half_weights[vertex.surface][(vertex.index * state->num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
surface_tool_first_half->set_bones(bones);
|
|
|
|
@@ -626,8 +733,8 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
polygon_vertex_counter++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
|
|
|
|
impact_points.append(polygon_centroid);
|
|
|
|
|
polygon_centroid /= polygon_set[state->element].vertices.size();
|
|
|
|
|
state->output->impact_points.append(polygon_centroid);
|
|
|
|
|
|
|
|
|
|
earcut_polygon.push_back(sub_polygon);
|
|
|
|
|
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
|
|
|
@@ -655,20 +762,28 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|
|
|
|
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]);
|
|
|
|
|
surface_tool_first_half->set_material(state->input->cap_materials[uv_plane]);
|
|
|
|
|
surface_tool_other_half->set_material(state->input->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);
|
|
|
|
|
state->first_half = surface_tool_first_half->commit(state->first_half);
|
|
|
|
|
state->other_half = surface_tool_other_half->commit(state->other_half);
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Created cap surfaces at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
memdelete(surface_tool_first_half);
|
|
|
|
|
memdelete(surface_tool_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");
|
|
|
|
|
// PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Generated final cap surface at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
|
|
return impact_points;
|
|
|
|
|
state->output->original_skeleton = state->input->skeleton;
|
|
|
|
|
state->output->main_half = state->first_half;
|
|
|
|
|
state->output->secondary_half = state->other_half;
|
|
|
|
|
|
|
|
|
|
state->current_stage = MeshEditSliceStage::SLICE_STAGE_COMPLETE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|