- MeshEditingLibrary now uses the mesh's full AABB for cap UV generation.
- MeshEditingLibrary can now also set X/Y/Z plane cap materials as needed.
This commit is contained in:
@@ -17,15 +17,7 @@
|
|||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
|
|
||||||
MeshEditingLibrary::MeshEditingLibrary()
|
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)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MeshEditingLibrary::~MeshEditingLibrary()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, Ref<ArrayMesh> out_first_half, Ref<ArrayMesh> out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material)
|
|
||||||
{
|
{
|
||||||
const Time *time = Time::get_singleton();
|
const Time *time = Time::get_singleton();
|
||||||
|
|
||||||
@@ -89,6 +81,8 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
|
|
||||||
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
for (uint8_t surface = 0; surface < num_surfaces; surface++)
|
||||||
{
|
{
|
||||||
|
Ref<Material> original_material = original_mesh->surface_get_material(surface);
|
||||||
|
|
||||||
const SkinnedVertices &surface_skinned_vertex_positions = skinned_vertex_positions[surface];
|
const SkinnedVertices &surface_skinned_vertex_positions = skinned_vertex_positions[surface];
|
||||||
|
|
||||||
const Array &surface_arrays = original_mesh->surface_get_arrays(surface);
|
const Array &surface_arrays = original_mesh->surface_get_arrays(surface);
|
||||||
@@ -458,8 +452,9 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
if (has_weight) first_half_section[ArrayMesh::ARRAY_WEIGHTS] = first_half_weights[surface];
|
if (has_weight) first_half_section[ArrayMesh::ARRAY_WEIGHTS] = first_half_weights[surface];
|
||||||
first_half_section[ArrayMesh::ARRAY_INDEX] = first_half_indices[surface];
|
first_half_section[ArrayMesh::ARRAY_INDEX] = first_half_indices[surface];
|
||||||
|
|
||||||
|
const uint16_t next_surface = out_first_half->get_surface_count();
|
||||||
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section);
|
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, first_half_section);
|
||||||
out_first_half->surface_set_material(surface, original_mesh->surface_get_material(surface));
|
out_first_half->surface_set_material(next_surface, original_material);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other_half_vertices[surface].size() > 0 && other_half_indices[surface].size() > 0)
|
if (other_half_vertices[surface].size() > 0 && other_half_indices[surface].size() > 0)
|
||||||
@@ -476,35 +471,36 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
if (has_weight) other_half_section[ArrayMesh::ARRAY_WEIGHTS] = other_half_weights[surface];
|
if (has_weight) other_half_section[ArrayMesh::ARRAY_WEIGHTS] = other_half_weights[surface];
|
||||||
other_half_section[ArrayMesh::ARRAY_INDEX] = other_half_indices[surface];
|
other_half_section[ArrayMesh::ARRAY_INDEX] = other_half_indices[surface];
|
||||||
|
|
||||||
|
const uint16_t next_surface = out_other_half->get_surface_count();
|
||||||
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section);
|
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, other_half_section);
|
||||||
out_other_half->surface_set_material(surface, original_mesh->surface_get_material(surface));
|
out_other_half->surface_set_material(next_surface, original_material);
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z;
|
||||||
|
const Basis &mesh_instance_basis = original_mesh_instance->get_basis();
|
||||||
|
const Vector3 &local_plane_normal = 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;
|
||||||
|
}
|
||||||
|
else if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(1.0f, 0.0f, 0.0f)))) > 0.5f)
|
||||||
|
{
|
||||||
|
uv_plane = MeshSlicePlaneOrientation::X;
|
||||||
|
}
|
||||||
|
|
||||||
if (clip_edges.size() > 0)
|
if (clip_edges.size() > 0)
|
||||||
{
|
{
|
||||||
std::vector<MeshEditEdge2D> edges_2d;
|
std::vector<MeshEditEdge2D> edges_2d;
|
||||||
std::vector<MeshEditPolygon2D> polygon_set;
|
std::vector<MeshEditPolygon2D> polygon_set;
|
||||||
std::vector<MeshEditPolygon2D> error_polygons;
|
std::vector<MeshEditPolygon2D> error_polygons;
|
||||||
const Transform3D &plane_inverse_transform = MeshEditingLibrary::project_edges(edges_2d, original_mesh_instance->get_transform(), clip_edges, local_plane);
|
const Transform3D &plane_inverse_transform = MeshEditingLibrary::project_edges(edges_2d, clip_edges, local_plane);
|
||||||
MeshEditingLibrary::build_2d_polygons_from_edges(polygon_set, edges_2d, error_polygons);
|
MeshEditingLibrary::build_2d_polygons_from_edges(polygon_set, edges_2d, error_polygons);
|
||||||
MeshEditingLibrary::draw_debug_polygons(original_mesh_instance, error_polygons, plane_inverse_transform, Color(1.0f, 0.0f, 0.0f, 1.0f));
|
MeshEditingLibrary::draw_debug_polygons(original_mesh_instance, error_polygons, plane_inverse_transform, Color(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
MeshSlicePlaneOrientation uv_plane = MeshSlicePlaneOrientation::Z;
|
const Vector3 &mesh_bounds = original_aabb.get_size();
|
||||||
const Basis &mesh_instance_basis = original_mesh_instance->get_basis();
|
|
||||||
const Vector3 &local_plane_normal = 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;
|
|
||||||
}
|
|
||||||
else if (UtilityFunctions::absf(local_plane_normal.dot(mesh_instance_basis.xform(Vector3(1.0f, 0.0f, 0.0f)))) > 0.5f)
|
|
||||||
{
|
|
||||||
uv_plane = MeshSlicePlaneOrientation::X;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vector3 &mesh_bounds = original_mesh->get_aabb().get_size();
|
|
||||||
const uint32_t num_polygons = polygon_set.size();
|
const uint32_t num_polygons = polygon_set.size();
|
||||||
for (uint32_t polygon_index = 0; polygon_index < num_polygons; polygon_index++)
|
for (uint32_t polygon_index = 0; polygon_index < num_polygons; polygon_index++)
|
||||||
{
|
{
|
||||||
@@ -588,7 +584,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
if (cap_section_bones.size()) cap_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones;
|
if (cap_section_bones.size()) cap_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones;
|
||||||
if (cap_section_weights.size()) cap_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights;
|
if (cap_section_weights.size()) cap_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights;
|
||||||
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_mesh_section);
|
out_first_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_mesh_section);
|
||||||
out_first_half->surface_set_material(out_first_half->get_surface_count()-1, cap_material);
|
out_first_half->surface_set_material(out_first_half->get_surface_count()-1, cap_materials[uv_plane]);
|
||||||
|
|
||||||
const uint32_t num_cap_triangles = cap_section_indices.size();
|
const uint32_t num_cap_triangles = cap_section_indices.size();
|
||||||
for (uint32_t i = 0; i < num_cap_triangles; i += 3)
|
for (uint32_t i = 0; i < num_cap_triangles; i += 3)
|
||||||
@@ -610,7 +606,7 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(MeshInstance3D *original_mesh_
|
|||||||
if (cap_section_bones.size()) cap_other_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones;
|
if (cap_section_bones.size()) cap_other_mesh_section[ArrayMesh::ARRAY_BONES] = cap_section_bones;
|
||||||
if (cap_section_weights.size()) cap_other_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights;
|
if (cap_section_weights.size()) cap_other_mesh_section[ArrayMesh::ARRAY_WEIGHTS] = cap_section_weights;
|
||||||
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_other_mesh_section);
|
out_other_half->add_surface_from_arrays(ArrayMesh::PRIMITIVE_TRIANGLES, cap_other_mesh_section);
|
||||||
out_other_half->surface_set_material(out_other_half->get_surface_count()-1, cap_material);
|
out_other_half->surface_set_material(out_other_half->get_surface_count()-1, cap_materials[uv_plane]);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Generated final cap surface at ", time->get_ticks_msec(), "ms");
|
PRINT_LOG(MESH_EDITING_LIBRARY_TAG, "Generated final cap surface at ", time->get_ticks_msec(), "ms");
|
||||||
@@ -717,7 +713,7 @@ SkinnedSurfaces MeshEditingLibrary::get_skinned_vertex_positions(const Mesh *mes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Transform3D MeshEditingLibrary::project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const Transform3D &to_node_space, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane)
|
const Transform3D MeshEditingLibrary::project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane)
|
||||||
{
|
{
|
||||||
out_2d_edges.resize(in_3d_edges.size());
|
out_2d_edges.resize(in_3d_edges.size());
|
||||||
|
|
||||||
@@ -863,11 +859,11 @@ const Vector2 MeshEditingLibrary::calculate_planar_uv(const Vector3 &vertex, con
|
|||||||
switch(axis)
|
switch(axis)
|
||||||
{
|
{
|
||||||
case MeshSlicePlaneOrientation::X:
|
case MeshSlicePlaneOrientation::X:
|
||||||
return Vector2(vertex.y / mesh_bounds.y, vertex.z / mesh_bounds.z);
|
return Vector2(1.0f - (vertex.z / mesh_bounds.z) + 0.5f, 1.0f - (vertex.y / mesh_bounds.y));
|
||||||
case MeshSlicePlaneOrientation::Y:
|
case MeshSlicePlaneOrientation::Y:
|
||||||
return Vector2(vertex.x / mesh_bounds.x, vertex.z / mesh_bounds.z);
|
return Vector2(1.0f - (vertex.x / mesh_bounds.x) + 0.5f, (vertex.z / mesh_bounds.z) + 0.5f);
|
||||||
case MeshSlicePlaneOrientation::Z: default:
|
case MeshSlicePlaneOrientation::Z: default:
|
||||||
return Vector2(vertex.x / mesh_bounds.x, vertex.y / mesh_bounds.y);
|
return Vector2(1.0f - (vertex.x / mesh_bounds.x) + 0.5f, 1.0f - (vertex.y / mesh_bounds.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ class MeshEditingLibrary : public Node
|
|||||||
GDCLASS(MeshEditingLibrary, Node);
|
GDCLASS(MeshEditingLibrary, Node);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MeshEditingLibrary();
|
MeshEditingLibrary(){}
|
||||||
~MeshEditingLibrary();
|
~MeshEditingLibrary(){}
|
||||||
|
|
||||||
enum MeshEditCapUV
|
enum MeshEditCapUV
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
CAP_UV_TILED
|
CAP_UV_TILED
|
||||||
};
|
};
|
||||||
|
|
||||||
static PackedVector3Array slice_mesh(MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, Ref<ArrayMesh> out_first_half, Ref<ArrayMesh> out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material);
|
static PackedVector3Array 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);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum MeshSlicePlaneOrientation
|
enum MeshSlicePlaneOrientation
|
||||||
@@ -85,7 +85,7 @@ private:
|
|||||||
|
|
||||||
static SkinnedSurfaces get_skinned_vertex_positions(const Mesh *mesh, const Skeleton3D *skeleton = nullptr, std::vector<std::vector<Transform3D>> &bone_transforms = std::vector<std::vector<Transform3D>>());
|
static SkinnedSurfaces get_skinned_vertex_positions(const Mesh *mesh, const Skeleton3D *skeleton = nullptr, std::vector<std::vector<Transform3D>> &bone_transforms = std::vector<std::vector<Transform3D>>());
|
||||||
|
|
||||||
static const Transform3D project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const Transform3D &to_node_space, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane);
|
static const Transform3D project_edges(std::vector<MeshEditEdge2D> &out_2d_edges, const std::vector<MeshEditEdge3D> &in_3d_edges, const Plane &plane);
|
||||||
static void build_2d_polygons_from_edges(std::vector<MeshEditPolygon2D> &out_polygons, const std::vector<MeshEditEdge2D> &in_edges, std::vector<MeshEditPolygon2D> &error_polygons);
|
static void build_2d_polygons_from_edges(std::vector<MeshEditPolygon2D> &out_polygons, const std::vector<MeshEditEdge2D> &in_edges, std::vector<MeshEditPolygon2D> &error_polygons);
|
||||||
static bool find_next_edge(MeshEditEdge2D &out_next_edge, std::vector<MeshEditEdge2D> &in_edge_set, const MeshEditVert2D &start);
|
static bool find_next_edge(MeshEditEdge2D &out_next_edge, std::vector<MeshEditEdge2D> &in_edge_set, const MeshEditVert2D &start);
|
||||||
static void fix_polygon_winding(MeshEditPolygon2D &polygon);
|
static void fix_polygon_winding(MeshEditPolygon2D &polygon);
|
||||||
|
|||||||
Reference in New Issue
Block a user