From 2504538a3a164f27a96f413f5b389f8dad6b2cac Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 28 Aug 2019 08:29:02 +0200 Subject: Added a basic PalettedBlockArea implementation (#4377) --- src/PalettedBlockArea.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/PalettedBlockArea.h (limited to 'src/PalettedBlockArea.h') diff --git a/src/PalettedBlockArea.h b/src/PalettedBlockArea.h new file mode 100644 index 000000000..3866d405b --- /dev/null +++ b/src/PalettedBlockArea.h @@ -0,0 +1,114 @@ +#pragma once + + + + + +#include + +#include "BlockTypePalette.h" +#include "Cuboid.h" + + + + + +/** Represents an area of blocks that are represented using a palette. +The object itself provides no thread safety, users of this class need to handle locking, if required. +The PalettedBlockArea always contains Blocks and their associated BlockEntities, it may optionally contain Entities. +There's no way to instantiate this class directly, you need to use either createFilled(), or read from cWorld. */ +class PalettedBlockArea +{ +public: + + /** Creates a new PBA of the specified size filled with the specified block. + Throws if there is an error (memory allocation etc.) */ + static PalettedBlockArea createFilled(Vector3i aSize, const AString & aBlockTypeName, const BlockState & aBlockState); + + /** Returns the actual size of the area in all 3 axes. */ + const Vector3i & size() const { return mSize; } + + /** Returns a cCuboid that encompasses the entire PBA. + Technically, {0, 0, 0} to mSize. */ + cCuboid whole() const; + + /** Sets a single block using its full blockspec. + The position must be valid (ASSERTed). + If the block is not already in palette, it is added. */ + void setBlock(Vector3i aPos, const AString & aBlockTypeName, const BlockState & aBlockState); + + /** Sets a single block using an index to the palette (retrieved earlier by paletteIndex()). + The position must be valid (ASSERTed). + The palette index must be valid (ASSERTed). */ + void setBlock(Vector3i aPos, UInt32 aPaletteIndex); + + /** Returns the index into the palette that is used by the specified full blockspec. + Adds the blockspec to palette if not already there. */ + UInt32 paletteIndex(const AString & aBlockTypeName, const BlockState & aBlockState); + + /** Returns the into the palette that is used by the specified full blockspec. + Returns if blockspec not in palette. */ + std::pair maybePaletteIndex(const AString & aBlockTypeName, const BlockState & aBlockState) const; + + /** Returns the index into the palette for the block at the specified pos. + The position must be valid (ASSERTed). */ + UInt32 blockPaletteIndex(Vector3i aPos) const; + + /** Returns the full blockspec of the block at the specified position. + The position must be valid (ASSERTed). */ + const std::pair & block(Vector3i aPos) const; + + /** Returns the blockspec represented by the specified palette index. + The index must be valid (ASSERTed). */ + const std::pair & paletteEntry(UInt32 aPaletteIndex) const; + + /** Returns true if the specified position is within the size bounds of the area. */ + bool isPositionValid(Vector3i aPos) const; + + /** Fills the entire PBA with a single block of the specified type. + The palette is reset to one containing only the single block. */ + void fill(const AString & aBlockTypeName, const BlockState & aBlockState); + + /** Pastes (copies verbatim) a cCuboid out of the src PBA into this PBA. + aSrcCuboid is the coord range in aSrc that will be copied (min-coord is inclusive, max-coord is exclusive). + aDstOrigin is the coord relative to this PBA where the lowest coords of the copied area will be put. + aDstOrigin can be outside of this PBA's coord range (only part of the src is copied). + Automatically crops aSrcCuboid so that the copied part is entirely inside this PBA's coord range. */ + void paste(const PalettedBlockArea & aSrc, const cCuboid & aSrcCuboid, Vector3i aDstOrigin = Vector3i()); + + /** Pastes (copies verbatim) the entire src PBA into this PBA. + aDstOrigin is the coord relative to this PBA where the lowest coords of the copied area will be put. + aDstOrigin can be outside of this PBA's coord range (only part of the src is copied). + Gracefully handles situations where the copied src PBA goes outside of this PBA's coord range. */ + inline void paste(const PalettedBlockArea & aSrc, Vector3i aDstOrigin = Vector3i()) + { + paste(aSrc, aSrc.whole(), aDstOrigin); + } + + /** Crops this PBA by the specified coords. + aArea is first cropped to the size of this PBA (so it's only possible to shrink a PBA, not enlarge). */ + void crop(const cCuboid & aArea); + + /** Returns the (reqd-only) palette used internally by this object. */ + const BlockTypePalette & palette() { return mPalette; } + + +protected: + + /** The palette used in the area. */ + BlockTypePalette mPalette; + + /** The blocks contained in the area, stored as indices into mPalette. */ + std::vector mBlocks; + + /** The size (dimensions) of the area. */ + Vector3i mSize; + + + /** Creates a new uninitialized instance (all sizes zero). */ + PalettedBlockArea(); + + /** Converts the position to index in mBlocks. + This may be removed later on when optimizing the RAM usage of this class by compressing low-palette-count PBAs. */ + UInt32 positionToIndex(Vector3i aPos) const; +}; -- cgit v1.2.3