summaryrefslogblamecommitdiffstats
path: root/src/ChunkData.h
blob: a984b752ebe66c8c39e9b0e520b404bb57d76664 (plain) (tree)
1
2
3
4
5
6
7
8
9
 







                                                                                                                    

            

                        
 
 
 
 


                                                                           
 
                                                           
 

                                                                                             
 


                                                                
 


                                                                                          
 






                                                                                                   
 


                                                                                           
 










                                                                     
 

                                                                                                                   
 

                                                            
 

                                                             
 
        
 

                                                                               
 
       
 

                                                    
 
                                                    
 

                                                                                          
 

                                                                                        
 

                                                                                                    
 


                                                                                                               
 
 
 
 
 


                    
 
                                                                                                                         
 

                                                                  
 
                                                          
 
        
 



                                                                                            
 
                                                         
 
                                                    
 

                                                                                                     
 

                                                                                                     
 

                                                                                                                          




  
 






























                                                                                                                                              
 


                                                                                                                            

// ChunkData.h

// Declares the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk





#pragma once

#include "FunctionRef.h"
#include "ChunkDef.h"





template <class ElementType, size_t ElementCount, ElementType DefaultValue>
struct ChunkDataStore
{
	using Type = std::array<ElementType, ElementCount>;

	/** Copy assign from another ChunkDataStore. */
	void Assign(const ChunkDataStore<ElementType, ElementCount, DefaultValue> & a_Other);

	/** Gets one value at the given position.
	Returns DefaultValue if the section is not allocated. */
	ElementType Get(Vector3i a_Position) const;

	/** Returns a raw pointer to the internal representation of the specified section.
	Will be nullptr if the section is not allocated. */
	Type * GetSection(size_t a_Y) const;

	/** Sets one value at the given position.
	Allocates a section if needed for the operation. */
	void Set(Vector3i a_Position, ElementType a_Value);

	/** Copies the data from the specified flat section array into the internal representation.
	Allocates a section if needed for the operation. */
	void SetSection(const ElementType (& a_Source)[ElementCount], size_t a_Y);

	/** Copies the data from the specified flat array into the internal representation.
	Allocates sections that are needed for the operation. */
	void SetAll(const ElementType (& a_Source)[cChunkDef::NumSections * ElementCount]);

	/** Contains all the sections this ChunkDataStore manages. */
	std::unique_ptr<Type> Store[cChunkDef::NumSections];
};





class ChunkBlockData
{
public:

	static constexpr size_t SectionBlockCount = cChunkDef::SectionHeight * cChunkDef::Width * cChunkDef::Width;
	static constexpr size_t SectionMetaCount = SectionBlockCount / 2;

	static constexpr BLOCKTYPE DefaultValue = 0x00;
	static constexpr NIBBLETYPE DefaultMetaValue = 0x00;

	using SectionType = BLOCKTYPE[SectionBlockCount];
	using SectionMetaType = NIBBLETYPE[SectionMetaCount];

private:

	ChunkDataStore<BLOCKTYPE, SectionBlockCount, DefaultValue> m_Blocks;
	ChunkDataStore<NIBBLETYPE, SectionMetaCount, DefaultMetaValue> m_Metas;

public:

	using BlockArray = decltype(m_Blocks)::Type;
	using MetaArray = decltype(m_Metas)::Type;

	void Assign(const ChunkBlockData & a_Other);

	BLOCKTYPE GetBlock(Vector3i a_Position) const { return m_Blocks.Get(a_Position); }
	NIBBLETYPE GetMeta(Vector3i a_Position) const { return m_Metas.Get(a_Position); }

	BlockArray * GetSection(size_t a_Y) const { return m_Blocks.GetSection(a_Y); }
	MetaArray * GetMetaSection(size_t a_Y) const { return m_Metas.GetSection(a_Y); }

	void SetBlock(Vector3i a_Position, BLOCKTYPE a_Block) { m_Blocks.Set(a_Position, a_Block); }
	void SetMeta(Vector3i a_Position, NIBBLETYPE a_Meta) { m_Metas.Set(a_Position, a_Meta); }

	void SetAll(const cChunkDef::BlockTypes & a_BlockSource, const cChunkDef::BlockNibbles & a_MetaSource);
	void SetSection(const SectionType & a_BlockSource, const SectionMetaType & a_MetaSource, size_t a_Y);
};





class ChunkLightData
{
public:

	static constexpr size_t SectionLightCount = (cChunkDef::SectionHeight * cChunkDef::Width * cChunkDef::Width) / 2;

	static constexpr NIBBLETYPE DefaultBlockLightValue = 0x00;
	static constexpr NIBBLETYPE DefaultSkyLightValue = 0xFF;

	using SectionType = NIBBLETYPE[SectionLightCount];

private:

	ChunkDataStore<NIBBLETYPE, SectionLightCount, DefaultBlockLightValue> m_BlockLights;
	ChunkDataStore<NIBBLETYPE, SectionLightCount, DefaultSkyLightValue> m_SkyLights;

public:

	using LightArray = decltype(m_BlockLights)::Type;

	void Assign(const ChunkLightData & a_Other);

	NIBBLETYPE GetBlockLight(Vector3i a_Position) const { return m_BlockLights.Get(a_Position); }
	NIBBLETYPE GetSkyLight(Vector3i a_Position) const { return m_SkyLights.Get(a_Position); }

	LightArray * GetBlockLightSection(size_t a_Y) const { return m_BlockLights.GetSection(a_Y); }
	LightArray * GetSkyLightSection(size_t a_Y) const { return m_SkyLights.GetSection(a_Y); }

	void SetAll(const cChunkDef::BlockNibbles & a_BlockLightSource, const cChunkDef::BlockNibbles & a_SkyLightSource);
	void SetSection(const SectionType & a_BlockLightSource, const SectionType & a_SkyLightSource, size_t a_Y);
};





namespace ChunkDef
{
	using cForEachSectionCallback = cFunctionRef<void(
		size_t,
		ChunkBlockData::BlockArray *,
		ChunkBlockData::MetaArray *,
		ChunkLightData::LightArray *,
		ChunkLightData::LightArray *)>;

	/** Invokes the callback functor for every chunk section containing at least one present block or light section data.
	This is used to collect all data for all sections. */
	inline void ForEachSection(const ChunkBlockData & a_BlockData, const ChunkLightData & a_LightData, cForEachSectionCallback a_Callback)
	{
		for (size_t Y = 0; Y < cChunkDef::NumSections; ++Y)
		{
			const auto Blocks = a_BlockData.GetSection(Y);
			const auto Metas = a_BlockData.GetMetaSection(Y);
			const auto BlockLights = a_LightData.GetBlockLightSection(Y);
			const auto SkyLights = a_LightData.GetSkyLightSection(Y);

			if ((Blocks != nullptr) || (Metas != nullptr) || (BlockLights != nullptr) || (SkyLights != nullptr))
			{
				a_Callback(Y, Blocks, Metas, BlockLights, SkyLights);
			}
		}
	}
}





extern template struct ChunkDataStore<BLOCKTYPE, ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue>;
extern template struct ChunkDataStore<NIBBLETYPE, ChunkBlockData::SectionMetaCount, ChunkLightData::DefaultBlockLightValue>;
extern template struct ChunkDataStore<NIBBLETYPE, ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue>;