Moved some utility functions
- sort goes to math funcs - math funcs specializations for vector types go to vector files - use ZN macros in a few more places
This commit is contained in:
parent
1e380c14fb
commit
e9af708c3b
@ -2,6 +2,7 @@
|
||||
#define VOXEL_GRAPH_RUNTIME_H
|
||||
|
||||
#include "../../util/math/interval.h"
|
||||
#include "../../util/math/vector3f.h"
|
||||
#include "../../util/math/vector3i.h"
|
||||
#include "../../util/span.h"
|
||||
#include "code_gen_helper.h"
|
||||
|
@ -217,7 +217,7 @@ CellTextureDatas<NVoxels> select_textures_4_per_voxel(const FixedArray<unsigned
|
||||
// Sort indices to avoid cases that are ambiguous for blending, like 1,2,3,4 and 2,1,3,4
|
||||
// TODO maybe we could require this sorting to be done up front?
|
||||
// Or maybe could be done after meshing so we do it less times?
|
||||
sort(cell_textures.indices[0], cell_textures.indices[1], cell_textures.indices[2], cell_textures.indices[3]);
|
||||
math::sort(cell_textures.indices[0], cell_textures.indices[1], cell_textures.indices[2], cell_textures.indices[3]);
|
||||
|
||||
cell_textures.packed_indices = pack_bytes(cell_textures.indices);
|
||||
|
||||
|
@ -27,7 +27,7 @@ private:
|
||||
MutexLock lock(mutex);
|
||||
auto it = blocks.find(block);
|
||||
// Must not add twice
|
||||
CRASH_COND(it != blocks.end());
|
||||
ZN_ASSERT(it == blocks.end());
|
||||
blocks.insert(block);
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ private:
|
||||
MutexLock lock(mutex);
|
||||
auto it = blocks.find(block);
|
||||
// Must exist
|
||||
CRASH_COND(it == blocks.end());
|
||||
ZN_ASSERT(it != blocks.end());
|
||||
blocks.erase(it);
|
||||
}
|
||||
};
|
||||
@ -78,7 +78,7 @@ private:
|
||||
inline unsigned int get_pool_index_from_size(size_t size) const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
// `get_next_power_of_two_32` takes unsigned int
|
||||
CRASH_COND(size > std::numeric_limits<unsigned int>::max());
|
||||
ZN_ASSERT(size <= std::numeric_limits<unsigned int>::max());
|
||||
#endif
|
||||
return math::get_shift_from_power_of_two_32(math::get_next_power_of_two_32(size));
|
||||
}
|
||||
|
17
util/funcs.h
17
util/funcs.h
@ -2,7 +2,6 @@
|
||||
#define HEADER_VOXEL_UTILITY_H
|
||||
|
||||
#include "span.h"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace zylann {
|
||||
@ -90,22 +89,6 @@ size_t find_duplicate(Span<const T> items) {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void sort(T &a, T &b) {
|
||||
if (a > b) {
|
||||
std::swap(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void sort(T &a, T &b, T &c, T &d) {
|
||||
sort(a, b);
|
||||
sort(c, d);
|
||||
sort(a, c);
|
||||
sort(b, d);
|
||||
sort(b, c);
|
||||
}
|
||||
|
||||
// Tests if POD items in an array are all the same.
|
||||
// Better tailored for more than hundred items that have power-of-two size.
|
||||
template <typename Item_T>
|
||||
|
@ -2,44 +2,10 @@
|
||||
#define VOXEL_MATH_FUNCS_H
|
||||
|
||||
#include "../errors.h"
|
||||
#include "vector2f.h"
|
||||
#include "vector3f.h"
|
||||
|
||||
#include <core/math/vector3.h>
|
||||
#include <core/math/vector3i.h>
|
||||
#include <core/math/math_funcs.h>
|
||||
|
||||
namespace zylann::math {
|
||||
|
||||
// Trilinear interpolation between corner values of a cube.
|
||||
//
|
||||
// 6---------------7
|
||||
// /| /|
|
||||
// / | / |
|
||||
// 5---------------4 |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | 2------------|--3 Y
|
||||
// | / | / | Z
|
||||
// |/ |/ |/
|
||||
// 1---------------0 X----o
|
||||
//
|
||||
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,
|
||||
Vector3f 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;
|
||||
@ -146,7 +112,7 @@ inline T squared(const T x) {
|
||||
// 6 | 2 | 2
|
||||
inline int floordiv(int x, int d) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(d <= 0);
|
||||
ZN_ASSERT(d > 0);
|
||||
#endif
|
||||
if (x < 0) {
|
||||
return (x - d + 1) / d;
|
||||
@ -200,18 +166,6 @@ inline double fract(double x) {
|
||||
return x - Math::floor(x);
|
||||
}
|
||||
|
||||
inline Vector3 fract(const Vector3 &p) {
|
||||
return Vector3(fract(p.x), fract(p.y), fract(p.z));
|
||||
}
|
||||
|
||||
inline bool is_valid_size(const Vector3 &s) {
|
||||
return s.x >= 0 && s.y >= 0 && s.z >= 0;
|
||||
}
|
||||
|
||||
inline bool is_valid_size(const Vector3i &s) {
|
||||
return s.x >= 0 && s.y >= 0 && s.z >= 0;
|
||||
}
|
||||
|
||||
inline bool is_power_of_two(size_t x) {
|
||||
return x != 0 && (x & (x - 1)) == 0;
|
||||
}
|
||||
@ -241,7 +195,7 @@ inline unsigned int get_shift_from_power_of_two_32(unsigned int pot) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
CRASH_NOW_MSG("Input was not a valid power of two");
|
||||
ZN_CRASH_MSG("Input was not a valid power of two");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -254,29 +208,10 @@ inline size_t alignup(size_t a, size_t align) {
|
||||
return (a + align - 1) & ~(align - 1);
|
||||
}
|
||||
|
||||
inline bool has_nan(const Vector3 &v) {
|
||||
return Math::is_nan(v.x) || Math::is_nan(v.y) || Math::is_nan(v.z);
|
||||
}
|
||||
|
||||
// inline bool is_power_of_two(int i) {
|
||||
// return i & (i - 1);
|
||||
// }
|
||||
|
||||
// Float version of Geometry::is_point_in_triangle()
|
||||
inline bool is_point_in_triangle(const Vector2f &s, const Vector2f &a, const Vector2f &b, const Vector2f &c) {
|
||||
const Vector2f an = a - s;
|
||||
const Vector2f bn = b - s;
|
||||
const Vector2f cn = c - s;
|
||||
|
||||
const bool orientation = an.cross(bn) > 0;
|
||||
|
||||
if ((bn.cross(cn) > 0) != orientation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (cn.cross(an) > 0) == orientation;
|
||||
}
|
||||
|
||||
// Float equivalent of Math::snapped, which only comes in `double` variant in Godot.
|
||||
inline float snappedf(float p_value, float p_step) {
|
||||
if (p_step != 0) {
|
||||
@ -285,6 +220,22 @@ inline float snappedf(float p_value, float p_step) {
|
||||
return p_value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void sort(T &a, T &b) {
|
||||
if (a > b) {
|
||||
std::swap(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void sort(T &a, T &b, T &c, T &d) {
|
||||
sort(a, b);
|
||||
sort(c, d);
|
||||
sort(a, c);
|
||||
sort(b, d);
|
||||
sort(b, c);
|
||||
}
|
||||
|
||||
} // namespace zylann::math
|
||||
|
||||
#endif // VOXEL_MATH_FUNCS_H
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define VOXEL_MATH_SDF_H
|
||||
|
||||
#include "interval.h"
|
||||
#include "vector3.h"
|
||||
#include <core/math/vector2.h>
|
||||
|
||||
namespace zylann::math {
|
||||
|
@ -75,6 +75,24 @@ inline Vector2f operator*(float p_scalar, const Vector2f &v) {
|
||||
return v * p_scalar;
|
||||
}
|
||||
|
||||
namespace math {
|
||||
|
||||
// Float version of Geometry::is_point_in_triangle()
|
||||
inline bool is_point_in_triangle(const Vector2f &s, const Vector2f &a, const Vector2f &b, const Vector2f &c) {
|
||||
const Vector2f an = a - s;
|
||||
const Vector2f bn = b - s;
|
||||
const Vector2f cn = c - s;
|
||||
|
||||
const bool orientation = an.cross(bn) > 0;
|
||||
|
||||
if ((bn.cross(cn) > 0) != orientation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (cn.cross(an) > 0) == orientation;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace zylann
|
||||
|
||||
#endif // ZYLANN_VECTOR2F_H
|
||||
|
18
util/math/vector3.h
Normal file
18
util/math/vector3.h
Normal file
@ -0,0 +1,18 @@
|
||||
#include "funcs.h"
|
||||
#include <core/math/vector3.h>
|
||||
|
||||
namespace zylann::math {
|
||||
|
||||
inline Vector3 fract(const Vector3 &p) {
|
||||
return Vector3(fract(p.x), fract(p.y), fract(p.z));
|
||||
}
|
||||
|
||||
inline bool is_valid_size(const Vector3 &s) {
|
||||
return s.x >= 0 && s.y >= 0 && s.z >= 0;
|
||||
}
|
||||
|
||||
inline bool has_nan(const Vector3 &v) {
|
||||
return Math::is_nan(v.x) || Math::is_nan(v.y) || Math::is_nan(v.z);
|
||||
}
|
||||
|
||||
} // namespace zylann::math
|
@ -177,6 +177,39 @@ inline Vector3f operator*(float p_scalar, const Vector3f &v) {
|
||||
return v * p_scalar;
|
||||
}
|
||||
|
||||
namespace math {
|
||||
|
||||
// Trilinear interpolation between corner values of a cube.
|
||||
//
|
||||
// 6---------------7
|
||||
// /| /|
|
||||
// / | / |
|
||||
// 5---------------4 |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | 2------------|--3 Y
|
||||
// | / | / | Z
|
||||
// |/ |/ |/
|
||||
// 1---------------0 X----o
|
||||
//
|
||||
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,
|
||||
Vector3f 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;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace zylann
|
||||
|
||||
#endif // ZYLANN_VECTOR3F_H
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "funcs.h"
|
||||
|
||||
#include <core/math/vector3.h>
|
||||
#include <core/math/vector3i.h>
|
||||
#include <core/templates/hashfuncs.h>
|
||||
#include <iosfwd>
|
||||
|
||||
@ -294,9 +295,9 @@ inline Vector3i from_cast(const Vector3 &f) {
|
||||
}
|
||||
|
||||
inline void sort_min_max(Vector3i &a, Vector3i &b) {
|
||||
zylann::sort(a.x, b.x);
|
||||
zylann::sort(a.y, b.y);
|
||||
zylann::sort(a.z, b.z);
|
||||
math::sort(a.x, b.x);
|
||||
math::sort(a.y, b.y);
|
||||
math::sort(a.z, b.z);
|
||||
}
|
||||
|
||||
// Returning a 64-bit integer because volumes can quickly overflow INT_MAX (like 1300^3),
|
||||
@ -345,6 +346,10 @@ inline bool is_unit_vector(const Vector3i v) {
|
||||
return Math::abs(v.x) + Math::abs(v.y) + Math::abs(v.z) == 1;
|
||||
}
|
||||
|
||||
inline bool is_valid_size(const Vector3i &s) {
|
||||
return s.x >= 0 && s.y >= 0 && s.z >= 0;
|
||||
}
|
||||
|
||||
} // namespace zylann::Vector3iUtil
|
||||
|
||||
inline Vector3i operator<<(const Vector3i &a, int b) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "fast_noise_2.h"
|
||||
#include "../math/funcs.h"
|
||||
#include "../math/vector3.h"
|
||||
#include <core/io/image.h>
|
||||
|
||||
namespace zylann {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef VOXEL_VIEWER_REF_COUNT_H
|
||||
#define VOXEL_VIEWER_REF_COUNT_H
|
||||
|
||||
#include <core/error/error_macros.h>
|
||||
#include "errors.h"
|
||||
|
||||
namespace zylann {
|
||||
|
||||
@ -14,7 +14,7 @@ public:
|
||||
}
|
||||
|
||||
inline void remove() {
|
||||
ERR_FAIL_COND_MSG(_count == 0, "Trying to decrease refcount when it's already zero");
|
||||
ZN_ASSERT_RETURN_MSG(_count != 0, "Trying to decrease refcount when it's already zero");
|
||||
--_count;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user