|
|
|
@@ -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,277 +16,324 @@
|
|
|
|
|
using namespace godot;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceInput> input)
|
|
|
|
|
Ref<MeshSliceState> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceInput> input)
|
|
|
|
|
{
|
|
|
|
|
Ref<MeshEditSliceOutput> out; out.instantiate();
|
|
|
|
|
Ref<MeshSliceState> fresh_state;
|
|
|
|
|
fresh_state.instantiate();
|
|
|
|
|
|
|
|
|
|
Ref<ArrayMesh> first_half; first_half.instantiate();
|
|
|
|
|
Ref<ArrayMesh> other_half; other_half.instantiate();
|
|
|
|
|
fresh_state->input = input;
|
|
|
|
|
|
|
|
|
|
const Time *time = Time::get_singleton();
|
|
|
|
|
fresh_state->output.instantiate();
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
fresh_state->first_half.instantiate();
|
|
|
|
|
fresh_state->other_half.instantiate();
|
|
|
|
|
|
|
|
|
|
const Ref<ArrayMesh> original_mesh = input->sliceable_mesh_instance->get_mesh();
|
|
|
|
|
const uint8_t num_surfaces = original_mesh->get_surface_count();
|
|
|
|
|
return fresh_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
void MeshEditingLibrary::slice_mesh_init(Ref<MeshSliceState> state)
|
|
|
|
|
{
|
|
|
|
|
{ // Initialise the state here
|
|
|
|
|
// const Time *time = Time::get_singleton();
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
// PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Started slicing mesh at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
state->original_mesh = state->input->mesh_instance->get_mesh();
|
|
|
|
|
state->num_surfaces = state->original_mesh->get_surface_count();
|
|
|
|
|
|
|
|
|
|
std::vector<uint8_t> num_bones_per_vertex; num_bones_per_vertex.resize(num_surfaces);
|
|
|
|
|
std::vector<uint8_t> num_custom0_per_vertex; num_custom0_per_vertex.resize(num_surfaces);
|
|
|
|
|
// PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Got skinned vertices at ", time->get_ticks_msec(), "ms");
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
state->surface_arrays_list.resize(state->num_surfaces);
|
|
|
|
|
state->skinned_vertex_positions.resize(state->num_surfaces);
|
|
|
|
|
state->skinned_vertex_transforms.resize(state->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);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
std::vector<PackedInt32Array> first_half_indices; first_half_indices.resize(num_surfaces);
|
|
|
|
|
std::vector<PackedInt32Array> other_half_indices; other_half_indices.resize(num_surfaces);
|
|
|
|
|
state->num_bones_per_vertex.resize(state->num_surfaces);
|
|
|
|
|
state->num_custom0_per_vertex.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<float>> vertex_distances; vertex_distances.resize(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);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
uint32_t first_half_split_map = 0x00000000;
|
|
|
|
|
uint32_t other_half_split_map = 0x00000000;
|
|
|
|
|
state->first_half_indices.resize(state->num_surfaces);
|
|
|
|
|
state->other_half_indices.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
std::vector<MeshEditEdge3D> clip_edges;
|
|
|
|
|
state->vertex_distances.resize(state->num_surfaces);
|
|
|
|
|
|
|
|
|
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
|
|
|
|
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++)
|
|
|
|
|
{
|
|
|
|
|
std::vector<Transform3D> 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;
|
|
|
|
|
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]);
|
|
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
surface_arrays_list[surface] = surface_arrays;
|
|
|
|
|
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::map<uint32_t, uint32_t> &base_to_first_sliced_vert_index = base_to_first_sliced_vert_indices[surface];
|
|
|
|
|
std::map<uint32_t, uint32_t> &base_to_other_sliced_vert_index = base_to_other_sliced_vert_indices[surface];
|
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)state->original_mesh->surface_get_format(state->surface);
|
|
|
|
|
|
|
|
|
|
std::vector<float> &vertex_distance = vertex_distances[surface];
|
|
|
|
|
vertex_distance.resize(num_vertices);
|
|
|
|
|
|
|
|
|
|
const int64_t &original_mesh_format_mask = (int64_t)original_mesh->surface_get_format(surface);
|
|
|
|
|
|
|
|
|
|
const bool has_normal = surface_normal_array.size() >= num_vertices; surface_has_normal[surface] = has_normal;
|
|
|
|
|
const bool has_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 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 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;
|
|
|
|
|
state->num_bones_per_vertex[state->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)) ==
|
|
|
|
|
(Mesh::ARRAY_CUSTOM_RGBA_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT)) ? 4 : 2 ) : 0;
|
|
|
|
|
num_custom0_per_vertex[surface] = surface_num_custom0_per_vertex;
|
|
|
|
|
state->num_custom0_per_vertex[state->surface] = surface_num_custom0_per_vertex;
|
|
|
|
|
|
|
|
|
|
for (uint32_t vertex = 0; vertex < num_vertices; 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++)
|
|
|
|
|
{
|
|
|
|
|
vertex_distance[vertex] = input->local_plane.distance_to(surface_skinned_vertex_positions[vertex]);
|
|
|
|
|
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];
|
|
|
|
|
|
|
|
|
|
if (vertex_distance[vertex] >= 0.0f)
|
|
|
|
|
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++)
|
|
|
|
|
{
|
|
|
|
|
base_to_first_sliced_vert_index[vertex] = first_half_vertices[surface].size();
|
|
|
|
|
vertex_distances[state->element] = state->input->local_plane.distance_to(state->skinned_vertex_positions[state->surface][state->element]);
|
|
|
|
|
|
|
|
|
|
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]); }
|
|
|
|
|
if (vertex_distances[state->element] >= 0.0f)
|
|
|
|
|
{
|
|
|
|
|
base_to_first_sliced_vert_index[state->element] = state->first_half_vertices[state->surface].size();
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
float hit_grid[] = { 0.0f, 0.0f };
|
|
|
|
|
for (uint8_t i = 0; i < surface_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);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
first_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
|
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 < surface_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 * surface_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)
|
|
|
|
|
{
|
|
|
|
|
float hit_grid[] = { 0.0f, 0.0f };
|
|
|
|
|
for (uint8_t i = 0; i < surface_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);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
other_half_split_map |= (0x00000001 << MeshEditingLibrary::uv_to_body_part_shift(hit_grid[0], hit_grid[1]));
|
|
|
|
|
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 < surface_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 * surface_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]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out->hit_map = first_half_split_map & other_half_split_map;
|
|
|
|
|
state->output->hit_map = state->first_half_split_map & state->other_half_split_map;
|
|
|
|
|
|
|
|
|
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
|
|
|
|
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 = original_mesh->surface_get_material(surface);
|
|
|
|
|
Ref<Material> original_material = state->original_mesh->surface_get_material(state->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];
|
|
|
|
|
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 = skinned_vertex_positions[surface];
|
|
|
|
|
std::vector<Transform3D> &surface_skinned_vertex_transforms = skinned_vertex_transforms[surface];
|
|
|
|
|
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 = vertex_distances[surface];
|
|
|
|
|
const std::vector<float> &vertex_distance = state->vertex_distances[state->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 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 = num_bones_per_vertex[surface];
|
|
|
|
|
const uint8_t &surface_num_custom0_per_vertex = num_custom0_per_vertex[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 (!(first_half_vertices[surface].size() > 0 && other_half_vertices[surface].size() > 0))
|
|
|
|
|
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_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_indices[surface].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_first_sliced_vert_indices[surface].find(base_v[i]);
|
|
|
|
|
sliced_other_v[i] = base_to_other_sliced_vert_indices[surface].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_first_sliced_vert_indices[surface].end()) != (sliced_other_v[i] != base_to_other_sliced_vert_indices[surface].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_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.
|
|
|
|
@@ -328,15 +373,15 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
@@ -349,14 +394,14 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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)
|
|
|
|
@@ -371,29 +416,29 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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)
|
|
|
|
@@ -404,16 +449,16 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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)
|
|
|
|
@@ -481,17 +526,17 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -504,23 +549,25 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
@@ -534,57 +581,60 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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 = first_half->get_surface_count();
|
|
|
|
|
first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
|
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 = other_half->get_surface_count();
|
|
|
|
|
other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section, Array(), Dictionary(), array_format_bit_mask);
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state->surface = 0;
|
|
|
|
|
state->current_stage = MeshEditSliceStage::SLICE_STAGE_APPLY_CAP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clip_edges.size() > 0)
|
|
|
|
|
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 = input->sliceable_mesh_instance->get_basis();
|
|
|
|
|
const Vector3 &local_plane_normal = input->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;
|
|
|
|
@@ -606,14 +656,14 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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, input->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(input->sliceable_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 = input->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>>;
|
|
|
|
@@ -624,47 +674,47 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
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 < 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 * num_bones_per_vertex[vertex.surface]) + i];
|
|
|
|
|
weights[i] = first_half_weights[vertex.surface][(vertex.index * 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);
|
|
|
|
@@ -683,8 +733,8 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
polygon_vertex_counter++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
|
|
|
|
out->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);
|
|
|
|
@@ -712,23 +762,28 @@ Ref<MeshEditSliceOutput> MeshEditingLibrary::slice_mesh(const Ref<MeshEditSliceI
|
|
|
|
|
surface_tool_first_half->generate_tangents();
|
|
|
|
|
surface_tool_other_half->generate_tangents();
|
|
|
|
|
|
|
|
|
|
surface_tool_first_half->set_material(input->cap_materials[uv_plane]);
|
|
|
|
|
surface_tool_other_half->set_material(input->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]);
|
|
|
|
|
|
|
|
|
|
first_half = surface_tool_first_half->commit(first_half);
|
|
|
|
|
other_half = surface_tool_other_half->commit(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");
|
|
|
|
|
|
|
|
|
|
out->main_half = first_half;
|
|
|
|
|
out->secondary_half = other_half;
|
|
|
|
|
state->output->original_skeleton = state->input->skeleton;
|
|
|
|
|
state->output->main_half = state->first_half;
|
|
|
|
|
state->output->secondary_half = state->other_half;
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
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();
|
|
|
|
|