From 53d36345e6bd7bf896d5edbd7cd62a5c5cbce0c5 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 11 Jul 2023 12:23:46 +0200 Subject: [PATCH] Added back CSG support code I removed. --- editor_modules/gltf/gltf_document.cpp | 40 +++++++++++++++++++ editor_modules/gltf/gltf_document.h | 8 ++++ scene/3d/room_manager.cpp | 57 ++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/editor_modules/gltf/gltf_document.cpp b/editor_modules/gltf/gltf_document.cpp index 3fc3606bd..a2d5816db 100644 --- a/editor_modules/gltf/gltf_document.cpp +++ b/editor_modules/gltf/gltf_document.cpp @@ -62,6 +62,10 @@ #include "modules/modules_enabled.gen.h" // For csg, gridmap, regex. +#ifdef MODULE_CSG_ENABLED +#include "modules/csg/csg_shape.h" +#endif // MODULE_CSG_ENABLED + #ifdef MODULE_REGEX_ENABLED #include "modules/regex/regex.h" #endif // MODULE_REGEX_ENABLED @@ -5350,6 +5354,13 @@ void GLTFDocument::_convert_scene_node(Ref p_state, Node *p_current, // We ignore the Pandemonium Engine node that is the skeleton. return; #endif +#ifdef MODULE_CSG_ENABLED + } else if (cast_to(p_current)) { + CSGShape *shape = cast_to(p_current); + if (shape->get_parent() && shape->is_root_shape()) { + _convert_csg_shape_to_gltf(shape, p_gltf_parent, gltf_node, p_state); + } +#endif // MODULE_CSG_ENABLED #ifdef MODULE_GRIDMAP_ENABLED } else if (cast_to(p_current)) { GridMap *gridmap = Object::cast_to(p_current); @@ -5389,6 +5400,35 @@ void GLTFDocument::_convert_scene_node(Ref p_state, Node *p_current, } } +#ifdef MODULE_CSG_ENABLED +void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape *p_current, GLTFNodeIndex p_gltf_parent, Ref p_gltf_node, Ref p_state) { + CSGShape *csg = p_current; + csg->call("_update_shape"); + Array meshes = csg->get_meshes(); + if (meshes.size() != 2) { + return; + } + Ref mat; + if (csg->get_material_override().is_valid()) { + mat = csg->get_material_override(); + } + Ref gltf_mesh; + gltf_mesh.instance(); + Ref import_mesh; + import_mesh.instance(); + Ref array_mesh = csg->get_meshes()[1]; + for (int32_t surface_i = 0; surface_i < array_mesh->get_surface_count(); surface_i++) { + import_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, array_mesh->surface_get_arrays(surface_i)); + } + gltf_mesh->set_mesh(import_mesh); + GLTFMeshIndex mesh_i = p_state->meshes.size(); + p_state->meshes.push_back(gltf_mesh); + p_gltf_node->mesh = mesh_i; + p_gltf_node->xform = csg->get_meshes()[0]; + p_gltf_node->set_name(_gen_unique_name(p_state, csg->get_name())); +} +#endif // MODULE_CSG_ENABLED + void GLTFDocument::_create_gltf_node(Ref p_state, Node *p_scene_parent, GLTFNodeIndex p_current_node_i, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref p_gltf_node) { p_state->scene_nodes.insert(p_current_node_i, p_scene_parent); diff --git a/editor_modules/gltf/gltf_document.h b/editor_modules/gltf/gltf_document.h index 2a075f07e..686b02fa9 100644 --- a/editor_modules/gltf/gltf_document.h +++ b/editor_modules/gltf/gltf_document.h @@ -49,6 +49,10 @@ class Skeleton; class BoneAttachment; #endif +#ifdef MODULE_CSG_ENABLED +class CSGShape; +#endif // MODULE_CSG_ENABLED + #ifdef MODULE_GRIDMAP_ENABLED class GridMap; #endif // MODULE_GRIDMAP_ENABLED @@ -333,6 +337,10 @@ public: const GLTFNodeIndex p_gltf_current, const GLTFNodeIndex p_gltf_root); +#ifdef MODULE_CSG_ENABLED + void _convert_csg_shape_to_gltf(CSGShape *p_current, GLTFNodeIndex p_gltf_parent, Ref p_gltf_node, Ref p_state); +#endif // MODULE_CSG_ENABLED + void _create_gltf_node(Ref p_state, Node *p_scene_parent, GLTFNodeIndex p_current_node_i, diff --git a/scene/3d/room_manager.cpp b/scene/3d/room_manager.cpp index c4beb1e2d..76517c543 100644 --- a/scene/3d/room_manager.cpp +++ b/scene/3d/room_manager.cpp @@ -30,12 +30,12 @@ #include "room_manager.h" -#include "core/containers/bitfield_dynamic.h" #include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/containers/bitfield_dynamic.h" #include "core/math/geometry.h" #include "core/math/quick_hull.h" #include "core/os/os.h" -#include "core/config/project_settings.h" #include "editor/editor_node.h" #include "mesh_instance.h" #include "multimesh_instance.h" @@ -54,6 +54,10 @@ #include "modules/modules_enabled.gen.h" // For csg. +#ifdef MODULE_CSG_ENABLED +#include "modules/csg/csg_shape.h" +#endif + // #define PANDEMONIUM_PORTALS_USE_BULLET_CONVEX_HULL #ifdef PANDEMONIUM_PORTALS_USE_BULLET_CONVEX_HULL @@ -1725,6 +1729,55 @@ bool RoomManager::_bound_findpoints_geom_instance(GeometryInstance *p_gi, Vector r_aabb.position = Vector3(FLT_MAX / 2, FLT_MAX / 2, FLT_MAX / 2); r_aabb.size = Vector3(-FLT_MAX, -FLT_MAX, -FLT_MAX); +#ifdef MODULE_CSG_ENABLED + CSGShape *shape = Object::cast_to(p_gi); + if (shape) { + // Shapes will not be up to date on the first frame due to a quirk + // of CSG - it defers updates to the next frame. So we need to explicitly + // force an update to make sure the CSG is correct on level load. + shape->force_update_shape(); + + Array arr = shape->get_meshes(); + if (!arr.size()) { + return false; + } + + Ref arr_mesh = arr[1]; + if (!arr_mesh.is_valid()) { + return false; + } + + if (arr_mesh->get_surface_count() == 0) { + return false; + } + + // for converting meshes to world space + Transform trans = p_gi->get_global_transform(); + + for (int surf = 0; surf < arr_mesh->get_surface_count(); surf++) { + Array arrays = arr_mesh->surface_get_arrays(surf); + + if (!arrays.size()) { + continue; + } + + PoolVector vertices = arrays[RS::ARRAY_VERTEX]; + + // convert to world space + for (int n = 0; n < vertices.size(); n++) { + Vector3 pt_world = trans.xform(vertices[n]); + r_room_pts.push_back(pt_world); + + // keep the bound up to date + r_aabb.expand_to(pt_world); + } + + } // for through the surfaces + + return true; + } // if csg shape +#endif + // multimesh MultiMeshInstance *mmi = Object::cast_to(p_gi); if (mmi) {