summaryrefslogtreecommitdiffstats
path: root/scene/3d/voxelizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/voxelizer.cpp')
-rw-r--r--scene/3d/voxelizer.cpp71
1 files changed, 61 insertions, 10 deletions
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 99392e9ba0..1074cad11e 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -382,8 +382,24 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
return mc;
}
-void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) {
- ERR_FAIL_COND_MSG(!p_xform.is_finite(), "Invalid mesh bake transform.");
+int Voxelizer::get_bake_steps(Ref<Mesh> &p_mesh) const {
+ int bake_total = 0;
+ for (int i = 0; i < p_mesh->get_surface_count(); i++) {
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
+ continue; // Only triangles.
+ }
+ Array a = p_mesh->surface_get_arrays(i);
+ Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
+ Vector<int> index = a[Mesh::ARRAY_INDEX];
+ bake_total += (index.size() > 0 ? index.size() : vertices.size()) / 3;
+ }
+ return bake_total;
+}
+
+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) {
+ ERR_FAIL_COND_V_MSG(!p_xform.is_finite(), BAKE_RESULT_INVALID_PARAMETER, "Invalid mesh bake transform.");
+
+ int bake_total = get_bake_steps(p_mesh), bake_current = 0;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
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
Vector2 uvs[3];
Vector3 normal[3];
+ bake_current++;
+ if (p_bake_step_func != nullptr && (bake_current & 2047) == 1) {
+ if (p_bake_step_func(bake_current, bake_total)) {
+ return BAKE_RESULT_CANCELLED;
+ }
+ }
+
for (int k = 0; k < 3; k++) {
vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
}
@@ -460,6 +483,13 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const V
Vector2 uvs[3];
Vector3 normal[3];
+ bake_current++;
+ if (p_bake_step_func != nullptr && (bake_current & 2047) == 1) {
+ if (p_bake_step_func(bake_current, bake_total)) {
+ return BAKE_RESULT_CANCELLED;
+ }
+ }
+
for (int k = 0; k < 3; k++) {
vtxs[k] = p_xform.xform(vr[j * 3 + k]);
}
@@ -487,6 +517,8 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const V
}
max_original_cells = bake_cells.size();
+
+ return BAKE_RESULT_OK;
}
void Voxelizer::_sort() {
@@ -821,7 +853,7 @@ static void edt(float *f, int stride, int n) {
#undef square
-Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
+Voxelizer::BakeResult Voxelizer::get_sdf_3d_image(Vector<uint8_t> &r_image, BakeStepFunc p_bake_step_function) const {
Vector3i octree_size = get_voxel_gi_octree_size();
uint32_t float_count = octree_size.x * octree_size.y * octree_size.z;
@@ -849,9 +881,17 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
//process in each direction
+ int bake_total = octree_size.x * 2 + octree_size.y, bake_current = 0;
+
//xy->z
- for (int i = 0; i < octree_size.x; i++) {
+ for (int i = 0; i < octree_size.x; i++, bake_current++) {
+ if (p_bake_step_function) {
+ if (p_bake_step_function(bake_current, bake_total)) {
+ memdelete_arr(work_memory);
+ return BAKE_RESULT_CANCELLED;
+ }
+ }
for (int j = 0; j < octree_size.y; j++) {
edt(&work_memory[i + j * y_mult], z_mult, octree_size.z);
}
@@ -859,23 +899,34 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
//xz->y
- for (int i = 0; i < octree_size.x; i++) {
+ for (int i = 0; i < octree_size.x; i++, bake_current++) {
+ if (p_bake_step_function) {
+ if (p_bake_step_function(bake_current, bake_total)) {
+ memdelete_arr(work_memory);
+ return BAKE_RESULT_CANCELLED;
+ }
+ }
for (int j = 0; j < octree_size.z; j++) {
edt(&work_memory[i + j * z_mult], y_mult, octree_size.y);
}
}
//yz->x
- for (int i = 0; i < octree_size.y; i++) {
+ for (int i = 0; i < octree_size.y; i++, bake_current++) {
+ if (p_bake_step_function) {
+ if (p_bake_step_function(bake_current, bake_total)) {
+ memdelete_arr(work_memory);
+ return BAKE_RESULT_CANCELLED;
+ }
+ }
for (int j = 0; j < octree_size.z; j++) {
edt(&work_memory[i * y_mult + j * z_mult], 1, octree_size.x);
}
}
- Vector<uint8_t> image3d;
- image3d.resize(float_count);
+ r_image.resize(float_count);
{
- uint8_t *w = image3d.ptrw();
+ uint8_t *w = r_image.ptrw();
for (uint32_t i = 0; i < float_count; i++) {
uint32_t d = uint32_t(Math::sqrt(work_memory[i]));
if (d == 0) {
@@ -888,7 +939,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
memdelete_arr(work_memory);
- return image3d;
+ return BAKE_RESULT_OK;
}
#undef INF