Add NodeCoord (in preparation for future changes)
This commit is contained in:
parent
febd3283da
commit
7bdea466b3
106
BlockPos.h
106
BlockPos.h
@ -4,18 +4,25 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
struct BlockPos {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
#if SIZE_MAX > (1LL << 36)
|
||||
std::size_t hash(void) const { return databasePos(); }
|
||||
#else
|
||||
std::size_t hash(void) const { return databasePos() % SIZE_MAX; }
|
||||
#endif
|
||||
BlockPos() : x(0), y(0), z(0) {}
|
||||
BlockPos(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
|
||||
int dimension[3];
|
||||
// Unfortunately, static member references are not supported (even though static member pointers are...)
|
||||
// I'd like to have:
|
||||
// static int BlockPos::&x = dimension[0];
|
||||
// (which would avoid the extra object size associated with non-static members)
|
||||
int &x = dimension[0];
|
||||
int &y = dimension[1];
|
||||
int &z = dimension[2];
|
||||
//#if SIZE_MAX > (1LL << 36)
|
||||
// std::size_t hash(void) const { return databasePos(); }
|
||||
//#else
|
||||
// std::size_t hash(void) const { return databasePos() % SIZE_MAX; }
|
||||
//#endif
|
||||
BlockPos() : dimension{0, 0, 0} {}
|
||||
BlockPos(int _x, int _y, int _z) : dimension{_x, _y, _z} {}
|
||||
BlockPos(const BlockPos &pos) : dimension{pos.x, pos.y, pos.z} {}
|
||||
BlockPos(int64_t i) { setFromDBPos(i); }
|
||||
int64_t databasePos(void) const { return getDBPos(); }
|
||||
|
||||
@ -24,6 +31,9 @@ struct BlockPos {
|
||||
void operator=(const BlockPos &p) { x = p.x; y = p.y; z = p.z; }
|
||||
void operator=(int64_t i) { setFromDBPos(i); }
|
||||
|
||||
static const int Any = INT_MIN;
|
||||
static const int Invalid = INT_MAX;
|
||||
|
||||
protected:
|
||||
// Include code copied from the minetest codebase.
|
||||
// Defines (at least) the following functions:
|
||||
@ -33,6 +43,54 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
struct NodeCoord : BlockPos
|
||||
{
|
||||
bool isBlock[3];
|
||||
// Unfortunately, static member references are not supported (even though static member pointers are...)
|
||||
bool &xBlock = isBlock[0];
|
||||
bool &yBlock = isBlock[1];
|
||||
bool &zBlock = isBlock[2];
|
||||
|
||||
NodeCoord() : BlockPos(), isBlock{false, false, false} {}
|
||||
NodeCoord(int _x, int _y, int _z) : BlockPos(_x, _y, _z), isBlock{false, false, false} {}
|
||||
NodeCoord(const BlockPos &pos, bool node = false) : BlockPos(pos), isBlock{pos.x == Any ? false : !node, pos.y == Any ? false : !node, pos.z == Any ? false : !node} {}
|
||||
NodeCoord(const NodeCoord &coord) : BlockPos(coord), isBlock{coord.xBlock, coord.yBlock, coord.zBlock} {}
|
||||
NodeCoord(int64_t i) : isBlock{true, true, true} { setFromDBPos(i); }
|
||||
|
||||
size_t hash(void) const;
|
||||
|
||||
bool operator==(const NodeCoord &coord) const;
|
||||
void operator=(const BlockPos &coord) { x = coord.x; y = coord.y; z = coord.z; xBlock = true; yBlock = true; zBlock = true; }
|
||||
void operator=(const NodeCoord &coord) { x = coord.x; y = coord.y; z = coord.z; xBlock = coord.xBlock; yBlock = coord.yBlock; zBlock = coord.zBlock; }
|
||||
};
|
||||
|
||||
// Use this for map or set storage only...
|
||||
struct NodeCoordHashed : NodeCoord
|
||||
{
|
||||
private:
|
||||
size_t m_hash;
|
||||
public:
|
||||
struct Hash {
|
||||
size_t operator()(const NodeCoordHashed &h) const { return h.hash(); }
|
||||
};
|
||||
NodeCoordHashed(const BlockPos &pos) : NodeCoord(pos) { rehash(); }
|
||||
NodeCoordHashed(const NodeCoord &coord) : NodeCoord(coord) { rehash(); }
|
||||
void rehash(void) { m_hash = NodeCoord::hash(); }
|
||||
unsigned hash(void) { rehash(); return m_hash; }
|
||||
unsigned hash(void) const { return m_hash; }
|
||||
bool operator==(const NodeCoordHashed &coord) const { if (m_hash != coord.m_hash) return false; return NodeCoord::operator==(coord); }
|
||||
void operator=(const NodeCoord &coord) { NodeCoord::operator=(coord); rehash(); }
|
||||
bool operator<(const NodeCoordHashed &coord) { return m_hash < coord.m_hash; }
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<NodeCoordHashed>
|
||||
{
|
||||
size_t operator()(const NodeCoordHashed &nch) const { return nch.hash(); }
|
||||
};
|
||||
}
|
||||
|
||||
// operator< should order the positions in the
|
||||
// order the corresponding pixels are generated:
|
||||
// First (most significant): z coordinate, descending (i.e. reversed)
|
||||
@ -55,7 +113,7 @@ inline bool BlockPos::operator<(const BlockPos& p) const
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool BlockPos::operator==(const BlockPos& p) const
|
||||
inline bool BlockPos::operator==(const BlockPos &p) const
|
||||
{
|
||||
if (z != p.z)
|
||||
return false;
|
||||
@ -66,4 +124,30 @@ inline bool BlockPos::operator==(const BlockPos& p) const
|
||||
return true;
|
||||
}
|
||||
|
||||
inline size_t NodeCoord::hash(void) const
|
||||
{
|
||||
size_t hash = 0xd3adb33f;
|
||||
for (int i=0; i<3; i++)
|
||||
// Nothing too fancy...
|
||||
hash = ((hash << 8) | (hash >> 24)) ^ (dimension[i] ^ (isBlock[i] ? 0x50000000 : 0));
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline bool NodeCoord::operator==(const NodeCoord &coord) const
|
||||
{
|
||||
if (z != coord.z)
|
||||
return false;
|
||||
if (y != coord.y)
|
||||
return false;
|
||||
if (x != coord.x)
|
||||
return false;
|
||||
if (zBlock != coord.zBlock)
|
||||
return false;
|
||||
if (yBlock != coord.yBlock)
|
||||
return false;
|
||||
if (xBlock != coord.xBlock)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // BLOCKPOS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user