mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-22 20:06:49 +01:00
156 lines
5.8 KiB
C++
156 lines
5.8 KiB
C++
#ifndef MERGE_GROUP_H
|
|
#define MERGE_GROUP_H
|
|
|
|
/*************************************************************************/
|
|
/* merge_group.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 "scene/main/spatial.h"
|
|
|
|
class MeshInstance;
|
|
class CSGShape;
|
|
class GridMap;
|
|
|
|
class MergeGroup : public Spatial {
|
|
GDCLASS(MergeGroup, Spatial);
|
|
friend class MergeGroupEditorPlugin;
|
|
|
|
public:
|
|
enum ParamEnabled {
|
|
PARAM_ENABLED_AUTO_MERGE,
|
|
PARAM_ENABLED_SHADOW_PROXY,
|
|
PARAM_ENABLED_CONVERT_CSGS,
|
|
PARAM_ENABLED_CONVERT_GRIDMAPS,
|
|
PARAM_ENABLED_COMBINE_SURFACES,
|
|
PARAM_ENABLED_CLEAN_MESHES,
|
|
PARAM_ENABLED_MAX,
|
|
};
|
|
|
|
enum Param {
|
|
PARAM_GROUP_SIZE,
|
|
PARAM_SPLITS_HORIZONTAL,
|
|
PARAM_SPLITS_VERTICAL,
|
|
PARAM_MIN_SPLIT_POLY_COUNT,
|
|
PARAM_MAX,
|
|
};
|
|
|
|
void merge_meshes();
|
|
bool merge_meshes_in_editor();
|
|
|
|
void set_param_enabled(ParamEnabled p_param, bool p_enabled);
|
|
bool get_param_enabled(ParamEnabled p_param);
|
|
|
|
void set_param(Param p_param, int p_value);
|
|
int get_param(Param p_param);
|
|
|
|
// These enable feedback in the Godot UI as we bake.
|
|
typedef bool (*BakeStepFunc)(float, const String &, void *, bool); // Progress, step description, userdata, force refresh.
|
|
typedef void (*BakeEndFunc)(uint32_t); // time_started
|
|
|
|
static BakeStepFunc bake_step_function;
|
|
static BakeStepFunc bake_substep_function;
|
|
static BakeEndFunc bake_end_function;
|
|
|
|
protected:
|
|
static void _bind_methods();
|
|
void _notification(int p_what);
|
|
|
|
private:
|
|
struct MeshAABB {
|
|
MeshInstance *mi = nullptr;
|
|
AABB aabb;
|
|
static int _sort_axis;
|
|
bool operator<(const MeshAABB &p_b) const {
|
|
real_t a_min = aabb.position.coord[_sort_axis];
|
|
real_t b_min = p_b.aabb.position.coord[_sort_axis];
|
|
return a_min < b_min;
|
|
}
|
|
};
|
|
|
|
// Main function.
|
|
bool _merge_meshes();
|
|
|
|
// Merging.
|
|
void _find_mesh_instances_recursive(int p_depth, Node *p_node, LocalVector<MeshInstance *> &r_mis, bool p_shadows, bool p_flag_invalid_meshes = false);
|
|
bool _merge_similar(LocalVector<MeshInstance *> &r_mis, bool p_shadows);
|
|
void _merge_list(const LocalVector<MeshInstance *> &p_mis, bool p_shadows, int p_whittle_group = -1);
|
|
void _merge_list_ex(const LocalVector<MeshAABB> &p_mesh_aabbs, bool p_shadows, int p_whittle_group = -1);
|
|
bool _join_similar(LocalVector<MeshInstance *> &r_mis);
|
|
void _split_mesh_by_surface(MeshInstance *p_mi, int p_num_surfaces);
|
|
bool _split_by_locality();
|
|
|
|
// Helper funcs.
|
|
void _convert_source_to_spatial(Spatial *p_node);
|
|
void _reset_mesh_instance(MeshInstance *p_mi);
|
|
void _move_children(Node *p_from, Node *p_to, bool p_recalculate_transforms = false);
|
|
void _recursive_tree_merge(int &r_whittle_group, LocalVector<MeshAABB> p_list);
|
|
void _delete_node(Node *p_node);
|
|
bool _node_ok_to_delete(Node *p_node);
|
|
void _cleanup_source_meshes(LocalVector<MeshInstance *> &r_cleanup_list);
|
|
void _delete_dangling_spatials(Node *p_node);
|
|
|
|
void _node_changed(Node *p_node);
|
|
void _node_changed_internal(Node *p_node);
|
|
|
|
// CSG
|
|
void _find_csg_recursive(int p_depth, Node *p_node, LocalVector<CSGShape *> &r_csgs);
|
|
void _split_csg_by_surface(CSGShape *p_shape);
|
|
|
|
bool _terminate_search(Node *p_node);
|
|
|
|
// Gridmap
|
|
void _find_gridmap_recursive(int p_depth, Node *p_node, LocalVector<GridMap *> &r_gridmaps);
|
|
void _bake_gridmap(GridMap *p_gridmap);
|
|
|
|
void _log(String p_string);
|
|
void _logt(int p_tabs, String p_string);
|
|
|
|
struct Data {
|
|
bool params_enabled[PARAM_ENABLED_MAX];
|
|
uint32_t params[PARAM_MAX];
|
|
|
|
// Hidden Params.
|
|
bool delete_sources = false;
|
|
bool convert_sources = false;
|
|
bool split_by_surface = false;
|
|
|
|
// Each merge is an iteration.
|
|
uint32_t iteration = 0;
|
|
Node *scene_root = nullptr;
|
|
|
|
Data();
|
|
} data;
|
|
};
|
|
|
|
VARIANT_ENUM_CAST(MergeGroup::Param);
|
|
VARIANT_ENUM_CAST(MergeGroup::ParamEnabled);
|
|
|
|
#endif // MERGE_GROUP_H
|