Skip to content

Instantly share code, notes, and snippets.

@MrSmith33
Created March 27, 2015 23:20
Show Gist options
  • Save MrSmith33/531fc47682f8d018e5a3 to your computer and use it in GitHub Desktop.
Save MrSmith33/531fc47682f8d018e5a3 to your computer and use it in GitHub Desktop.
voxel interfaces
alias FrameId = size_t;
struct Chunk
{
ivec4 position;
ChunkSnapshot*[] snapshots;
// returns latest (newest) snapshot that is not writeable anymore. FrameId < currentTimestamp
// returns null if no data avaliable
ChunkSnapshot* getReadableSnapshot(FrameId currentTimestamp)
// returns snapshot for frame 'timestamp'.
ChunkSnapshot* getSnapshot(FrameId timestamp)
// Dups newest one and adds it to list if newFrameId > newestSnapshotFrame.
// If there was no previous snapshots returns null and nothing is duped
ChunkSnapshot* getWriteableSnapshot(FrameId currentTimestamp)
// returns FrameId of the newest snapshot.
// If it is equal to current FrameId than this chunk has been modifed in this frame.
// returns 0 if chunk has no data.
FrameId newestSnapshotFrameId()
}
struct ChunkSnapshot
{
FrameId timestamp;
BlockData blockData;
ChunkSnapshot* dup();
}
struct BlockData
{
BlockId[] blocks;
bool setBlockType(ubyte cx, ubyte cy, ubyte cz, BlockId BlockId)
bool setBlockType(size_t index, BlockId BlockId)
BlockId getBlockType(ubyte cx, ubyte cy, ubyte cz)
BlockId getBlockType(size_t index)
}
struct ClientWorldViewMan
{
ChunkRange visibleRegion;
ivec4 observerPosition = ivec4(int.max, int.max, int.max);
uint viewRadius = VIEW_RADIUS;
void updateObserverPosition(vec3 cameraPos)
}
struct ChunkProvider
{
// ChunkStorage.onChunkLoaded is stored here
void delegate(Chunk* chunk) onChunkLoaded;
void update()
void loadChunk(ivec4 coord)
}
struct ChunkStorage
{
void update()
Chunk* getChunk(ivec4 coord)
bool loadChunk(ivec4 coord)
void unloadChunk(ivec4 coord)
void onChunkModified(Chunk* chunk)
private:
// called by ChunkProvider when chunk gets loaded
void onChunkLoaded()
ChunkProvider* chunkProvider;
Chunk*[ivec4] chunks;
Queue!(Chunk*) //chunks that have snapshots to be deleted
Queue!(Chunk*) //modified chunks that have observers. Send changes at frame end and clear list.
}
struct ChunkObserverList
{
ClientId[] observers;
}
struct ObservedChunkStorage
{
private ChunkStorage storage;
alias storage this;
ChunkObserverList[ivec4] chunkObservers;
void addObserver(ChunkRange range, ClientId id)
void removeObserver(ChunkRange range, ClientId id)
}
struct SnapshottedChunkStorage
{
private ObservedChunkStorage storage;
alias storage this;
FrameId currentTimestamp;
}
ivec4 blockToChunkPosition(ivec4 blockPos)
ivec4 worldToChunkPos(ivec4 blockPos)
struct WorldAccess(ChunkStorageT)
{
BlockId getBlock(ivec4 blockPos)
{
ivec4 chunkPos = worldToChunkPos(blockPosition);
Chunk* chunk = chunkStorage.getChunk(chunkPos);
if (chunk)
{
ChunkSnapshot* snapshot = chunk.getReadableSnapshot(chunkStorage.currentTimestamp);
auto blockIndex = worldToChunkBlockIndex(blockId);
snapshot.blockData.getBlockType(blockIndex);
}
else
return 0; // unknown block. Indicates that chunk is not loaded.
}
bool setBlock(ivec4 blockPos, BlockId blockId)
{
ivec4 chunkPos = worldToChunkPos(blockPosition);
Chunk* chunk = chunkStorage.getChunk(chunkPos);
if (chunk)
{
ChunkSnapshot* snapshot = chunk.getWriteableSnapshot(chunkStorage.currentTimestamp);
// chunk was not loaded yet
if (snapshot is null)
return false;
auto blockIndex = worldToChunkBlockIndex(blockPos);
snapshot.blockData.setBlockType(blockIndex, blockId);
chunkStorage.onChunkModified(chunk);
return true;
}
else
return false;
}
bool isBlockLoaded(ivec4 blockPos)
bool loadBlockRange(AABB aabb)
FrameId currentTimestamp()
private:
ChunkStorageT* chunkStorage;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment