+ static Pos ToPos(int idx) {
+ return Pos(
+ (idx % Width()),
+ ((idx / Width()) % Height()),
+ (idx / (Width() * Height()))
+ );
+ }
+ glm::mat4 ToTransform(int idx) const;
+
+ static constexpr bool IsBorder(int idx) {
+ return
+ idx < Width() * Height() || // low Z plane
+ idx % Width() == 0 || // low X plane
+ (idx / (Width() * Height())) == Depth() - 1 || // high Z plane
+ idx % Width() == Width() - 1 || // high X plane
+ (idx / Width()) % Height() == 0 || // low Y plane
+ (idx / Width()) % Height() == Height() - 1; // high Y plane
+ }
+
+ bool IsSurface(int index) const { return IsSurface(ToPos(index)); }
+ bool IsSurface(const Block::Pos &pos) const { return IsSurface(Pos(pos)); }
+ bool IsSurface(const Pos &pos) const;
+
+ void SetNeighbor(Chunk &);
+ bool HasNeighbor(Block::Face f) const { return neighbor[f]; }
+ Chunk &GetNeighbor(Block::Face f) { return *neighbor[f]; }
+ const Chunk &GetNeighbor(Block::Face f) const { return *neighbor[f]; }
+ void ClearNeighbors();
+ void Unlink();
+ void Relink();
+
+ // check if block at given index is completely enclosed (and therefore invisible)
+ bool Obstructed(int idx) const;