Namespace SDF functions

This commit is contained in:
Marc Gilleron 2022-01-03 03:18:58 +00:00
parent 82e9625bc8
commit 24e9e36434
5 changed files with 35 additions and 35 deletions

View File

@ -156,12 +156,12 @@ inline float sdf_blend(float src_value, float dst_value, VoxelTool::Mode mode) {
float res;
switch (mode) {
case VoxelTool::MODE_ADD:
res = sdf_union(src_value, dst_value);
res = zylann::math::sdf_union(src_value, dst_value);
break;
case VoxelTool::MODE_REMOVE:
// Relative complement (or difference)
res = sdf_subtract(dst_value, src_value);
res = zylann::math::sdf_subtract(dst_value, src_value);
break;
case VoxelTool::MODE_SET:
@ -189,7 +189,7 @@ void VoxelTool::do_sphere(Vector3 center, float radius) {
if (_channel == VoxelBuffer::CHANNEL_SDF) {
box.for_each_cell([this, center, radius](Vector3i pos) {
float d = _sdf_scale * sdf_sphere(pos, center, radius);
float d = _sdf_scale * zylann::math::sdf_sphere(pos, center, radius);
_set_voxel_f(pos, sdf_blend(d, get_voxel_f(pos), _mode));
});
@ -220,8 +220,8 @@ void VoxelTool::sdf_stamp_erase(Ref<VoxelBuffer> stamp, Vector3i pos) {
box.for_each_cell_zxy([this, stamp, pos](Vector3i pos_in_volume) {
const Vector3i pos_in_stamp = pos_in_volume - pos;
const float dst_sdf = stamp->get_voxel_f(
pos_in_stamp.x, pos_in_stamp.y, pos_in_stamp.z, VoxelBuffer::CHANNEL_SDF);
const float dst_sdf =
stamp->get_voxel_f(pos_in_stamp.x, pos_in_stamp.y, pos_in_stamp.z, VoxelBuffer::CHANNEL_SDF);
if (dst_sdf <= 0.f) {
_set_voxel_f(pos_in_volume, 1.f);
}
@ -242,15 +242,11 @@ void VoxelTool::do_box(Vector3i begin, Vector3i end) {
if (_channel == VoxelBuffer::CHANNEL_SDF) {
// TODO Better quality
box.for_each_cell([this](Vector3i pos) {
_set_voxel_f(pos, sdf_blend(-1.0, get_voxel_f(pos), _mode));
});
box.for_each_cell([this](Vector3i pos) { _set_voxel_f(pos, sdf_blend(-1.0, get_voxel_f(pos), _mode)); });
} else {
int value = _mode == MODE_REMOVE ? _eraser_value : _value;
box.for_each_cell([this, value](Vector3i pos) {
_set_voxel(pos, value);
});
box.for_each_cell([this, value](Vector3i pos) { _set_voxel(pos, value); });
}
_post_edit(box);
@ -261,8 +257,8 @@ void VoxelTool::copy(Vector3i pos, Ref<VoxelBuffer> dst, uint8_t channel_mask) c
ERR_PRINT("Not implemented");
}
void VoxelTool::paste(Vector3i p_pos, Ref<VoxelBuffer> p_voxels, uint8_t channels_mask, bool use_mask,
uint64_t mask_value) {
void VoxelTool::paste(
Vector3i p_pos, Ref<VoxelBuffer> p_voxels, uint8_t channels_mask, bool use_mask, uint64_t mask_value) {
ERR_FAIL_COND(p_voxels.is_null());
ERR_PRINT("Not implemented");
}
@ -322,8 +318,8 @@ void VoxelTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_voxel_metadata", "pos"), &VoxelTool::_b_get_voxel_metadata);
ClassDB::bind_method(D_METHOD("copy", "src_pos", "dst_buffer", "channels_mask"), &VoxelTool::_b_copy);
ClassDB::bind_method(D_METHOD("paste", "dst_pos", "src_buffer", "channels_mask", "src_mask_value"),
&VoxelTool::_b_paste);
ClassDB::bind_method(
D_METHOD("paste", "dst_pos", "src_buffer", "channels_mask", "src_mask_value"), &VoxelTool::_b_paste);
ClassDB::bind_method(D_METHOD("raycast", "origin", "direction", "max_distance", "collision_mask"),
&VoxelTool::_b_raycast, DEFVAL(10.0), DEFVAL(0xffffffff));

View File

@ -21,13 +21,13 @@ template <typename Op, typename Shape> struct SdfOperation16bit {
struct SdfUnion {
inline float operator()(float a, float b) const {
return sdf_union(a, b);
return zylann::math::sdf_union(a, b);
}
};
struct SdfSubtract {
inline float operator()(float a, float b) const {
return sdf_subtract(a, b);
return zylann::math::sdf_subtract(a, b);
}
};
@ -43,7 +43,7 @@ struct SdfSphere {
float scale;
inline float operator()(Vector3 pos) const {
return scale * sdf_sphere(pos, center, radius);
return scale * zylann::math::sdf_sphere(pos, center, radius);
}
};

View File

@ -367,11 +367,13 @@ template <typename F> inline Interval sdf_smooth_op(Interval b, Interval a, floa
Interval sdf_smooth_union(Interval p_b, Interval p_a, float p_s) {
// TODO Not tested
// Had to use a lambda because otherwise it's ambiguous
return sdf_smooth_op(p_b, p_a, p_s, [](float b, float a, float s) { return sdf_smooth_union(b, a, s); });
return sdf_smooth_op(
p_b, p_a, p_s, [](float b, float a, float s) { return zylann::math::sdf_smooth_union(b, a, s); });
}
Interval sdf_smooth_subtract(Interval p_b, Interval p_a, float p_s) {
return sdf_smooth_op(p_b, p_a, p_s, [](float b, float a, float s) { return sdf_smooth_subtract(b, a, s); });
return sdf_smooth_op(
p_b, p_a, p_s, [](float b, float a, float s) { return zylann::math::sdf_smooth_subtract(b, a, s); });
}
static Interval get_fnl_cellular_value_range_2d(const FastNoiseLite *noise, Interval x, Interval y) {

View File

@ -998,8 +998,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const VoxelGraphRuntime::Buffer &sz = ctx.get_input(5);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] =
sdf_box(Vector3(x.data[i], y.data[i], z.data[i]), Vector3(sx.data[i], sy.data[i], sz.data[i]));
out.data[i] = zylann::math::sdf_box(
Vector3(x.data[i], y.data[i], z.data[i]), Vector3(sx.data[i], sy.data[i], sz.data[i]));
}
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
@ -1009,7 +1009,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval sx = ctx.get_input(3);
const Interval sy = ctx.get_input(4);
const Interval sz = ctx.get_input(5);
ctx.set_output(0, sdf_box(x, y, z, sx, sy, sz));
ctx.set_output(0, zylann::math::sdf_box(x, y, z, sx, sy, sz));
};
}
{
@ -1057,7 +1057,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const VoxelGraphRuntime::Buffer &r1 = ctx.get_input(4);
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = sdf_torus(x.data[i], y.data[i], z.data[i], r0.data[i], r1.data[i]);
out.data[i] = zylann::math::sdf_torus(x.data[i], y.data[i], z.data[i], r0.data[i], r1.data[i]);
}
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
@ -1066,7 +1066,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
const Interval z = ctx.get_input(2);
const Interval r0 = ctx.get_input(3);
const Interval r1 = ctx.get_input(4);
ctx.set_output(0, sdf_torus(x, y, z, r0, r1));
ctx.set_output(0, zylann::math::sdf_torus(x, y, z, r0, r1));
};
}
{
@ -1103,12 +1103,12 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
}
} else if (params.smoothness > 0.0001f) {
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = sdf_smooth_union(a.data[i], b.data[i], params.smoothness);
out.data[i] = zylann::math::sdf_smooth_union(a.data[i], b.data[i], params.smoothness);
}
} else {
// Fallback on hard-union, smooth union does not support zero smoothness
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = sdf_union(a.data[i], b.data[i]);
out.data[i] = zylann::math::sdf_union(a.data[i], b.data[i]);
}
}
};
@ -1187,12 +1187,12 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
}
} else if (params.smoothness > 0.0001f) {
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = sdf_smooth_subtract(a.data[i], b.data[i], params.smoothness);
out.data[i] = zylann::math::sdf_smooth_subtract(a.data[i], b.data[i], params.smoothness);
}
} else {
// Fallback on hard-subtract, smooth subtract does not support zero smoothness
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = sdf_subtract(a.data[i], b.data[i]);
out.data[i] = zylann::math::sdf_subtract(a.data[i], b.data[i]);
}
}
};

