Namespaced math funcs
This commit is contained in:
parent
a9476227cb
commit
e20684ce69
edition
editor/graph
generators
graph
image_range_grid.cpprange_utility.cppvoxel_generator_graph.cppvoxel_graph_node_db.cppvoxel_graph_runtime.cpp
simple
meshers
blocky
dmc
transvoxel
server
storage
streams
terrain
tests
util
@ -51,8 +51,8 @@ inline void normalize_weights_preserving(FixedArray<float, 4> &weights, unsigned
|
||||
}
|
||||
}*/
|
||||
|
||||
inline void blend_texture_packed_u16(int texture_index, float target_weight,
|
||||
uint16_t &encoded_indices, uint16_t &encoded_weights) {
|
||||
inline void blend_texture_packed_u16(
|
||||
int texture_index, float target_weight, uint16_t &encoded_indices, uint16_t &encoded_weights) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_COND(target_weight < 0.f || target_weight > 1.f);
|
||||
#endif
|
||||
@ -98,7 +98,7 @@ inline void blend_texture_packed_u16(int texture_index, float target_weight,
|
||||
normalize_weights_preserving(weights_f, component_index);
|
||||
|
||||
for (unsigned int i = 0; i < weights_f.size(); ++i) {
|
||||
weights[i] = clamp(weights_f[i] * 255.f, 0.f, 255.f);
|
||||
weights[i] = zylann::math::clamp(weights_f[i] * 255.f, 0.f, 255.f);
|
||||
}
|
||||
|
||||
encoded_indices = encode_indices_to_packed_u16(indices[0], indices[1], indices[2], indices[3]);
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "../util/macros.h"
|
||||
#include "../util/profiling.h"
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelTool::VoxelTool() {
|
||||
_sdf_scale = VoxelBufferInternal::get_sdf_quantization_scale(VoxelBufferInternal::DEFAULT_SDF_CHANNEL_DEPTH);
|
||||
}
|
||||
@ -45,7 +47,7 @@ float VoxelTool::get_sdf_scale() const {
|
||||
}
|
||||
|
||||
void VoxelTool::set_sdf_scale(float s) {
|
||||
_sdf_scale = max(s, 0.00001f);
|
||||
_sdf_scale = math::max(s, 0.00001f);
|
||||
}
|
||||
|
||||
void VoxelTool::set_texture_index(int ti) {
|
||||
@ -58,7 +60,7 @@ int VoxelTool::get_texture_index() const {
|
||||
}
|
||||
|
||||
void VoxelTool::set_texture_opacity(float opacity) {
|
||||
_texture_params.opacity = clamp(opacity, 0.f, 1.f);
|
||||
_texture_params.opacity = math::clamp(opacity, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float VoxelTool::get_texture_opacity() const {
|
||||
@ -66,7 +68,7 @@ float VoxelTool::get_texture_opacity() const {
|
||||
}
|
||||
|
||||
void VoxelTool::set_texture_falloff(float falloff) {
|
||||
_texture_params.sharpness = 1.f / clamp(falloff, 0.001f, 1.f);
|
||||
_texture_params.sharpness = 1.f / math::clamp(falloff, 0.001f, 1.f);
|
||||
}
|
||||
|
||||
float VoxelTool::get_texture_falloff() const {
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
class VoxelBuffer;
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace VoxelToolOps {
|
||||
|
||||
template <typename Op, typename Shape> struct SdfOperation16bit {
|
||||
@ -70,7 +72,8 @@ struct TextureBlendSphereOp {
|
||||
const float distance_squared = Vector3(pos).distance_squared_to(center);
|
||||
if (distance_squared < radius_squared) {
|
||||
const float distance_from_radius = radius - Math::sqrt(distance_squared);
|
||||
const float target_weight = tp.opacity * clamp(tp.sharpness * (distance_from_radius / radius), 0.f, 1.f);
|
||||
const float target_weight =
|
||||
tp.opacity * math::clamp(tp.sharpness * (distance_from_radius / radius), 0.f, 1.f);
|
||||
blend_texture_packed_u16(tp.index, target_weight, indices, weights);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include <scene/3d/physics_body_3d.h>
|
||||
#include <scene/main/timer.h>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
VoxelToolLodTerrain::VoxelToolLodTerrain(VoxelLodTerrain *terrain) : _terrain(terrain) {
|
||||
ERR_FAIL_COND(terrain == nullptr);
|
||||
// At the moment, only LOD0 is supported.
|
||||
@ -37,7 +40,7 @@ template <typename Volume_F> float get_sdf_interpolated(const Volume_F &f, Vecto
|
||||
const float s011 = f(Vector3i(c.x, c.y + 1, c.z + 1));
|
||||
const float s111 = f(Vector3i(c.x + 1, c.y + 1, c.z + 1));
|
||||
|
||||
return interpolate(s000, s100, s101, s001, s010, s110, s111, s011, fract(pos));
|
||||
return math::interpolate(s000, s100, s101, s001, s010, s110, s111, s011, math::fract(pos));
|
||||
}
|
||||
|
||||
// Binary search can be more accurate than linear regression because the SDF can be inaccurate in the first place.
|
||||
@ -378,7 +381,7 @@ int VoxelToolLodTerrain::get_raycast_binary_search_iterations() const {
|
||||
}
|
||||
|
||||
void VoxelToolLodTerrain::set_raycast_binary_search_iterations(int iterations) {
|
||||
_raycast_binary_search_iterations = clamp(iterations, 0, 16);
|
||||
_raycast_binary_search_iterations = math::clamp(iterations, 0, 16);
|
||||
}
|
||||
|
||||
namespace zylann::voxel {
|
||||
@ -714,7 +717,7 @@ Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, Node *par
|
||||
|
||||
Array VoxelToolLodTerrain::separate_floating_chunks(AABB world_box, Node *parent_node) {
|
||||
ERR_FAIL_COND_V(_terrain == nullptr, Array());
|
||||
ERR_FAIL_COND_V(!is_valid_size(world_box.size), Array());
|
||||
ERR_FAIL_COND_V(!math::is_valid_size(world_box.size), Array());
|
||||
Ref<VoxelMesher> mesher = _terrain->get_mesher();
|
||||
Array materials;
|
||||
materials.append(_terrain->get_material());
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "../util/godot/funcs.h"
|
||||
#include "../util/voxel_raycast.h"
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelToolTerrain::VoxelToolTerrain() {}
|
||||
|
||||
VoxelToolTerrain::VoxelToolTerrain(VoxelTerrain *terrain) {
|
||||
@ -232,7 +234,7 @@ void VoxelToolTerrain::run_blocky_random_tick(
|
||||
ERR_FAIL_COND(callback.is_null());
|
||||
ERR_FAIL_COND(batch_count <= 0);
|
||||
ERR_FAIL_COND(voxel_count < 0);
|
||||
ERR_FAIL_COND(!is_valid_size(voxel_area.size));
|
||||
ERR_FAIL_COND(!math::is_valid_size(voxel_area.size));
|
||||
|
||||
if (voxel_count == 0) {
|
||||
return;
|
||||
@ -328,7 +330,7 @@ void VoxelToolTerrain::run_blocky_random_tick(
|
||||
void VoxelToolTerrain::for_each_voxel_metadata_in_area(AABB voxel_area, const Callable &callback) {
|
||||
ERR_FAIL_COND(_terrain == nullptr);
|
||||
ERR_FAIL_COND(callback.is_null());
|
||||
ERR_FAIL_COND(!is_valid_size(voxel_area.size));
|
||||
ERR_FAIL_COND(!math::is_valid_size(voxel_area.size));
|
||||
|
||||
const Box3i voxel_box =
|
||||
Box3i(Vector3iUtil::from_floored(voxel_area.position), Vector3iUtil::from_floored(voxel_area.size));
|
||||
|
@ -398,7 +398,7 @@ void VoxelGraphEditor::create_node_gui(uint32_t node_id) {
|
||||
// These nodes have an output for implementation reasons, some outputs can process the data like any other node.
|
||||
const bool hide_outputs = node_type.category == VoxelGraphNodeDB::CATEGORY_OUTPUT;
|
||||
|
||||
const unsigned int row_count = max(node_type.inputs.size(), hide_outputs ? 0 : node_type.outputs.size());
|
||||
const unsigned int row_count = math::max(node_type.inputs.size(), hide_outputs ? 0 : node_type.outputs.size());
|
||||
const Color port_color(0.4, 0.4, 1.0);
|
||||
|
||||
// TODO Insert a summary so the graph would be readable without having to inspect nodes
|
||||
@ -898,7 +898,7 @@ void VoxelGraphEditor::update_slice_previews() {
|
||||
for (int y = 0; y < im.get_height(); ++y) {
|
||||
for (int x = 0; x < im.get_width(); ++x) {
|
||||
const float v = buffer.data[i];
|
||||
const float g = clamp((v - info.min_value) * info.value_scale, 0.f, 1.f);
|
||||
const float g = math::clamp((v - info.min_value) * info.value_scale, 0.f, 1.f);
|
||||
im.set_pixel(x, im.get_height() - y - 1, Color(g, g, g));
|
||||
++i;
|
||||
}
|
||||
|
@ -127,8 +127,8 @@ static void interval_to_pixels(Interval i, int &out_min, int &out_max, int len)
|
||||
// Images are finite, intervals are not.
|
||||
// It's useless to let the range span a potentially infinite area.
|
||||
// The image can repeat, so we clamp to one repetition.
|
||||
out_min = ::clamp(imin, -len, len);
|
||||
out_max = ::clamp(imax, -len, len);
|
||||
out_min = clamp(imin, -len, len);
|
||||
out_max = clamp(imax, -len, len);
|
||||
}
|
||||
|
||||
Interval ImageRangeGrid::get_range(Interval xr, Interval yr) const {
|
||||
|
@ -23,11 +23,11 @@ inline Interval get_noise_range_2d(Noise_F noise_func, const Interval &x, const
|
||||
const float mid_y = 0.5 * (y.min + y.max);
|
||||
const float mid_value = noise_func(mid_x, mid_y);
|
||||
|
||||
const float diag = Math::sqrt(::squared(x.length()) + ::squared(y.length()));
|
||||
const float diag = Math::sqrt(squared(x.length()) + squared(y.length()));
|
||||
|
||||
return Interval( //
|
||||
::max(mid_value - max_derivative_half_diagonal * diag, -1.f),
|
||||
::min(mid_value + max_derivative_half_diagonal * diag, 1.f));
|
||||
max(mid_value - max_derivative_half_diagonal * diag, -1.f),
|
||||
min(mid_value + max_derivative_half_diagonal * diag, 1.f));
|
||||
}
|
||||
|
||||
template <typename Noise_F>
|
||||
@ -40,11 +40,11 @@ inline Interval get_noise_range_3d(
|
||||
const float mid_z = 0.5 * (z.min + z.max);
|
||||
const float mid_value = noise_func(mid_x, mid_y, mid_z);
|
||||
|
||||
const float diag = Math::sqrt(::squared(x.length()) + ::squared(y.length()) + ::squared(z.length()));
|
||||
const float diag = Math::sqrt(squared(x.length()) + squared(y.length()) + squared(z.length()));
|
||||
|
||||
return Interval( //
|
||||
::max(mid_value - max_derivative_half_diagonal * diag, -1.f),
|
||||
::min(mid_value + max_derivative_half_diagonal * diag, 1.f));
|
||||
max(mid_value - max_derivative_half_diagonal * diag, -1.f),
|
||||
min(mid_value + max_derivative_half_diagonal * diag, 1.f));
|
||||
}
|
||||
|
||||
Interval get_osn_octave_range_2d(OpenSimplexNoise *noise, const Interval &p_x, const Interval &p_y, int octave) {
|
||||
|
@ -243,7 +243,7 @@ float VoxelGeneratorGraph::get_sdf_clip_threshold() const {
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::set_sdf_clip_threshold(float t) {
|
||||
_sdf_clip_threshold = max(t, 0.f);
|
||||
_sdf_clip_threshold = math::max(t, 0.f);
|
||||
}
|
||||
|
||||
int VoxelGeneratorGraph::get_used_channels_mask() const {
|
||||
@ -314,7 +314,7 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span<const WeightOutput> we
|
||||
const float weight = buffers[oi][value_index];
|
||||
// TODO Optimization: weight output nodes could already multiply by 255 and clamp afterward
|
||||
// so we would not need to do it here
|
||||
weights[oi] = clamp(weight * 255.f, 0.f, 255.f);
|
||||
weights[oi] = math::clamp(weight * 255.f, 0.f, 255.f);
|
||||
indices[oi] = weight_outputs[oi].layer_index;
|
||||
}
|
||||
debug_check_texture_indices(indices);
|
||||
@ -338,7 +338,7 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span<const WeightOutput> we
|
||||
FixedArray<uint8_t, 4> indices;
|
||||
for (unsigned int oi = 0; oi < buffers_count; ++oi) {
|
||||
const float weight = buffers[oi][value_index];
|
||||
weights[oi] = clamp(weight * 255.f, 0.f, 255.f);
|
||||
weights[oi] = math::clamp(weight * 255.f, 0.f, 255.f);
|
||||
indices[oi] = weight_outputs[oi].layer_index;
|
||||
}
|
||||
const uint16_t encoded_indices =
|
||||
@ -372,7 +372,7 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span<const WeightOutput> we
|
||||
for (unsigned int oi = 0; oi < buffers_count && recorded_weights < indices.size(); ++oi) {
|
||||
const float weight = buffers[oi][value_index];
|
||||
if (weight > pivot) {
|
||||
weights[recorded_weights] = clamp(weight * 255.f, 0.f, 255.f);
|
||||
weights[recorded_weights] = math::clamp(weight * 255.f, 0.f, 255.f);
|
||||
indices[recorded_weights] = weight_outputs[oi].layer_index;
|
||||
++recorded_weights;
|
||||
} else {
|
||||
|
@ -314,7 +314,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
const VoxelGraphRuntime::Buffer &input = ctx.get_input(0);
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
for (unsigned int i = 0; i < out.size; ++i) {
|
||||
out.data[i] = ::clamp(input.data[i], 0.f, 1.f);
|
||||
out.data[i] = clamp(input.data[i], 0.f, 1.f);
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -478,7 +478,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
t.inputs.push_back(Port("length"));
|
||||
t.outputs.push_back(Port("out"));
|
||||
t.process_buffer_func = [](ProcessBufferContext &ctx) {
|
||||
do_binop(ctx, [](float a, float b) { return ::wrapf(a, b); });
|
||||
do_binop(ctx, [](float a, float b) { return wrapf(a, b); });
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
const Interval a = ctx.get_input(0);
|
||||
@ -534,7 +534,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
const VoxelGraphRuntime::Buffer &y1 = ctx.get_input(3);
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
for (uint32_t i = 0; i < out.size; ++i) {
|
||||
out.data[i] = Math::sqrt(::squared(x1.data[i] - x0.data[i]) + ::squared(y1.data[i] - y0.data[i]));
|
||||
out.data[i] = Math::sqrt(squared(x1.data[i] - x0.data[i]) + squared(y1.data[i] - y0.data[i]));
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -568,8 +568,8 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
const VoxelGraphRuntime::Buffer &z1 = ctx.get_input(5);
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
for (uint32_t i = 0; i < out.size; ++i) {
|
||||
out.data[i] = Math::sqrt(::squared(x1.data[i] - x0.data[i]) + ::squared(y1.data[i] - y0.data[i]) +
|
||||
::squared(z1.data[i] - z0.data[i]));
|
||||
out.data[i] = Math::sqrt(squared(x1.data[i] - x0.data[i]) + squared(y1.data[i] - y0.data[i]) +
|
||||
squared(z1.data[i] - z0.data[i]));
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -609,7 +609,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
const Params p = ctx.get_params<Params>();
|
||||
for (uint32_t i = 0; i < out.size; ++i) {
|
||||
out.data[i] = ::clamp(a.data[i], p.min, p.max);
|
||||
out.data[i] = clamp(a.data[i], p.min, p.max);
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -773,7 +773,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
const Params p = ctx.get_params<Params>();
|
||||
for (uint32_t i = 0; i < out.size; ++i) {
|
||||
out.data[i] = ::smoothstep(p.edge0, p.edge1, a.data[i]);
|
||||
out.data[i] = smoothstep(p.edge0, p.edge1, a.data[i]);
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -1032,8 +1032,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
const VoxelGraphRuntime::Buffer &r = ctx.get_input(3);
|
||||
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
|
||||
for (uint32_t i = 0; i < out.size; ++i) {
|
||||
out.data[i] =
|
||||
Math::sqrt(::squared(x.data[i]) + ::squared(y.data[i]) + ::squared(z.data[i])) - r.data[i];
|
||||
out.data[i] = Math::sqrt(squared(x.data[i]) + squared(y.data[i]) + squared(z.data[i])) - r.data[i];
|
||||
}
|
||||
};
|
||||
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
|
||||
@ -1389,7 +1388,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
const float x = xb.data[i];
|
||||
const float y = yb.data[i];
|
||||
const float z = zb.data[i];
|
||||
const float len = Math::sqrt(::squared(x) + ::squared(y) + ::squared(z));
|
||||
const float len = Math::sqrt(squared(x) + squared(y) + squared(z));
|
||||
out_nx.data[i] = x / len;
|
||||
out_ny.data[i] = y / len;
|
||||
out_nz.data[i] = z / len;
|
||||
|
@ -609,7 +609,7 @@ void VoxelGraphRuntime::prepare_state(State &state, unsigned int buffer_size) co
|
||||
CRASH_COND(buffer.data != nullptr);
|
||||
// TODO Use pool?
|
||||
// New buffers get an up-to-date size, but must also comply with common capacity
|
||||
const unsigned int bs = max(state.buffer_capacity, buffer_size);
|
||||
const unsigned int bs = math::max(state.buffer_capacity, buffer_size);
|
||||
buffer.data = reinterpret_cast<float *>(memalloc(bs * sizeof(float)));
|
||||
buffer.capacity = bs;
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
#include "../../util/fixed_array.h"
|
||||
#include "../../util/span.h"
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace {
|
||||
|
||||
inline float get_height_repeat(const Image &im, int x, int y) {
|
||||
return im.get_pixel(wrap(x, im.get_width()), wrap(y, im.get_height())).r;
|
||||
return im.get_pixel(math::wrap(x, im.get_width()), math::wrap(y, im.get_height())).r;
|
||||
}
|
||||
|
||||
inline float get_height_blurred(const Image &im, int x, int y) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "voxel_generator_waves.h"
|
||||
#include <cmath>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelGeneratorWaves::VoxelGeneratorWaves() {
|
||||
_parameters.pattern_size = Vector2(30, 30);
|
||||
// This might be a different default value than the base class,
|
||||
@ -8,8 +10,7 @@ VoxelGeneratorWaves::VoxelGeneratorWaves() {
|
||||
set_height_range(30);
|
||||
}
|
||||
|
||||
VoxelGeneratorWaves::~VoxelGeneratorWaves() {
|
||||
}
|
||||
VoxelGeneratorWaves::~VoxelGeneratorWaves() {}
|
||||
|
||||
VoxelGenerator::Result VoxelGeneratorWaves::generate_block(VoxelBlockRequest &input) {
|
||||
Parameters params;
|
||||
@ -20,8 +21,7 @@ VoxelGenerator::Result VoxelGeneratorWaves::generate_block(VoxelBlockRequest &in
|
||||
|
||||
VoxelBufferInternal &out_buffer = input.voxel_buffer;
|
||||
const Vector2 freq(
|
||||
Math_PI / static_cast<float>(params.pattern_size.x),
|
||||
Math_PI / static_cast<float>(params.pattern_size.y));
|
||||
Math_PI / static_cast<float>(params.pattern_size.x), Math_PI / static_cast<float>(params.pattern_size.y));
|
||||
const Vector2 offset = params.pattern_offset;
|
||||
|
||||
return VoxelGeneratorHeightmap::generate(
|
||||
@ -39,8 +39,8 @@ Vector2 VoxelGeneratorWaves::get_pattern_size() const {
|
||||
|
||||
void VoxelGeneratorWaves::set_pattern_size(Vector2 size) {
|
||||
RWLockWrite wlock(_parameters_lock);
|
||||
size.x = max(size.x, 0.1f);
|
||||
size.y = max(size.y, 0.1f);
|
||||
size.x = math::max(size.x, 0.1f);
|
||||
size.y = math::max(size.y, 0.1f);
|
||||
_parameters.pattern_size = size;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#define STRLEN(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
Voxel::Voxel() :
|
||||
_id(-1), _material_id(0), _transparency_index(0), _color(1.f, 1.f, 1.f), _geometry_type(GEOMETRY_NONE) {}
|
||||
|
||||
@ -105,7 +107,7 @@ void Voxel::set_transparent(bool t) {
|
||||
}
|
||||
|
||||
void Voxel::set_transparency_index(int i) {
|
||||
_transparency_index = clamp(i, 0, 255);
|
||||
_transparency_index = math::clamp(i, 0, 255);
|
||||
}
|
||||
|
||||
void Voxel::set_geometry_type(GeometryType type) {
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include <bitset>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelLibrary::VoxelLibrary() {}
|
||||
|
||||
VoxelLibrary::~VoxelLibrary() {}
|
||||
@ -139,6 +141,8 @@ template <typename F> static void rasterize_triangle_barycentric(Vector2 a, Vect
|
||||
b += 0.001 * (b - m);
|
||||
c += 0.001 * (c - m);
|
||||
|
||||
using namespace math;
|
||||
|
||||
const int min_x = (int)Math::floor(min(min(a.x, b.x), c.x));
|
||||
const int min_y = (int)Math::floor(min(min(a.y, b.y), c.y));
|
||||
const int max_x = (int)Math::ceil(max(max(a.x, b.x), c.x));
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "../../util/span.h"
|
||||
#include <core/os/os.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
// Utility functions
|
||||
namespace {
|
||||
|
||||
@ -349,7 +351,7 @@ Ref<VoxelLibrary> VoxelMesherBlocky::get_library() const {
|
||||
|
||||
void VoxelMesherBlocky::set_occlusion_darkness(float darkness) {
|
||||
RWLockWrite wlock(_parameters_lock);
|
||||
_parameters.baked_occlusion_darkness = clamp(darkness, 0.0f, 1.0f);
|
||||
_parameters.baked_occlusion_darkness = math::clamp(darkness, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
float VoxelMesherBlocky::get_occlusion_darkness() const {
|
||||
|
@ -11,9 +11,7 @@ struct HermiteValue {
|
||||
float sdf; // Signed "distance" to surface
|
||||
Vector3 gradient; // Derivation of the density
|
||||
|
||||
HermiteValue() :
|
||||
sdf(1.0) {
|
||||
}
|
||||
HermiteValue() : sdf(1.0) {}
|
||||
};
|
||||
|
||||
inline float get_isolevel_clamped(const VoxelBufferInternal &voxels, unsigned int x, unsigned int y, unsigned int z) {
|
||||
@ -23,8 +21,8 @@ inline float get_isolevel_clamped(const VoxelBufferInternal &voxels, unsigned in
|
||||
return voxels.get_voxel_f(x, y, z, VoxelBufferInternal::CHANNEL_SDF);
|
||||
}
|
||||
|
||||
inline HermiteValue get_hermite_value(const VoxelBufferInternal &voxels,
|
||||
unsigned int x, unsigned int y, unsigned int z) {
|
||||
inline HermiteValue get_hermite_value(
|
||||
const VoxelBufferInternal &voxels, unsigned int x, unsigned int y, unsigned int z) {
|
||||
HermiteValue v;
|
||||
|
||||
v.sdf = voxels.get_voxel_f(x, y, z, VoxelBufferInternal::CHANNEL_SDF);
|
||||
@ -69,10 +67,9 @@ inline HermiteValue get_interpolated_hermite_value(const VoxelBufferInternal &vo
|
||||
Vector3 rpos = pos - Vector3(x0, y0, z0);
|
||||
|
||||
HermiteValue v;
|
||||
v.sdf = ::interpolate(v0.sdf, v1.sdf, v2.sdf, v3.sdf, v4.sdf, v5.sdf, v6.sdf, v7.sdf, rpos);
|
||||
v.gradient = ::interpolate(
|
||||
v0.gradient, v1.gradient, v2.gradient, v3.gradient,
|
||||
v4.gradient, v5.gradient, v6.gradient, v7.gradient, rpos);
|
||||
v.sdf = zylann::math::interpolate(v0.sdf, v1.sdf, v2.sdf, v3.sdf, v4.sdf, v5.sdf, v6.sdf, v7.sdf, rpos);
|
||||
v.gradient = zylann::math::interpolate(v0.gradient, v1.gradient, v2.gradient, v3.gradient, v4.gradient, v5.gradient,
|
||||
v6.gradient, v7.gradient, rpos);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "mesh_builder.h"
|
||||
#include <core/os/time.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
// Dual marching cubes
|
||||
// Algorithm taken from https://www.volume-gfx.com/volume-rendering/dual-marching-cubes/
|
||||
// Partially based on Ogre's implementation, adapted for requirements of this module with a few extras
|
||||
@ -123,7 +125,7 @@ bool can_split(Vector3i node_origin, int node_size, const VoxelAccess &voxels, f
|
||||
|
||||
HermiteValue value = get_hermite_value(voxels.buffer, pos.x, pos.y, pos.z);
|
||||
|
||||
float interpolated_value = ::interpolate(v0, v1, v2, v3, v4, v5, v6, v7, positions_ratio[i]);
|
||||
float interpolated_value = math::interpolate(v0, v1, v2, v3, v4, v5, v6, v7, positions_ratio[i]);
|
||||
|
||||
float gradient_magnitude = value.gradient.length();
|
||||
if (gradient_magnitude < FLT_EPSILON) {
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../../util/profiling.h"
|
||||
#include "transvoxel_tables.cpp"
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace Transvoxel {
|
||||
|
||||
static const float TRANSITION_CELL_SCALE = 0.25;
|
||||
@ -542,7 +544,7 @@ void build_regular_mesh(Span<const Sdf_T> sdf_data, TextureIndicesData texture_i
|
||||
FixedArray<uint8_t, MAX_TEXTURE_BLENDS> weights;
|
||||
for (unsigned int i = 0; i < MAX_TEXTURE_BLENDS; ++i) {
|
||||
weights[i] = static_cast<uint8_t>(
|
||||
clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f));
|
||||
math::clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f));
|
||||
}
|
||||
add_texture_data(output.texturing_data, cell_textures.packed_indices, weights);
|
||||
}
|
||||
@ -1037,7 +1039,7 @@ void build_transition_mesh(Span<const Sdf_T> sdf_data, TextureIndicesData textur
|
||||
FixedArray<uint8_t, MAX_TEXTURE_BLENDS> weights;
|
||||
for (unsigned int i = 0; i < cell_textures.indices.size(); ++i) {
|
||||
weights[i] = static_cast<uint8_t>(
|
||||
clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f));
|
||||
math::clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f));
|
||||
}
|
||||
add_texture_data(output.texturing_data, cell_textures.packed_indices, weights);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "../../util/profiling.h"
|
||||
#include "transvoxel_tables.cpp"
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelMesherTransvoxel::VoxelMesherTransvoxel() {
|
||||
set_padding(Transvoxel::MIN_PADDING, Transvoxel::MAX_PADDING);
|
||||
}
|
||||
@ -250,7 +252,7 @@ bool VoxelMesherTransvoxel::is_mesh_optimization_enabled() const {
|
||||
}
|
||||
|
||||
void VoxelMesherTransvoxel::set_mesh_optimization_error_threshold(float threshold) {
|
||||
_mesh_optimization_params.error_threshold = clamp(threshold, 0.f, 1.f);
|
||||
_mesh_optimization_params.error_threshold = math::clamp(threshold, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float VoxelMesherTransvoxel::get_mesh_optimization_error_threshold() const {
|
||||
@ -258,7 +260,7 @@ float VoxelMesherTransvoxel::get_mesh_optimization_error_threshold() const {
|
||||
}
|
||||
|
||||
void VoxelMesherTransvoxel::set_mesh_optimization_target_ratio(float ratio) {
|
||||
_mesh_optimization_params.target_ratio = clamp(ratio, 0.f, 1.f);
|
||||
_mesh_optimization_params.target_ratio = math::clamp(ratio, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float VoxelMesherTransvoxel::get_mesh_optimization_target_ratio() const {
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <scene/main/window.h> // Needed for doing `Node *root = SceneTree::get_root()`, Window* is forward-declared
|
||||
#include <thread>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace {
|
||||
VoxelServer *g_voxel_server = nullptr;
|
||||
// Could be atomics, but it's for debugging so I don't bother for now
|
||||
@ -72,20 +74,21 @@ VoxelServer::VoxelServer() {
|
||||
_main_thread_time_budget_usec =
|
||||
1000 * int(ProjectSettings::get_singleton()->get("voxel/threads/main/time_budget_ms"));
|
||||
|
||||
const int minimum_thread_count = max(1, int(ProjectSettings::get_singleton()->get("voxel/threads/count/minimum")));
|
||||
const int minimum_thread_count =
|
||||
math::max(1, int(ProjectSettings::get_singleton()->get("voxel/threads/count/minimum")));
|
||||
|
||||
// How many threads below available count on the CPU should we set as limit
|
||||
const int thread_count_margin =
|
||||
max(1, int(ProjectSettings::get_singleton()->get("voxel/threads/count/margin_below_max")));
|
||||
math::max(1, int(ProjectSettings::get_singleton()->get("voxel/threads/count/margin_below_max")));
|
||||
|
||||
// Portion of available CPU threads to attempt using
|
||||
const float threads_ratio =
|
||||
clamp(float(ProjectSettings::get_singleton()->get("voxel/threads/count/ratio_over_max")), 0.f, 1.f);
|
||||
math::clamp(float(ProjectSettings::get_singleton()->get("voxel/threads/count/ratio_over_max")), 0.f, 1.f);
|
||||
|
||||
const int maximum_thread_count = max(hw_threads_hint - thread_count_margin, minimum_thread_count);
|
||||
const int maximum_thread_count = math::max(hw_threads_hint - thread_count_margin, minimum_thread_count);
|
||||
// `-1` is for the stream thread
|
||||
const int thread_count_by_ratio = int(Math::round(float(threads_ratio) * hw_threads_hint)) - 1;
|
||||
const int thread_count = clamp(thread_count_by_ratio, minimum_thread_count, maximum_thread_count);
|
||||
const int thread_count = math::clamp(thread_count_by_ratio, minimum_thread_count, maximum_thread_count);
|
||||
PRINT_VERBOSE(String("Voxel: automatic thread count set to {0}").format(varray(thread_count)));
|
||||
|
||||
if (thread_count > hw_threads_hint) {
|
||||
@ -286,14 +289,14 @@ void VoxelServer::init_priority_dependency(VoxelServer::PriorityDependency &dep,
|
||||
// Distance beyond which no field of view can overlap the block.
|
||||
// Doubling block radius to account for an extra margin of blocks,
|
||||
// since they are used to provide neighbors when meshing
|
||||
dep.drop_distance_squared =
|
||||
squared(_world.shared_priority_dependency->highest_view_distance + 2.f * transformed_block_radius);
|
||||
dep.drop_distance_squared = math::squared(
|
||||
_world.shared_priority_dependency->highest_view_distance + 2.f * transformed_block_radius);
|
||||
break;
|
||||
|
||||
case VOLUME_SPARSE_OCTREE:
|
||||
// Distance beyond which it is safe to drop a block without risking to block LOD subdivision.
|
||||
// This does not depend on viewer's view distance, but on LOD precision instead.
|
||||
dep.drop_distance_squared = squared(2.f * transformed_block_radius *
|
||||
dep.drop_distance_squared = math::squared(2.f * transformed_block_radius *
|
||||
get_octree_lod_block_region_extent(volume.octree_lod_distance, block_size));
|
||||
break;
|
||||
|
||||
|
@ -101,11 +101,11 @@ inline float u16_to_norm(uint16_t v) {
|
||||
}
|
||||
|
||||
inline uint8_t norm_to_u8(float v) {
|
||||
return clamp(static_cast<int>(128.f * v + 128.f), 0, 0xff);
|
||||
return zylann::math::clamp(static_cast<int>(128.f * v + 128.f), 0, 0xff);
|
||||
}
|
||||
|
||||
inline uint16_t norm_to_u16(float v) {
|
||||
return clamp(static_cast<int>(0x8000 * v + 0x8000), 0, 0xffff);
|
||||
return zylann::math::clamp(static_cast<int>(0x8000 * v + 0x8000), 0, 0xffff);
|
||||
}
|
||||
|
||||
/*static inline float quantized_u8_to_real(uint8_t v) {
|
||||
|
@ -78,7 +78,7 @@ private:
|
||||
// `get_next_power_of_two_32` takes unsigned int
|
||||
CRASH_COND(size > std::numeric_limits<unsigned int>::max());
|
||||
#endif
|
||||
return get_shift_from_power_of_two_32(get_next_power_of_two_32(size));
|
||||
return zylann::math::get_shift_from_power_of_two_32(zylann::math::get_next_power_of_two_32(size));
|
||||
}
|
||||
|
||||
inline size_t get_size_from_pool_index(unsigned int i) const {
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../util/serialization.h"
|
||||
#include <core/variant/variant.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace {
|
||||
const uint32_t TRAILING_MAGIC = 0x900df00d;
|
||||
}
|
||||
@ -15,7 +17,7 @@ const float VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM = 0.01f;
|
||||
// TODO Unify with functions from VoxelBuffer?
|
||||
|
||||
inline uint8_t norm_to_u8(float x) {
|
||||
return clamp(static_cast<int>(128.f * x + 128.f), 0, 0xff);
|
||||
return math::clamp(static_cast<int>(128.f * x + 128.f), 0, 0xff);
|
||||
}
|
||||
|
||||
inline float u8_to_norm(uint8_t v) {
|
||||
@ -57,7 +59,7 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
|
||||
zylann::MemoryWriter w(dst, zylann::ENDIANESS_BIG_ENDIAN);
|
||||
|
||||
ERR_FAIL_COND_V(src.position_range < 0.f, false);
|
||||
const float position_range = max(src.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM);
|
||||
const float position_range = math::max(src.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM);
|
||||
|
||||
w.store_8(version);
|
||||
w.store_8(src.layers.size());
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <core/os/time.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace {
|
||||
const uint8_t FORMAT_VERSION = 3;
|
||||
|
||||
@ -547,7 +549,7 @@ void VoxelStreamRegionFiles::close_oldest_region() {
|
||||
}
|
||||
|
||||
static inline int convert_block_coordinate(int p_x, int old_size, int new_size) {
|
||||
return ::floordiv(p_x * old_size, new_size);
|
||||
return math::floordiv(p_x * old_size, new_size);
|
||||
}
|
||||
|
||||
static Vector3i convert_block_coordinates(Vector3i pos, Vector3i old_size, Vector3i new_size) {
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <core/core_string_names.h>
|
||||
#include <scene/resources/mesh.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
namespace {
|
||||
const float MAX_DENSITY = 1.f;
|
||||
const char *DENSITY_HINT_STRING = "0.0, 1.0, 0.01";
|
||||
@ -96,7 +98,8 @@ void VoxelInstanceGenerator::generate_transforms(std::vector<Transform3D> &out_t
|
||||
// so it's possible a different emit mode will produce different amounts of instances.
|
||||
// I had to use `uint64` and clamp it because floats can't contain `0xffffffff` accurately. Instead
|
||||
// it results in `0x100000000`, one unit above.
|
||||
const uint32_t density_u32 = min(uint64_t(0xffffffff * (_density / MAX_DENSITY)), uint64_t(0xffffffff));
|
||||
const uint32_t density_u32 =
|
||||
math::min(uint64_t(0xffffffff * (_density / MAX_DENSITY)), uint64_t(0xffffffff));
|
||||
const int size = vertices.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
// TODO We could actually generate indexes and pick those,
|
||||
@ -418,7 +421,7 @@ void VoxelInstanceGenerator::generate_transforms(std::vector<Transform3D> &out_t
|
||||
CRASH_COND(vertex_index >= noise_cache.size());
|
||||
#endif
|
||||
// Multiplied noise because it gives more pronounced results
|
||||
const float n = clamp(noise_cache[vertex_index] * 2.f, 0.f, 1.f);
|
||||
const float n = math::clamp(noise_cache[vertex_index] * 2.f, 0.f, 1.f);
|
||||
r *= Math::lerp(1.f, n, _noise_on_scale);
|
||||
}
|
||||
|
||||
@ -444,7 +447,7 @@ void VoxelInstanceGenerator::generate_transforms(std::vector<Transform3D> &out_t
|
||||
}
|
||||
|
||||
void VoxelInstanceGenerator::set_density(float density) {
|
||||
density = max(density, 0.f);
|
||||
density = math::max(density, 0.f);
|
||||
if (density == _density) {
|
||||
return;
|
||||
}
|
||||
@ -507,7 +510,7 @@ VoxelInstanceGenerator::Distribution VoxelInstanceGenerator::get_scale_distribut
|
||||
}
|
||||
|
||||
void VoxelInstanceGenerator::set_vertical_alignment(float amount) {
|
||||
amount = clamp(amount, 0.f, 1.f);
|
||||
amount = math::clamp(amount, 0.f, 1.f);
|
||||
if (_vertical_alignment == amount) {
|
||||
return;
|
||||
}
|
||||
@ -532,8 +535,8 @@ float VoxelInstanceGenerator::get_offset_along_normal() const {
|
||||
}
|
||||
|
||||
void VoxelInstanceGenerator::set_min_slope_degrees(float degrees) {
|
||||
_min_slope_degrees = clamp(degrees, 0.f, 180.f);
|
||||
const float max_surface_normal_y = min(1.f, Math::cos(Math::deg2rad(_min_slope_degrees)));
|
||||
_min_slope_degrees = math::clamp(degrees, 0.f, 180.f);
|
||||
const float max_surface_normal_y = math::min(1.f, Math::cos(Math::deg2rad(_min_slope_degrees)));
|
||||
if (max_surface_normal_y == _max_surface_normal_y) {
|
||||
return;
|
||||
}
|
||||
@ -546,8 +549,8 @@ float VoxelInstanceGenerator::get_min_slope_degrees() const {
|
||||
}
|
||||
|
||||
void VoxelInstanceGenerator::set_max_slope_degrees(float degrees) {
|
||||
_max_slope_degrees = clamp(degrees, 0.f, 180.f);
|
||||
const float min_surface_normal_y = max(-1.f, Math::cos(Math::deg2rad(_max_slope_degrees)));
|
||||
_max_slope_degrees = math::clamp(degrees, 0.f, 180.f);
|
||||
const float min_surface_normal_y = math::max(-1.f, Math::cos(Math::deg2rad(_max_slope_degrees)));
|
||||
if (min_surface_normal_y == _min_surface_normal_y) {
|
||||
return;
|
||||
}
|
||||
@ -640,7 +643,7 @@ VoxelInstanceGenerator::Dimension VoxelInstanceGenerator::get_noise_dimension()
|
||||
}
|
||||
|
||||
void VoxelInstanceGenerator::set_noise_on_scale(float amount) {
|
||||
amount = clamp(amount, 0.f, 1.f);
|
||||
amount = math::clamp(amount, 0.f, 1.f);
|
||||
if (amount == _noise_on_scale) {
|
||||
return;
|
||||
}
|
||||
|
@ -78,8 +78,8 @@ public:
|
||||
void set_lod_distance(float p_lod_distance) {
|
||||
// Distance must be greater than a threshold,
|
||||
// otherwise lods will decimate too fast and it will look messy
|
||||
_lod_distance =
|
||||
clamp(p_lod_distance, VoxelConstants::MINIMUM_LOD_DISTANCE, VoxelConstants::MAXIMUM_LOD_DISTANCE);
|
||||
_lod_distance = zylann::math::clamp(
|
||||
p_lod_distance, VoxelConstants::MINIMUM_LOD_DISTANCE, VoxelConstants::MAXIMUM_LOD_DISTANCE);
|
||||
}
|
||||
|
||||
float get_lod_distance() const {
|
||||
@ -266,7 +266,7 @@ private:
|
||||
const int lod_factor = get_lod_factor(lod);
|
||||
const int chunk_size = _base_size * lod_factor;
|
||||
const Vector3 world_center = static_cast<real_t>(chunk_size) * (Vector3(node_pos) + Vector3(0.5, 0.5, 0.5));
|
||||
const float split_distance_sq = squared(_lod_distance * lod_factor);
|
||||
const float split_distance_sq = zylann::math::squared(_lod_distance * lod_factor);
|
||||
Node *node = get_node(node_index);
|
||||
|
||||
if (!node->has_children()) {
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include <scene/3d/mesh_instance_3d.h>
|
||||
#include <scene/resources/packed_scene.h>
|
||||
|
||||
using namespace zylann;
|
||||
//using namespace voxel;
|
||||
|
||||
namespace {
|
||||
|
||||
Ref<ArrayMesh> build_mesh(
|
||||
@ -382,7 +385,7 @@ void VoxelLodTerrain::_on_stream_params_changed() {
|
||||
|
||||
void VoxelLodTerrain::set_mesh_block_size(unsigned int mesh_block_size) {
|
||||
// Mesh block size cannot be smaller than data block size, for now
|
||||
mesh_block_size = clamp(mesh_block_size, get_data_block_size(), VoxelConstants::MAX_BLOCK_SIZE);
|
||||
mesh_block_size = math::clamp(mesh_block_size, get_data_block_size(), VoxelConstants::MAX_BLOCK_SIZE);
|
||||
|
||||
// Only these sizes are allowed at the moment. This stuff is still not supported in a generic way yet,
|
||||
// some code still exploits the fact it's a multiple of data block size, for performance
|
||||
@ -814,7 +817,8 @@ void VoxelLodTerrain::set_lod_distance(float p_lod_distance) {
|
||||
return;
|
||||
}
|
||||
|
||||
_lod_distance = clamp(p_lod_distance, VoxelConstants::MINIMUM_LOD_DISTANCE, VoxelConstants::MAXIMUM_LOD_DISTANCE);
|
||||
_lod_distance =
|
||||
math::clamp(p_lod_distance, VoxelConstants::MINIMUM_LOD_DISTANCE, VoxelConstants::MAXIMUM_LOD_DISTANCE);
|
||||
|
||||
for (Map<Vector3i, OctreeItem>::Element *E = _lod_octrees.front(); E; E = E->next()) {
|
||||
OctreeItem &item = E->value();
|
||||
@ -907,7 +911,7 @@ void VoxelLodTerrain::set_generate_collisions(bool enabled) {
|
||||
|
||||
void VoxelLodTerrain::set_collision_lod_count(int lod_count) {
|
||||
ERR_FAIL_COND(lod_count < 0);
|
||||
_collision_lod_count = static_cast<unsigned int>(min(lod_count, get_lod_count()));
|
||||
_collision_lod_count = static_cast<unsigned int>(math::min(lod_count, get_lod_count()));
|
||||
}
|
||||
|
||||
int VoxelLodTerrain::get_collision_lod_count() const {
|
||||
@ -1097,12 +1101,12 @@ void VoxelLodTerrain::try_schedule_loading_with_neighbors_no_lock(
|
||||
const int bound_max_y = (_bounds_in_voxels.pos.y + _bounds_in_voxels.size.y) >> p;
|
||||
const int bound_max_z = (_bounds_in_voxels.pos.z + _bounds_in_voxels.size.z) >> p;
|
||||
|
||||
const int min_x = max(p_data_block_pos.x - 1, bound_min_x);
|
||||
const int min_y = max(p_data_block_pos.y - 1, bound_min_y);
|
||||
const int min_z = max(p_data_block_pos.z - 1, bound_min_z);
|
||||
const int max_x = min(p_data_block_pos.x + 2, bound_max_x);
|
||||
const int max_y = min(p_data_block_pos.y + 2, bound_max_y);
|
||||
const int max_z = min(p_data_block_pos.z + 2, bound_max_z);
|
||||
const int min_x = math::max(p_data_block_pos.x - 1, bound_min_x);
|
||||
const int min_y = math::max(p_data_block_pos.y - 1, bound_min_y);
|
||||
const int min_z = math::max(p_data_block_pos.z - 1, bound_min_z);
|
||||
const int max_x = math::min(p_data_block_pos.x + 2, bound_max_x);
|
||||
const int max_y = math::min(p_data_block_pos.y + 2, bound_max_y);
|
||||
const int max_z = math::min(p_data_block_pos.z + 2, bound_max_z);
|
||||
|
||||
// Not locking here, we assume it's done by the caller
|
||||
//RWLockRead rlock(data_lod.map_lock);
|
||||
@ -2562,7 +2566,7 @@ void VoxelLodTerrain::set_voxel_bounds(Box3i p_box) {
|
||||
}
|
||||
|
||||
void VoxelLodTerrain::set_collision_update_delay(int delay_msec) {
|
||||
_collision_update_delay = clamp(delay_msec, 0, 4000);
|
||||
_collision_update_delay = math::clamp(delay_msec, 0, 4000);
|
||||
}
|
||||
|
||||
int VoxelLodTerrain::get_collision_update_delay() const {
|
||||
@ -2570,7 +2574,7 @@ int VoxelLodTerrain::get_collision_update_delay() const {
|
||||
}
|
||||
|
||||
void VoxelLodTerrain::set_lod_fade_duration(float seconds) {
|
||||
_lod_fade_duration = clamp(seconds, 0.f, 1.f);
|
||||
_lod_fade_duration = math::clamp(seconds, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float VoxelLodTerrain::get_lod_fade_duration() const {
|
||||
@ -2594,7 +2598,7 @@ void VoxelLodTerrain::_b_save_modified_blocks() {
|
||||
}
|
||||
|
||||
void VoxelLodTerrain::_b_set_voxel_bounds(AABB aabb) {
|
||||
ERR_FAIL_COND(!is_valid_size(aabb.size));
|
||||
ERR_FAIL_COND(!math::is_valid_size(aabb.size));
|
||||
set_voxel_bounds(Box3i(Vector3iUtil::from_rounded(aabb.position), Vector3iUtil::from_rounded(aabb.size)));
|
||||
}
|
||||
|
||||
@ -2824,7 +2828,7 @@ void VoxelLodTerrain::update_gizmos() {
|
||||
const Transform3D t = parent_transform * local_transform;
|
||||
// Squaring because lower lod indexes are more interesting to see, so we give them more contrast.
|
||||
// Also this might be better with sRGB?
|
||||
const float g = squared(max(1.f - float(lod_index) / lod_count_f, 0.f));
|
||||
const float g = math::squared(math::max(1.f - float(lod_index) / lod_count_f, 0.f));
|
||||
dr.draw_box_mm(t, Color8(255, uint8_t(g * 254.f), 0, 255));
|
||||
});
|
||||
}
|
||||
@ -2861,7 +2865,7 @@ void VoxelLodTerrain::set_show_gizmos(bool enable) {
|
||||
|
||||
// This copies at multiple LOD levels to debug mips
|
||||
Array VoxelLodTerrain::_b_debug_print_sdf_top_down(Vector3i center, Vector3i extents) {
|
||||
ERR_FAIL_COND_V(!is_valid_size(extents), Array());
|
||||
ERR_FAIL_COND_V(!math::is_valid_size(extents), Array());
|
||||
|
||||
Array image_array;
|
||||
image_array.resize(get_lod_count());
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <core/core_string_names.h>
|
||||
#include <scene/3d/mesh_instance_3d.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
VoxelTerrain::VoxelTerrain() {
|
||||
// Note: don't do anything heavy in the constructor.
|
||||
// Godot may create and destroy dozens of instances of all node types on startup,
|
||||
@ -190,7 +192,7 @@ unsigned int VoxelTerrain::get_mesh_block_size_pow2() const {
|
||||
}
|
||||
|
||||
void VoxelTerrain::set_mesh_block_size(unsigned int mesh_block_size) {
|
||||
mesh_block_size = clamp(mesh_block_size, get_data_block_size(), VoxelConstants::MAX_BLOCK_SIZE);
|
||||
mesh_block_size = math::clamp(mesh_block_size, get_data_block_size(), VoxelConstants::MAX_BLOCK_SIZE);
|
||||
|
||||
unsigned int po2;
|
||||
switch (mesh_block_size) {
|
||||
@ -885,7 +887,7 @@ void VoxelTerrain::process_viewers() {
|
||||
static_cast<unsigned int>(static_cast<float>(viewer.view_distance) * view_distance_scale);
|
||||
const Vector3 local_position = world_to_local_transform.xform(viewer.world_position);
|
||||
|
||||
state.view_distance_voxels = min(view_distance_voxels, self._max_view_distance_voxels);
|
||||
state.view_distance_voxels = math::min(view_distance_voxels, self._max_view_distance_voxels);
|
||||
state.local_position_voxels = Vector3iUtil::from_floored(local_position);
|
||||
state.requires_collisions = VoxelServer::get_singleton()->is_viewer_requiring_collisions(viewer_id);
|
||||
state.requires_meshes = VoxelServer::get_singleton()->is_viewer_requiring_visuals(viewer_id);
|
||||
@ -899,7 +901,7 @@ void VoxelTerrain::process_viewers() {
|
||||
Vector3i data_block_pos;
|
||||
|
||||
if (state.requires_meshes || state.requires_collisions) {
|
||||
const int view_distance_mesh_blocks = ceildiv(state.view_distance_voxels, mesh_block_size);
|
||||
const int view_distance_mesh_blocks = math::ceildiv(state.view_distance_voxels, mesh_block_size);
|
||||
const int render_to_data_factor = (mesh_block_size / data_block_size);
|
||||
const Vector3i mesh_block_pos =
|
||||
Vector3iUtil::floordiv(state.local_position_voxels, mesh_block_size);
|
||||
@ -913,7 +915,7 @@ void VoxelTerrain::process_viewers() {
|
||||
.clipped(bounds_in_mesh_blocks);
|
||||
|
||||
} else {
|
||||
view_distance_data_blocks = ceildiv(state.view_distance_voxels, data_block_size);
|
||||
view_distance_data_blocks = math::ceildiv(state.view_distance_voxels, data_block_size);
|
||||
|
||||
data_block_pos = Vector3iUtil::floordiv(state.local_position_voxels, data_block_size);
|
||||
state.mesh_box = Box3i();
|
||||
@ -1298,11 +1300,12 @@ void VoxelTerrain::set_bounds(Box3i box) {
|
||||
// Round to block size
|
||||
_bounds_in_voxels = _bounds_in_voxels.snapped(get_data_block_size());
|
||||
|
||||
const unsigned int largest_dimension = static_cast<unsigned int>(max(max(box.size.x, box.size.y), box.size.z));
|
||||
const unsigned int largest_dimension =
|
||||
static_cast<unsigned int>(math::max(math::max(box.size.x, box.size.y), box.size.z));
|
||||
if (largest_dimension > MAX_VIEW_DISTANCE_FOR_LARGE_VOLUME) {
|
||||
// Cap view distance to make sure you don't accidentally blow up memory when changing parameters
|
||||
if (_max_view_distance_voxels > MAX_VIEW_DISTANCE_FOR_LARGE_VOLUME) {
|
||||
_max_view_distance_voxels = min(_max_view_distance_voxels, MAX_VIEW_DISTANCE_FOR_LARGE_VOLUME);
|
||||
_max_view_distance_voxels = math::min(_max_view_distance_voxels, MAX_VIEW_DISTANCE_FOR_LARGE_VOLUME);
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
@ -1340,7 +1343,7 @@ void VoxelTerrain::_b_save_block(Vector3i p_block_pos) {
|
||||
}
|
||||
|
||||
void VoxelTerrain::_b_set_bounds(AABB aabb) {
|
||||
ERR_FAIL_COND(!is_valid_size(aabb.size));
|
||||
ERR_FAIL_COND(!math::is_valid_size(aabb.size));
|
||||
set_bounds(Box3i(Vector3iUtil::from_rounded(aabb.position), Vector3iUtil::from_rounded(aabb.size)));
|
||||
}
|
||||
|
||||
|
@ -82,13 +82,13 @@ template <typename F2, typename F3, typename FloatT> void test_min_max(F2 noise_
|
||||
|
||||
FloatT n = noise_func_2d(x, y);
|
||||
|
||||
min_value_2d = min(n, min_value_2d);
|
||||
max_value_2d = max(n, max_value_2d);
|
||||
min_value_2d = math::min(n, min_value_2d);
|
||||
max_value_2d = math::max(n, max_value_2d);
|
||||
|
||||
n = noise_func_3d(x, y, z);
|
||||
|
||||
min_value_3d = min(n, min_value_3d);
|
||||
max_value_3d = max(n, max_value_3d);
|
||||
min_value_3d = math::min(n, min_value_3d);
|
||||
max_value_3d = math::max(n, max_value_3d);
|
||||
}
|
||||
|
||||
print_line(String("2D | Min: {0}, Max: {1}").format(varray(min_value_2d, max_value_2d)));
|
||||
|
@ -739,7 +739,7 @@ void test_instance_data_serialization() {
|
||||
ERR_FAIL_COND(dst_data.position_range < 0.f);
|
||||
ERR_FAIL_COND(dst_data.position_range != src_data.position_range);
|
||||
|
||||
const float distance_error = max(src_data.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM) /
|
||||
const float distance_error = math::max(src_data.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM) /
|
||||
float(VoxelInstanceBlockData::POSITION_RESOLUTION);
|
||||
|
||||
// Compare layers
|
||||
@ -756,7 +756,7 @@ void test_instance_data_serialization() {
|
||||
}
|
||||
ERR_FAIL_COND(src_layer.instances.size() != dst_layer.instances.size());
|
||||
|
||||
const float scale_error = max(src_layer.scale_max - src_layer.scale_min,
|
||||
const float scale_error = math::max(src_layer.scale_max - src_layer.scale_min,
|
||||
VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) /
|
||||
float(VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RESOLUTION);
|
||||
|
||||
|
@ -33,16 +33,16 @@ public:
|
||||
static inline Box3i get_bounding_box(Box3i a, Box3i b) {
|
||||
Box3i box;
|
||||
|
||||
box.pos.x = min(a.pos.x, b.pos.x);
|
||||
box.pos.y = min(a.pos.y, b.pos.y);
|
||||
box.pos.z = min(a.pos.z, b.pos.z);
|
||||
box.pos.x = zylann::math::min(a.pos.x, b.pos.x);
|
||||
box.pos.y = zylann::math::min(a.pos.y, b.pos.y);
|
||||
box.pos.z = zylann::math::min(a.pos.z, b.pos.z);
|
||||
|
||||
Vector3i max_a = a.pos + a.size;
|
||||
Vector3i max_b = b.pos + b.size;
|
||||
|
||||
box.size.x = max(max_a.x, max_b.x) - box.pos.x;
|
||||
box.size.y = max(max_a.y, max_b.y) - box.pos.y;
|
||||
box.size.z = max(max_a.z, max_b.z) - box.pos.z;
|
||||
box.size.x = zylann::math::max(max_a.x, max_b.x) - box.pos.x;
|
||||
box.size.y = zylann::math::max(max_a.y, max_b.y) - box.pos.y;
|
||||
box.size.z = zylann::math::max(max_a.z, max_b.z) - box.pos.z;
|
||||
|
||||
return box;
|
||||
}
|
||||
@ -288,8 +288,8 @@ public:
|
||||
int max_pos = pos + size;
|
||||
int lim_max_pos = lim_pos + lim_size;
|
||||
|
||||
pos = clamp(pos, lim_pos, lim_max_pos);
|
||||
max_pos = clamp(max_pos, lim_pos, lim_max_pos);
|
||||
pos = zylann::math::clamp(pos, lim_pos, lim_max_pos);
|
||||
max_pos = zylann::math::clamp(max_pos, lim_pos, lim_max_pos);
|
||||
|
||||
size = max_pos - pos;
|
||||
if (size < 0) {
|
||||
@ -329,13 +329,13 @@ public:
|
||||
|
||||
void merge_with(const Box3i &other) {
|
||||
const Vector3i min_pos( //
|
||||
min(pos.x, other.pos.x), //
|
||||
min(pos.y, other.pos.y), //
|
||||
min(pos.z, other.pos.z));
|
||||
zylann::math::min(pos.x, other.pos.x), //
|
||||
zylann::math::min(pos.y, other.pos.y), //
|
||||
zylann::math::min(pos.z, other.pos.z));
|
||||
const Vector3i max_pos( //
|
||||
max(pos.x + size.x, other.pos.x + other.size.x), //
|
||||
max(pos.y + size.y, other.pos.y + other.size.y), //
|
||||
max(pos.z + size.z, other.pos.z + other.size.z));
|
||||
zylann::math::max(pos.x + size.x, other.pos.x + other.size.x), //
|
||||
zylann::math::max(pos.y + size.y, other.pos.y + other.size.y), //
|
||||
zylann::math::max(pos.z + size.z, other.pos.z + other.size.z));
|
||||
pos = min_pos;
|
||||
size = max_pos - min_pos;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <core/math/vector3.h>
|
||||
|
||||
namespace zylann::math {
|
||||
|
||||
// Trilinear interpolation between corner values of a cube.
|
||||
//
|
||||
// 6---------------7
|
||||
@ -200,4 +202,6 @@ inline size_t alignup(size_t a, size_t align) {
|
||||
// return i & (i - 1);
|
||||
// }
|
||||
|
||||
} // namespace zylann::math
|
||||
|
||||
#endif // VOXEL_MATH_FUNCS_H
|
||||
|
@ -27,7 +27,7 @@ struct Interval {
|
||||
}
|
||||
|
||||
inline static Interval from_unordered_values(float a, float b) {
|
||||
return Interval(::min(a, b), ::max(a, b));
|
||||
return Interval(math::min(a, b), math::max(a, b));
|
||||
}
|
||||
|
||||
inline static Interval from_infinity() {
|
||||
@ -112,7 +112,7 @@ struct Interval {
|
||||
const float b = min * other.max;
|
||||
const float c = max * other.min;
|
||||
const float d = max * other.max;
|
||||
return Interval{ ::min(a, b, c, d), ::max(a, b, c, d) };
|
||||
return Interval{ math::min(a, b, c, d), math::max(a, b, c, d) };
|
||||
}
|
||||
|
||||
inline void operator*=(float x) {
|
||||
@ -136,7 +136,7 @@ struct Interval {
|
||||
const float b = min / other.max;
|
||||
const float c = max / other.min;
|
||||
const float d = max / other.max;
|
||||
return Interval{ ::min(a, b, c, d), ::max(a, b, c, d) };
|
||||
return Interval{ math::min(a, b, c, d), math::max(a, b, c, d) };
|
||||
}
|
||||
|
||||
inline Interval operator/(float x) const {
|
||||
@ -156,33 +156,33 @@ inline Interval operator*(float b, const Interval &a) {
|
||||
// Functions declared outside, so using intervals or numbers can be the same code (templatable)
|
||||
|
||||
inline Interval min_interval(const Interval &a, const Interval &b) {
|
||||
return Interval(::min(a.min, b.min), ::min(a.max, b.max));
|
||||
return Interval(min(a.min, b.min), min(a.max, b.max));
|
||||
}
|
||||
|
||||
inline Interval max_interval(const Interval &a, const Interval &b) {
|
||||
return Interval(::max(a.min, b.min), ::max(a.max, b.max));
|
||||
return Interval(max(a.min, b.min), max(a.max, b.max));
|
||||
}
|
||||
|
||||
inline Interval min_interval(const Interval &a, const float b) {
|
||||
return Interval(::min(a.min, b), ::min(a.max, b));
|
||||
return Interval(min(a.min, b), min(a.max, b));
|
||||
}
|
||||
|
||||
inline Interval max_interval(const Interval &a, const float b) {
|
||||
return Interval(::max(a.min, b), ::max(a.max, b));
|
||||
return Interval(max(a.min, b), max(a.max, b));
|
||||
}
|
||||
|
||||
inline Interval sqrt(const Interval &i) {
|
||||
return Interval{ Math::sqrt(::max(0.f, i.min)), Math::sqrt(::max(0.f, i.max)) };
|
||||
return Interval{ Math::sqrt(max(0.f, i.min)), Math::sqrt(max(0.f, i.max)) };
|
||||
}
|
||||
|
||||
inline Interval abs(const Interval &i) {
|
||||
return Interval{ i.contains(0) ? 0 : ::min(Math::abs(i.min), Math::abs(i.max)),
|
||||
::max(Math::abs(i.min), Math::abs(i.max)) };
|
||||
return Interval{ i.contains(0) ? 0 : min(Math::abs(i.min), Math::abs(i.max)),
|
||||
max(Math::abs(i.min), Math::abs(i.max)) };
|
||||
}
|
||||
|
||||
inline Interval clamp(const Interval &i, const Interval &p_min, const Interval &p_max) {
|
||||
if (p_min.is_single_value() && p_max.is_single_value()) {
|
||||
return { ::clamp(i.min, p_min.min, p_max.min), ::clamp(i.max, p_min.min, p_max.min) };
|
||||
return { clamp(i.min, p_min.min, p_max.min), clamp(i.max, p_min.min, p_max.min) };
|
||||
}
|
||||
if (i.min >= p_min.max && i.max <= p_max.min) {
|
||||
return i;
|
||||
@ -338,8 +338,8 @@ inline Interval smoothstep(float p_from, float p_to, Interval p_weight) {
|
||||
return Interval::from_single_value(p_from);
|
||||
}
|
||||
// Smoothstep is monotonic
|
||||
float v0 = ::smoothstep(p_from, p_to, p_weight.min);
|
||||
float v1 = ::smoothstep(p_from, p_to, p_weight.max);
|
||||
float v0 = smoothstep(p_from, p_to, p_weight.min);
|
||||
float v1 = smoothstep(p_from, p_to, p_weight.max);
|
||||
if (v0 <= v1) {
|
||||
return Interval(v0, v1);
|
||||
} else {
|
||||
|
@ -48,13 +48,13 @@ inline float sdf_subtract(float a, float b) {
|
||||
}
|
||||
|
||||
inline float sdf_smooth_union(float a, float b, float s) {
|
||||
float h = ::clamp(0.5f + 0.5f * (b - a) / s, 0.0f, 1.0f);
|
||||
float h = clamp(0.5f + 0.5f * (b - a) / s, 0.0f, 1.0f);
|
||||
return Math::lerp(b, a, h) - s * h * (1.0f - h);
|
||||
}
|
||||
|
||||
// Inverted a and b because it subtracts SDF a from SDF b
|
||||
inline float sdf_smooth_subtract(float b, float a, float s) {
|
||||
float h = ::clamp(0.5f - 0.5f * (b + a) / s, 0.0f, 1.0f);
|
||||
float h = clamp(0.5f - 0.5f * (b + a) / s, 0.0f, 1.0f);
|
||||
return Math::lerp(b, -a, h) + s * h * (1.0f - h);
|
||||
}
|
||||
|
||||
|
@ -324,19 +324,20 @@ inline Vector3i from_zxy_index(unsigned int i, const Vector3i area_size) {
|
||||
}
|
||||
|
||||
inline Vector3i floordiv(const Vector3i v, const Vector3i d) {
|
||||
return Vector3i(::floordiv(v.x, d.x), ::floordiv(v.y, d.y), ::floordiv(v.z, d.z));
|
||||
return Vector3i(
|
||||
zylann::math::floordiv(v.x, d.x), zylann::math::floordiv(v.y, d.y), zylann::math::floordiv(v.z, d.z));
|
||||
}
|
||||
|
||||
inline Vector3i floordiv(const Vector3i v, const int d) {
|
||||
return Vector3i(::floordiv(v.x, d), ::floordiv(v.y, d), ::floordiv(v.z, d));
|
||||
return Vector3i(zylann::math::floordiv(v.x, d), zylann::math::floordiv(v.y, d), zylann::math::floordiv(v.z, d));
|
||||
}
|
||||
|
||||
inline Vector3i ceildiv(const Vector3i v, const int d) {
|
||||
return Vector3i(::ceildiv(v.x, d), ::ceildiv(v.y, d), ::ceildiv(v.z, d));
|
||||
return Vector3i(zylann::math::ceildiv(v.x, d), zylann::math::ceildiv(v.y, d), zylann::math::ceildiv(v.z, d));
|
||||
}
|
||||
|
||||
inline Vector3i wrap(const Vector3i v, const Vector3i d) {
|
||||
return Vector3i(::wrap(v.x, d.x), ::wrap(v.y, d.y), ::wrap(v.z, d.z));
|
||||
return Vector3i(zylann::math::wrap(v.x, d.x), zylann::math::wrap(v.y, d.y), zylann::math::wrap(v.z, d.z));
|
||||
}
|
||||
|
||||
inline bool all_members_equal(const Vector3i v) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "../math/funcs.h"
|
||||
#include <core/io/image.h>
|
||||
|
||||
using namespace zylann;
|
||||
|
||||
FastNoise2::FastNoise2() {
|
||||
// Setup default
|
||||
update_generator();
|
||||
@ -174,7 +176,7 @@ bool FastNoise2::is_terrace_enabled() const {
|
||||
}
|
||||
|
||||
void FastNoise2::set_terrace_multiplier(float m) {
|
||||
const float clamped_multiplier = max(m, 0.f);
|
||||
const float clamped_multiplier = math::max(m, 0.f);
|
||||
if (clamped_multiplier == _terrace_multiplier) {
|
||||
return;
|
||||
}
|
||||
@ -187,7 +189,7 @@ float FastNoise2::get_terrace_multiplier() const {
|
||||
}
|
||||
|
||||
void FastNoise2::set_terrace_smoothness(float s) {
|
||||
const float clamped_smoothness = max(s, 0.f);
|
||||
const float clamped_smoothness = math::max(s, 0.f);
|
||||
if (_terrace_smoothness == clamped_smoothness) {
|
||||
return;
|
||||
}
|
||||
@ -279,7 +281,7 @@ FastNoise2::CellularReturnType FastNoise2::get_cellular_return_type() const {
|
||||
}
|
||||
|
||||
void FastNoise2::set_cellular_jitter(float jitter) {
|
||||
jitter = clamp(jitter, 0.f, 1.f);
|
||||
jitter = math::clamp(jitter, 0.f, 1.f);
|
||||
if (_cellular_jitter == jitter) {
|
||||
return;
|
||||
}
|
||||
@ -323,7 +325,7 @@ void FastNoise2::get_noise_2d_grid(Vector2 origin, Vector2i size, Span<float> ds
|
||||
|
||||
void FastNoise2::get_noise_3d_grid(Vector3 origin, Vector3i size, Span<float> dst) const {
|
||||
ERR_FAIL_COND(!is_valid());
|
||||
ERR_FAIL_COND(!is_valid_size(size));
|
||||
ERR_FAIL_COND(!math::is_valid_size(size));
|
||||
ERR_FAIL_COND(dst.size() != size.x * size.y * size.z);
|
||||
_generator->GenUniformGrid3D(dst.data(), origin.x, origin.y, origin.z, size.x, size.y, size.z, 1.f, _seed);
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ FastNoiseLite::CellularReturnType FastNoiseLite::get_cellular_return_type() cons
|
||||
}
|
||||
|
||||
void FastNoiseLite::set_cellular_jitter(float jitter) {
|
||||
jitter = clamp(jitter, 0.f, 1.f);
|
||||
jitter = zylann::math::clamp(jitter, 0.f, 1.f);
|
||||
if (_cellular_jitter == jitter) {
|
||||
return;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ void ProgressiveTaskRunner::process() {
|
||||
// As the number of pending tasks decreases, we want to keep running the highest amount we calculated.
|
||||
// we reset when we are done.
|
||||
|
||||
_dequeue_count = max(int64_t(_dequeue_count), (int64_t(_tasks.size()) * delta_msec) / COMPLETION_TIME_MSEC);
|
||||
_dequeue_count = min(_dequeue_count, max(MIN_COUNT, unsigned int(_tasks.size())));
|
||||
_dequeue_count = math::max(int64_t(_dequeue_count), (int64_t(_tasks.size()) * delta_msec) / COMPLETION_TIME_MSEC);
|
||||
_dequeue_count = math::min(_dequeue_count, math::max(MIN_COUNT, unsigned int(_tasks.size())));
|
||||
|
||||
unsigned int count = _dequeue_count;
|
||||
while (_tasks.size() > 0 && count > 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user