Skip to content

Commit 5b11eb6

Browse files
committed
Merge pull request #99562 from badsectoracula/improve_voxelgi_bake_ui
Add VoxelGI bake cancelling and progress UI improvement
2 parents fc6c8bb + da19116 commit 5b11eb6

File tree

6 files changed

+116
-36
lines changed

6 files changed

+116
-36
lines changed

editor/plugins/voxel_gi_editor_plugin.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,15 @@ void VoxelGIEditorPlugin::make_visible(bool p_visible) {
146146

147147
EditorProgress *VoxelGIEditorPlugin::tmp_progress = nullptr;
148148

149-
void VoxelGIEditorPlugin::bake_func_begin(int p_steps) {
149+
void VoxelGIEditorPlugin::bake_func_begin() {
150150
ERR_FAIL_COND(tmp_progress != nullptr);
151151

152-
tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), p_steps));
152+
tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), 1000, true));
153153
}
154154

155-
void VoxelGIEditorPlugin::bake_func_step(int p_step, const String &p_description) {
156-
ERR_FAIL_NULL(tmp_progress);
157-
tmp_progress->step(p_description, p_step, false);
155+
bool VoxelGIEditorPlugin::bake_func_step(int p_progress, const String &p_description) {
156+
ERR_FAIL_NULL_V(tmp_progress, false);
157+
return tmp_progress->step(p_description, p_progress, false);
158158
}
159159

160160
void VoxelGIEditorPlugin::bake_func_end() {

editor/plugins/voxel_gi_editor_plugin.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class VoxelGIEditorPlugin : public EditorPlugin {
5050
EditorFileDialog *probe_file = nullptr;
5151

5252
static EditorProgress *tmp_progress;
53-
static void bake_func_begin(int p_steps);
54-
static void bake_func_step(int p_step, const String &p_description);
53+
static void bake_func_begin();
54+
static bool bake_func_step(int p_progress, const String &p_description);
5555
static void bake_func_end();
5656

5757
void _bake();

scene/3d/voxel_gi.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,17 @@ VoxelGI::BakeBeginFunc VoxelGI::bake_begin_function = nullptr;
389389
VoxelGI::BakeStepFunc VoxelGI::bake_step_function = nullptr;
390390
VoxelGI::BakeEndFunc VoxelGI::bake_end_function = nullptr;
391391

392+
static int voxelizer_plot_bake_base = 0;
393+
static int voxelizer_plot_bake_total = 0;
394+
395+
static bool voxelizer_plot_bake_step_function(int current, int) {
396+
return VoxelGI::bake_step_function((voxelizer_plot_bake_base + current) * 500 / voxelizer_plot_bake_total, RTR("Plotting Meshes"));
397+
}
398+
399+
static bool voxelizer_sdf_bake_step_function(int current, int total) {
400+
return VoxelGI::bake_step_function(500 + current * 500 / total, RTR("Generating Distance Field"));
401+
}
402+
392403
Vector3i VoxelGI::get_estimated_cell_size() const {
393404
static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
394405
int cell_subdiv = subdiv_value[subdiv];
@@ -432,22 +443,27 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) {
432443
_find_meshes(p_from_node, mesh_list);
433444

434445
if (bake_begin_function) {
435-
bake_begin_function(mesh_list.size() + 1);
446+
bake_begin_function();
436447
}
437448

438-
int pmc = 0;
449+
Voxelizer::BakeStepFunc voxelizer_step_func = bake_step_function != nullptr ? voxelizer_plot_bake_step_function : nullptr;
439450

451+
voxelizer_plot_bake_total = voxelizer_plot_bake_base = 0;
440452
for (PlotMesh &E : mesh_list) {
441-
if (bake_step_function) {
442-
bake_step_function(pmc, RTR("Plotting Meshes") + " " + itos(pmc) + "/" + itos(mesh_list.size()));
453+
voxelizer_plot_bake_total += baker.get_bake_steps(E.mesh);
454+
}
455+
for (PlotMesh &E : mesh_list) {
456+
if (baker.plot_mesh(E.local_xform, E.mesh, E.instance_materials, E.override_material, voxelizer_step_func) != Voxelizer::BAKE_RESULT_OK) {
457+
baker.end_bake();
458+
if (bake_end_function) {
459+
bake_end_function();
460+
}
461+
return;
443462
}
444-
445-
pmc++;
446-
447-
baker.plot_mesh(E.local_xform, E.mesh, E.instance_materials, E.override_material);
463+
voxelizer_plot_bake_base += baker.get_bake_steps(E.mesh);
448464
}
449465
if (bake_step_function) {
450-
bake_step_function(pmc++, RTR("Finishing Plot"));
466+
bake_step_function(500, RTR("Finishing Plot"));
451467
}
452468

453469
baker.end_bake();
@@ -476,19 +492,22 @@ void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) {
476492
}
477493

478494
if (bake_step_function) {
479-
bake_step_function(pmc++, RTR("Generating Distance Field"));
495+
bake_step_function(500, RTR("Generating Distance Field"));
480496
}
481497

482-
Vector<uint8_t> df = baker.get_sdf_3d_image();
498+
voxelizer_step_func = bake_step_function != nullptr ? voxelizer_sdf_bake_step_function : nullptr;
483499

484-
RS::get_singleton()->voxel_gi_set_baked_exposure_normalization(probe_data_new->get_rid(), exposure_normalization);
500+
Vector<uint8_t> df;
501+
if (baker.get_sdf_3d_image(df, voxelizer_step_func) == Voxelizer::BAKE_RESULT_OK) {
502+
RS::get_singleton()->voxel_gi_set_baked_exposure_normalization(probe_data_new->get_rid(), exposure_normalization);
485503

486-
probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-size / 2, size), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count());
504+
probe_data_new->allocate(baker.get_to_cell_space_xform(), AABB(-size / 2, size), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count());
487505

488-
set_probe_data(probe_data_new);
506+
set_probe_data(probe_data_new);
489507
#ifdef TOOLS_ENABLED
490-
probe_data_new->set_edited(true); //so it gets saved
508+
probe_data_new->set_edited(true); //so it gets saved
491509
#endif
510+
}
492511
}
493512

494513
if (bake_end_function) {

scene/3d/voxel_gi.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ class VoxelGI : public VisualInstance3D {
108108

109109
};
110110

111-
typedef void (*BakeBeginFunc)(int);
112-
typedef void (*BakeStepFunc)(int, const String &);
111+
typedef void (*BakeBeginFunc)();
112+
typedef bool (*BakeStepFunc)(int, const String &);
113113
typedef void (*BakeEndFunc)();
114114

115115
private:

scene/3d/voxelizer.cpp

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,24 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
382382
return mc;
383383
}
384384

385-
void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) {
386-
ERR_FAIL_COND_MSG(!p_xform.is_finite(), "Invalid mesh bake transform.");
385+
int Voxelizer::get_bake_steps(Ref<Mesh> &p_mesh) const {
386+
int bake_total = 0;
387+
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
388+
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
389+
continue; // Only triangles.
390+
}
391+
Array a = p_mesh->surface_get_arrays(i);
392+
Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
393+
Vector<int> index = a[Mesh::ARRAY_INDEX];
394+
bake_total += (index.size() > 0 ? index.size() : vertices.size()) / 3;
395+
}
396+
return bake_total;
397+
}
398+
399+
Voxelizer::BakeResult Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material, BakeStepFunc p_bake_step_func) {
400+
ERR_FAIL_COND_V_MSG(!p_xform.is_finite(), BAKE_RESULT_INVALID_PARAMETER, "Invalid mesh bake transform.");
401+
402+
int bake_total = get_bake_steps(p_mesh), bake_current = 0;
387403

388404
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
389405
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
@@ -428,6 +444,13 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const V
428444
Vector2 uvs[3];
429445
Vector3 normal[3];
430446

447+
bake_current++;
448+
if (p_bake_step_func != nullptr && (bake_current & 2047) == 1) {
449+
if (p_bake_step_func(bake_current, bake_total)) {
450+
return BAKE_RESULT_CANCELLED;
451+
}
452+
}
453+
431454
for (int k = 0; k < 3; k++) {
432455
vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
433456
}
@@ -460,6 +483,13 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const V
460483
Vector2 uvs[3];
461484
Vector3 normal[3];
462485

486+
bake_current++;
487+
if (p_bake_step_func != nullptr && (bake_current & 2047) == 1) {
488+
if (p_bake_step_func(bake_current, bake_total)) {
489+
return BAKE_RESULT_CANCELLED;
490+
}
491+
}
492+
463493
for (int k = 0; k < 3; k++) {
464494
vtxs[k] = p_xform.xform(vr[j * 3 + k]);
465495
}
@@ -487,6 +517,8 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const V
487517
}
488518

