Initial commit: Final state of the master project
This commit is contained in:
114
Research/scene/Octree/Node.h
Normal file
114
Research/scene/Octree/Node.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
// Dynamic arrays are more memory efficient (as they don't require explicitly storing the capacity, size, etc)
|
||||
// But using them is less save. In Windows it seems to work fine, but segmentation errors occur on linux using dynamic arrays.
|
||||
#define USE_DYNAMIC_ARRAY
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <typeinfo>
|
||||
#include "../../inc/glm/glm.hpp"
|
||||
#include "../../core/Defines.h"
|
||||
#include "../../core/Util/SmallDynamicArray.h"
|
||||
#include "ChildMask.h"
|
||||
|
||||
class BaseTree;
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node(const BaseTree* rootIndex, unsigned8 level = 0);
|
||||
//Node(const Node& node); // Copy ctor
|
||||
Node(Node&& node)
|
||||
{
|
||||
mChildren = std::move(node.mChildren);
|
||||
mIndex = std::move(node.mIndex);
|
||||
mChildMask = std::move(node.mChildMask);
|
||||
mLevel = std::move(node.mLevel);
|
||||
mTree = std::move(node.mTree);
|
||||
}// Move ctor
|
||||
|
||||
//Node(const Node& node) {
|
||||
// mChildren = node.mChildren);
|
||||
//}
|
||||
//Node& operator=(const Node&) = default;
|
||||
|
||||
~Node();
|
||||
|
||||
//Node& operator=(const Node& other); // Copy assignment
|
||||
Node& operator=(Node&& other) // Move assignment
|
||||
{
|
||||
mChildren = std::move(other.mChildren);
|
||||
mIndex = std::move(other.mIndex);
|
||||
mChildMask = std::move(other.mChildMask);
|
||||
mLevel = std::move(other.mLevel);
|
||||
mTree = std::move(other.mTree);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetChild(const ChildIndex index, Node* child);
|
||||
Node* GetChild(const ChildIndex index) const;
|
||||
inline bool HasChild(const ChildIndex index) const { return mChildMask.Get(index); }
|
||||
inline unsigned GetChildIndex(const ChildIndex index) const
|
||||
{
|
||||
if (!HasChild(index))
|
||||
return 0;
|
||||
ChildIndex vIndex = mChildMask.GetSetBefore(index);
|
||||
return mChildren[vIndex];
|
||||
}
|
||||
|
||||
inline bool HasChildren() const { return mChildMask.mask != 0; }
|
||||
inline unsigned* GetChildren() const { return (unsigned*)&mChildren[0]; }
|
||||
// Replaces the current children of this node by the children in the given array of children.
|
||||
// The given array should have at least as many members as the number of set bits in the new child mask.
|
||||
void SetChildren(ChildMask mask, const unsigned* children);
|
||||
|
||||
void MoveToTree(BaseTree* tree);
|
||||
|
||||
// Returns the number of direct children this node has (e.g. the number of "1" in the childmask)
|
||||
inline unsigned8 GetChildCount() const { return mChildMask.GetSet(); }
|
||||
|
||||
inline unsigned8 GetLevel() const { return mLevel; }
|
||||
inline void SetLevel(unsigned8 level) { mLevel = level; }
|
||||
inline unsigned GetIndex() const { return mIndex; }
|
||||
inline void SetIndex(unsigned32 index) { mIndex = index; }
|
||||
// If the tree type is equal to the current tree type, moved the node to the new tree.
|
||||
inline ChildMask GetChildmask() const { return mChildMask; }
|
||||
|
||||
// Returns the total number of octree nodes (including the current node) that can be reached from this nodes
|
||||
unsigned64 GetOctreeNodeCount(bool (*f)(const Node*)) const;
|
||||
unsigned64 GetOctreeNodeCount() const { return GetOctreeNodeCount([](const Node* node) { return true; }); }
|
||||
|
||||
// Returns the number of leaf voxels in this octree (if it wasn't compressed)
|
||||
unsigned64 GetLeafVoxelCount() const;
|
||||
|
||||
// Returns true if this node is smaller than the other node. Used for sorting
|
||||
bool Compare(const Node& node) const;
|
||||
// Returns true if this node is equal to the other node
|
||||
bool Equals(const Node& node) const;
|
||||
|
||||
// Adds the the given to the tree at the given coordinate. The node should specify at which level it needs to be added. If a node already exists at the given coordinate,
|
||||
// false is returned
|
||||
Node* AddNode(glm::uvec3 coordinates, const unsigned8 level);
|
||||
bool HasNode(glm::uvec3 coord, const unsigned8 level) const;
|
||||
ChildIndex GetChildIndex(const glm::uvec3 coord, const unsigned8 level) const;
|
||||
void SetChildIndex(const ChildIndex index, const unsigned32 childIndex);
|
||||
|
||||
void Traverse(const std::function<void(const Node*)>& f) const;
|
||||
|
||||
void WriteProperties(std::ostream& file);
|
||||
void ReadProperties(std::istream& file);
|
||||
void CopyProperties(Node* source);
|
||||
protected:
|
||||
Node* AddChild(const ChildIndex index);
|
||||
|
||||
#ifdef USE_DYNAMIC_ARRAY
|
||||
SmallDynamicArray<unsigned32> mChildren; // Array (with length of the number of children), containing the indices of child nodes
|
||||
#else
|
||||
std::vector<unsigned32> mChildren;
|
||||
#endif
|
||||
|
||||
unsigned32 mIndex;
|
||||
ChildMask mChildMask;
|
||||
unsigned8 mLevel; // the level of the current node, where the root has level 0
|
||||
unsigned16 mTree; // the tree to which this node
|
||||
};
|
||||
Reference in New Issue
Block a user