You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-14 13:41:12 +00:00
Add VoxelGI bake cancelling and progress UI improvement
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user