489519
max_original_cells = bake_cells.size();
520+
521+
return BAKE_RESULT_OK;
490522
}
491523

492524
void Voxelizer::_sort() {
@@ -821,7 +853,7 @@ static void edt(float *f, int stride, int n) {
821853

822854
#undef square
823855

824-
Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
856+
Voxelizer::BakeResult Voxelizer::get_sdf_3d_image(Vector<uint8_t> &r_image, BakeStepFunc p_bake_step_function) const {
825857
Vector3i octree_size = get_voxel_gi_octree_size();
826858

827859
uint32_t float_count = octree_size.x * octree_size.y * octree_size.z;
@@ -849,33 +881,52 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
849881

850882
//process in each direction
851883

884+
int bake_total = octree_size.x * 2 + octree_size.y, bake_current = 0;
885+
852886
//xy->z
853887

854-
for (int i = 0; i < octree_size.x; i++) {
888+
for (int i = 0; i < octree_size.x; i++, bake_current++) {
889+
if (p_bake_step_function) {
890+
if (p_bake_step_function(bake_current, bake_total)) {
891+
memdelete_arr(work_memory);
892+
return BAKE_RESULT_CANCELLED;
893+
}
894+
}
855895
for (int j = 0; j < octree_size.y; j++) {
856896
edt(&work_memory[i + j * y_mult], z_mult, octree_size.z);
857897
}
858898
}
859899

860900
//xz->y
861901

862-
for (int i = 0; i < octree_size.x; i++) {
902+
for (int i = 0; i < octree_size.x; i++, bake_current++) {
903+
if (p_bake_step_function) {
904+
if (p_bake_step_function(bake_current, bake_total)) {
905+
memdelete_arr(work_memory);
906+
return BAKE_RESULT_CANCELLED;
907+
}
908+
}
863909
for (int j = 0; j < octree_size.z; j++) {
864910
edt(&work_memory[i + j * z_mult], y_mult, octree_size.y);
865911
}
866912
}
867913

868914
//yz->x
869-
for (int i = 0; i < octree_size.y; i++) {
915+
for (int i = 0; i < octree_size.y; i++, bake_current++) {
916+
if (p_bake_step_function) {
917+
if (p_bake_step_function(bake_current, bake_total)) {
918+
memdelete_arr(work_memory);
919+
return BAKE_RESULT_CANCELLED;
920+
}
921+
}
870922
for (int j = 0; j < octree_size.z; j++) {
871923
edt(&work_memory[i * y_mult + j * z_mult], 1, octree_size.x);
872924
}
873925
}
874926

875-
Vector<uint8_t> image3d;
876-
image3d.resize(float_count);
927+
r_image.resize(float_count);
877928
{
878-
uint8_t *w = image3d.ptrw();
929+
uint8_t *w = r_image.ptrw();
879930
for (uint32_t i = 0; i < float_count; i++) {
880931
uint32_t d = uint32_t(Math::sqrt(work_memory[i]));
881932
if (d == 0) {
@@ -888,7 +939,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
888939

889940
memdelete_arr(work_memory);
890941

891-
return image3d;
942+
return BAKE_RESULT_OK;
892943
}
893944

894945
#undef INF

scene/3d/voxelizer.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@
3434
#include "scene/resources/multimesh.h"
3535

3636
class Voxelizer {
37+
public:
38+
enum BakeResult {
39+
BAKE_RESULT_OK,
40+
BAKE_RESULT_INVALID_PARAMETER,
41+
BAKE_RESULT_CANCELLED,
42+
};
43+
44+
typedef bool (*BakeStepFunc)(int, int);
45+
3746
private:
3847
enum : uint32_t {
3948
CHILD_EMPTY = 0xFFFFFFFF
@@ -112,7 +121,8 @@ class Voxelizer {
112121

113122
public:
114123
void begin_bake(int p_subdiv, const AABB &p_bounds, float p_exposure_normalization);
115-
void plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material);
124+
int get_bake_steps(Ref<Mesh> &p_mesh) const;
125+
BakeResult plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material, BakeStepFunc p_bake_step_function);
116126
void end_bake();
117127

118128
int get_voxel_gi_octree_depth() const;
@@ -121,7 +131,7 @@ class Voxelizer {
121131
Vector<uint8_t> get_voxel_gi_octree_cells() const;
122132
Vector<uint8_t> get_voxel_gi_data_cells() const;
123133
Vector<int> get_voxel_gi_level_cell_count() const;
124-
Vector<uint8_t> get_sdf_3d_image() const;
134+
BakeResult get_sdf_3d_image(Vector<uint8_t> &r_image, BakeStepFunc p_bake_step_function) const;
125135

126136
Ref<MultiMesh> create_debug_multimesh();
127137

0 commit comments

Comments
 (0)