Files
CDAG/Research/scene/PoolBuilder/BaseTreePoolBuilder.h

112 lines
5.7 KiB
C++

#pragma once
#include <vector>
#include "BasePoolBuilder.h"
#include "../Octree/BaseTree.h"
// Pool builder class that can be used to build a pool for a specific kind of tree. Constructor should indicate the tree type.
class BaseTreePoolBuilder : public BasePoolBuilder<BaseTree>
{
public:
BaseTreePoolBuilder() { mIsBuilding = false; }
virtual ~BaseTreePoolBuilder() override {}
size_t GetPoolSize(const BaseTree* tree) override;
bool BuildPool(const BaseTree* tree, std::vector<unsigned8>& pool) override;
bool VerifyPool(std::vector<unsigned8>& pool, const unsigned8& depth) const override;
size_t GetMinimumNodePoolTexelCount(const BaseTree* tree);
unsigned32 GetTreeInfoBytesSize(const BaseTree* tree) const;
static const size_t WORD_SIZE = 4;
protected:
inline static void RoundToWords(size_t& value) { value += (WORD_SIZE - (value % WORD_SIZE)) % WORD_SIZE; }
// Returns the size of a node without the pointers (but with the additional pointer, node and nodepool information if needed)
inline size_t GetBaseNodeSize(const BaseTree* tree, const unsigned32& nodeId) const
{
auto node = tree->GetNode(nodeId);
unsigned8 level = node->GetLevel();
size_t additionalPointerBytes = 0;
if (node->GetChildCount() > 0)
{
size_t additionalBytesPerPointer = tree->GetAdditionalBytesPerPointer(level);
// Word-align additional bytes per pointer
if (WordAligned()) RoundToWords(additionalBytesPerPointer);
additionalPointerBytes = (node->GetChildCount() - (LastChildHasAdditionalBytesPerPointer(tree) ? 0 : 1)) * additionalBytesPerPointer;
}
size_t basicNodeSize = 1 + tree->GetAdditionalBytesPerNode(level) + GetAdditionalPoolInfoForNodeSize(tree, nodeId);
if (WordAligned()) RoundToWords(basicNodeSize);
return additionalPointerBytes + basicNodeSize;
}
inline size_t GetNodeSize(const BaseTree* tree, const unsigned32& nodeId) const
{
const Node* node = tree->GetNode(nodeId);
size_t nodeSize = GetBaseNodeSize(tree, nodeId);
unsigned32* children = node->GetChildren();
for (ChildIndex c = 0; c < node->GetChildCount(); c++)
{
size_t pointerSize = GetBytesPerPointer(tree, children[c]);
if (WordAligned()) RoundToWords(pointerSize);
nodeSize += pointerSize;
}
return nodeSize;
}
inline bool HasAdditionalBytesPerNode(const BaseTree* tree) const
{
std::vector<unsigned8> additionalBytesPerNode = tree->GetAdditionalBytesPerNode();
bool hasAdditionalBytesPerNode = false; for (auto abpn : additionalBytesPerNode) if (abpn != 0) hasAdditionalBytesPerNode = true;
return hasAdditionalBytesPerNode;
}
inline bool HasAdditionalBytesPerPointer(const BaseTree* tree) const
{
std::vector<unsigned8> additionalBytesPerPointer = tree->GetAdditionalBytesPerPointer();
bool hasAdditionalBytesPerPointer = false; for (auto abpp : additionalBytesPerPointer) if (abpp != 0) hasAdditionalBytesPerPointer = true;
return hasAdditionalBytesPerPointer;
}
inline bool LastChildHasAdditionalBytesPerPointer(const BaseTree* tree) const
{
return tree->LastChildHasAdditionalBytes();
}
// Use this method to pre-calculate information needed to build the tree
virtual void InitBuild(const BaseTree* tree) = 0;
// Use this method to finalize the build process and clear resources
virtual void FinishBuild(const BaseTree* tree) = 0;
// Subtrees can use this to ask for the pool to be word aligned. If a subclass returns true, additional pointer and pool sizes will be rounded to word sizes (i.e. 4 bytes)
virtual bool WordAligned() const = 0;
// Should return the number of bytes required for a pointer to the the node with nodeIndex.
virtual unsigned8 GetBytesPerPointer(const BaseTree* tree, const unsigned32& nodeIndex) const = 0;
// Should return the bytes containing a pointer to the node with the given index.
virtual std::vector<unsigned8> WrapPointer(const BaseTree* root, const unsigned32& nodeIndex, const unsigned32& indexInPool, const unsigned32& pointer) const = 0;
// Pool info required for the tree. The size of this should be determined only by the depth of the tree.
virtual size_t GetPoolInfoSize(const BaseTree* tree) const = 0;
// Pool info required for the tree (e.g. level offsets in memory, pointer sizes per level).
virtual std::vector<unsigned8> GetPoolInfo(const BaseTree* tree, const std::vector<size_t>& nodePointers, const std::vector<unsigned32>& nodeOrder) = 0;
// Additional pool info of variable size, such as lookup tables.
virtual size_t GetAdditionalPoolInfoSize(const BaseTree* tree) const { return 0; }
// Additional pool info of variable size, such as lookup tables.
virtual std::vector<unsigned8> GetAdditionalPoolInfo(const BaseTree* tree, const std::vector<size_t>& nodePointers, const std::vector<unsigned32>& nodeOrder) { return std::vector<unsigned8>(); }
virtual unsigned8 GetAdditionalPoolInfoForNodeSize(const BaseTree* tree, const unsigned32& nodeIndex) const { return 0; }
virtual std::vector<unsigned8> GetAdditionalPoolInfoForNode(const BaseTree* tree, const unsigned32& nodeIndex, const unsigned32& indexInPool) const { return std::vector<unsigned8>(); }
// Can be used to change the order of the nodes in memory.
virtual void OrderNodes(const BaseTree* tree, std::vector<unsigned32>& nodeOrder) const;
std::vector<unsigned8> GetBytesForNode(const BaseTree* tree,const unsigned32& nodeId, const std::vector<size_t>& nodePointers, const std::vector<unsigned32>& reverseNodeMap,
const std::vector<unsigned8>& additionalBytesPerNode, const std::vector<unsigned8>& additionalBytesPerPointer) const;
size_t GetAdditionalTreeInfoStart(const BaseTree* tree) const;
size_t GetAdditionalPoolInfoStart(const BaseTree* tree) const;
bool mIsBuilding;
};