Skip to content

Commit

Permalink
added frustum length customization
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriySalnikov committed Mar 29, 2024
1 parent e268ce4 commit d8f5ba9
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 19 deletions.
4 changes: 2 additions & 2 deletions dd3d_web_build/headless_test.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ func start() -> bool:
await get_tree().process_frame

DebugDraw3D.draw_sphere(Vector3.ZERO)
DebugDraw3D.config.culling_distance = 50
print(\"culling_distance: \", DebugDraw3D.config.culling_distance)
DebugDraw3D.config.frustum_length_scale = 0.07
print(\"frustum_length_scale: \", DebugDraw3D.config.frustum_length_scale)

await get_tree().create_timer(2).timeout

Expand Down
4 changes: 2 additions & 2 deletions examples_dd3d/DebugDrawDemoScene.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extends Node3D
@export var draw_1m_boxes := false
@export_range(0, 5, 0.001) var debug_thickness := 0.1
@export_range(0, 1, 0.001) var debug_center_brightness := 0.8
@export_range(0, 1024) var start_culling_distance := 75.0
@export_range(0, 1) var camera_frustum_scale := 0.9

@export_group("Text groups", "text_groups")
@export var text_groups_show_hints := true
Expand Down Expand Up @@ -148,7 +148,7 @@ func main_update(delta: float) -> void:
DebugDrawManager.debug_enabled = !DebugDrawManager.debug_enabled


DebugDraw3D.config.culling_distance = start_culling_distance
DebugDraw3D.config.frustum_length_scale = camera_frustum_scale

# Zones with black borders
for z in $Zones.get_children():
Expand Down
17 changes: 17 additions & 0 deletions examples_dd3d/DebugDrawDemoScene.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,22 @@ max_value = 0.5
step = 0.001
value = 0.05

[node name="HBox5" type="HBoxContainer" parent="Settings/HBox/PanelContainer/VBox"]
layout_mode = 2

[node name="Label" type="Label" parent="Settings/HBox/PanelContainer/VBox/HBox5"]
layout_mode = 2
text = "Frustum Scale"

[node name="FrustumScaleSlider" type="HSlider" parent="Settings/HBox/PanelContainer/VBox/HBox5"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
max_value = 1.0
step = 0.001
value = 0.5

[node name="UpdateInPhysics" type="CheckBox" parent="Settings/HBox/PanelContainer/VBox"]
unique_name_in_owner = true
layout_mode = 2
Expand Down Expand Up @@ -892,6 +908,7 @@ text = "Switch to C#"
[connection signal="value_changed" from="MusicVisualizer/VBox/HBoxContainer/VolumeSlider" to="MusicVisualizer" method="_on_volume_slider_value_changed"]
[connection signal="toggled" from="MusicVisualizer/VBox/HBoxContainer/MuteMaster" to="MusicVisualizer" method="_on_mute_master_toggled"]
[connection signal="value_changed" from="Settings/HBox/PanelContainer/VBox/HBox3/ThicknessSlider" to="Settings" method="_on_thickness_slider_value_changed"]
[connection signal="value_changed" from="Settings/HBox/PanelContainer/VBox/HBox5/FrustumScaleSlider" to="Settings" method="_on_frustum_scale_slider_value_changed"]
[connection signal="toggled" from="Settings/HBox/PanelContainer/VBox/UpdateInPhysics" to="Settings" method="_on_update_in_physics_toggled"]
[connection signal="toggled" from="Settings/HBox/PanelContainer/VBox/FPSEnabled" to="Settings" method="_on_CheckBox_toggled"]
[connection signal="toggled" from="Settings/HBox/PanelContainer/VBox/FPSMS" to="Settings" method="_on_FPSMS_toggled"]
Expand Down
8 changes: 8 additions & 0 deletions examples_dd3d/demo_settings_panel.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func _ready():
%BufferSlider.value = test.buffer_size

%ThicknessSlider.value = get_parent().debug_thickness
%FrustumScaleSlider.value = get_parent().camera_frustum_scale
%UpdateInPhysics.text = "Update in physics (%d Ticks) *" % ProjectSettings.get_setting("physics/common/physics_ticks_per_second")
%UpdateInPhysics.button_pressed = get_parent().update_in_physics

Expand Down Expand Up @@ -73,6 +74,12 @@ func _on_thickness_slider_value_changed(value):
get_parent().debug_thickness = value


func _on_frustum_scale_slider_value_changed(value):
if not is_ready: return

get_parent().camera_frustum_scale = value


func _on_update_in_physics_toggled(toggled_on):
get_parent().update_in_physics = toggled_on

Expand All @@ -94,3 +101,4 @@ func _on_draw_1m_boxes_toggled(toggled_on):
if get_parent().draw_array_of_boxes:
DebugDraw3D.clear_all()
get_parent().timer_cubes = 0

10 changes: 5 additions & 5 deletions src/3d/config_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void DebugDraw3DConfig::_bind_methods() {
REG_PROP_BOOL(freeze_3d_render);
REG_PROP_BOOL(visible_instance_bounds);
REG_PROP_BOOL(use_frustum_culling);
REG_PROP(culling_distance, Variant::FLOAT);
REG_PROP(frustum_length_scale, Variant::FLOAT);
REG_PROP_BOOL(force_use_camera_from_scene);
REG_PROP(geometry_render_layers, Variant::INT);
REG_PROP(line_hit_color, Variant::COLOR);
Expand Down Expand Up @@ -45,12 +45,12 @@ bool DebugDraw3DConfig::is_use_frustum_culling() const {
return use_frustum_culling;
}

void DebugDraw3DConfig::set_culling_distance(const real_t &_distance) {
cull_by_distance = Math::clamp(_distance, 0.0f, 1.0f);
void DebugDraw3DConfig::set_frustum_length_scale(const real_t &_distance) {
frustum_length_scale = Math::clamp(_distance, 0.0f, 1.0f);
}

real_t DebugDraw3DConfig::get_culling_distance() const {
return cull_by_distance;
real_t DebugDraw3DConfig::get_frustum_length_scale() const {
return frustum_length_scale;
}

void DebugDraw3DConfig::set_force_use_camera_from_scene(const bool &_state) {
Expand Down
6 changes: 3 additions & 3 deletions src/3d/config_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class DebugDraw3DConfig : public RefCounted {
bool freeze_3d_render = false;
bool visible_instance_bounds = false;
bool use_frustum_culling = true;
real_t cull_by_distance = 0;
real_t frustum_length_scale = 0;
bool force_use_camera_from_scene = false;
Color line_hit_color = Colors::red;
Color line_after_hit_color = Colors::green;
Expand Down Expand Up @@ -57,8 +57,8 @@ class DebugDraw3DConfig : public RefCounted {
*
* If set to 0, this parameter will be ignored and instances will be drawn at any distance.
*/
void set_culling_distance(const real_t &_distance);
real_t get_culling_distance() const;
void set_frustum_length_scale(const real_t &_distance);
real_t get_frustum_length_scale() const;

/**
* Set to force the use of the scene's default camera.
Expand Down
6 changes: 6 additions & 0 deletions src/3d/debug_draw_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ DebugDraw3D *DebugDraw3D::singleton = nullptr;
const char *DebugDraw3D::s_use_icosphere = "use_icosphere";
const char *DebugDraw3D::s_use_icosphere_hd = "use_icosphere_for_hd";
const char *DebugDraw3D::s_add_bevel_to_volumetric = "add_bevel_to_volumetric_geometry";
const char *DebugDraw3D::s_default_frustum_scale = "defaults/frustum_length_scale";

const char *DebugDraw3D::s_default_thickness = "volumetric_defaults/thickness";
const char *DebugDraw3D::s_default_center_brightness = "volumetric_defaults/center_brightness";
const char *DebugDraw3D::s_default_hd_spheres = "volumetric_defaults/hd_spheres";
Expand Down Expand Up @@ -135,13 +137,17 @@ void DebugDraw3D::init(DebugDrawManager *p_root) {
DEFINE_SETTING(root_settings_section + s_add_bevel_to_volumetric, true, Variant::BOOL);
DEFINE_SETTING(root_settings_section + s_use_icosphere, false, Variant::BOOL);
DEFINE_SETTING(root_settings_section + s_use_icosphere_hd, true, Variant::BOOL);
DEFINE_SETTING_AND_GET_HINT(real_t def_frustum_scale, root_settings_section + s_default_frustum_scale, 0.5f, Variant::FLOAT, PROPERTY_HINT_RANGE, "0,1,0.0001");

DEFINE_SETTING_AND_GET_HINT(real_t def_thickness, root_settings_section + s_default_thickness, 0.05f, Variant::FLOAT, PROPERTY_HINT_RANGE, "0,100,0.0001");
DEFINE_SETTING_AND_GET_HINT(real_t def_brightness, root_settings_section + s_default_center_brightness, 0.8f, Variant::FLOAT, PROPERTY_HINT_RANGE, "0,1,0.0001");
DEFINE_SETTING_AND_GET(real_t def_hd_sphere, root_settings_section + s_default_hd_spheres, false, Variant::BOOL);
DEFINE_SETTING_AND_GET_HINT(real_t def_plane_size, root_settings_section + s_default_plane_size, 0, Variant::FLOAT, PROPERTY_HINT_RANGE, "0,10000,0.001");

default_scoped_config.instantiate();

config->set_frustum_length_scale(def_frustum_scale);

default_scoped_config->set_thickness(def_thickness);
default_scoped_config->set_center_brightness(def_brightness);
default_scoped_config->set_hd_sphere(def_hd_sphere);
Expand Down
2 changes: 2 additions & 0 deletions src/3d/debug_draw_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ class DebugDraw3D : public Object, public IScopeStorage<DebugDraw3DScopeConfig,
const static char *s_use_icosphere;
const static char *s_use_icosphere_hd;
const static char *s_add_bevel_to_volumetric;
const static char *s_default_frustum_scale;

const static char *s_default_thickness;
const static char *s_default_center_brightness;
const static char *s_default_hd_spheres;
Expand Down
31 changes: 24 additions & 7 deletions src/3d/debug_geometry_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,42 +224,45 @@ void DebugGeometryContainer::update_geometry(double p_delta) {
for (const auto &vp_p : available_viewports) {
// Collect frustums and camera positions

std::vector<Array> frustum_arrays;
std::vector<std::pair<Array, Camera3D *> > frustum_arrays;
frustum_arrays.reserve(1);

auto custom_editor_viewports = owner->get_custom_editor_viewports();
Camera3D *vp_cam = vp_p->get_camera_3d();

if ((owner->get_config()->is_force_use_camera_from_scene() || !custom_editor_viewports.size()) && vp_cam) {
frustum_arrays.push_back(vp_cam->get_frustum());
frustum_arrays.push_back({ vp_cam->get_frustum(), vp_cam });
} else if (custom_editor_viewports.size() > 0) {
for (auto vp : custom_editor_viewports) {
if (vp->get_update_mode() == SubViewport::UpdateMode::UPDATE_ALWAYS) {
auto c = vp->get_camera_3d();
frustum_arrays.push_back(c->get_frustum());
frustum_arrays.push_back({ c->get_frustum(), c });
}
}
}

// Convert Array to vector
if (frustum_arrays.size()) {
for (auto &arr : frustum_arrays) {
for (auto &pair : frustum_arrays) {
Array &arr = pair.first;
if (arr.size() == 6) {
std::array<Plane, 6> a;
for (int i = 0; i < arr.size(); i++)
a[i] = (Plane)arr[i];

MathUtils::scale_frustum_far_plane_distance(a, pair.second->get_global_transform(), owner->get_config()->get_frustum_length_scale());

if (owner->get_config()->is_use_frustum_culling())
frustum_planes.push_back(a);

auto cube = MathUtils::get_frustum_cube(a);
AABB aabb = MathUtils::calculate_vertex_bounds(cube.data(), cube.size());
SphereBounds sb = aabb;
frustum_boxes.push_back(aabb);

#if false
// Debug camera bounds
{
SphereBounds sb = aabb;
auto cfg = owner->new_scoped_config()->set_thickness(0.1f)->set_hd_sphere(true); //->set_viewport(vp_p);
owner->draw_sphere(sb.position, sb.radius, Colors::crimson);
owner->draw_aabb(aabb, Colors::yellow);
Expand All @@ -284,6 +287,8 @@ void DebugGeometryContainer::update_geometry(double p_delta) {
Viewport *vp;
if (available_viewports.size()) {
vp = *available_viewports.begin();
auto cfg = std::make_shared<DebugDraw3DScopeConfig::Data>(owner->scoped_config()->data);
cfg->thickness = 0;

std::vector<AABBMinMax> new_instances;
geometry_pool.for_each_instance([&new_instances](DelayedRendererInstance *o) {
Expand All @@ -292,8 +297,6 @@ void DebugGeometryContainer::update_geometry(double p_delta) {
new_instances.push_back(o->bounds);
});

auto cfg = std::make_shared<DebugDraw3DScopeConfig::Data>(owner->scoped_config()->data);

// Draw custom sphere for 1 frame
for (auto &i : new_instances) {
cfg->viewport = vp;
Expand Down Expand Up @@ -349,6 +352,20 @@ void DebugGeometryContainer::update_geometry(double p_delta) {
Colors::debug_sphere_bounds,
SphereBounds(center, radius));
});

for (const auto &frustum : culling_data->m_frustums) {
size_t s = GeometryGenerator::CubeIndexes.size();
std::unique_ptr<Vector3[]> l(new Vector3[s]);
GeometryGenerator::CreateCameraFrustumLinesWireframe(frustum, l.get());

geometry_pool.add_or_update_line(
cfg,
0,
ProcessType::PROCESS,
std::move(l),
s,
Colors::orange_red);
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/utils/math_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class MathUtils {
_FORCE_INLINE_ static real_t get_max_vector_length(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c);
_FORCE_INLINE_ static real_t get_max_basis_length(const Basis &p_b);
_FORCE_INLINE_ static AABB calculate_vertex_bounds(const Vector3 *p_lines, size_t p_count);

_FORCE_INLINE_ static std::array<Vector3, 8> get_frustum_cube(const std::array<Plane, 6> p_frustum);
_FORCE_INLINE_ static void scale_frustum_far_plane_distance(std::array<Plane, 6> &p_frustum, const Transform3D &p_camera_xf, const real_t &p_scale);
};

struct SphereBounds {
Expand Down Expand Up @@ -176,6 +178,20 @@ std::array<Vector3, 8> MathUtils::get_frustum_cube(const std::array<Plane, 6> p_
});
}

_FORCE_INLINE_ void MathUtils::scale_frustum_far_plane_distance(std::array<Plane, 6> &p_frustum, const Transform3D &p_camera_xf, const real_t &p_scale) {
// near, far, left, top, right, bottom
// 0, 1, 2, 3, 4, 5
real_t near_len = p_frustum[0].distance_to(p_camera_xf.origin);
real_t far_len = p_frustum[1].distance_to(p_camera_xf.origin);

if (abs(near_len) > abs(far_len)) {
std::swap(near_len, far_len);
p_frustum[1] = Plane(p_frustum[1].normal, p_camera_xf.origin + p_camera_xf.basis.get_column(2) * ((1.f - p_scale) * (far_len + near_len) - near_len));
} else {
p_frustum[1] = Plane(p_frustum[1].normal, p_camera_xf.origin + p_camera_xf.basis.get_column(2) * (p_scale * (far_len + near_len) - near_len));
}
}

bool AABBMinMax::intersects(const AABBMinMax &p_aabb) const {
return min.x < p_aabb.max.x &&
max.x > p_aabb.min.x &&
Expand Down

0 comments on commit d8f5ba9

Please sign in to comment.