#ifndef MERGING_TOOL_H #define MERGING_TOOL_H /*************************************************************************/ /* merging_tool.h */ /*************************************************************************/ /* This file is part of: */ /* PANDEMONIUM ENGINE */ /* https://github.com/Relintai/pandemonium_engine */ /*************************************************************************/ /* Copyright (c) 2022-present Péter Magyar. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "core/containers/local_vector.h" #include "core/containers/vector.h" #include "scene/resources/mesh/mesh.h" class MeshInstance; class GeometryInstance; class CSGShape; class SurfaceTool; struct CSGBrush; #ifdef DEV_ENABLED // Only enable this for development testing. // #define PANDEMONIUM_MERGING_VERBOSE #endif // NOTE : These merging and joining functions DO NOT move children, or delete source nodes. That is the responsibility of the caller. class MergingTool { public: // Are two mesh instances mergeable with each other? static bool is_mergeable_with(const MeshInstance &p_mi, const MeshInstance &p_other, bool p_check_surface_material_match); static bool is_shadow_mergeable_with(const MeshInstance &p_mi, const MeshInstance &p_other); // Merges all mesh details. static bool merge_meshes(MeshInstance &r_dest_mi, Vector p_list, bool p_use_global_space, bool p_check_compatibility); // Join all surfaces into one ubermesh. static bool join_meshes(MeshInstance &r_dest_mi, Vector p_list); // Adds a surface from one mesh to another. static bool join_mesh_surface(const MeshInstance &p_source_mi, uint32_t p_source_surface_id, MeshInstance &r_dest_mi); // Only concerned with data necessary for shadow proxy - opaque tris, no normals / tangents / uvs etc. static bool merge_shadow_meshes(MeshInstance &r_dest_mi, Vector p_list, bool p_use_global_space, bool p_check_compatibility); // For splitting a MeshInstance with multiple surfaces to a MeshInstance per surface. static bool split_surface_to_mesh_instance(const MeshInstance &p_source_mi, int p_surface_id, MeshInstance &r_mi); // Convert a CSG surface to MeshInstance. static bool split_csg_surface_to_mesh_instance(const CSGShape &p_shape, MeshInstance &r_mi, const Ref &p_array_mesh, CSGBrush *p_brush, int p_surface); // Remove degenerate triangles. static bool clean_mesh_instance(MeshInstance &p_mi); static void split_mesh_instance_by_locality(MeshInstance &r_mi, const AABB &p_bound, uint32_t p_splits_horz, uint32_t p_splits_vert, uint32_t p_min_split_poly_count); // For debugging purposes. static void debug_mesh_instance(const MeshInstance &p_mi); #ifdef DEV_ENABLED static void debug_branch(Node *p_node, const char *p_title = nullptr, int p_depth = 0); #endif #ifdef TOOLS_ENABLED static void append_editor_description(Node *p_node, String p_string, Node *p_node_named = nullptr); #endif // Helper functions (used from MergeGroup). static void _set_owner_logged(Node *p_node, Node *p_owner); static void _reparent(Node *p_branch, Node *p_new_parent, Node *p_new_owner); static void _invalidate_owner_recursive(Node *p_node, Node *p_old_owner, Node *p_new_owner); static bool _node_has_valid_children(Node *p_node); static void _mesh_set_storage_mode(Mesh *p_mesh, Mesh::StorageMode p_mode); private: static void _reparent_subscene_send_new_owner(Node *p_node, Node *p_new_owner); static void _copy_mesh_instance_settings(const MeshInstance &p_source, MeshInstance &r_dest, bool p_copy_transform, bool p_copy_materials); static bool _is_mergeable_with_common(const MeshInstance &p_mi, const MeshInstance &p_other); static bool _is_shadow_mergeable(const MeshInstance &p_mi); static bool _is_material_opaque(const Ref &p_mat); static bool _ensure_indices_valid(LocalVector &r_indices, const PoolVector &p_verts); static bool _check_for_valid_indices(const LocalVector &p_inds, const PoolVector &p_verts, LocalVector *r_inds); static bool _triangle_is_degenerate(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, real_t p_epsilon); static int _clean_mesh_surface(const String &p_source_name, const Transform &p_xform, Ref &p_rmesh, int p_surface_id, Ref r_dest_mesh); static void _copy_geometry_instance_settings(const GeometryInstance &p_source, MeshInstance &r_dest, bool p_copy_transform); static void _set_rmesh_material(MeshInstance &r_mi, Ref r_rmesh, int p_surface_id, Ref p_material); static void _split_mesh_instance_by_locality(const SurfaceTool &p_st_main, const MeshInstance &p_source_mi, const LocalVector &p_tri_ids, uint32_t p_local_id, uint32_t p_surface_id, uint32_t p_x, uint32_t p_y, uint32_t p_z); static void _merge_log(String p_string, int p_priority = 1); }; #endif // MERGING_TOOL_H