Namespace SDF functions
This commit is contained in:
parent
82e9625bc8
commit
24e9e36434
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user