@@ -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
492524void 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
0 commit comments