View File

@ -4,23 +4,23 @@
#include "interval.h"
#include <core/math/vector2.h>
namespace zylann::math {
// Signed-distance-field functions.
// For more, see https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
inline float sdf_box(const Vector3 pos, const Vector3 extents) {
Vector3 d = pos.abs() - extents;
return min(max(d.x, max(d.y, d.z)), 0.f) +
Vector3(max(d.x, 0.f), max(d.y, 0.f), max(d.z, 0.f)).length();
return min(max(d.x, max(d.y, d.z)), 0.f) + Vector3(max(d.x, 0.f), max(d.y, 0.f), max(d.z, 0.f)).length();
}
inline Interval sdf_box(
const Interval &x, const Interval &y, const Interval &z,
const Interval &sx, const Interval &sy, const Interval &sz) {
inline Interval sdf_box(const Interval &x, const Interval &y, const Interval &z, const Interval &sx, const Interval &sy,
const Interval &sz) {
Interval dx = abs(x) - sx;
Interval dy = abs(y) - sy;
Interval dz = abs(z) - sz;
return min_interval(max_interval(dx, max_interval(dy, dz)), 0.f) +
get_length(max_interval(dx, 0.f), max_interval(dy, 0.f), max_interval(dz, 0.f));
get_length(max_interval(dx, 0.f), max_interval(dy, 0.f), max_interval(dz, 0.f));
}
inline float sdf_sphere(Vector3 pos, Vector3 center, float radius) {
@ -58,4 +58,6 @@ inline float sdf_smooth_subtract(float b, float a, float s) {
return Math::lerp(b, -a, h) + s * h * (1.0f - h);
}
} // namespace zylann::math
#endif // VOXEL_MATH_SDF_H