diff --git a/examples_dd3d/DebugDrawDemoScene.gd b/examples_dd3d/DebugDrawDemoScene.gd index d5e303e8..ee1d702b 100644 --- a/examples_dd3d/DebugDrawDemoScene.gd +++ b/examples_dd3d/DebugDrawDemoScene.gd @@ -7,8 +7,8 @@ extends Node3D @export var test_graphs := false @export var more_test_cases := true @export var draw_array_of_boxes := false -@export_range(0, 2, 0.001) var debug_thickness := 0.075 -@export_range(0, 1024) var start_culling_distance := 0.0 +@export_range(0, 5, 0.001) var debug_thickness := 0.05 +@export_range(0, 1024) var start_culling_distance := 55.0 @export_group("Text groups", "text_groups") @export var text_groups_show_hints := true @@ -17,16 +17,16 @@ extends Node3D @export var text_groups_position := DebugDrawConfig2D.POSITION_LEFT_TOP @export var text_groups_offset := Vector2i(8, 8) @export var text_groups_padding := Vector2i(3, 1) -@export_range(1, 100) var text_groups_default_font_size := 12 -@export_range(1, 100) var text_groups_title_font_size := 14 -@export_range(1, 100) var text_groups_text_font_size := 12 +@export_range(1, 100) var text_groups_default_font_size := 15 +@export_range(1, 100) var text_groups_title_font_size := 20 +@export_range(1, 100) var text_groups_text_font_size := 17 @export_group("Graphs", "graph") @export var graph_offset := Vector2i(8, 8) @export var graph_size := Vector2i(200, 80) @export_range(1, 100) var graph_title_font_size := 14 @export_range(1, 100) var graph_text_font_size := 12 -@export_range(0, 64) var graph_text_precision := 2 +@export_range(0, 64) var graph_text_precision := 1 @export_range(1, 32) var graph_line_width := 1.0 @export_range(1, 512) var graph_buffer_size := 128 @export var graph_frame_time_mode := true @@ -68,6 +68,9 @@ func _update_keys_just_press(): func _process(delta: float) -> void: + if Input.is_action_just_pressed("ui_end"): + DebugDraw3D.regenerate_geometry_meshes() + DebugDraw3D.scoped_config().set_thickness(debug_thickness) if false: #test var s11 = DebugDraw3D.new_scoped_config() diff --git a/examples_dd3d/DebugDrawDemoScene.tscn b/examples_dd3d/DebugDrawDemoScene.tscn index 8868590f..ccb72388 100644 --- a/examples_dd3d/DebugDrawDemoScene.tscn +++ b/examples_dd3d/DebugDrawDemoScene.tscn @@ -220,14 +220,7 @@ func _on_Button_pressed() -> void: process_priority = 1 script = ExtResource("1") custom_font = ExtResource("2_aedbq") -draw_array_of_boxes = true -start_culling_distance = 55.0 -text_groups_show_stats = true text_groups_position = 2 -text_groups_default_font_size = 15 -text_groups_title_font_size = 20 -text_groups_text_font_size = 17 -graph_text_precision = 1 [node name="Camera" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.953191, 0.30237, 0, -0.30237, 0.953191, -3.988, 13.525, 37.21) @@ -388,13 +381,13 @@ transform = Transform3D(0.834492, 0, -0.551019, 0, 1, 0, 0.55102, 0, 0.834493, - transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.18606, -0.331599, 6.66091) [node name="Arrow" type="Node3D" parent="Misc"] -transform = Transform3D(0.802141, -0.286294, -0.524028, -0.539546, 0.0285125, -0.841473, 0.25585, 0.957718, -0.131597, -4.38512, -1.18432, 6.66091) +transform = Transform3D(0.802141, -0.286294, -0.524028, -0.539546, 0.0285125, -0.841473, 0.25585, 0.957718, -0.131597, -4.06502, -0.670307, 6.7413) [node name="Position" type="Node3D" parent="Misc"] transform = Transform3D(1.51514, 0.589536, 1.00858, -1.34875, 0.662262, 1.133, 0, -0.462445, 2.90833, -2.73567, -0.331599, 2.69873) [node name="GizmoNormal" type="Node3D" parent="Misc"] -transform = Transform3D(1.98138, 0, -0.70285, 0, 0.999999, 0, 0.434655, 0, 3.20395, -2.69921, -0.331599, 4.79165) +transform = Transform3D(1.95938, 0, -0.848962, 0, 0.999999, 0, 0.525014, 0, 3.16837, -2.69921, -0.306246, 4.79165) [node name="GizmoTransform" type="Node3D" parent="Misc"] transform = Transform3D(0.879881, 0.248446, -0.405072, -0.346604, 0.918688, -0.189411, 0.325077, 0.307059, 0.894449, -4.428, -0.458, 4.259) @@ -431,7 +424,7 @@ transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 9.40939e-07, 1, 0, -2.76085 transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 6.87561e-07, 1, 0, -2.87275e-08, -1.49012e-08, 1, -0.1559, -0.407045, 0.0523388) [node name="4" type="Node3D" parent="Lines"] -transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 3.42235e-07, 1, 0, -4.57815e-08, -1.49012e-08, 1, 1.18591, 1.8987, 0.301906) +transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 4.9239e-07, 1, 0, -3.40677e-08, -1.49012e-08, 1, 1.18591, 1.8987, 0.301906) [node name="5" type="Node3D" parent="Lines"] transform = Transform3D(-0.998871, -0.0207882, -0.0355643, 0.0855375, -0.5714, -2.68836, 0.0136011, -0.249864, 0.572532, 1.43126, 0.26242, 1.92347) diff --git a/src/3d/debug_draw_3d.cpp b/src/3d/debug_draw_3d.cpp index 635e0097..48d69edf 100644 --- a/src/3d/debug_draw_3d.cpp +++ b/src/3d/debug_draw_3d.cpp @@ -10,7 +10,6 @@ GODOT_WARNING_DISABLE() #include -#include #include GODOT_WARNING_RESTORE() @@ -36,6 +35,7 @@ void DebugDraw3D::_bind_methods() { #pragma endregion #pragma region Draw Functions + ClassDB::bind_method(D_METHOD(NAMEOF(regenerate_geometry_meshes)), &DebugDraw3D::regenerate_geometry_meshes); ClassDB::bind_method(D_METHOD(NAMEOF(clear_all)), &DebugDraw3D::clear_all); ClassDB::bind_method(D_METHOD(NAMEOF(draw_sphere), "position", "radius", "color", "duration"), &DebugDraw3D::draw_sphere, 0.5f, Colors::empty_color, 0); @@ -99,9 +99,9 @@ void DebugDraw3D::init(DebugDrawManager *root) { root_node = root; set_config(nullptr); - root_settings_section = String(Utils::root_settings_section) + "3D/"; + root_settings_section = String(Utils::root_settings_section) + "3d/"; DEFINE_SETTING_AND_GET(bool add_bevel, root_settings_section + s_add_bevel_to_volumetric, true, Variant::BOOL); - DEFINE_SETTING_AND_GET(real_t def_thickness, root_settings_section + s_default_thickness, 0.075f, Variant::FLOAT); + DEFINE_SETTING_AND_GET(real_t def_thickness, root_settings_section + s_default_thickness, 0.05f, Variant::FLOAT); stats_3d.instantiate(); default_scoped_config.instantiate(); @@ -111,8 +111,6 @@ void DebugDraw3D::init(DebugDrawManager *root) { _load_materials(); #ifndef DISABLE_DEBUG_RENDERING - DEV_PRINT_STD("To regenerate the 3D geometry press the \"%s\" action\n", reload_action_name); - dgc = std::make_unique(this, add_bevel); #endif } @@ -128,17 +126,6 @@ void DebugDraw3D::process(double delta) { ZoneScoped; FrameMarkStart("3D Setup"); #ifndef DISABLE_DEBUG_RENDERING -#ifdef DEV_ENABLED - if (Input::get_singleton()->is_action_just_pressed(reload_action_name)) { - LOCK_GUARD(datalock); - Node *old_world = dgc->get_world(); - dgc.reset(); - - _load_materials(); - dgc = std::make_unique(this, PS()->get_setting(root_settings_section + s_add_bevel_to_volumetric)); - dgc->set_world(old_world); - } -#endif // Update 3D debug dgc->update_geometry(delta); @@ -445,6 +432,17 @@ Ref DebugDraw3D::get_render_stats() { return stats_3d; } +void DebugDraw3D::regenerate_geometry_meshes() { +#ifndef DISABLE_DEBUG_RENDERING + LOCK_GUARD(datalock); + Node *old_world = dgc->get_world(); + dgc.reset(); + + dgc = std::make_unique(this, PS()->get_setting(root_settings_section + s_add_bevel_to_volumetric)); + dgc->set_world(old_world); +#endif +} + void DebugDraw3D::clear_all() { ZoneScoped; #ifndef DISABLE_DEBUG_RENDERING @@ -465,6 +463,10 @@ void DebugDraw3D::clear_all() { #ifndef DISABLE_DEBUG_RENDERING +Vector3 DebugDraw3D::get_up_vector(const Vector3 &dir) { + return (Math::is_equal_approx(dir.x, 0) && Math::is_equal_approx(dir.z, 0)) || Math::is_equal_approx(dir.y, 0) ? Vector3_UP_OF : Vector3_UP; +} + void DebugDraw3D::add_or_update_line_with_thickness(real_t _exp_time, const std::vector &_lines, const Color &_col, const std::function _custom_upd) { ZoneScoped; @@ -481,11 +483,10 @@ void DebugDraw3D::add_or_update_line_with_thickness(real_t _exp_time, const std: Vector3 diff = _lines[i + 1] - a; real_t len = diff.length(); Vector3 center = diff.normalized() * len * .5f; - Vector3 up = center.x == 0 && center.z == 0 ? Vector3_UP_OF : Vector3_UP; dgc->geometry_pool.add_or_update_instance( InstanceType::LINE_VOLUMETRIC, _exp_time, - Transform3D(Basis().looking_at(center, up).scaled(Vector3(len, len, len)), a), // slow + Transform3D(Basis().looking_at(center, get_up_vector(center)).scaled(Vector3(len, len, len)), a), // slow _col, _scoped_config_to_custom(scfg.ptr()), SphereBounds(a + center, len * .5f)); @@ -568,12 +569,12 @@ void DebugDraw3D::draw_cylinder_ab(const Vector3 &a, const Vector3 &b, const rea ZoneScoped; CHECK_BEFORE_CALL(); - // TODO SLOOOOOW + // TODO sloooow Vector3 diff = b - a; real_t len = diff.length(); real_t diameter = radius * 2; Vector3 center = diff.normalized() * len * .5f; - Vector3 up = (Math::is_equal_approx(center.x, 0) && Math::is_equal_approx(center.z, 0)) || Math::is_equal_approx(center.y, 0) ? Vector3_UP_OF : Vector3_UP; + Vector3 up = get_up_vector(center); Vector3 center_rot = center.rotated(center.cross(up), Math::deg_to_rad(90.f)); // Convert +Y of cylinder to -Z Transform3D t = Transform3D(Basis().looking_at(center_rot, up).scaled_local(Vector3(diameter, len, diameter)), a + center); @@ -739,8 +740,8 @@ void DebugDraw3D::create_arrow(const Vector3 &a, const Vector3 &b, const Color & Vector3 dir = (b - a); real_t size = (is_absolute_size ? arrow_size : dir.length() * arrow_size) * 2; - const Vector3 UP = Vector3(0.0000000001f, 1, 0); - Transform3D t = Transform3D(Basis().looking_at(dir, UP).scaled(Vector3(size, size, size)), b); + Vector3 up = get_up_vector(dir); + Transform3D t = Transform3D(Basis().looking_at(dir, up).scaled(Vector3(size, size, size)), b); Ref scfg = scoped_config_for_current_thread(); diff --git a/src/3d/debug_draw_3d.h b/src/3d/debug_draw_3d.h index f602507b..ae9bfbd0 100644 --- a/src/3d/debug_draw_3d.h +++ b/src/3d/debug_draw_3d.h @@ -73,9 +73,6 @@ class DebugDraw3D : public Object, public IScopedStorage { #endif #ifndef DISABLE_DEBUG_RENDERING -#ifdef DEV_ENABLED - const char *reload_action_name = "ui_end"; -#endif // Meshes std::unique_ptr dgc; @@ -100,6 +97,7 @@ class DebugDraw3D : public Object, public IScopedStorage { InstanceType _scoped_config_type_convert(ConvertableInstanceType type, DDScopedConfig3D *cfg); GeometryType _scoped_config_get_geometry_type(DDScopedConfig3D *cfg); + _FORCE_INLINE_ Vector3 get_up_vector(const Vector3 &dir); void add_or_update_line_with_thickness(real_t _exp_time, const std::vector &_lines, const Color &_col, const std::function _custom_upd = nullptr); #endif @@ -173,6 +171,8 @@ class DebugDraw3D : public Object, public IScopedStorage { {} #endif + void regenerate_geometry_meshes(); + /// Clear all 3D objects void clear_all(); diff --git a/src/3d/debug_geometry_container.cpp b/src/3d/debug_geometry_container.cpp index fb4bdeeb..e802d182 100644 --- a/src/3d/debug_geometry_container.cpp +++ b/src/3d/debug_geometry_container.cpp @@ -73,8 +73,7 @@ DebugGeometryContainer::DebugGeometryContainer(class DebugDraw3D *root, const bo auto array_mesh_cube_centered_volumetric = GeometryGenerator::ConvertWireframeToVolumetric(array_mesh_cube_center, add_bevel); CreateMMI(InstanceType::CUBE_CENTERED_VOLUMETRIC, UsingShaderType::Expandable, NAMEOF(mmi_cubes_centered_volumetric), array_mesh_cube_centered_volumetric); - auto array_mesh_arrow_head_simple = GeometryGenerator::CreateMeshNative(Mesh::PrimitiveType::PRIMITIVE_LINES, GeometryGenerator::ArrowheadVertices, GeometryGenerator::ArrowheadIndicesSimplified); - auto array_mesh_arrow_head_volumetric = GeometryGenerator::ConvertWireframeToVolumetric(array_mesh_arrow_head_simple, add_bevel, true); + auto array_mesh_arrow_head_volumetric = GeometryGenerator::CreateVolumetricArrowHead(.25f, 1.f, 1.f, add_bevel); CreateMMI(InstanceType::ARROWHEAD_VOLUMETRIC, UsingShaderType::Expandable, NAMEOF(mmi_arrowheads_volumetric), array_mesh_arrow_head_volumetric); auto array_mesh_pos_volumetric = GeometryGenerator::ConvertWireframeToVolumetric(array_mesh_pos, add_bevel); diff --git a/src/3d/geometry_generators.cpp b/src/3d/geometry_generators.cpp index 3b7c73a1..8fb52371 100644 --- a/src/3d/geometry_generators.cpp +++ b/src/3d/geometry_generators.cpp @@ -230,22 +230,20 @@ Ref GeometryGenerator::ConvertWireframeToVolumetric(Ref me if (has_indexes) { for (int i = 0; i < indexes.size(); i += 2) { Vector3 normal_a = has_normals ? normals[indexes[i]] : Vector3(0, 1, 0.0001f); - Vector3 normal_b = has_normals ? normals[indexes[i + 1]] : Vector3(0, 1, 0.0001f); if (add_bevel) - GenerateVolumetricSegmentBevel(vertexes[indexes[i]], vertexes[indexes[i + 1]], normal_a, normal_b, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); + GenerateVolumetricSegmentBevel(vertexes[indexes[i]], vertexes[indexes[i + 1]], normal_a, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); else - GenerateVolumetricSegment(vertexes[indexes[i]], vertexes[indexes[i + 1]], normal_a, normal_b, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); + GenerateVolumetricSegment(vertexes[indexes[i]], vertexes[indexes[i + 1]], normal_a, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); } } else { for (int i = 0; i < vertexes.size(); i += 2) { Vector3 normal_a = has_normals ? normals[i] : Vector3(0, 1, 0.0001f); - Vector3 normal_b = has_normals ? normals[i + 1] : Vector3(0, 1, 0.0001f); if (add_bevel) - GenerateVolumetricSegmentBevel(vertexes[i], vertexes[i + 1], normal_a, normal_b, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); + GenerateVolumetricSegmentBevel(vertexes[i], vertexes[i + 1], normal_a, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); else - GenerateVolumetricSegment(vertexes[i], vertexes[i + 1], normal_a, normal_b, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); + GenerateVolumetricSegment(vertexes[i], vertexes[i + 1], normal_a, res_vertexes, res_custom0, res_indexes, res_uv, add_caps); } } @@ -260,20 +258,20 @@ Ref GeometryGenerator::ConvertWireframeToVolumetric(Ref me ArrayMesh::ARRAY_CUSTOM_RGB_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT); } -void GeometryGenerator::GenerateVolumetricSegment(const Vector3 &a, const Vector3 &b, const Vector3 &normal_a, const Vector3 &normal_b, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps) { +void GeometryGenerator::GenerateVolumetricSegment(const Vector3 &a, const Vector3 &b, const Vector3 &normal, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps) { ZoneScoped; bool debug_size = false; Vector3 debug_mult = debug_size ? Vector3(1, 1, 1) * 0.5 : Vector3(); Vector3 dir = (b - a).normalized(); int64_t base_idx = vertexes.size(); - auto add_side = [&dir, &vertexes, &indexes, &custom0, &uv, &debug_mult](Vector3 pos_a, Vector3 pos_b, Vector3 normal_a, Vector3 normal_b, bool is_rotated) { + auto add_side = [&dir, &vertexes, &indexes, &custom0, &uv, &debug_mult](Vector3 pos_a, Vector3 pos_b, Vector3 normal, bool is_rotated) { int64_t start_idx = vertexes.size(); - Vector3 right_a = dir.cross(normal_a.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); + Vector3 right_a = dir.cross(normal.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); Vector3 left_a = right_a * -1; - Vector3 right_b = dir.cross(normal_b.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); + Vector3 right_b = dir.cross(normal.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); Vector3 left_b = right_b * -1; right_a /= Math::sqrt(2.0f); @@ -312,8 +310,8 @@ void GeometryGenerator::GenerateVolumetricSegment(const Vector3 &a, const Vector custom0.push_back(left_b); }; - add_side(a, b, normal_a, normal_b, false); - add_side(a, b, normal_a, normal_b, true); + add_side(a, b, normal, false); + add_side(a, b, normal, true); if (add_caps) { // Start cap @@ -334,7 +332,7 @@ void GeometryGenerator::GenerateVolumetricSegment(const Vector3 &a, const Vector } } -void GeometryGenerator::GenerateVolumetricSegmentBevel(const Vector3 &a, const Vector3 &b, const Vector3 &normal_a, const Vector3 &normal_b, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps) { +void GeometryGenerator::GenerateVolumetricSegmentBevel(const Vector3 &a, const Vector3 &b, const Vector3 &normal, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps) { ZoneScoped; bool debug_size = false; Vector3 debug_mult = debug_size ? Vector3(1, 1, 1) * 0.5f : Vector3(); @@ -353,13 +351,13 @@ void GeometryGenerator::GenerateVolumetricSegmentBevel(const Vector3 &a, const V custom0.push_back(Vector3_ZERO); custom0.push_back(Vector3_ZERO); - auto add_side = [&half_len, &dir, &base_idx, &vertexes, &indexes, &custom0, &uv, &debug_mult](Vector3 pos_a, Vector3 pos_b, Vector3 normal_a, Vector3 normal_b, bool is_rotated) { + auto add_side = [&half_len, &dir, &base_idx, &vertexes, &indexes, &custom0, &uv, &debug_mult](Vector3 pos_a, Vector3 pos_b, Vector3 normal, real_t angle) { int64_t start_idx = vertexes.size(); - Vector3 right_a = dir.cross(normal_a.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); + Vector3 right_a = dir.cross(normal.rotated(dir, Math::deg_to_rad(angle))).normalized(); Vector3 left_a = right_a * -1; - Vector3 right_b = dir.cross(normal_a.rotated(dir, Math::deg_to_rad(is_rotated ? -45.f : 45.f))).normalized(); + Vector3 right_b = dir.cross(normal.rotated(dir, Math::deg_to_rad(angle))).normalized(); Vector3 left_b = right_b * -1; right_a /= Math::sqrt(2.0f); @@ -404,8 +402,8 @@ void GeometryGenerator::GenerateVolumetricSegmentBevel(const Vector3 &a, const V custom0.push_back(left_b); }; - add_side(a, b, normal_a, normal_b, false); - add_side(a, b, normal_a, normal_b, true); + add_side(a, b, normal, 45.f); + add_side(a, b, normal, -45.f); if (add_caps) { // Start cap @@ -438,6 +436,108 @@ void GeometryGenerator::GenerateVolumetricSegmentBevel(const Vector3 &a, const V } } +Ref GeometryGenerator::CreateVolumetricArrowHead(const real_t &radius, const real_t &length, const real_t &offset_mult, const bool &add_bevel) { + PackedVector3Array vertexes; + PackedVector2Array uv; + PackedVector3Array custom0; + PackedInt32Array indexes; + + auto rotate = [](PackedVector3Array &arr, int start, int end, real_t scale) { + for (int i = start; i <= end; i++) { + arr[i] = arr[i].rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / scale; + } + }; + + real_t front_offset = add_bevel ? .5f : 0; + real_t square_diag_mult = Math::sqrt(2.f); + + vertexes.push_back(Vector3(0, 0, 0)); // 0 + + vertexes.push_back(Vector3(0, 0, -0.00001f).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 1 + vertexes.push_back(Vector3(0, 0, -0.00001f).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 2 + vertexes.push_back(Vector3(0, 0, -0.00001f).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 3 + vertexes.push_back(Vector3(0, 0, -0.00001f).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 4 + + vertexes.push_back(Vector3(0, radius, length).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 5 + vertexes.push_back(Vector3(0, -radius, length).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 6 + vertexes.push_back(Vector3(radius, 0, length).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 7 + vertexes.push_back(Vector3(-radius, 0, length).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); // 8 + + custom0.push_back(Vector3(0, 0, 0)); + custom0.push_back(Vector3(0, 1, 0).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult - Vector3_FORWARD * front_offset); + custom0.push_back(Vector3(0, -1, 0).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult - Vector3_FORWARD * front_offset); + custom0.push_back(Vector3(1, 0, 0).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult - Vector3_FORWARD * front_offset); + custom0.push_back(Vector3(-1, 0, 0).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult - Vector3_FORWARD * front_offset); + + custom0.push_back(Vector3(0, 1 + radius * 2, offset_mult * length * 2).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); + custom0.push_back(Vector3(0, -(1 + radius * 2), offset_mult * length * 2).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); + custom0.push_back(Vector3(1 + radius * 2, 0, offset_mult * length * 2).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); + custom0.push_back(Vector3(-(1 + radius * 2), 0, offset_mult * length * 2).rotated(Vector3_FORWARD, Math::deg_to_rad(45.f)) / square_diag_mult); + + uv.push_back(Vector2(.5f, .5f)); + + uv.push_back(Vector2(0, 0)); + uv.push_back(Vector2(0, 0)); + uv.push_back(Vector2(0, 0)); + uv.push_back(Vector2(0, 0)); + + uv.push_back(Vector2(.5f, .5f)); + uv.push_back(Vector2(.5f, .5f)); + uv.push_back(Vector2(.5f, .5f)); + uv.push_back(Vector2(.5f, .5f)); + + indexes.push_back(0); + indexes.push_back(1); + indexes.push_back(3); + indexes.push_back(0); + indexes.push_back(3); + indexes.push_back(2); + indexes.push_back(0); + indexes.push_back(2); + indexes.push_back(4); + indexes.push_back(0); + indexes.push_back(4); + indexes.push_back(1); + + indexes.push_back(1); + indexes.push_back(3); + indexes.push_back(5); + indexes.push_back(3); + indexes.push_back(7); + indexes.push_back(5); + + indexes.push_back(1); + indexes.push_back(5); + indexes.push_back(8); + indexes.push_back(1); + indexes.push_back(8); + indexes.push_back(4); + + indexes.push_back(2); + indexes.push_back(6); + indexes.push_back(8); + indexes.push_back(2); + indexes.push_back(8); + indexes.push_back(4); + + indexes.push_back(3); + indexes.push_back(7); + indexes.push_back(6); + indexes.push_back(3); + indexes.push_back(6); + indexes.push_back(2); + + return CreateMesh( + Mesh::PRIMITIVE_TRIANGLES, + vertexes, + indexes, + PackedColorArray(), + PackedVector3Array(), + uv, + Utils::convert_packed_array_to_diffrent_types(custom0), + ArrayMesh::ARRAY_CUSTOM_RGB_FLOAT << Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT); +} + Ref GeometryGenerator::CreateCameraFrustumLines(const std::array &frustum) { ZoneScoped; std::vector res; diff --git a/src/3d/geometry_generators.h b/src/3d/geometry_generators.h index b35b404c..bd0b868c 100644 --- a/src/3d/geometry_generators.h +++ b/src/3d/geometry_generators.h @@ -12,8 +12,8 @@ using namespace godot; class GeometryGenerator { private: - static void GenerateVolumetricSegment(const Vector3 &a, const Vector3 &b, const Vector3 &normal_a, const Vector3 &normal_b, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps = true); - static void GenerateVolumetricSegmentBevel(const Vector3 &a, const Vector3 &b, const Vector3 &normal_a, const Vector3 &normal_b, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps = true); + static void GenerateVolumetricSegment(const Vector3 &a, const Vector3 &b, const Vector3 &normal, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps = true); + static void GenerateVolumetricSegmentBevel(const Vector3 &a, const Vector3 &b, const Vector3 &normal, PackedVector3Array &vertexes, PackedVector3Array &custom0, PackedInt32Array &indexes, PackedVector2Array &uv, const bool &add_caps = true); public: #pragma region Predefined Geometry Parts @@ -52,6 +52,7 @@ class GeometryGenerator { static Ref CreateMesh(Mesh::PrimitiveType type, const PackedVector3Array &vertices, const PackedInt32Array &indices = {}, const PackedColorArray &colors = {}, const PackedVector3Array &normals = {}, const PackedVector2Array &uv = {}, const PackedFloat32Array &custom0 = {}, BitField flags = 0); static Ref ConvertWireframeToVolumetric(Ref mesh, const bool &add_bevel, const bool &add_caps = false); + static Ref CreateVolumetricArrowHead(const real_t &radius, const real_t &length, const real_t &offset_mult, const bool &add_bevel); static Ref CreateCameraFrustumLines(const std::array &frustum); static void CreateCameraFrustumLinesWireframe(const std::array &frustum, std::vector *vertexes, std::vector *normals); diff --git a/src/debug_draw_manager.cpp b/src/debug_draw_manager.cpp index 03ff6b79..6a4c4abb 100644 --- a/src/debug_draw_manager.cpp +++ b/src/debug_draw_manager.cpp @@ -17,6 +17,11 @@ using namespace godot; DebugDrawManager *DebugDrawManager::singleton = nullptr; +const char *DebugDrawManager::s_initial_state = "initial_debug_state"; +const char *DebugDrawManager::s_manager_aliases = NAMEOF(DebugDrawManager) "_singleton_aliases "; +const char *DebugDrawManager::s_dd2d_aliases = NAMEOF(DebugDraw2D) "_singleton_aliases"; +const char *DebugDrawManager::s_dd3d_aliases = NAMEOF(DebugDraw3D) "_singleton_aliases"; + const char *DebugDrawManager::s_extension_unloading = "extension_unloading"; void DebugDrawManager::_bind_methods() { @@ -183,6 +188,7 @@ DebugDrawManager::DebugDrawManager() { DebugDrawManager::~DebugDrawManager() { UNASSIGN_SINGLETON(DebugDrawManager); + deinit(); } void DebugDrawManager::clear_all() { @@ -206,25 +212,79 @@ bool DebugDrawManager::is_debug_enabled() const { void DebugDrawManager::init() { ZoneScoped; - DEFINE_SETTING_AND_GET(bool initial_debug_state, String(Utils::root_settings_section) + "initial_debug_state", true, Variant::BOOL); + DEFINE_SETTING_AND_GET(bool initial_debug_state, String(Utils::root_settings_section) + s_initial_state, true, Variant::BOOL); set_debug_enabled(initial_debug_state); + manager_aliases.push_back(StringName("Dmgr")); + dd2d_aliases.push_back(StringName("Dbg2")); + dd3d_aliases.push_back(StringName("Dbg3")); + + root_settings_section = String(Utils::root_settings_section) + "common/"; + DEFINE_SETTING_AND_GET_HINT(Variant mgr_a, root_settings_section + s_manager_aliases, manager_aliases, Variant::ARRAY, PropertyHint::PROPERTY_HINT_TYPE_STRING, FMT_STR("{0}:", Variant::STRING_NAME)); + DEFINE_SETTING_AND_GET_HINT(Variant dd2d_a, root_settings_section + s_dd2d_aliases, dd2d_aliases, Variant::ARRAY, PropertyHint::PROPERTY_HINT_TYPE_STRING, FMT_STR("{0}:", Variant::STRING_NAME)); + DEFINE_SETTING_AND_GET_HINT(Variant dd3d_a, root_settings_section + s_dd3d_aliases, dd3d_aliases, Variant::ARRAY, PropertyHint::PROPERTY_HINT_TYPE_STRING, FMT_STR("{0}:", Variant::STRING_NAME)); + + manager_aliases = TypedArray(mgr_a); + dd2d_aliases = TypedArray(dd2d_a); + dd3d_aliases = TypedArray(dd3d_a); + // Draw everything after calls from scripts to avoid lagging set_process_priority(INT32_MAX); Engine::get_singleton()->register_singleton(NAMEOF(DebugDrawManager), this); - - debug_draw_3d_singleton = memnew(DebugDraw3D); - Engine::get_singleton()->register_singleton(NAMEOF(DebugDraw3D), debug_draw_3d_singleton); - Engine::get_singleton()->register_singleton("Dbg3", debug_draw_3d_singleton); + _register_singleton_aliases(manager_aliases, this); debug_draw_2d_singleton = memnew(DebugDraw2D); Engine::get_singleton()->register_singleton(NAMEOF(DebugDraw2D), debug_draw_2d_singleton); - Engine::get_singleton()->register_singleton("Dbg2", debug_draw_2d_singleton); + _register_singleton_aliases(dd2d_aliases, debug_draw_2d_singleton); + + debug_draw_3d_singleton = memnew(DebugDraw3D); + Engine::get_singleton()->register_singleton(NAMEOF(DebugDraw3D), debug_draw_3d_singleton); + _register_singleton_aliases(dd3d_aliases, debug_draw_3d_singleton); call_deferred(NAMEOF(_integrate_into_engine)); } +void DebugDrawManager::deinit() { + ZoneScoped; + is_closing = true; + + if (Engine::get_singleton()->has_singleton(NAMEOF(DebugDrawManager))) { + Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDrawManager)); + _unregister_singleton_aliases(manager_aliases); + } + + if (debug_draw_2d_singleton) { + Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDraw2D)); + _unregister_singleton_aliases(dd2d_aliases); + memdelete(debug_draw_2d_singleton); + debug_draw_2d_singleton = nullptr; + } + + if (debug_draw_3d_singleton) { + Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDraw3D)); + _unregister_singleton_aliases(dd3d_aliases); + memdelete(debug_draw_3d_singleton); + debug_draw_3d_singleton = nullptr; + } + + emit_signal(s_extension_unloading); +} + +void DebugDrawManager::_register_singleton_aliases(const TypedArray &names, Object *instance) { + for (int i = 0; i < names.size(); i++) { + if (!names[i].operator godot::StringName().is_empty()) + Engine::get_singleton()->register_singleton(names[i], instance); + } +} + +void DebugDrawManager::_unregister_singleton_aliases(const TypedArray &names) { + for (int i = 0; i < names.size(); i++) { + if (!names[i].operator godot::StringName().is_empty()) + Engine::get_singleton()->unregister_singleton(names[i]); + } +} + void DebugDrawManager::_process(double delta) { // To discover what causes the constant look here: // https://github.com/godotengine/godot/blob/baf6b4634d08bc3e193a38b86e96945052002f64/servers/rendering/rendering_server_default.h#L104 @@ -258,31 +318,6 @@ void DebugDrawManager::_process(double delta) { } } -void DebugDrawManager::_exit_tree() { - ZoneScoped; - is_closing = true; - - if (Engine::get_singleton()->has_singleton(NAMEOF(DebugDrawManager))) { - Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDrawManager)); - } - - if (debug_draw_3d_singleton) { - Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDraw3D)); - Engine::get_singleton()->unregister_singleton("Dbg3"); - memdelete(debug_draw_3d_singleton); - debug_draw_3d_singleton = nullptr; - } - - if (debug_draw_2d_singleton) { - Engine::get_singleton()->unregister_singleton(NAMEOF(DebugDraw2D)); - Engine::get_singleton()->unregister_singleton("Dbg2"); - memdelete(debug_draw_2d_singleton); - debug_draw_2d_singleton = nullptr; - } - - emit_signal(s_extension_unloading); -} - #ifdef TOOLS_ENABLED void DebugDrawManager::_try_to_update_cs_bindings() { ZoneScoped; diff --git a/src/debug_draw_manager.h b/src/debug_draw_manager.h index 34783ed1..6d9224e6 100644 --- a/src/debug_draw_manager.h +++ b/src/debug_draw_manager.h @@ -12,6 +12,12 @@ class DebugDrawManager : public CanvasLayer { protected: static DebugDrawManager *singleton; + String root_settings_section; + const static char *s_initial_state; + const static char *s_manager_aliases; + const static char *s_dd2d_aliases; + const static char *s_dd3d_aliases; + static void _bind_methods(); double log_flush_time = 0; @@ -22,12 +28,19 @@ class DebugDrawManager : public CanvasLayer { class DebugDraw3D *debug_draw_3d_singleton = nullptr; class DebugDraw2D *debug_draw_2d_singleton = nullptr; + TypedArray manager_aliases; + TypedArray dd2d_aliases; + TypedArray dd3d_aliases; + Node *_get_current_scene(); void _connect_scene_changed(); void _on_scene_changed(bool _is_scene_null); void _integrate_into_engine(); + void _register_singleton_aliases(const TypedArray &names, Object *instance); + void _unregister_singleton_aliases(const TypedArray &names); + #ifdef TOOLS_ENABLED void _try_to_update_cs_bindings(); #endif @@ -47,6 +60,6 @@ class DebugDrawManager : public CanvasLayer { bool is_debug_enabled() const; void init(); + void deinit(); virtual void _process(double delta) override; - virtual void _exit_tree() override; }; \ No newline at end of file diff --git a/src/editor/asset_library_update_checker.cpp b/src/editor/asset_library_update_checker.cpp index 84b8e127..7a62d521 100644 --- a/src/editor/asset_library_update_checker.cpp +++ b/src/editor/asset_library_update_checker.cpp @@ -223,4 +223,4 @@ AssetLibraryUpdateChecker::~AssetLibraryUpdateChecker() { } #endif -#endif \ No newline at end of file +#endif diff --git a/src/register_types.cpp b/src/register_types.cpp index 470238ec..446fe109 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -71,7 +71,7 @@ void initialize_debug_draw_3d_module(ModuleInitializationLevel p_level) { void uninitialize_debug_draw_3d_module(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { - // If this library is disabled manually before deleting the scene tree, + // If this library is disabled manually before deleting the scene tree (hot-reload), // then an attempt is made to delete this node manually. if (Engine::get_singleton()->get_main_loop() && UtilityFunctions::is_instance_valid(debug_draw_manager)) { memdelete(debug_draw_manager); diff --git a/src/utils/utils.h b/src/utils/utils.h index 663c0f73..58f2dbb7 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -121,6 +121,20 @@ static String get_file_name_in_repository(const String &name) { PS()->set_initial_value(path, def); \ } \ var = PS()->get_setting(path) +#define DEFINE_SETTING_AND_GET_HINT(var, path, def, type, hint, hint_string) \ + { \ + if (!PS()->has_setting(path)) { \ + PS()->set_setting(path, def); \ + } \ + Dictionary info; \ + info["name"] = path; \ + info["type"] = type; \ + info["hint"] = hint; \ + info["hint_string"] = hint_string; \ + PS()->add_property_info(info); \ + PS()->set_initial_value(path, def); \ + } \ + var = PS()->get_setting(path) #define DEFINE_SETTING_READ_ONLY(path, def, type) \ { \ PS()->set_setting(path, def); \