Reorganized some utility files

master
Marc Gilleron 2021-02-17 20:34:35 +00:00
parent d08c911579
commit d1207bdd96
58 changed files with 326 additions and 304 deletions

2
SCsub
View File

@ -28,6 +28,7 @@ voxel_files = [
"generators/simple/*.cpp",
"util/*.cpp",
"util/godot/*.cpp",
#"util/noise/*.cpp",
"util/noise/fast_noise_lite.cpp",
"util/noise/fast_noise_lite_gradient.cpp",
@ -36,7 +37,6 @@ voxel_files = [
"terrain/instancing/*.cpp",
"server/*.cpp",
"math/*.cpp",
"edition/*.cpp",
"thirdparty/lz4/*.c",

View File

@ -1,7 +1,7 @@
#ifndef CUBE_TABLES_H
#define CUBE_TABLES_H
#include "math/vector3i.h"
#include "util/math/vector3i.h"
#include <core/math/vector3.h>
namespace Cube {

View File

@ -1,7 +1,7 @@
#ifndef VOXEL_TOOL_H
#define VOXEL_TOOL_H
#include "../math/rect3i.h"
#include "../util/math/rect3i.h"
#include <core/reference.h>
class VoxelBuffer;

View File

@ -1,7 +1,6 @@
#include "voxel_debug.h"
#include "../util/direct_mesh_instance.h"
#include "../util/fixed_array.h"
#include "../util/utility.h"
#include "../util/godot/direct_mesh_instance.h"
#include <scene/resources/mesh.h>
namespace VoxelDebug {

View File

@ -1,8 +1,8 @@
#ifndef IMAGE_RANGE_GRID_H
#define IMAGE_RANGE_GRID_H
#include "../../math/interval.h"
#include "../../util/fixed_array.h"
#include "../../util/math/interval.h"
class Image;

View File

@ -1,6 +1,5 @@
#include "range_utility.h"
#include "../../util/noise/fast_noise_lite.h"
#include "../../util/utility.h"
#include <core/image.h>
#include <modules/opensimplex/open_simplex_noise.h>

View File

@ -1,7 +1,8 @@
#ifndef RANGE_UTILITY_H
#define RANGE_UTILITY_H
#include "../../math/interval.h"
#include "../../util/math/interval.h"
#include <core/math/rect2.h>
class Curve;
class OpenSimplexNoise;

View File

@ -1,4 +1,5 @@
#include "voxel_graph_runtime.h"
#include "../../util/funcs.h"
#include "../../util/macros.h"
#include "../../util/noise/fast_noise_lite.h"
#include "../../util/profiling.h"
@ -7,7 +8,6 @@
#include "voxel_generator_graph.h"
#include "voxel_graph_node_db.h"
//#include <core/image.h>
#include <core/math/math_funcs.h>
#include <modules/opensimplex/open_simplex_noise.h>
#include <scene/resources/curve.h>

View File

@ -1,10 +1,11 @@
#ifndef VOXEL_GRAPH_RUNTIME_H
#define VOXEL_GRAPH_RUNTIME_H
#include "../../math/interval.h"
#include "../../math/vector3i.h"
#include "../../util/array_slice.h"
#include "../../util/math/interval.h"
#include "../../util/math/vector3i.h"
#include "program_graph.h"
#include <core/reference.h>
class ImageRangeGrid;

View File

@ -1,5 +1,4 @@
#include "voxel_generator_waves.h"
#include "../../util/utility.h"
#include <cmath>
VoxelGeneratorWaves::VoxelGeneratorWaves() {

View File

@ -1,4 +1,5 @@
#include "voxel_generator_script.h"
#include "../util/godot/funcs.h"
#include "../voxel_string_names.h"
VoxelGeneratorScript::VoxelGeneratorScript() {

View File

@ -5,6 +5,7 @@
#include "../../util/fixed_array.h"
#include <scene/resources/mesh.h>
#include <vector>
class VoxelLibrary;

View File

@ -2,7 +2,7 @@
#include "../../cube_tables.h"
#include "../../storage/voxel_buffer.h"
#include "../../util/array_slice.h"
#include "../../util/utility.h"
#include "../../util/funcs.h"
#include <core/os/os.h>
// Utility functions

View File

@ -1,10 +1,9 @@
#ifndef VOXEL_COLOR_PALETTE_H
#define VOXEL_COLOR_PALETTE_H
#include "../../math/color8.h"
#include "../../util/fixed_array.h"
#include "../../util/math/color8.h"
#include <core/resource.h>
#include <vector>
// Associates small numbers to colors, so colored voxels can be specified using less memory.
class VoxelColorPalette : public Resource {

View File

@ -1,5 +1,6 @@
#include "voxel_mesher_cubes.h"
#include "../../storage/voxel_buffer.h"
#include "../../util/funcs.h"
namespace {
// 2-----3

View File

@ -3,6 +3,7 @@
#include "../voxel_mesher.h"
#include "voxel_color_palette.h"
#include <vector>
// A super simple mesher only producing colored cubes
class VoxelMesherCubes : public VoxelMesher {

View File

@ -2,7 +2,7 @@
#define HERMITE_VALUE_H
#include "../../storage/voxel_buffer.h"
#include "../../util/utility.h"
#include "../../util/math/funcs.h"
#include <core/math/vector3.h>
namespace dmc {
@ -17,16 +17,13 @@ struct HermiteValue {
};
inline float get_isolevel_clamped(const VoxelBuffer &voxels, unsigned int x, unsigned int y, unsigned int z) {
x = x >= (unsigned int)voxels.get_size().x ? voxels.get_size().x - 1 : x;
y = y >= (unsigned int)voxels.get_size().y ? voxels.get_size().y - 1 : y;
z = z >= (unsigned int)voxels.get_size().z ? voxels.get_size().z - 1 : z;
return voxels.get_voxel_f(x, y, z, VoxelBuffer::CHANNEL_SDF);
}
inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, unsigned int x, unsigned int y, unsigned int z) {
HermiteValue v;
v.sdf = voxels.get_voxel_f(x, y, z, VoxelBuffer::CHANNEL_SDF);
@ -43,7 +40,6 @@ inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, unsigned int x,
}
inline HermiteValue get_interpolated_hermite_value(const VoxelBuffer &voxels, Vector3 pos) {
int x0 = static_cast<int>(pos.x);
int y0 = static_cast<int>(pos.y);
int z0 = static_cast<int>(pos.z);

View File

@ -1,4 +1,6 @@
#include "mesh_builder.h"
#include "../../util/funcs.h"
#include <scene/resources/mesh.h>
namespace dmc {

View File

@ -1,9 +1,8 @@
#ifndef MESH_BUILDER_H
#define MESH_BUILDER_H
#include "../../util/utility.h"
#include <core/map.h>
#include <scene/resources/mesh.h>
#include <core/math/vector3.h>
#include <vector>
namespace dmc {

View File

@ -1,7 +1,7 @@
#include "voxel_mesher_transvoxel.h"
#include "../../storage/voxel_buffer.h"
#include "../../util/funcs.h"
#include "transvoxel_tables.cpp"
#include <core/os/os.h>
namespace {
static const unsigned int MESH_COMPRESSION_FLAGS =

View File

@ -4,7 +4,7 @@
#include "../../cube_tables.h"
#include "../../util/fixed_array.h"
#include "../voxel_mesher.h"
#include <scene/resources/mesh.h>
#include <vector>
class VoxelMesherTransvoxelInternal {
public:
@ -57,6 +57,8 @@ private:
MeshArrays _output;
};
class ArrayMesh;
class VoxelMesherTransvoxel : public VoxelMesher {
GDCLASS(VoxelMesherTransvoxel, VoxelMesher)

View File

@ -1,5 +1,6 @@
#include "voxel_mesher.h"
#include "../storage/voxel_buffer.h"
#include "../util/godot/funcs.h"
Ref<Mesh> VoxelMesher::build_mesh(Ref<VoxelBuffer> voxels, Array materials) {
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());

View File

@ -1,5 +1,6 @@
#include "voxel_server.h"
#include "../meshers/transvoxel/voxel_mesher_transvoxel.h"
#include "../util/funcs.h"
#include "../util/macros.h"
#include "../util/profiling.h"
#include "../voxel_constants.h"

View File

@ -1,9 +1,9 @@
#ifndef VOXEL_BUFFER_H
#define VOXEL_BUFFER_H
#include "../math/rect3i.h"
#include "../util/array_slice.h"
#include "../util/fixed_array.h"
#include "../util/math/rect3i.h"
#include "../voxel_constants.h"
#include <core/map.h>

View File

@ -1,7 +1,7 @@
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#include "../math/vector3i.h"
#include "../util/math/vector3i.h"
#include <core/os/dir_access.h>
#include <core/os/file_access.h>

View File

@ -1,8 +1,9 @@
#include "instance_data.h"
#include "../util/array_slice.h"
#include "../util/math/funcs.h"
#include "../util/serialization.h"
#include "../util/utility.h"
#include "../voxel_constants.h"
#include <core/variant.h>
namespace {
const uint32_t TRAILING_MAGIC = 0x900df00d;

View File

@ -1,10 +1,10 @@
#ifndef REGION_FILE_H
#define REGION_FILE_H
#include "../../math/color8.h"
#include "../../math/vector3i.h"
#include "../../storage/voxel_buffer.h"
#include "../../util/fixed_array.h"
#include "../../util/math/color8.h"
#include "../../util/math/vector3i.h"
#include <vector>
class FileAccess;

View File

@ -1,9 +1,8 @@
#include "voxel_stream_region_files.h"
#include "../../math/rect3i.h"
#include "../../server/voxel_server.h"
#include "../../util/macros.h"
#include "../../util/math/rect3i.h"
#include "../../util/profiling.h"
#include "../../util/utility.h"
#include <core/io/json.h>
#include <core/os/os.h>

View File

@ -1,8 +1,9 @@
#ifndef VOX_LOADER_H
#define VOX_LOADER_H
#include "../math/vector3i.h"
#include "../meshers/cubes/voxel_color_palette.h"
#include "../util/math/vector3i.h"
#include <vector>
class VoxelBuffer;

View File

@ -1,8 +1,8 @@
#ifndef VOXEL_BLOCK_REQUEST_H
#define VOXEL_BLOCK_REQUEST_H
#include "../math/vector3i.h"
#include "../storage/voxel_buffer.h"
#include "../util/math/vector3i.h"
#include "instance_data.h"
#include <memory>

View File

@ -1,8 +1,8 @@
#include "voxel_block_serializer.h"
#include "../math/vector3i.h"
#include "../storage/voxel_buffer.h"
#include "../storage/voxel_memory_pool.h"
#include "../util/macros.h"
#include "../util/math/vector3i.h"
#include "../util/profiling.h"
#include "compressed_data.h"

View File

@ -1,6 +1,5 @@
#include "voxel_stream_block_files.h"
#include "../server/voxel_server.h"
#include "../util/utility.h"
#include <core/os/dir_access.h>
#include <core/os/file_access.h>

View File

@ -1,4 +1,5 @@
#include "voxel_stream_script.h"
#include "../util/godot/funcs.h"
#include "../voxel_string_names.h"
VoxelStream::Result VoxelStreamScript::emerge_block(Ref<VoxelBuffer> out_buffer, Vector3i origin_in_voxels, int lod) {

View File

@ -1,4 +1,5 @@
#include "voxel_instance_generator.h"
#include "../../util/funcs.h"
#include "../../util/profiling.h"
#include <core/core_string_names.h>

View File

@ -2,7 +2,7 @@
#define VOXEL_INSTANCE_GENERATOR_H
//#include "../../storage/voxel_buffer.h"
#include "../../math/vector3i.h"
#include "../../util/math/vector3i.h"
#include "../../util/noise/fast_noise_lite.h"
#include <core/resource.h>

View File

@ -1,5 +1,6 @@
#include "voxel_instancer.h"
#include "../../edition/voxel_tool.h"
#include "../../util/funcs.h"
#include "../../util/macros.h"
#include "../../util/profiling.h"
#include "../voxel_lod_terrain.h"

View File

@ -1,11 +1,11 @@
#ifndef VOXEL_INSTANCER_H
#define VOXEL_INSTANCER_H
#include "../../math/rect3i.h"
#include "../../streams/instance_data.h"
#include "../../util/array_slice.h"
#include "../../util/direct_multimesh_instance.h"
#include "../../util/fixed_array.h"
#include "../../util/godot/direct_multimesh_instance.h"
#include "../../util/math/rect3i.h"
#include "voxel_instance_generator.h"
#include "voxel_instance_library.h"

View File

@ -1,8 +1,8 @@
#ifndef LOD_OCTREE_H
#define LOD_OCTREE_H
#include "../math/vector3i.h"
#include "../octree_tables.h"
#include "../util/math/vector3i.h"
#include "../voxel_constants.h"
// Octree designed to handle level of detail.

View File

@ -3,8 +3,8 @@
#include "../cube_tables.h"
#include "../storage/voxel_buffer.h"
#include "../util/direct_mesh_instance.h"
#include "../util/direct_static_body.h"
#include "../util/godot/direct_mesh_instance.h"
#include "../util/godot/direct_static_body.h"
#include "voxel_viewer_ref_count.h"
//#define VOXEL_DEBUG_LOD_MATERIALS

View File

@ -1,9 +1,11 @@
#include "voxel_lod_terrain.h"
#include "../edition/voxel_tool_lod_terrain.h"
#include "../math/rect3i.h"
#include "../meshers/transvoxel/voxel_mesher_transvoxel.h"
#include "../server/voxel_server.h"
#include "../util/funcs.h"
#include "../util/godot/funcs.h"
#include "../util/macros.h"
#include "../util/math/rect3i.h"
#include "../util/profiling.h"
#include "../util/profiling_clock.h"
#include "../voxel_string_names.h"

View File

@ -1,10 +1,11 @@
#include "voxel_terrain.h"
#include "../edition/voxel_tool_terrain.h"
#include "../server/voxel_server.h"
#include "../util/funcs.h"
#include "../util/godot/funcs.h"
#include "../util/macros.h"
#include "../util/profiling.h"
#include "../util/profiling_clock.h"
#include "../util/utility.h"
#include "../voxel_constants.h"
#include "../voxel_string_names.h"
#include "voxel_block.h"

118
util/funcs.h Normal file
View File

@ -0,0 +1,118 @@
#ifndef HEADER_VOXEL_UTILITY_H
#define HEADER_VOXEL_UTILITY_H
#include <core/pool_vector.h>
#include <core/vector.h>
#include <vector>
#ifdef DEBUG_ENABLED
#include <core/error_macros.h>
#endif
// Takes elements starting from a given position and moves them at the beginning,
// then shrink the array to fit them. Other elements are discarded.
template <typename T>
void shift_up(Vector<T> &v, unsigned int pos) {
unsigned int j = 0;
for (unsigned int i = pos; i < (unsigned int)v.size(); ++i, ++j) {
v.write[j] = v[i];
}
int remaining = v.size() - pos;
v.resize(remaining);
}
template <typename T>
void shift_up(std::vector<T> &v, unsigned int pos) {
unsigned int j = 0;
for (unsigned int i = pos; i < v.size(); ++i, ++j) {
v[j] = v[i];
}
int remaining = v.size() - pos;
v.resize(remaining);
}
// Pops the last element of the vector and place it at the given position.
// (The element that was at this position is the one removed).
template <typename T>
void unordered_remove(Vector<T> &v, unsigned int pos) {
int last = v.size() - 1;
v.write[pos] = v[last];
v.resize(last);
}
template <typename T>
void unordered_remove(std::vector<T> &v, unsigned int pos) {
v[pos] = v.back();
v.pop_back();
}
// Removes all items satisfying the given predicate.
// This can change the size of the container, and original order of items is not preserved.
template <typename T, typename F>
inline void unordered_remove_if(std::vector<T> &vec, F predicate) {
for (unsigned int i = 0; i < vec.size(); ++i) {
if (predicate(vec[i])) {
vec[i] = vec.back();
vec.pop_back();
// Note: can underflow, but it should be fine since it's incremented right after.
// TODO Use a while()?
--i;
}
}
}
template <typename T>
inline void unordered_remove_value(std::vector<T> &vec, T v) {
for (size_t i = 0; i < vec.size(); ++i) {
if (vec[i] == v) {
vec[i] = vec.back();
vec.pop_back();
break;
}
}
}
template <typename T>
inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
dst.insert(dst.end(), src.begin(), src.end());
}
// Removes all items satisfying the given predicate.
// This can reduce the size of the container. Items are moved to preserve order.
//template <typename T, typename F>
//inline void remove_if(std::vector<T> &vec, F predicate) {
// unsigned int j = 0;
// for (unsigned int i = 0; i < vec.size(); ++i) {
// if (predicate(vec[i])) {
// continue;
// } else {
// if (i != j) {
// vec[j] = vec[i];
// }
// ++j;
// }
// }
// vec.resize(j);
//}
template <typename T>
void copy_to(PoolVector<T> &to, const Vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
for (unsigned int i = 0; i < from.size(); ++i) {
w[i] = from[i];
}
}
inline String ptr2s(const void *p) {
return String::num_uint64((uint64_t)p, 16);
}
template <typename T>
void raw_copy_to(PoolVector<T> &to, const std::vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
memcpy(w.ptr(), from.data(), from.size() * sizeof(T));
}
#endif // HEADER_VOXEL_UTILITY_H

View File

@ -1,5 +1,5 @@
#include "direct_mesh_instance.h"
#include "profiling.h"
#include "../profiling.h"
#include <scene/resources/world.h>
DirectMeshInstance::DirectMeshInstance() {

View File

@ -1,5 +1,5 @@
#include "direct_multimesh_instance.h"
#include "profiling.h"
#include "../profiling.h"
#include <scene/resources/world.h>

View File

@ -1,7 +1,7 @@
#ifndef DIRECT_MULTIMESH_INSTANCE_H
#define DIRECT_MULTIMESH_INSTANCE_H
#include "array_slice.h"
#include "../array_slice.h"
#include <core/rid.h>
#include <scene/resources/multimesh.h>

View File

@ -1,5 +1,5 @@
#include "direct_static_body.h"
#include "profiling.h"
#include "../profiling.h"
#include <scene/resources/world.h>
#include <servers/physics/physics_server_sw.h>

View File

@ -1,5 +1,4 @@
#include "utility.h"
#include "../cube_tables.h"
#include "funcs.h"
#include <core/engine.h>
#include <scene/resources/mesh.h>
@ -24,7 +23,9 @@ bool is_mesh_empty(Ref<Mesh> mesh_ref) {
return false;
}
bool try_call_script(const Object *obj, StringName method_name, const Variant **args, unsigned int argc, Variant *out_ret) {
bool try_call_script(
const Object *obj, StringName method_name, const Variant **args, unsigned int argc, Variant *out_ret) {
ScriptInstance *script = obj->get_script_instance();
// TODO Is has_method() needed? I've seen `call()` being called anyways in ButtonBase
if (script == nullptr || !script->has_method(method_name)) {

21
util/godot/funcs.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef VOXEL_UTILITY_GODOT_FUNCS_H
#define VOXEL_UTILITY_GODOT_FUNCS_H
#include <core/reference.h>
#include <core/variant.h>
class Mesh;
bool is_surface_triangulated(Array surface);
bool is_mesh_empty(Ref<Mesh> mesh_ref);
bool try_call_script(
const Object *obj, StringName method_name, const Variant **args, unsigned int argc, Variant *out_ret);
inline bool try_call_script(
const Object *obj, StringName method_name, Variant arg0, Variant arg1, Variant arg2, Variant *out_ret) {
const Variant *args[3] = { &arg0, &arg1, &arg2 };
return try_call_script(obj, method_name, args, 3, out_ret);
}
#endif // VOXEL_UTILITY_GODOT_FUNCS_H

122
util/math/funcs.h Normal file
View File

@ -0,0 +1,122 @@
#ifndef VOXEL_MATH_FUNCS_H
#define VOXEL_MATH_FUNCS_H
#include <core/math/vector3.h>
// Trilinear interpolation between corner values of a cube.
// Cube points respect the same position as in octree_tables.h
template <typename T>
inline T interpolate(const T v0, const T v1, const T v2, const T v3, const T v4, const T v5, const T v6, const T v7,
Vector3 position) {
const float one_min_x = 1.f - position.x;
const float one_min_y = 1.f - position.y;
const float one_min_z = 1.f - position.z;
const float one_min_x_one_min_y = one_min_x * one_min_y;
const float x_one_min_y = position.x * one_min_y;
T res = one_min_z * (v0 * one_min_x_one_min_y + v1 * x_one_min_y + v4 * one_min_x * position.y);
res += position.z * (v3 * one_min_x_one_min_y + v2 * x_one_min_y + v7 * one_min_x * position.y);
res += position.x * position.y * (v5 * one_min_z + v6 * position.z);
return res;
}
template <typename T>
inline T min(const T a, const T b) {
return a < b ? a : b;
}
template <typename T>
inline T max(const T a, const T b) {
return a > b ? a : b;
}
template <typename T>
inline T min(const T a, const T b, const T c, const T d) {
return min(min(a, b), min(c, d));
}
template <typename T>
inline T max(const T a, const T b, const T c, const T d) {
return max(max(a, b), max(c, d));
}
template <typename T>
inline T clamp(const T x, const T min_value, const T max_value) {
if (x < min_value) {
return min_value;
}
if (x >= max_value) {
return max_value;
}
return x;
}
template <typename T>
inline T squared(const T x) {
return x * x;
}
template <typename T>
inline void sort_min_max(T &a, T &b) {
if (a > b) {
T temp = a;
a = b;
b = temp;
}
}
// TODO Rename udiv => floordiv
// Performs euclidean division, aka floored division.
// This implementation expects a strictly positive divisor.
//
// x | `/` | udiv
// ----------------------
// -6 | -2 | -2
// -5 | -1 | -2
// -4 | -1 | -2
// -3 | -1 | -1
// -2 | 0 | -1
// -1 | 0 | -1
// 0 | 0 | 0
// 1 | 0 | 0
// 2 | 0 | 0
// 3 | 1 | 1
// 4 | 1 | 1
// 5 | 1 | 1
// 6 | 2 | 2
inline int udiv(int x, int d) {
#ifdef DEBUG_ENABLED
CRASH_COND(d < 0);
#endif
if (x < 0) {
return (x - d + 1) / d;
} else {
return x / d;
}
}
// TODO Rename `wrapi`
// `Math::wrapi` with zero min
inline int wrap(int x, int d) {
return ((unsigned int)x - (x < 0)) % (unsigned int)d;
//return ((x % d) + d) % d;
}
// Math::wrapf with zero min
inline float wrapf(float x, float d) {
return Math::is_zero_approx(d) ? 0.f : x - (d * Math::floor(x / d));
}
// Similar to Math::smoothstep but doesn't use macro to clamp
inline float smoothstep(float p_from, float p_to, float p_weight) {
if (Math::is_equal_approx(p_from, p_to)) {
return p_from;
}
float x = clamp((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
return x * x * (3.0f - 2.0f * x);
}
#endif // VOXEL_MATH_FUNCS_H

View File

@ -1,7 +1,7 @@
#ifndef INTERVAL_H
#define INTERVAL_H
#include "../util/utility.h"
#include "funcs.h"
#include <limits>
// For interval arithmetic

View File

@ -1,9 +1,10 @@
#ifndef VOXEL_VECTOR3I_H
#define VOXEL_VECTOR3I_H
#include "../util/utility.h"
#include "funcs.h"
#include <core/hashfuncs.h>
#include <core/math/vector3.h>
#include <functional>
struct Vector3i {
static const unsigned int AXIS_X = 0;

View File

@ -1,6 +1,5 @@
#include "fast_noise_lite.h"
#include "../utility.h"
#include "../math/funcs.h"
#include <core/core_string_names.h>
FastNoiseLite::FastNoiseLite() {

View File

@ -1,249 +0,0 @@
#ifndef HEADER_VOXEL_UTILITY_H
#define HEADER_VOXEL_UTILITY_H
#include <core/math/vector3.h>
#include <core/pool_vector.h>
#include <core/reference.h>
#include <core/vector.h>
#include <vector>
#ifdef DEBUG_ENABLED
#include <core/error_macros.h>
#endif
class Mesh;
class Object;
// Takes elements starting from a given position and moves them at the beginning,
// then shrink the array to fit them. Other elements are discarded.
template <typename T>
void shift_up(Vector<T> &v, unsigned int pos) {
unsigned int j = 0;
for (unsigned int i = pos; i < (unsigned int)v.size(); ++i, ++j) {
v.write[j] = v[i];
}
int remaining = v.size() - pos;
v.resize(remaining);
}
template <typename T>
void shift_up(std::vector<T> &v, unsigned int pos) {
unsigned int j = 0;
for (unsigned int i = pos; i < v.size(); ++i, ++j) {
v[j] = v[i];
}
int remaining = v.size() - pos;
v.resize(remaining);
}
// Pops the last element of the vector and place it at the given position.
// (The element that was at this position is the one removed).
template <typename T>
void unordered_remove(Vector<T> &v, unsigned int pos) {
int last = v.size() - 1;
v.write[pos] = v[last];
v.resize(last);
}
template <typename T>
void unordered_remove(std::vector<T> &v, unsigned int pos) {
v[pos] = v.back();
v.pop_back();
}
// Removes all items satisfying the given predicate.
// This can change the size of the container, and original order of items is not preserved.
template <typename T, typename F>
inline void unordered_remove_if(std::vector<T> &vec, F predicate) {
for (unsigned int i = 0; i < vec.size(); ++i) {
if (predicate(vec[i])) {
vec[i] = vec.back();
vec.pop_back();
// Note: can underflow, but it should be fine since it's incremented right after.
// TODO Use a while()?
--i;
}
}
}
template <typename T>
inline void unordered_remove_value(std::vector<T> &vec, T v) {
for (size_t i = 0; i < vec.size(); ++i) {
if (vec[i] == v) {
vec[i] = vec.back();
vec.pop_back();
break;
}
}
}
// Removes all items satisfying the given predicate.
// This can reduce the size of the container. Items are moved to preserve order.
//template <typename T, typename F>
//inline void remove_if(std::vector<T> &vec, F predicate) {
// unsigned int j = 0;
// for (unsigned int i = 0; i < vec.size(); ++i) {
// if (predicate(vec[i])) {
// continue;
// } else {
// if (i != j) {
// vec[j] = vec[i];
// }
// ++j;
// }
// }
// vec.resize(j);
//}
template <typename T>
void copy_to(PoolVector<T> &to, const Vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
for (unsigned int i = 0; i < from.size(); ++i) {
w[i] = from[i];
}
}
inline String ptr2s(const void *p) {
return String::num_uint64((uint64_t)p, 16);
}
template <typename T>
void raw_copy_to(PoolVector<T> &to, const std::vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
memcpy(w.ptr(), from.data(), from.size() * sizeof(T));
}
// TODO Move math funcs under math/ folder and wrap them in a namespace
// Trilinear interpolation between corner values of a cube.
// Cube points respect the same position as in octree_tables.h
template <typename T>
inline T interpolate(const T v0, const T v1, const T v2, const T v3, const T v4, const T v5, const T v6, const T v7, Vector3 position) {
const float one_min_x = 1.f - position.x;
const float one_min_y = 1.f - position.y;
const float one_min_z = 1.f - position.z;
const float one_min_x_one_min_y = one_min_x * one_min_y;
const float x_one_min_y = position.x * one_min_y;
T res = one_min_z * (v0 * one_min_x_one_min_y + v1 * x_one_min_y + v4 * one_min_x * position.y);
res += position.z * (v3 * one_min_x_one_min_y + v2 * x_one_min_y + v7 * one_min_x * position.y);
res += position.x * position.y * (v5 * one_min_z + v6 * position.z);
return res;
}
template <typename T>
inline T min(const T a, const T b) {
return a < b ? a : b;
}
template <typename T>
inline T max(const T a, const T b) {
return a > b ? a : b;
}
template <typename T>
inline T min(const T a, const T b, const T c, const T d) {
return min(min(a, b), min(c, d));
}
template <typename T>
inline T max(const T a, const T b, const T c, const T d) {
return max(max(a, b), max(c, d));
}
template <typename T>
inline T clamp(const T x, const T min_value, const T max_value) {
if (x < min_value) {
return min_value;
}
if (x >= max_value) {
return max_value;
}
return x;
}
template <typename T>
inline T squared(const T x) {
return x * x;
}
template <typename T>
inline void sort_min_max(T &a, T &b) {
if (a > b) {
T temp = a;
a = b;
b = temp;
}
}
bool is_surface_triangulated(Array surface);
bool is_mesh_empty(Ref<Mesh> mesh_ref);
template <typename T>
inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
dst.insert(dst.end(), src.begin(), src.end());
}
// TODO Rename udiv => floordiv
// Performs euclidean division, aka floored division.
// This implementation expects a strictly positive divisor.
//
// x | `/` | udiv
// ----------------------
// -6 | -2 | -2
// -5 | -1 | -2
// -4 | -1 | -2
// -3 | -1 | -1
// -2 | 0 | -1
// -1 | 0 | -1
// 0 | 0 | 0
// 1 | 0 | 0
// 2 | 0 | 0
// 3 | 1 | 1
// 4 | 1 | 1
// 5 | 1 | 1
// 6 | 2 | 2
inline int udiv(int x, int d) {
#ifdef DEBUG_ENABLED
CRASH_COND(d < 0);
#endif
if (x < 0) {
return (x - d + 1) / d;
} else {
return x / d;
}
}
// TODO Rename `wrapi`
// `Math::wrapi` with zero min
inline int wrap(int x, int d) {
return ((unsigned int)x - (x < 0)) % (unsigned int)d;
//return ((x % d) + d) % d;
}
// Math::wrapf with zero min
inline float wrapf(float x, float d) {
return Math::is_zero_approx(d) ? 0.f : x - (d * Math::floor(x / d));
}
// Similar to Math::smoothstep but doesn't use macro to clamp
inline float smoothstep(float p_from, float p_to, float p_weight) {
if (Math::is_equal_approx(p_from, p_to)) {
return p_from;
}
float x = clamp((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
return x * x * (3.0f - 2.0f * x);
}
bool try_call_script(const Object *obj, StringName method_name, const Variant **args, unsigned int argc, Variant *out_ret);
inline bool try_call_script(const Object *obj, StringName method_name, Variant arg0, Variant arg1, Variant arg2, Variant *out_ret) {
const Variant *args[3] = { &arg0, &arg1, &arg2 };
return try_call_script(obj, method_name, args, 3, out_ret);
}
#endif // HEADER_VOXEL_UTILITY_H

View File

@ -1,4 +1,4 @@
#include "../math/vector3i.h"
#include "../util/math/vector3i.h"
#include "../util/profiling.h"
#include <core/math/vector3.h>