2014-04-26 13:50:23 -04:00
|
|
|
|
2014-05-29 12:25:08 -04:00
|
|
|
// ChunkData.cpp
|
|
|
|
|
|
|
|
// Implements the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk
|
|
|
|
|
2014-04-26 13:50:23 -04:00
|
|
|
#include "Globals.h"
|
2014-05-21 14:58:48 -04:00
|
|
|
#include "ChunkData.h"
|
2020-04-03 02:57:01 -04:00
|
|
|
#include "BlockType.h"
|
2014-04-26 13:50:23 -04:00
|
|
|
|
2014-05-29 12:25:08 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-02-04 17:15:31 -05:00
|
|
|
namespace
|
2014-05-29 12:25:08 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
struct SectionIndices
|
2014-05-29 12:25:08 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
size_t Section = 0; // Index into m_Sections
|
|
|
|
size_t Index = 0; // Index into a single sChunkSection
|
2018-02-04 17:15:31 -05:00
|
|
|
};
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
inline SectionIndices IndicesFromRelPos(const Vector3i a_RelPos)
|
2018-02-04 17:15:31 -05:00
|
|
|
{
|
|
|
|
ASSERT(cChunkDef::IsValidRelPos(a_RelPos));
|
2014-05-24 08:37:25 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
return
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
static_cast<size_t>(a_RelPos.y / cChunkDef::SectionHeight),
|
2021-04-30 09:23:46 -04:00
|
|
|
cChunkDef::MakeIndex(a_RelPos.x, a_RelPos.y % cChunkDef::SectionHeight, a_RelPos.z)
|
2021-03-05 08:03:55 -05:00
|
|
|
};
|
2016-03-24 12:18:14 -04:00
|
|
|
}
|
2014-05-28 05:35:55 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
bool IsCompressed(const size_t ElementCount)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return ElementCount != ChunkBlockData::SectionBlockCount;
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template <size_t ElementCount, typename ValueType>
|
|
|
|
ValueType UnpackDefaultValue(const ValueType DefaultValue)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
if (IsCompressed(ElementCount))
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return DefaultValue & 0xF;
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
return DefaultValue;
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
2021-03-05 08:03:55 -05:00
|
|
|
} // namespace (anonymous)
|
2014-05-24 08:37:25 -04:00
|
|
|
|
2014-05-28 05:35:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
void ChunkDataStore<ElementType, ElementCount, DefaultValue>::Assign(const ChunkDataStore<ElementType, ElementCount, DefaultValue> & a_Other)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
Store[Y].reset();
|
2014-05-24 08:37:25 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
if (const auto & Other = a_Other.Store[Y]; Other != nullptr)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
Store[Y] = std::make_unique<Type>(*Other);
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 05:35:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
ElementType ChunkDataStore<ElementType, ElementCount, DefaultValue>::Get(const Vector3i a_Position) const
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
const auto Indices = IndicesFromRelPos(a_Position);
|
|
|
|
const auto & Section = Store[Indices.Section];
|
2014-05-28 05:35:55 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
if (Section != nullptr)
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
if (IsCompressed(ElementCount))
|
2014-05-24 08:37:25 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return cChunkDef::ExpandNibble(Section->data(), Indices.Index);
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return (*Section)[Indices.Index];
|
2014-05-24 08:37:25 -04:00
|
|
|
}
|
|
|
|
}
|
2017-08-21 12:56:53 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
return UnpackDefaultValue<ElementCount>(DefaultValue);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
typename ChunkDataStore<ElementType, ElementCount, DefaultValue>::Type * ChunkDataStore<ElementType, ElementCount, DefaultValue>::GetSection(const size_t a_Y) const
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return Store[a_Y].get();
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
void ChunkDataStore<ElementType, ElementCount, DefaultValue>::Set(const Vector3i a_Position, const ElementType a_Value)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
const auto Indices = IndicesFromRelPos(a_Position);
|
|
|
|
auto & Section = Store[Indices.Section];
|
2014-04-26 13:50:23 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
if (Section == nullptr)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
if (a_Value == UnpackDefaultValue<ElementCount>(DefaultValue))
|
2014-04-27 10:38:16 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
return;
|
2014-04-27 10:38:16 -04:00
|
|
|
}
|
2014-04-26 13:50:23 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
Section = cpp20::make_unique_for_overwrite<Type>();
|
|
|
|
std::fill(Section->begin(), Section->end(), DefaultValue);
|
2017-08-20 18:23:23 -04:00
|
|
|
}
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
if (IsCompressed(ElementCount))
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
cChunkDef::PackNibble(Section->data(), Indices.Index, a_Value);
|
2017-08-20 18:23:23 -04:00
|
|
|
}
|
2021-03-05 08:03:55 -05:00
|
|
|
else
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
(*Section)[Indices.Index] = a_Value;
|
2017-08-20 18:23:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
void ChunkDataStore<ElementType, ElementCount, DefaultValue>::SetSection(const ElementType (& a_Source)[ElementCount], const size_t a_Y)
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
auto & Section = Store[a_Y];
|
|
|
|
const auto SourceEnd = std::end(a_Source);
|
2017-08-20 18:23:23 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
if (Section != nullptr)
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
std::copy(a_Source, SourceEnd, Section->begin());
|
2017-08-20 18:23:23 -04:00
|
|
|
}
|
2021-03-05 08:03:55 -05:00
|
|
|
else if (std::any_of(a_Source, SourceEnd, [](const auto Value) { return Value != DefaultValue; }))
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
Section = cpp20::make_unique_for_overwrite<Type>();
|
|
|
|
std::copy(a_Source, SourceEnd, Section->begin());
|
2017-08-20 18:23:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template<class ElementType, size_t ElementCount, ElementType DefaultValue>
|
|
|
|
void ChunkDataStore<ElementType, ElementCount, DefaultValue>::SetAll(const ElementType (& a_Source)[cChunkDef::NumSections * ElementCount])
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
for (size_t Y = 0; Y != cChunkDef::NumSections; Y++)
|
2017-08-20 18:23:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
SetSection(*reinterpret_cast<const ElementType (*)[ElementCount]>(a_Source + Y * ElementCount), Y);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkBlockData::Assign(const ChunkBlockData & a_Other)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_Blocks.Assign(a_Other.m_Blocks);
|
|
|
|
m_Metas.Assign(a_Other.m_Metas);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-29 12:25:08 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkBlockData::SetAll(const cChunkDef::BlockTypes & a_BlockSource, const cChunkDef::BlockNibbles & a_MetaSource)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_Blocks.SetAll(a_BlockSource);
|
|
|
|
m_Metas.SetAll(a_MetaSource);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-07-26 17:24:36 -04:00
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkBlockData::SetSection(const SectionType & a_BlockSource, const SectionMetaType & a_MetaSource, const size_t a_Y)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_Blocks.SetSection(a_BlockSource, a_Y);
|
|
|
|
m_Metas.SetSection(a_MetaSource, a_Y);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkLightData::Assign(const ChunkLightData & a_Other)
|
2017-08-21 12:56:53 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_BlockLights.Assign(a_Other.m_BlockLights);
|
|
|
|
m_SkyLights.Assign(a_Other.m_SkyLights);
|
2017-08-21 12:56:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkLightData::SetAll(const cChunkDef::BlockNibbles & a_BlockLightSource, const cChunkDef::BlockNibbles & a_SkyLightSource)
|
2014-04-26 13:50:23 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_BlockLights.SetAll(a_BlockLightSource);
|
|
|
|
m_SkyLights.SetAll(a_SkyLightSource);
|
2014-04-26 13:50:23 -04:00
|
|
|
}
|
2014-04-27 11:11:56 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-28 05:35:55 -04:00
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
void ChunkLightData::SetSection(const SectionType & a_BlockLightSource, const SectionType & a_SkyLightSource, const size_t a_Y)
|
2014-04-27 11:11:56 -04:00
|
|
|
{
|
2021-03-05 08:03:55 -05:00
|
|
|
m_BlockLights.SetSection(a_BlockLightSource, a_Y);
|
|
|
|
m_SkyLights.SetSection(a_SkyLightSource, a_Y);
|
2014-04-27 11:11:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-28 05:35:55 -04:00
|
|
|
|
|
|
|
|
2021-03-05 08:03:55 -05:00
|
|
|
template struct ChunkDataStore<BLOCKTYPE, ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue>;
|
|
|
|
template struct ChunkDataStore<NIBBLETYPE, ChunkBlockData::SectionMetaCount, ChunkLightData::DefaultBlockLightValue>;
|
|
|
|
template struct ChunkDataStore<NIBBLETYPE, ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue>;
|