2018-09-24 16:54:07 -07:00
|
|
|
#ifndef HEADER_VOXEL_UTILITY_H
|
|
|
|
#define HEADER_VOXEL_UTILITY_H
|
|
|
|
|
2019-04-20 17:14:28 -07:00
|
|
|
#include <core/pool_vector.h>
|
2019-04-13 10:47:35 -07:00
|
|
|
#include <core/ustring.h>
|
|
|
|
#include <core/vector.h>
|
2019-04-29 13:32:28 -07:00
|
|
|
#include <scene/resources/mesh.h>
|
2019-04-20 13:21:45 -07:00
|
|
|
#include <vector>
|
2018-09-24 16:54:07 -07:00
|
|
|
|
|
|
|
// 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>
|
2019-06-17 22:24:56 -07:00
|
|
|
void shift_up(Vector<T> &v, unsigned int pos) {
|
2018-09-24 16:54:07 -07:00
|
|
|
|
2019-06-17 22:24:56 -07:00
|
|
|
unsigned int j = 0;
|
|
|
|
for (unsigned int i = pos; i < (unsigned int)v.size(); ++i, ++j) {
|
2018-09-24 16:54:07 -07:00
|
|
|
v.write[j] = v[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
int remaining = v.size() - pos;
|
|
|
|
v.resize(remaining);
|
|
|
|
}
|
|
|
|
|
2019-05-03 16:02:10 -07:00
|
|
|
template <typename T>
|
2019-06-17 22:24:56 -07:00
|
|
|
void shift_up(std::vector<T> &v, unsigned int pos) {
|
2019-05-03 16:02:10 -07:00
|
|
|
|
2019-06-17 22:24:56 -07:00
|
|
|
unsigned int j = 0;
|
|
|
|
for (unsigned int i = pos; i < v.size(); ++i, ++j) {
|
2019-05-03 16:02:10 -07:00
|
|
|
v[j] = v[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
int remaining = v.size() - pos;
|
|
|
|
v.resize(remaining);
|
|
|
|
}
|
|
|
|
|
2018-09-24 16:54:07 -07:00
|
|
|
// 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>
|
2019-06-17 22:24:56 -07:00
|
|
|
void unordered_remove(Vector<T> &v, unsigned int pos) {
|
2018-09-24 16:54:07 -07:00
|
|
|
int last = v.size() - 1;
|
|
|
|
v.write[pos] = v[last];
|
|
|
|
v.resize(last);
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 16:31:09 -07:00
|
|
|
inline String ptr2s(const void *p) {
|
|
|
|
return String::num_uint64((uint64_t)p, 16);
|
|
|
|
}
|
|
|
|
|
2019-04-20 13:21:45 -07:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2019-04-21 11:31:35 -07:00
|
|
|
// Trilinear interpolation between corner values of a cube.
|
2019-04-28 09:58:29 -07:00
|
|
|
// Cube points respect the same position as in octree_tables.h
|
2019-04-21 11:31:35 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-04-22 12:15:46 -07:00
|
|
|
inline float min(const float &a, const float &b) {
|
|
|
|
return a < b ? a : b;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline float max(const float &a, const float &b) {
|
|
|
|
return a > b ? a : b;
|
|
|
|
}
|
|
|
|
|
2019-04-29 13:32:28 -07:00
|
|
|
inline bool is_mesh_empty(Ref<Mesh> mesh_ref) {
|
|
|
|
if (mesh_ref.is_null())
|
|
|
|
return true;
|
|
|
|
const Mesh &mesh = **mesh_ref;
|
|
|
|
if (mesh.get_surface_count() == 0)
|
|
|
|
return true;
|
|
|
|
if (mesh.surface_get_array_len(0) == 0)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-05-12 08:33:25 -07:00
|
|
|
template <typename T>
|
|
|
|
inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
|
|
|
|
dst.insert(dst.end(), src.begin(), src.end());
|
|
|
|
}
|
|
|
|
|
2019-05-27 16:40:09 -07:00
|
|
|
inline int udiv(int x, int d) {
|
|
|
|
if (x < 0) {
|
2019-06-01 17:46:41 -07:00
|
|
|
return (x - d + 1) / d;
|
2019-05-27 16:40:09 -07:00
|
|
|
} else {
|
|
|
|
return x / d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-14 15:25:05 -07:00
|
|
|
// `wrapi` with zero min
|
2019-08-17 11:34:40 -07:00
|
|
|
inline int wrap(int x, int d) {
|
2019-08-14 15:25:05 -07:00
|
|
|
return ((x % d) + d) % d;
|
2019-05-27 16:40:09 -07:00
|
|
|
}
|
|
|
|
|
2018-09-24 16:54:07 -07:00
|
|
|
#endif // HEADER_VOXEL_UTILITY_H
|