Configure clang-format to put a newline after template declarations
This commit is contained in:
parent
0c290082ff
commit
64415a3c86
@ -31,7 +31,7 @@ AllowShortFunctionsOnASingleLine: Empty
|
|||||||
# AlwaysBreakAfterDefinitionReturnType: None
|
# AlwaysBreakAfterDefinitionReturnType: None
|
||||||
# AlwaysBreakAfterReturnType: None
|
# AlwaysBreakAfterReturnType: None
|
||||||
# AlwaysBreakBeforeMultilineStrings: false
|
# AlwaysBreakBeforeMultilineStrings: false
|
||||||
# AlwaysBreakTemplateDeclarations: MultiLine
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
# AttributeMacros:
|
# AttributeMacros:
|
||||||
# - __capability
|
# - __capability
|
||||||
# BinPackArguments: true
|
# BinPackArguments: true
|
||||||
|
@ -11,7 +11,8 @@ class VoxelBuffer;
|
|||||||
|
|
||||||
namespace zylann::voxel::ops {
|
namespace zylann::voxel::ops {
|
||||||
|
|
||||||
template <typename Op, typename Shape> struct SdfOperation16bit {
|
template <typename Op, typename Shape>
|
||||||
|
struct SdfOperation16bit {
|
||||||
Op op;
|
Op op;
|
||||||
Shape shape;
|
Shape shape;
|
||||||
inline uint16_t operator()(Vector3i pos, uint16_t sdf) const {
|
inline uint16_t operator()(Vector3i pos, uint16_t sdf) const {
|
||||||
|
@ -9,7 +9,8 @@ namespace zylann {
|
|||||||
// Stores uniquely-identified structs in a packed array.
|
// Stores uniquely-identified structs in a packed array.
|
||||||
// Always use the IDs if you want to store a reference somewhere. Addresses aren't stable.
|
// Always use the IDs if you want to store a reference somewhere. Addresses aren't stable.
|
||||||
// IDs are made unique with a generation system.
|
// IDs are made unique with a generation system.
|
||||||
template <typename T> class StructDB {
|
template <typename T>
|
||||||
|
class StructDB {
|
||||||
private:
|
private:
|
||||||
struct Slot {
|
struct Slot {
|
||||||
T data;
|
T data;
|
||||||
@ -130,7 +131,8 @@ public:
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> inline void for_each(F f) {
|
template <typename F>
|
||||||
|
inline void for_each(F f) {
|
||||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||||
Slot &s = _slots[i];
|
Slot &s = _slots[i];
|
||||||
if (s.valid) {
|
if (s.valid) {
|
||||||
@ -139,7 +141,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> inline void for_each(F f) const {
|
template <typename F>
|
||||||
|
inline void for_each(F f) const {
|
||||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||||
const Slot &s = _slots[i];
|
const Slot &s = _slots[i];
|
||||||
if (s.valid) {
|
if (s.valid) {
|
||||||
@ -148,7 +151,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> inline void for_each_with_id(F f) {
|
template <typename F>
|
||||||
|
inline void for_each_with_id(F f) {
|
||||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||||
Slot &s = _slots[i];
|
Slot &s = _slots[i];
|
||||||
if (s.valid) {
|
if (s.valid) {
|
||||||
@ -157,7 +161,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> inline void for_each_with_id(F f) const {
|
template <typename F>
|
||||||
|
inline void for_each_with_id(F f) const {
|
||||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||||
const Slot &s = _slots[i];
|
const Slot &s = _slots[i];
|
||||||
if (s.valid) {
|
if (s.valid) {
|
||||||
|
@ -134,7 +134,8 @@ public:
|
|||||||
bool is_viewer_requiring_collisions(uint32_t viewer_id) const;
|
bool is_viewer_requiring_collisions(uint32_t viewer_id) const;
|
||||||
bool viewer_exists(uint32_t viewer_id) const;
|
bool viewer_exists(uint32_t viewer_id) const;
|
||||||
|
|
||||||
template <typename F> inline void for_each_viewer(F f) const {
|
template <typename F>
|
||||||
|
inline void for_each_viewer(F f) const {
|
||||||
_world.viewers.for_each_with_id(f);
|
_world.viewers.for_each_with_id(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <> struct hash<String> {
|
template <>
|
||||||
|
struct hash<String> {
|
||||||
size_t operator()(const String &v) const {
|
size_t operator()(const String &v) const {
|
||||||
return v.hash();
|
return v.hash();
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,14 @@ size_t get_metadata_size_in_bytes(const VoxelBufferInternal &buffer) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline void write(uint8_t *&dst, T d) {
|
template <typename T>
|
||||||
|
inline void write(uint8_t *&dst, T d) {
|
||||||
*(T *)dst = d;
|
*(T *)dst = d;
|
||||||
dst += sizeof(T);
|
dst += sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T read(uint8_t *&src) {
|
template <typename T>
|
||||||
|
inline T read(uint8_t *&src) {
|
||||||
T d = *(T *)src;
|
T d = *(T *)src;
|
||||||
src += sizeof(T);
|
src += sizeof(T);
|
||||||
return d;
|
return d;
|
||||||
|
@ -53,8 +53,7 @@ public:
|
|||||||
// TODO Merge support functions into a single getter with Feature bitmask
|
// TODO Merge support functions into a single getter with Feature bitmask
|
||||||
virtual bool supports_instance_blocks() const;
|
virtual bool supports_instance_blocks() const;
|
||||||
|
|
||||||
virtual void load_instance_blocks(
|
virtual void load_instance_blocks(Span<VoxelStreamInstanceDataRequest> out_blocks, Span<Result> out_results);
|
||||||
Span<VoxelStreamInstanceDataRequest> out_blocks, Span<Result> out_results);
|
|
||||||
|
|
||||||
virtual void save_instance_blocks(Span<VoxelStreamInstanceDataRequest> p_blocks);
|
virtual void save_instance_blocks(Span<VoxelStreamInstanceDataRequest> p_blocks);
|
||||||
|
|
||||||
@ -68,7 +67,9 @@ public:
|
|||||||
std::vector<Block> blocks;
|
std::vector<Block> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool supports_loading_all_blocks() const { return false; }
|
virtual bool supports_loading_all_blocks() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void load_all_blocks(FullLoadingResult &result);
|
virtual void load_all_blocks(FullLoadingResult &result);
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ public:
|
|||||||
inline void operator()(Vector3i node_pos, int lod) {}
|
inline void operator()(Vector3i node_pos, int lod) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DestroyAction_T> void clear(DestroyAction_T &destroy_action) {
|
template <typename DestroyAction_T>
|
||||||
|
void clear(DestroyAction_T &destroy_action) {
|
||||||
join_all_recursively(&_root, Vector3i(), _max_depth, destroy_action);
|
join_all_recursively(&_root, Vector3i(), _max_depth, destroy_action);
|
||||||
_is_root_created = false;
|
_is_root_created = false;
|
||||||
_max_depth = 0;
|
_max_depth = 0;
|
||||||
@ -116,7 +117,8 @@ public:
|
|||||||
// Nodes may be subdivided if conditions are met, or unsubdivided if they aren't.
|
// Nodes may be subdivided if conditions are met, or unsubdivided if they aren't.
|
||||||
// This is not fully recursive. It is expected to be called over several frames,
|
// This is not fully recursive. It is expected to be called over several frames,
|
||||||
// so the shape is obtained progressively.
|
// so the shape is obtained progressively.
|
||||||
template <typename UpdateActions_T> void update(Vector3 view_pos, UpdateActions_T &actions) {
|
template <typename UpdateActions_T>
|
||||||
|
void update(Vector3 view_pos, UpdateActions_T &actions) {
|
||||||
if (_is_root_created || _root.has_children()) {
|
if (_is_root_created || _root.has_children()) {
|
||||||
update(ROOT_INDEX, Vector3i(), _max_depth, view_pos, actions);
|
update(ROOT_INDEX, Vector3i(), _max_depth, view_pos, actions);
|
||||||
} else {
|
} else {
|
||||||
@ -148,7 +150,8 @@ public:
|
|||||||
// The box is given in unit coordinates of the octree (1 unit is the size of a leaf node at maximum depth).
|
// The box is given in unit coordinates of the octree (1 unit is the size of a leaf node at maximum depth).
|
||||||
// Returns true if the predicate matches any node, false otherwise.
|
// Returns true if the predicate matches any node, false otherwise.
|
||||||
// predicate: `bool is_match(Vector3i node_pos, int lod_index, const NodeData &data)`
|
// predicate: `bool is_match(Vector3i node_pos, int lod_index, const NodeData &data)`
|
||||||
template <typename Predicate_T> bool find_in_box(Box3i box, Predicate_T predicate) const {
|
template <typename Predicate_T>
|
||||||
|
bool find_in_box(Box3i box, Predicate_T predicate) const {
|
||||||
Box3i root_box(Vector3i(), Vector3iUtil::create(1 << _max_depth));
|
Box3i root_box(Vector3i(), Vector3iUtil::create(1 << _max_depth));
|
||||||
box.clip(root_box);
|
box.clip(root_box);
|
||||||
return find_in_box_recursive(box, Vector3i(), ROOT_INDEX, _max_depth, predicate);
|
return find_in_box_recursive(box, Vector3i(), ROOT_INDEX, _max_depth, predicate);
|
||||||
@ -156,7 +159,8 @@ public:
|
|||||||
|
|
||||||
// Executes a function on all leaf nodes intersecting the box.
|
// Executes a function on all leaf nodes intersecting the box.
|
||||||
// f: `void f(Vector3i node_pos, int lod_index, NodeData &data)`
|
// f: `void f(Vector3i node_pos, int lod_index, NodeData &data)`
|
||||||
template <typename F> void for_leaves_in_box(Box3i box, F f) {
|
template <typename F>
|
||||||
|
void for_leaves_in_box(Box3i box, F f) {
|
||||||
Box3i root_box(Vector3i(), Vector3iUtil::create(1 << _max_depth));
|
Box3i root_box(Vector3i(), Vector3iUtil::create(1 << _max_depth));
|
||||||
box.clip(root_box);
|
box.clip(root_box);
|
||||||
return for_leaves_in_box_recursive(box, Vector3i(), ROOT_INDEX, _max_depth, f);
|
return for_leaves_in_box_recursive(box, Vector3i(), ROOT_INDEX, _max_depth, f);
|
||||||
@ -164,7 +168,8 @@ public:
|
|||||||
|
|
||||||
// Executes a function on all leaf nodes of the octree.
|
// Executes a function on all leaf nodes of the octree.
|
||||||
// f: `void f(Vector3i node_pos, int lod_index, const NodeData &data)`
|
// f: `void f(Vector3i node_pos, int lod_index, const NodeData &data)`
|
||||||
template <typename F> void for_each_leaf(F f) const {
|
template <typename F>
|
||||||
|
void for_each_leaf(F f) const {
|
||||||
return for_each_leaf_recursive(Vector3i(), ROOT_INDEX, _max_depth, f);
|
return for_each_leaf_recursive(Vector3i(), ROOT_INDEX, _max_depth, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +186,8 @@ public:
|
|||||||
|
|
||||||
// Subdivides the octree recursively, solely based on `can_split`.
|
// Subdivides the octree recursively, solely based on `can_split`.
|
||||||
// Does not unsubdivide existing nodes.
|
// Does not unsubdivide existing nodes.
|
||||||
template <typename Actions_T> void subdivide(Actions_T &actions) {
|
template <typename Actions_T>
|
||||||
|
void subdivide(Actions_T &actions) {
|
||||||
if (!_is_root_created && actions.can_split(Vector3i(), _max_depth, _root.data)) {
|
if (!_is_root_created && actions.can_split(Vector3i(), _max_depth, _root.data)) {
|
||||||
actions.create_child(Vector3i(), _max_depth, _root.data);
|
actions.create_child(Vector3i(), _max_depth, _root.data);
|
||||||
_is_root_created = true;
|
_is_root_created = true;
|
||||||
@ -398,7 +404,8 @@ private:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> void for_each_leaf_recursive(Vector3i node_pos, int node_index, int depth, F f) const {
|
template <typename F>
|
||||||
|
void for_each_leaf_recursive(Vector3i node_pos, int node_index, int depth, F f) const {
|
||||||
const Node *node = get_node(node_index);
|
const Node *node = get_node(node_index);
|
||||||
if (node->has_children()) {
|
if (node->has_children()) {
|
||||||
const int first_child_index = node->first_child;
|
const int first_child_index = node->first_child;
|
||||||
|
@ -88,7 +88,8 @@ public:
|
|||||||
bool try_set_voxel_without_update(Vector3i pos, unsigned int channel, uint64_t value);
|
bool try_set_voxel_without_update(Vector3i pos, unsigned int channel, uint64_t value);
|
||||||
void copy(Vector3i p_origin_voxels, VoxelBufferInternal &dst_buffer, uint8_t channels_mask);
|
void copy(Vector3i p_origin_voxels, VoxelBufferInternal &dst_buffer, uint8_t channels_mask);
|
||||||
|
|
||||||
template <typename F> void write_box(const Box3i &p_voxel_box, unsigned int channel, F action) {
|
template <typename F>
|
||||||
|
void write_box(const Box3i &p_voxel_box, unsigned int channel, F action) {
|
||||||
const Box3i voxel_box = p_voxel_box.clipped(_bounds_in_voxels);
|
const Box3i voxel_box = p_voxel_box.clipped(_bounds_in_voxels);
|
||||||
if (_full_load_mode == false && !is_area_editable(voxel_box)) {
|
if (_full_load_mode == false && !is_area_editable(voxel_box)) {
|
||||||
PRINT_VERBOSE("Area not editable");
|
PRINT_VERBOSE("Area not editable");
|
||||||
|
@ -97,7 +97,8 @@ public:
|
|||||||
return _transition_mask;
|
return _transition_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> void for_each_mesh_instance_with_transform(F f) const {
|
template <typename F>
|
||||||
|
void for_each_mesh_instance_with_transform(F f) const {
|
||||||
const Transform3D local_transform(Basis(), _position_in_voxels);
|
const Transform3D local_transform(Basis(), _position_in_voxels);
|
||||||
const Transform3D world_transform = local_transform;
|
const Transform3D world_transform = local_transform;
|
||||||
f(_mesh_instance, world_transform);
|
f(_mesh_instance, world_transform);
|
||||||
|
@ -18,10 +18,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline Vector3i to_local(Vector3i pos) const {
|
inline Vector3i to_local(Vector3i pos) const {
|
||||||
return Vector3i(
|
return Vector3i(pos.x & _block_size_mask, pos.y & _block_size_mask, pos.z & _block_size_mask);
|
||||||
pos.x & _block_size_mask,
|
|
||||||
pos.y & _block_size_mask,
|
|
||||||
pos.z & _block_size_mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts block coodinates into voxel coordinates
|
// Converts block coodinates into voxel coordinates
|
||||||
@ -34,9 +31,15 @@ public:
|
|||||||
|
|
||||||
void create(unsigned int block_size_po2, int lod_index);
|
void create(unsigned int block_size_po2, int lod_index);
|
||||||
|
|
||||||
inline unsigned int get_block_size() const { return _block_size; }
|
inline unsigned int get_block_size() const {
|
||||||
inline unsigned int get_block_size_pow2() const { return _block_size_pow2; }
|
return _block_size;
|
||||||
inline unsigned int get_block_size_mask() const { return _block_size_mask; }
|
}
|
||||||
|
inline unsigned int get_block_size_pow2() const {
|
||||||
|
return _block_size_pow2;
|
||||||
|
}
|
||||||
|
inline unsigned int get_block_size_mask() const {
|
||||||
|
return _block_size_mask;
|
||||||
|
}
|
||||||
|
|
||||||
void set_lod_index(int lod_index);
|
void set_lod_index(int lod_index);
|
||||||
unsigned int get_lod_index() const;
|
unsigned int get_lod_index() const;
|
||||||
|
@ -19,7 +19,8 @@ enum Tests { //
|
|||||||
|
|
||||||
// Sample a maximum change across the given step.
|
// Sample a maximum change across the given step.
|
||||||
// The result is not normalized for performance.
|
// The result is not normalized for performance.
|
||||||
template <typename F2, typename FloatT> FloatT get_derivative(FloatT x, FloatT y, FloatT step, F2 noise_func_2d) {
|
template <typename F2, typename FloatT>
|
||||||
|
FloatT get_derivative(FloatT x, FloatT y, FloatT step, F2 noise_func_2d) {
|
||||||
FloatT n0, n1, d;
|
FloatT n0, n1, d;
|
||||||
FloatT max_derivative = 0.0;
|
FloatT max_derivative = 0.0;
|
||||||
|
|
||||||
@ -68,7 +69,8 @@ FloatT get_derivative(FloatT x, FloatT y, FloatT z, FloatT step, F3 noise_func_3
|
|||||||
return max_derivative;
|
return max_derivative;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F2, typename F3, typename FloatT> void test_min_max(F2 noise_func_2d, F3 noise_func_3d) {
|
template <typename F2, typename F3, typename FloatT>
|
||||||
|
void test_min_max(F2 noise_func_2d, F3 noise_func_3d) {
|
||||||
FloatT min_value_2d = std::numeric_limits<FloatT>::max();
|
FloatT min_value_2d = std::numeric_limits<FloatT>::max();
|
||||||
FloatT max_value_2d = std::numeric_limits<FloatT>::min();
|
FloatT max_value_2d = std::numeric_limits<FloatT>::min();
|
||||||
|
|
||||||
@ -96,7 +98,8 @@ template <typename F2, typename F3, typename FloatT> void test_min_max(F2 noise_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generic analysis for noise functions
|
// Generic analysis for noise functions
|
||||||
template <typename F2, typename F3, typename FloatT> void test_derivatives_tpl(F2 noise_func_2d, F3 noise_func_3d) {
|
template <typename F2, typename F3, typename FloatT>
|
||||||
|
void test_derivatives_tpl(F2 noise_func_2d, F3 noise_func_3d) {
|
||||||
const int iterations = ITERATIONS;
|
const int iterations = ITERATIONS;
|
||||||
const int step_resolution_count = STEP_RESOLUTION_COUNT;
|
const int step_resolution_count = STEP_RESOLUTION_COUNT;
|
||||||
const FloatT step_min = STEP_MIN;
|
const FloatT step_min = STEP_MIN;
|
||||||
@ -166,7 +169,8 @@ template <typename F2, typename F3, typename FloatT> void test_derivatives_tpl(F
|
|||||||
print_line(String("Min max derivative: {0}").format(varray(min_max_derivative)));
|
print_line(String("Min max derivative: {0}").format(varray(min_max_derivative)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F3> void test_derivatives_with_image(String fpath, double step, F3 noise_func_3d) {
|
template <typename F3>
|
||||||
|
void test_derivatives_with_image(String fpath, double step, F3 noise_func_3d) {
|
||||||
const double x_min = 500.0;
|
const double x_min = 500.0;
|
||||||
const double y = 500.0;
|
const double y = 500.0;
|
||||||
const double z_min = 500.0;
|
const double z_min = 500.0;
|
||||||
@ -200,7 +204,8 @@ template <typename F3> void test_derivatives_with_image(String fpath, double ste
|
|||||||
im->save_png(fpath);
|
im->save_png(fpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F3> void test_derivatives_with_image(String fname, int steps_resolution, F3 noise_func_3d) {
|
template <typename F3>
|
||||||
|
void test_derivatives_with_image(String fname, int steps_resolution, F3 noise_func_3d) {
|
||||||
for (int i = 0; i < steps_resolution; ++i) {
|
for (int i = 0; i < steps_resolution; ++i) {
|
||||||
const double step =
|
const double step =
|
||||||
Math::lerp(STEP_MIN, STEP_MAX, static_cast<double>(i) / static_cast<double>(steps_resolution));
|
Math::lerp(STEP_MIN, STEP_MAX, static_cast<double>(i) / static_cast<double>(steps_resolution));
|
||||||
@ -209,7 +214,8 @@ template <typename F3> void test_derivatives_with_image(String fname, int steps_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F2, typename F3> void test_noise(String name, int tests, F2 noise_func_2d, F3 noise_func_3d) {
|
template <typename F2, typename F3>
|
||||||
|
void test_noise(String name, int tests, F2 noise_func_2d, F3 noise_func_3d) {
|
||||||
print_line(String("--- {0}:").format(varray(name)));
|
print_line(String("--- {0}:").format(varray(name)));
|
||||||
|
|
||||||
if (tests & TEST_MIN_MAX) {
|
if (tests & TEST_MIN_MAX) {
|
||||||
|
33
util/funcs.h
33
util/funcs.h
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
// Takes elements starting from a given position and moves them at the beginning,
|
// Takes elements starting from a given position and moves them at the beginning,
|
||||||
// then shrink the array to fit them. Other elements are discarded.
|
// then shrink the array to fit them. Other elements are discarded.
|
||||||
template <typename T> void shift_up(Vector<T> &v, unsigned int pos) {
|
template <typename T>
|
||||||
|
void shift_up(Vector<T> &v, unsigned int pos) {
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
for (unsigned int i = pos; i < (unsigned int)v.size(); ++i, ++j) {
|
for (unsigned int i = pos; i < (unsigned int)v.size(); ++i, ++j) {
|
||||||
v.write[j] = v[i];
|
v.write[j] = v[i];
|
||||||
@ -21,7 +22,8 @@ template <typename T> void shift_up(Vector<T> &v, unsigned int pos) {
|
|||||||
v.resize(remaining);
|
v.resize(remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void shift_up(std::vector<T> &v, unsigned int pos) {
|
template <typename T>
|
||||||
|
void shift_up(std::vector<T> &v, unsigned int pos) {
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
for (unsigned int i = pos; i < v.size(); ++i, ++j) {
|
for (unsigned int i = pos; i < v.size(); ++i, ++j) {
|
||||||
v[j] = v[i];
|
v[j] = v[i];
|
||||||
@ -32,20 +34,23 @@ template <typename T> void shift_up(std::vector<T> &v, unsigned int pos) {
|
|||||||
|
|
||||||
// Pops the last element of the vector and place it at the given position.
|
// 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).
|
// (The element that was at this position is the one removed).
|
||||||
template <typename T> void unordered_remove(Vector<T> &v, unsigned int pos) {
|
template <typename T>
|
||||||
|
void unordered_remove(Vector<T> &v, unsigned int pos) {
|
||||||
int last = v.size() - 1;
|
int last = v.size() - 1;
|
||||||
v.write[pos] = v[last];
|
v.write[pos] = v[last];
|
||||||
v.resize(last);
|
v.resize(last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void unordered_remove(std::vector<T> &v, unsigned int pos) {
|
template <typename T>
|
||||||
|
void unordered_remove(std::vector<T> &v, unsigned int pos) {
|
||||||
v[pos] = v.back();
|
v[pos] = v.back();
|
||||||
v.pop_back();
|
v.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes all items satisfying the given predicate.
|
// Removes all items satisfying the given predicate.
|
||||||
// This can change the size of the container, and original order of items is not preserved.
|
// 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) {
|
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) {
|
for (unsigned int i = 0; i < vec.size(); ++i) {
|
||||||
if (predicate(vec[i])) {
|
if (predicate(vec[i])) {
|
||||||
vec[i] = vec.back();
|
vec[i] = vec.back();
|
||||||
@ -57,7 +62,8 @@ template <typename T, typename F> inline void unordered_remove_if(std::vector<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline bool unordered_remove_value(std::vector<T> &vec, T v) {
|
template <typename T>
|
||||||
|
inline bool unordered_remove_value(std::vector<T> &vec, T v) {
|
||||||
for (size_t i = 0; i < vec.size(); ++i) {
|
for (size_t i = 0; i < vec.size(); ++i) {
|
||||||
if (vec[i] == v) {
|
if (vec[i] == v) {
|
||||||
vec[i] = vec.back();
|
vec[i] = vec.back();
|
||||||
@ -68,7 +74,8 @@ template <typename T> inline bool unordered_remove_value(std::vector<T> &vec, T
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
|
template <typename T>
|
||||||
|
inline void append_array(std::vector<T> &dst, const std::vector<T> &src) {
|
||||||
dst.insert(dst.end(), src.begin(), src.end());
|
dst.insert(dst.end(), src.begin(), src.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,20 +101,23 @@ inline String ptr2s(const void *p) {
|
|||||||
return String::num_uint64((uint64_t)p, 16);
|
return String::num_uint64((uint64_t)p, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void raw_copy_to(Vector<T> &to, const std::vector<T> &from) {
|
template <typename T>
|
||||||
|
void raw_copy_to(Vector<T> &to, const std::vector<T> &from) {
|
||||||
to.resize(from.size());
|
to.resize(from.size());
|
||||||
// resize can fail in case allocation was not possible
|
// resize can fail in case allocation was not possible
|
||||||
ERR_FAIL_COND(from.size() != static_cast<size_t>(to.size()));
|
ERR_FAIL_COND(from.size() != static_cast<size_t>(to.size()));
|
||||||
memcpy(to.ptrw(), from.data(), from.size() * sizeof(T));
|
memcpy(to.ptrw(), from.data(), from.size() * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline void sort(T &a, T &b) {
|
template <typename T>
|
||||||
|
inline void sort(T &a, T &b) {
|
||||||
if (a > b) {
|
if (a > b) {
|
||||||
std::swap(a, b);
|
std::swap(a, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline void sort(T &a, T &b, T &c, T &d) {
|
template <typename T>
|
||||||
|
inline void sort(T &a, T &b, T &c, T &d) {
|
||||||
sort(a, b);
|
sort(a, b);
|
||||||
sort(c, d);
|
sort(c, d);
|
||||||
sort(a, c);
|
sort(a, c);
|
||||||
@ -117,7 +127,8 @@ template <typename T> inline void sort(T &a, T &b, T &c, T &d) {
|
|||||||
|
|
||||||
// Tests if POD items in an array are all the same.
|
// Tests if POD items in an array are all the same.
|
||||||
// Better tailored for more than hundred items that have power-of-two size.
|
// Better tailored for more than hundred items that have power-of-two size.
|
||||||
template <typename Item_T> inline bool is_uniform(const Item_T *p_data, size_t item_count) {
|
template <typename Item_T>
|
||||||
|
inline bool is_uniform(const Item_T *p_data, size_t item_count) {
|
||||||
const Item_T v0 = p_data[0];
|
const Item_T v0 = p_data[0];
|
||||||
|
|
||||||
//typedef size_t Bucket_T;
|
//typedef size_t Bucket_T;
|
||||||
|
@ -234,7 +234,8 @@ Array generate_debug_seams_wireframe_surface(Ref<Mesh> src_mesh, int surface_ind
|
|||||||
// return wire_mesh;
|
// return wire_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F> void for_each_node_depth_first(Node *parent, F f) {
|
template <typename F>
|
||||||
|
void for_each_node_depth_first(Node *parent, F f) {
|
||||||
ERR_FAIL_COND(parent == nullptr);
|
ERR_FAIL_COND(parent == nullptr);
|
||||||
f(parent);
|
f(parent);
|
||||||
for (int i = 0; i < parent->get_child_count(); ++i) {
|
for (int i = 0; i < parent->get_child_count(); ++i) {
|
||||||
|
@ -34,18 +34,21 @@ Array generate_debug_seams_wireframe_surface(Ref<Mesh> src_mesh, int surface_ind
|
|||||||
|
|
||||||
// `(ref1 = ref2).is_valid()` does not work because Ref<T> does not implement an `operator=` returning the value.
|
// `(ref1 = ref2).is_valid()` does not work because Ref<T> does not implement an `operator=` returning the value.
|
||||||
// So instead we can write it as `try_get_as(ref2, ref1)`
|
// So instead we can write it as `try_get_as(ref2, ref1)`
|
||||||
template <typename From_T, typename To_T> inline bool try_get_as(Ref<From_T> from, Ref<To_T> &to) {
|
template <typename From_T, typename To_T>
|
||||||
|
inline bool try_get_as(Ref<From_T> from, Ref<To_T> &to) {
|
||||||
to = from;
|
to = from;
|
||||||
return to.is_valid();
|
return to.is_valid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a shared_ptr which will use Godot's allocation functions
|
// Creates a shared_ptr which will use Godot's allocation functions
|
||||||
template <typename T> inline std::shared_ptr<T> gd_make_shared() {
|
template <typename T>
|
||||||
|
inline std::shared_ptr<T> gd_make_shared() {
|
||||||
// std::make_shared() apparently wont allow us to specify custom new and delete
|
// std::make_shared() apparently wont allow us to specify custom new and delete
|
||||||
return std::shared_ptr<T>(memnew(T), memdelete<T>);
|
return std::shared_ptr<T>(memnew(T), memdelete<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Arg_T> inline std::shared_ptr<T> gd_make_shared(Arg_T arg) {
|
template <typename T, typename Arg_T>
|
||||||
|
inline std::shared_ptr<T> gd_make_shared(Arg_T arg) {
|
||||||
return std::shared_ptr<T>(memnew(T(arg)), memdelete<T>);
|
return std::shared_ptr<T>(memnew(T(arg)), memdelete<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +65,8 @@ inline std::shared_ptr<T> gd_make_shared(Arg0_T arg0, Arg1_T arg1, Arg2_T arg2)
|
|||||||
void set_nodes_owner(Node *root, Node *owner);
|
void set_nodes_owner(Node *root, Node *owner);
|
||||||
void set_nodes_owner_except_root(Node *root, Node *owner);
|
void set_nodes_owner_except_root(Node *root, Node *owner);
|
||||||
|
|
||||||
template <typename T> struct RefHasher {
|
template <typename T>
|
||||||
|
struct RefHasher {
|
||||||
static _FORCE_INLINE_ uint32_t hash(const Ref<T> &v) {
|
static _FORCE_INLINE_ uint32_t hash(const Ref<T> &v) {
|
||||||
return uint32_t(uint64_t(v.ptr())) * (0x9e3779b1L);
|
return uint32_t(uint64_t(v.ptr())) * (0x9e3779b1L);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,8 @@ public:
|
|||||||
inline void operator()(const Vector3i pos) {}
|
inline void operator()(const Vector3i pos) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename A> inline void for_each_cell(A a) const {
|
template <typename A>
|
||||||
|
inline void for_each_cell(A a) const {
|
||||||
const Vector3i max = pos + size;
|
const Vector3i max = pos + size;
|
||||||
Vector3i p;
|
Vector3i p;
|
||||||
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
||||||
@ -110,7 +111,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename A> inline void for_each_cell_zxy(A a) const {
|
template <typename A>
|
||||||
|
inline void for_each_cell_zxy(A a) const {
|
||||||
const Vector3i max = pos + size;
|
const Vector3i max = pos + size;
|
||||||
Vector3i p;
|
Vector3i p;
|
||||||
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
||||||
@ -123,7 +125,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if all cells of the box comply with the given predicate on their position.
|
// Returns true if all cells of the box comply with the given predicate on their position.
|
||||||
template <typename A> inline bool all_cells_match(A a) const {
|
template <typename A>
|
||||||
|
inline bool all_cells_match(A a) const {
|
||||||
const Vector3i max = pos + size;
|
const Vector3i max = pos + size;
|
||||||
Vector3i p;
|
Vector3i p;
|
||||||
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
for (p.z = pos.z; p.z < max.z; ++p.z) {
|
||||||
@ -151,7 +154,8 @@ public:
|
|||||||
// | B |
|
// | B |
|
||||||
// o---------o
|
// o---------o
|
||||||
//
|
//
|
||||||
template <typename A> void difference(const Box3i &b, A action) const {
|
template <typename A>
|
||||||
|
void difference(const Box3i &b, A action) const {
|
||||||
if (!intersects(b)) {
|
if (!intersects(b)) {
|
||||||
action(*this);
|
action(*this);
|
||||||
return;
|
return;
|
||||||
@ -214,7 +218,8 @@ public:
|
|||||||
|
|
||||||
// Calls a function on all side cell positions belonging to the box.
|
// Calls a function on all side cell positions belonging to the box.
|
||||||
// This function was implemented with no particular order in mind.
|
// This function was implemented with no particular order in mind.
|
||||||
template <typename F> void for_inner_outline(F f) const {
|
template <typename F>
|
||||||
|
void for_inner_outline(F f) const {
|
||||||
// o-------o
|
// o-------o
|
||||||
// /| /|
|
// /| /|
|
||||||
// / | / |
|
// / | / |
|
||||||
|
@ -14,11 +14,9 @@ struct Color8 {
|
|||||||
uint8_t components[4];
|
uint8_t components[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
Color8() :
|
Color8() : r(0), g(0), b(0), a(0) {}
|
||||||
r(0), g(0), b(0), a(0) {}
|
|
||||||
|
|
||||||
Color8(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a) :
|
Color8(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a) : r(p_r), g(p_g), b(p_b), a(p_a) {}
|
||||||
r(p_r), g(p_g), b(p_b), a(p_a) {}
|
|
||||||
|
|
||||||
Color8(Color c) {
|
Color8(Color c) {
|
||||||
r = c.r * 255;
|
r = c.r * 255;
|
||||||
@ -29,44 +27,32 @@ struct Color8 {
|
|||||||
|
|
||||||
static inline Color8 from_u8(uint8_t v) {
|
static inline Color8 from_u8(uint8_t v) {
|
||||||
// rrggbbaa
|
// rrggbbaa
|
||||||
return Color8(
|
return Color8(v >> 6, ((v >> 4) & 3), ((v >> 2) & 3), v & 3);
|
||||||
v >> 6,
|
|
||||||
((v >> 4) & 3),
|
|
||||||
((v >> 2) & 3),
|
|
||||||
v & 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Color8 from_u16(uint16_t v) {
|
static inline Color8 from_u16(uint16_t v) {
|
||||||
// rrrrgggg bbbbaaaa 🐐
|
// rrrrgggg bbbbaaaa 🐐
|
||||||
return Color8(
|
return Color8(v >> 12, ((v >> 8) & 0xf), ((v >> 4) & 0xf), v & 0xf);
|
||||||
v >> 12,
|
|
||||||
((v >> 8) & 0xf),
|
|
||||||
((v >> 4) & 0xf),
|
|
||||||
v & 0xf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Color8 from_u32(uint32_t c) {
|
static inline Color8 from_u32(uint32_t c) {
|
||||||
// rrrrrrrr gggggggg bbbbbbbb aaaaaaaa
|
// rrrrrrrr gggggggg bbbbbbbb aaaaaaaa
|
||||||
return Color8(
|
return Color8(c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
|
||||||
c >> 24,
|
|
||||||
(c >> 16) & 0xff,
|
|
||||||
(c >> 8) & 0xff,
|
|
||||||
c & 0xff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t to_u8() const {
|
inline uint8_t to_u8() const {
|
||||||
// Lossy
|
// Lossy
|
||||||
return ((r >> 6) << 6) |
|
return ((r >> 6) << 6) | //
|
||||||
((g >> 6) << 4) |
|
((g >> 6) << 4) | //
|
||||||
((b >> 6) << 2) |
|
((b >> 6) << 2) | //
|
||||||
(a >> 6);
|
(a >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t to_u16() const {
|
inline uint16_t to_u16() const {
|
||||||
// Lossy
|
// Lossy
|
||||||
return ((r >> 4) << 12) |
|
return ((r >> 4) << 12) | //
|
||||||
((g >> 4) << 8) |
|
((g >> 4) << 8) | //
|
||||||
((b >> 4) << 4) |
|
((b >> 4) << 4) | //
|
||||||
(a >> 4);
|
(a >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,27 +35,33 @@ inline T interpolate(const T v0, const T v1, const T v2, const T v3, const T v4,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T min(const T a, const T b) {
|
template <typename T>
|
||||||
|
inline T min(const T a, const T b) {
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T max(const T a, const T b) {
|
template <typename T>
|
||||||
|
inline T max(const T a, const T b) {
|
||||||
return a > b ? a : b;
|
return a > b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T min(const T a, const T b, const T c, const T d) {
|
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));
|
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) {
|
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));
|
return max(max(a, b), max(c, d));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T min(const T a, const T b, const T c, const T d, const T e, const T f) {
|
template <typename T>
|
||||||
|
inline T min(const T a, const T b, const T c, const T d, const T e, const T f) {
|
||||||
return min(min(min(a, b), min(c, d)), min(e, f));
|
return min(min(min(a, b), min(c, d)), min(e, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T max(const T a, const T b, const T c, const T d, const T e, const T f) {
|
template <typename T>
|
||||||
|
inline T max(const T a, const T b, const T c, const T d, const T e, const T f) {
|
||||||
return max(max(max(a, b), max(c, d)), max(e, f));
|
return max(max(max(a, b), max(c, d)), max(e, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +75,8 @@ inline T max(const T a, const T b, const T c, const T d, const T e, const T f, c
|
|||||||
return max(max(a, b, c, d), max(e, f, g, h));
|
return max(max(a, b, c, d), max(e, f, g, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T clamp(const T x, const T min_value, const T max_value) {
|
template <typename T>
|
||||||
|
inline T clamp(const T x, const T min_value, const T max_value) {
|
||||||
// TODO Optimization: clang can optimize a min/max implementation. Worth changing to that?
|
// TODO Optimization: clang can optimize a min/max implementation. Worth changing to that?
|
||||||
if (x < min_value) {
|
if (x < min_value) {
|
||||||
return min_value;
|
return min_value;
|
||||||
@ -80,7 +87,8 @@ template <typename T> inline T clamp(const T x, const T min_value, const T max_v
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline T squared(const T x) {
|
template <typename T>
|
||||||
|
inline T squared(const T x) {
|
||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +377,8 @@ struct Vector3iHasher {
|
|||||||
|
|
||||||
// For STL
|
// For STL
|
||||||
namespace std {
|
namespace std {
|
||||||
template <> struct hash<Vector3i> {
|
template <>
|
||||||
|
struct hash<Vector3i> {
|
||||||
size_t operator()(const Vector3i &v) const {
|
size_t operator()(const Vector3i &v) const {
|
||||||
return Vector3iHasher::hash(v);
|
return Vector3iHasher::hash(v);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
|
|
||||||
// This one does not map directly to FastNoise unfortunately,
|
// This one does not map directly to FastNoise unfortunately,
|
||||||
// because Godot's UI wants consecutive values starting from 0...
|
// because Godot's UI wants consecutive values starting from 0...
|
||||||
enum FractalType {
|
enum FractalType { //
|
||||||
FRACTAL_NONE,
|
FRACTAL_NONE,
|
||||||
FRACTAL_DOMAIN_WARP_PROGRESSIVE,
|
FRACTAL_DOMAIN_WARP_PROGRESSIVE,
|
||||||
FRACTAL_DOMAIN_WARP_INDEPENDENT
|
FRACTAL_DOMAIN_WARP_INDEPENDENT
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
namespace zylann {
|
namespace zylann {
|
||||||
|
|
||||||
template <class T> class ObjectPool {
|
template <class T>
|
||||||
|
class ObjectPool {
|
||||||
public:
|
public:
|
||||||
T *create() {
|
T *create() {
|
||||||
if (_objects.empty()) {
|
if (_objects.empty()) {
|
||||||
|
@ -9,10 +9,7 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class Span {
|
class Span {
|
||||||
public:
|
public:
|
||||||
inline Span() :
|
inline Span() : _ptr(nullptr), _size(0) {}
|
||||||
_ptr(nullptr),
|
|
||||||
_size(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Span(T *p_ptr, size_t p_begin, size_t p_end) {
|
inline Span(T *p_ptr, size_t p_begin, size_t p_end) {
|
||||||
CRASH_COND(p_end < p_begin);
|
CRASH_COND(p_end < p_begin);
|
||||||
@ -20,8 +17,7 @@ public:
|
|||||||
_size = p_end - p_begin;
|
_size = p_end - p_begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Span(T *p_ptr, size_t p_size) :
|
inline Span(T *p_ptr, size_t p_size) : _ptr(p_ptr), _size(p_size) {}
|
||||||
_ptr(p_ptr), _size(p_size) {}
|
|
||||||
|
|
||||||
inline Span(Span<T> &p_other, size_t p_begin, size_t p_end) {
|
inline Span(Span<T> &p_other, size_t p_begin, size_t p_end) {
|
||||||
CRASH_COND(p_end < p_begin);
|
CRASH_COND(p_end < p_begin);
|
||||||
|
@ -88,7 +88,8 @@ public:
|
|||||||
void enqueue(Span<IThreadedTask *> tasks);
|
void enqueue(Span<IThreadedTask *> tasks);
|
||||||
|
|
||||||
// TODO Lambda might not be the best API. memcpying to a vector would ensure we lock for a shorter time.
|
// TODO Lambda might not be the best API. memcpying to a vector would ensure we lock for a shorter time.
|
||||||
template <typename F> void dequeue_completed_tasks(F f) {
|
template <typename F>
|
||||||
|
void dequeue_completed_tasks(F f) {
|
||||||
MutexLock lock(_completed_tasks_mutex);
|
MutexLock lock(_completed_tasks_mutex);
|
||||||
for (size_t i = 0; i < _completed_tasks.size(); ++i) {
|
for (size_t i = 0; i < _completed_tasks.size(); ++i) {
|
||||||
IThreadedTask *task = _completed_tasks[i];
|
IThreadedTask *task = _completed_tasks[i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user