Skip to content

Commit

Permalink
Formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Jun 9, 2024
1 parent 01f91fb commit a95b030
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 123 deletions.
204 changes: 158 additions & 46 deletions edition/mesh_sdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include "../util/voxel_raycast.h"

// Debug
//#define ZN_MESH_SDF_DEBUG_SLICES
// #define ZN_MESH_SDF_DEBUG_SLICES
#ifdef ZN_MESH_SDF_DEBUG_SLICES
#include "../util/math/color.h"
#include <core/io/image.h>
#endif
//#define ZN_MESH_SDF_DEBUG_BATCH
// #define ZN_MESH_SDF_DEBUG_BATCH
#ifdef ZN_MESH_SDF_DEBUG_BATCH
#include "../ddd.h"
#endif
Expand All @@ -31,12 +31,18 @@ namespace zylann::voxel::mesh_sdf {

// First tries with floats, as it is the most common case when data is float.
// In case of occasional parallel results, retry with doubles, as it often clears it up.
math::TriangleIntersectionResult ray_intersects_triangle2(const Vector3f &p_from, const Vector3f &p_dir,
const Vector3f &p_v0, const Vector3f &p_v1, const Vector3f &p_v2) {
math::TriangleIntersectionResult ray_intersects_triangle2(
const Vector3f &p_from,
const Vector3f &p_dir,
const Vector3f &p_v0,
const Vector3f &p_v1,
const Vector3f &p_v2
) {
math::TriangleIntersectionResult r = math::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2);
if (r.case_id == math::TriangleIntersectionResult::PARALLEL) {
r = math::ray_intersects_triangle(
to_vec3d(p_from), to_vec3d(p_dir), to_vec3d(p_v0), to_vec3d(p_v1), to_vec3d(p_v2));
to_vec3d(p_from), to_vec3d(p_dir), to_vec3d(p_v0), to_vec3d(p_v1), to_vec3d(p_v2)
);
}
return r;
}
Expand Down Expand Up @@ -110,7 +116,9 @@ const Triangle *raycast(const ChunkGrid &chunk_grid, Vector3f ray_position, Vect
#ifdef ZN_MESH_SDF_DEBUG_BATCH
DDD::draw_wirebox_min_max( //
to_vec3f(cpos) * chunk_grid.chunk_size + chunk_grid.min_pos,
to_vec3f(cpos + Vector3i(1, 1, 1)) * chunk_grid.chunk_size + chunk_grid.min_pos, Color(0, 1, 1));
to_vec3f(cpos + Vector3i(1, 1, 1)) * chunk_grid.chunk_size + chunk_grid.min_pos,
Color(0, 1, 1)
);
#endif
const unsigned int loc = Vector3iUtil::get_zxy_index(rs.hit_prev_position, chunk_grid.size);
ZN_ASSERT(loc < chunk_grid.chunks.size());
Expand Down Expand Up @@ -156,8 +164,16 @@ const Triangle *raycast(const ChunkGrid &chunk_grid, Vector3f ray_position, Vect
Vector3i hit_prev_chunk_pos;
float distance_along_ray;
float distance_along_ray_prev;
if (!voxel_raycast(cposf, ray_dir, raycast_chunk, max_distance_chunks, hit_chunk_pos, hit_prev_chunk_pos,
distance_along_ray, distance_along_ray_prev)) {
if (!voxel_raycast(
cposf,
ray_dir,
raycast_chunk,
max_distance_chunks,
hit_chunk_pos,
hit_prev_chunk_pos,
distance_along_ray,
distance_along_ray_prev
)) {
// In case the distance to travel is smaller than a chunk, the voxel_raycast won't "enter" any chunk and return
// false. Note, `hit_position` isn't used.
raycast_chunk({ math::floor_to_int(cposf), 0.f, Vector3i(), max_distance });
Expand All @@ -168,7 +184,11 @@ const Triangle *raycast(const ChunkGrid &chunk_grid, Vector3f ray_position, Vect
}

bool find_sdf_sign_with_raycast(
const ChunkGrid &chunk_grid, Vector3f ray_position, const Triangle &ref_triangle, int &out_sign) {
const ChunkGrid &chunk_grid,
Vector3f ray_position,
const Triangle &ref_triangle,
int &out_sign
) {
// ZN_PROFILE_SCOPE();

const Vector3f ref_center = (ref_triangle.v1 + ref_triangle.v2 + ref_triangle.v3) / 3.f;
Expand All @@ -191,7 +211,8 @@ bool find_sdf_sign_with_raycast(
if (s_tri_not_found_error == false) {
s_tri_not_found_error = true;
ZN_PRINT_VERBOSE(
format("Could not find triangle by raycast, dp: {}", math::dot(get_normal(ref_triangle), ray_dir)));
format("Could not find triangle by raycast, dp: {}", math::dot(get_normal(ref_triangle), ray_dir))
);
}
#endif
return false;
Expand Down Expand Up @@ -243,8 +264,14 @@ enum Flag { //
FLAG_FROZEN
};

void fix_sdf_sign_from_boundary(Span<float> sdf_grid, Span<uint8_t> flag_grid, Vector3i res, Vector3f min_pos,
Vector3f max_pos, StdVector<Vector3i> &seeds) {
void fix_sdf_sign_from_boundary(
Span<float> sdf_grid,
Span<uint8_t> flag_grid,
Vector3i res,
Vector3f min_pos,
Vector3f max_pos,
StdVector<Vector3i> &seeds
) {
ZN_PROFILE_SCOPE();
ZN_ASSERT(sdf_grid.size() == flag_grid.size());

Expand Down Expand Up @@ -413,7 +440,12 @@ void compute_near_chunks(ChunkGrid &chunk_grid) {
}

void partition_triangles(
int subdiv, Span<const Triangle> triangles, Vector3f min_pos, Vector3f max_pos, ChunkGrid &chunk_grid) {
int subdiv,
Span<const Triangle> triangles,
Vector3f min_pos,
Vector3f max_pos,
ChunkGrid &chunk_grid
) {
ZN_PROFILE_SCOPE();

// TODO This rarely causes SDF errors, but not sure yet what it is yet
Expand Down Expand Up @@ -547,10 +579,13 @@ float get_distance_to_triangle_squared_precalc(const Triangle &t, const Vector3f

if (det < 2.f) {
// Outside of the prism: get distance to closest edge
return min(min( //
length_squared(t.v21 * clamp(dot(t.v21, p1) * t.inv_v21_length_squared, 0.f, 1.f) - p1),
length_squared(t.v32 * clamp(dot(t.v32, p2) * t.inv_v32_length_squared, 0.f, 1.f) - p2)),
length_squared(t.v13 * clamp(dot(t.v13, p3) * t.inv_v13_length_squared, 0.f, 1.f) - p3));
return min(
min( //
length_squared(t.v21 * clamp(dot(t.v21, p1) * t.inv_v21_length_squared, 0.f, 1.f) - p1),
length_squared(t.v32 * clamp(dot(t.v32, p2) * t.inv_v32_length_squared, 0.f, 1.f) - p2)
),
length_squared(t.v13 * clamp(dot(t.v13, p3) * t.inv_v13_length_squared, 0.f, 1.f) - p3)
);
} else {
// Inside the prism: get distance to plane
return squared(dot(t.nor, p1)) * t.inv_nor_length_squared;
Expand Down Expand Up @@ -737,8 +772,13 @@ struct EvaluatorCG {
}
};

void generate_mesh_sdf_approx_interp(Span<float> sdf_grid, const Vector3i res, Span<const Triangle> triangles,
const Vector3f min_pos, const Vector3f max_pos) {
void generate_mesh_sdf_approx_interp(
Span<float> sdf_grid,
const Vector3i res,
Span<const Triangle> triangles,
const Vector3f min_pos,
const Vector3f max_pos
) {
ZN_PROFILE_SCOPE();

static const float FAR_SD = 9999999.f;
Expand Down Expand Up @@ -848,7 +888,8 @@ void generate_mesh_sdf_approx_interp(Span<float> sdf_grid, const Vector3i res, S
}
const Vector3f ipf = to_vec3f(grid_pos - cell_box.position) / float(node_size_cells);
const float sd = math::interpolate_trilinear(
sd000, sd100, sd101, sd001, sd010, sd110, sd111, sd011, ipf);
sd000, sd100, sd101, sd001, sd010, sd110, sd111, sd011, ipf
);
ZN_ASSERT(i < sdf_grid.size());
sdf_grid[i] = sd;
}
Expand All @@ -860,8 +901,14 @@ void generate_mesh_sdf_approx_interp(Span<float> sdf_grid, const Vector3i res, S
}
}

void generate_mesh_sdf_naive(Span<float> sdf_grid, const Vector3i res, const Box3i sub_box,
Span<const Triangle> triangles, const Vector3f min_pos, const Vector3f max_pos) {
void generate_mesh_sdf_naive(
Span<float> sdf_grid,
const Vector3i res,
const Box3i sub_box,
Span<const Triangle> triangles,
const Vector3f min_pos,
const Vector3f max_pos
) {
ZN_PROFILE_SCOPE();
ZN_ASSERT(Box3i(Vector3i(), res).contains(sub_box));
ZN_ASSERT(int64_t(sdf_grid.size()) == Vector3iUtil::get_volume(res));
Expand Down Expand Up @@ -894,8 +941,14 @@ void generate_mesh_sdf_naive(Span<float> sdf_grid, const Vector3i res, const Box
// println(format("Spent {} usec", usec));
}

void generate_mesh_sdf_partitioned(Span<float> sdf_grid, const Vector3i res, const Box3i sub_box,
const Vector3f min_pos, const Vector3f max_pos, const ChunkGrid &chunk_grid) {
void generate_mesh_sdf_partitioned(
Span<float> sdf_grid,
const Vector3i res,
const Box3i sub_box,
const Vector3f min_pos,
const Vector3f max_pos,
const ChunkGrid &chunk_grid
) {
ZN_PROFILE_SCOPE();
ZN_ASSERT(Box3i(Vector3i(), res).contains(sub_box));
ZN_ASSERT(int64_t(sdf_grid.size()) == Vector3iUtil::get_volume(res));
Expand Down Expand Up @@ -924,8 +977,14 @@ void generate_mesh_sdf_partitioned(Span<float> sdf_grid, const Vector3i res, con
}
}

void generate_mesh_sdf_partitioned(Span<float> sdf_grid, const Vector3i res, Span<const Triangle> triangles,
const Vector3f min_pos, const Vector3f max_pos, int subdiv) {
void generate_mesh_sdf_partitioned(
Span<float> sdf_grid,
const Vector3i res,
Span<const Triangle> triangles,
const Vector3f min_pos,
const Vector3f max_pos,
int subdiv
) {
// TODO Make this thread-local?
ChunkGrid chunk_grid;
partition_triangles(subdiv, triangles, min_pos, max_pos, chunk_grid);
Expand All @@ -934,7 +993,12 @@ void generate_mesh_sdf_partitioned(Span<float> sdf_grid, const Vector3i res, Spa
}

CheckResult check_sdf(
Span<const float> sdf_grid, Vector3i res, Span<const Triangle> triangles, Vector3f min_pos, Vector3f max_pos) {
Span<const float> sdf_grid,
Vector3i res,
Span<const Triangle> triangles,
Vector3f min_pos,
Vector3f max_pos
) {
CheckResult result;
result.ok = false;

Expand Down Expand Up @@ -970,7 +1034,7 @@ CheckResult check_sdf(
const Vector3i npos = pos + dirs[dir];

if (npos.x < 0 || npos.y < 0 || npos.z < 0 || npos.x >= res.x || npos.y >= res.y ||
npos.z >= res.z) {
npos.z >= res.z) {
continue;
}

Expand All @@ -983,8 +1047,15 @@ CheckResult check_sdf(
const float variation = Math::abs(v - nv);

if (variation > max_variation) {
ZN_PRINT_VERBOSE(format("Found variation of {} > {}, {} and {}, at cell {} and {}", variation,
max_variation, v, nv, pos, npos));
ZN_PRINT_VERBOSE(
format("Found variation of {} > {}, {} and {}, at cell {} and {}",
variation,
max_variation,
v,
nv,
pos,
npos)
);

const Vector3f posf0 = eval.grid_to_space(pos);
const Vector3f posf1 = eval.grid_to_space(npos);
Expand All @@ -1010,13 +1081,23 @@ CheckResult check_sdf(
return result;
}

void generate_mesh_sdf_naive(Span<float> sdf_grid, const Vector3i res, Span<const Triangle> triangles,
const Vector3f min_pos, const Vector3f max_pos) {
void generate_mesh_sdf_naive(
Span<float> sdf_grid,
const Vector3i res,
Span<const Triangle> triangles,
const Vector3f min_pos,
const Vector3f max_pos
) {
generate_mesh_sdf_naive(sdf_grid, res, Box3i(Vector3i(), res), triangles, min_pos, max_pos);
}

bool prepare_triangles(Span<const Vector3> vertices, Span<const int> indices, StdVector<Triangle> &triangles,
Vector3f &out_min_pos, Vector3f &out_max_pos) {
bool prepare_triangles(
Span<const Vector3> vertices,
Span<const int> indices,
StdVector<Triangle> &triangles,
Vector3f &out_min_pos,
Vector3f &out_max_pos
) {
ZN_PROFILE_SCOPE();

// The mesh can't be closed if it has less than 4 vertices
Expand Down Expand Up @@ -1082,10 +1163,17 @@ void GenMeshSDFSubBoxTask::run(ThreadedTaskContext &ctx) {

if (shared_data->use_chunk_grid) {
generate_mesh_sdf_partitioned(
sdf_grid, buffer.get_size(), box, shared_data->min_pos, shared_data->max_pos, shared_data->chunk_grid);
sdf_grid, buffer.get_size(), box, shared_data->min_pos, shared_data->max_pos, shared_data->chunk_grid
);
} else {
generate_mesh_sdf_naive(sdf_grid, buffer.get_size(), box, to_span(shared_data->triangles), shared_data->min_pos,
shared_data->max_pos);
generate_mesh_sdf_naive(
sdf_grid,
buffer.get_size(),
box,
to_span(shared_data->triangles),
shared_data->min_pos,
shared_data->max_pos
);
}

if (shared_data->pending_jobs.fetch_sub(1, std::memory_order_acq_rel) == 1) {
Expand All @@ -1100,7 +1188,11 @@ void GenMeshSDFSubBoxTask::run(ThreadedTaskContext &ctx) {
static const float FAR_SD = 9999999.f;

int find_sdf_sign_with_raycast_multi_attempt(
const ChunkGrid &chunk_grid, Span<const Triangle> triangles, Vector3f pos, unsigned int &ref_triangle_index) {
const ChunkGrid &chunk_grid,
Span<const Triangle> triangles,
Vector3f pos,
unsigned int &ref_triangle_index
) {
// TODO Optimization: It could be faster to target a triangle close to the cell?
int sign_sum = 0;
// Do multiple raycasts to reduce ambiguity.
Expand All @@ -1125,9 +1217,16 @@ int find_sdf_sign_with_raycast_multi_attempt(
return sign_sum;
}

void generate_mesh_sdf_hull(Span<float> sdf_grid, const Vector3i res, Span<const Triangle> triangles,
const Vector3f min_pos, const Vector3f max_pos, const ChunkGrid &chunk_grid, Span<uint8_t> flag_grid,
uint8_t near_surface_flag_value) {
void generate_mesh_sdf_hull(
Span<float> sdf_grid,
const Vector3i res,
Span<const Triangle> triangles,
const Vector3f min_pos,
const Vector3f max_pos,
const ChunkGrid &chunk_grid,
Span<uint8_t> flag_grid,
uint8_t near_surface_flag_value
) {
ZN_PROFILE_SCOPE();
ZN_ASSERT(sdf_grid.size() == flag_grid.size());

Expand Down Expand Up @@ -1212,7 +1311,8 @@ void generate_mesh_sdf_hull(Span<float> sdf_grid, const Vector3i res, Span<const
#endif

const int sign_sum = find_sdf_sign_with_raycast_multi_attempt(
chunk_grid, triangles, grid_to_space(grid_pos), ref_triangle_index);
chunk_grid, triangles, grid_to_space(grid_pos), ref_triangle_index
);

#ifdef ZN_MESH_SDF_DEBUG_BATCH
DDD::save_batch_to_json("ddd_ofs.json");
Expand All @@ -1237,7 +1337,12 @@ struct Seed {
#ifdef ZN_MESH_SDF_DEBUG_SLICES

void debug_print_sdf_image_slice(
Span<const float> sdf_grid, Vector3i res, const int y, int iteration, StdVector<Seed> *seeds) {
Span<const float> sdf_grid,
Vector3i res,
const int y,
int iteration,
StdVector<Seed> *seeds
) {
Ref<Image> im;
im.instantiate();
im->create(res.x, res.z, false, Image::FORMAT_RGB8);
Expand Down Expand Up @@ -1282,8 +1387,15 @@ void debug_print_sdf_image_slice(

#endif

void generate_mesh_sdf_approx_floodfill(Span<float> sdf_grid, const Vector3i res, Span<const Triangle> triangles,
const ChunkGrid &chunk_grid, const Vector3f min_pos, const Vector3f max_pos, bool boundary_sign_fix) {
void generate_mesh_sdf_approx_floodfill(
Span<float> sdf_grid,
const Vector3i res,
Span<const Triangle> triangles,
const ChunkGrid &chunk_grid,
const Vector3f min_pos,
const Vector3f max_pos,
bool boundary_sign_fix
) {
ZN_PROFILE_SCOPE();

StdVector<uint8_t> flag_grid;
Expand Down Expand Up @@ -1325,7 +1437,7 @@ void generate_mesh_sdf_approx_floodfill(Span<float> sdf_grid, const Vector3i res
for (unsigned int dir = 0; dir < dirs6.size(); ++dir) {
const Vector3i npos = pos + dirs6[dir];
if (npos.x < 0 || npos.y < 0 || npos.z < 0 || npos.x >= res.x || npos.y >= res.y ||
npos.z >= res.z) {
npos.z >= res.z) {
continue;
}

Expand Down
Loading

0 comments on commit a95b030

Please sign in to comment.