Blocks now represented by Objects instead of ints

This commit is contained in:
Simon Lübeß
2021-03-06 20:46:08 +01:00
parent 3449463282
commit 4e87f5f144
7 changed files with 111 additions and 77 deletions
+20
View File
@@ -0,0 +1,20 @@
using GlitchyEngine.Math;
namespace Sandbox.VoxelFun
{
class Block
{
private uint16 _blockID;
public uint16 ID => _blockID;
public Color Color {get;}
public BlockFace VisibleNeighbors {get;}
public this(Color color, BlockFace visibleNeighbors = .None)
{
Color = color;
VisibleNeighbors = visibleNeighbors;
}
}
}
+29
View File
@@ -0,0 +1,29 @@
using System;
using System.Collections;
namespace Sandbox.VoxelFun
{
static class Blocks
{
static uint16 _sLastId;
static List<Block> _blocks = new List<Block>() ~ DeleteContainerAndItems!(_);
/// Air is a special Block. It defines the absence of a block.
public static Block Air = RegisterBlock(.. new Block(.White, .All));
public static Block Stone = RegisterBlock(.. new Block(.Gray));
public static Block Grass = RegisterBlock(.. new Block(.Green));
public static Block Dirt = RegisterBlock(.. new Block(.Brown));
private static void RegisterBlock(Block block)
{
block.[Friend]_blockID = _sLastId;
_sLastId++;
_blocks.Add(block);
}
public static Block GetFromId(int id)
{
return _blocks[id];
}
}
}
+28 -10
View File
@@ -34,7 +34,7 @@ namespace Sandbox.VoxelFun
set => _isGeometryDirty = value;
}
public void SetBlock(Int32_3 coordinate, uint8 blockId)
public void SetBlock(Int32_3 coordinate, Block blockId)
{
Log.EngineLogger.AssertDebug(coordinate.X >= 0 && coordinate.Y >= 0 && coordinate.Z >= 0 && coordinate.X < VoxelChunk.Size.X && coordinate.Y < VoxelChunk.Size.Y && coordinate.Z < VoxelChunk.Size.Z, "Specified coordinate is out of range.");
@@ -45,7 +45,7 @@ namespace Sandbox.VoxelFun
ChunkManager.[Friend]chunkPosLock.Exit();
}
public uint8 GetBlock(Int32_3 coordinate)
public Block GetBlock(Int32_3 coordinate)
{
Log.EngineLogger.AssertDebug(coordinate.X >= 0 && coordinate.Y >= 0 && coordinate.Z >= 0 && coordinate.X < VoxelChunk.Size.X && coordinate.Y < VoxelChunk.Size.Y && coordinate.Z < VoxelChunk.Size.Z, "Specified coordinate is out of range.");
@@ -54,7 +54,15 @@ namespace Sandbox.VoxelFun
public void Serialize(Stream stream)
{
stream.Write(Data);
uint16[VoxelChunk.SizeX][VoxelChunk.SizeY][VoxelChunk.SizeZ] rawData = ?;
for(int x = 0; x < VoxelChunk.SizeX; x++)
for(int y = 0; y < VoxelChunk.SizeY; y++)
for(int z = 0; z < VoxelChunk.SizeZ; z++)
{
rawData[x][y][z] = Data.Data[x][y][z].ID;
}
stream.Write(rawData);
_isDirty = false;
}
}
@@ -362,14 +370,23 @@ namespace Sandbox.VoxelFun
if(!File.Exists(chunkFileName))
return .Err;
uint16[VoxelChunk.SizeX][VoxelChunk.SizeY][VoxelChunk.SizeZ] rawData;
FileStream fs = scope FileStream();
fs.Open(chunkFileName, .Read, .Read);
outChunk.Data = fs.Read<VoxelChunk>();
rawData = fs.Read<decltype(rawData)>();
fs.Close();
for(int x = 0; x < VoxelChunk.SizeX; x++)
for(int y = 0; y < VoxelChunk.SizeY; y++)
for(int z = 0; z < VoxelChunk.SizeZ; z++)
{
outChunk.Data.Data[x][y][z] = Blocks.GetFromId(rawData[x][y][z]);
}
return .Ok;
}
@@ -433,8 +450,9 @@ namespace Sandbox.VoxelFun
float gradientValue = cy / (float)(settings.TerrainFloorHeight * 2 - 1);
// determine whether or not gradient value is air
uint8 stepValue = gradientValue < 0.5f ? 1 : 0;
Block stepValue = gradientValue < 0.5f ? Blocks.Stone : Blocks.Air;
// Note these objects will be invalid
chunk.Data.Data[x][y][z] = stepValue;
}
@@ -448,7 +466,7 @@ namespace Sandbox.VoxelFun
struct GroundLayer
{
public int Depth;
public uint8 BlockType;
public Block BlockType;
}
void GroundLayers(Chunk chunk)
@@ -457,17 +475,17 @@ namespace Sandbox.VoxelFun
layers[0] = .()
{
Depth = 1,
BlockType = 3
BlockType = Blocks.Grass
};
layers[1] = .()
{
Depth = 4,
BlockType = 2
BlockType = Blocks.Dirt
};
layers[2] = .()
{
Depth = 0,
BlockType = 1
BlockType = Blocks.Stone
};
for(int x < VoxelChunk.SizeX)
@@ -478,7 +496,7 @@ namespace Sandbox.VoxelFun
for(int y = VoxelChunk.SizeY - 1; y > 0; y--)
{
if(chunk.Data.Data[x][y][z] == 0)
if(chunk.Data.Data[x][y][z] == Blocks.Air)
{
currentDepth--;
+1 -1
View File
@@ -11,6 +11,6 @@ namespace Sandbox.VoxelFun
public const Int32_3 Size = .(SizeX, SizeY, SizeZ);
public const Vector3 VectorSize = .(SizeX, SizeY, SizeZ);
public uint8[SizeX][SizeY][SizeZ] Data;
public Block[SizeX][SizeY][SizeZ] Data;
}
}
+12 -55
View File
@@ -47,52 +47,23 @@ namespace Sandbox.VoxelFun
public GraphicsContext Context;
public VertexLayout Layout;
[Inline]
Color HtoRGB(float h)
{
var h;
h = h % 360.0f;
float x = (1 - Math.Abs((h / 60.0f) % 2 - 1));
Vector3 cStrich;
if(h < 60)
cStrich = .(1, x, 0);
else if(h < 120)
cStrich = .(x, 1, 0);
else if(h < 180)
cStrich = .(0, 1, x);
else if(h < 240)
cStrich = .(0, x, 1);
else if(h < 300)
cStrich = .(x, 0, 1);
else
cStrich = .(1, 0, x);
cStrich *= 255.0f;
return .((uint8)cStrich.X, (uint8)cStrich.Y, (uint8)cStrich.Z);
}
//[/Inline]
BlockFace GetVisibleFaces(VoxelChunk chunk, int x, int y, int z)
{
BlockFace visibleFaces = .None;
if(z == 0 || chunk.Data[x][y][z - 1] == 0)
if(z == 0 || chunk.Data[x][y][z - 1].VisibleNeighbors.HasFlag(.Front))
visibleFaces |= .Back;
if(z == VoxelChunk.SizeZ - 1 || chunk.Data[x][y][z + 1] == 0)
if(z == VoxelChunk.SizeZ - 1 || chunk.Data[x][y][z + 1].VisibleNeighbors.HasFlag(.Back))
visibleFaces |= .Front;
if(x == 0 || chunk.Data[x - 1][y][z] == 0)
if(x == 0 || chunk.Data[x - 1][y][z].VisibleNeighbors.HasFlag(.Right))
visibleFaces |= .Left;
if(x == VoxelChunk.SizeX - 1 || chunk.Data[x + 1][y][z] == 0)
if(x == VoxelChunk.SizeX - 1 || chunk.Data[x + 1][y][z].VisibleNeighbors.HasFlag(.Left))
visibleFaces |= .Right;
if(y == 0 || chunk.Data[x][y - 1][z] == 0)
if(y == 0 || chunk.Data[x][y - 1][z].VisibleNeighbors.HasFlag(.Top))
visibleFaces |= .Bottom;
if(y == VoxelChunk.SizeY - 1 || chunk.Data[x][y + 1][z] == 0)
if(y == VoxelChunk.SizeY - 1 || chunk.Data[x][y + 1][z].VisibleNeighbors.HasFlag(.Bottom))
visibleFaces |= .Top;
return visibleFaces;
@@ -110,16 +81,16 @@ namespace Sandbox.VoxelFun
for(int y < VoxelChunk.SizeY)
for(int z < VoxelChunk.SizeZ)
{
uint16 blockIndex = chunk.Data[x][y][z];
Block block = chunk.Data[x][y][z];
Vector3 blockPos = .(x, y, z);
if(blockIndex != 0)
if(block != Blocks.Air)
{
BlockFace visibleFaces = GetVisibleFaces(chunk, x, y, z);
if(visibleFaces != .None)
GenerateBlockModel(blockIndex, blockPos, visibleFaces, vertices, indices, ref lastIndex);
GenerateBlockModel(block, blockPos, visibleFaces, vertices, indices, ref lastIndex);
}
}
@@ -149,7 +120,7 @@ namespace Sandbox.VoxelFun
sw.Stop();
Debug.WriteLine($"Generation: {sw.ElapsedMilliseconds}");
Debug.WriteLine($"Geometry Generation: {sw.ElapsedMilliseconds}");
delete sw;
@@ -159,23 +130,9 @@ namespace Sandbox.VoxelFun
Random r = new Random(1337) ~ delete _;
float f = 0.0f;
public static void GenerateBlockModel(uint16 blockIndex, Vector3 blockPosition, BlockFace visibleFaces, List<VertexColorTexture> vertices, List<uint32> indices, ref uint32 lastIndex)
public static void GenerateBlockModel(Block block, Vector3 blockPosition, BlockFace visibleFaces, List<VertexColorTexture> vertices, List<uint32> indices, ref uint32 lastIndex)
{
Color c = .Pink;
if(blockIndex == 1)
c = .Gray;
else if(blockIndex == 2)
c = .SaddleBrown;
else if(blockIndex == 3)
c = .Green;
//Color c = .(blockIndex, blockIndex, blockIndex);
//c = HtoRGB(f += r.Next(0, 0xBEEF));
if(blockPosition.Y == 63)
c = .Red;
Color c = block.Color;
if(visibleFaces.HasFlag(.Back))
{
+9 -5
View File
@@ -63,6 +63,8 @@ namespace Sandbox.VoxelFun
RasterizerState _rasterizerState ~ delete _;
EffectLibrary _effectLibrary ~ delete _;
Effect _effect ~ _?.ReleaseRef();
Effect _textureEffect ~ _?.ReleaseRef();
@@ -88,11 +90,13 @@ namespace Sandbox.VoxelFun
{
_context = Application.Get().Window.Context..AddRef();
_effectLibrary = new EffectLibrary(_context);
_depthStencilTarget = new DepthStencilTarget(_context, _context.SwapChain.Width, _context.SwapChain.Height);
_effect = new Effect(_context, "content\\Shaders\\basicShader.hlsl");
_effect = _effectLibrary.Load("content\\Shaders\\basicShader.hlsl");
_textureEffect = new Effect(_context, "content\\Shaders\\textureShader.hlsl");
_textureEffect = _effectLibrary.Load("content\\Shaders\\textureShader.hlsl");
// Create Input Layout
@@ -174,7 +178,7 @@ namespace Sandbox.VoxelFun
uint32 i = 0;
VoxelGeometryGenerator.GenerateBlockModel(0, .Zero, .All, vertices, indices, ref i);
VoxelGeometryGenerator.GenerateBlockModel(Blocks.Stone, .Zero, .All, vertices, indices, ref i);
let qvb = new VertexBuffer(_context, typeof(VertexColorTexture), (.)vertices.Count, .Immutable);
qvb.SetData<VertexColorTexture>(vertices);
@@ -402,7 +406,7 @@ namespace Sandbox.VoxelFun
{
if(Input.IsMouseButtonPressing(.LeftButton))
{
_world.SetBlock(intersectInfo.Coordinate, 0);
_world.SetBlock(intersectInfo.Coordinate, Blocks.Air);
}
else if(Input.IsMouseButtonPressing(.RightButton))
{
@@ -426,7 +430,7 @@ namespace Sandbox.VoxelFun
Log.ClientLogger.Error("Unknown block face.");
}
_world.SetBlock(newBlockCoord, 1);
_world.SetBlock(newBlockCoord, Blocks.Stone);
}
}
+11 -5
View File
@@ -181,6 +181,12 @@ namespace Sandbox.VoxelFun
return Vector3.Floor(chunkPosition);
}
/*
public struct BlockIntersection
{
Int32_3 BlockCoordinate;
}
*/
public Int32_3 RaycastBlock(Ray ray, float maxDistance, GeometryBinding geo, Effect effect, out Vector3 intersectionPosition, out BlockFace intersectionFace)
{
Vector3 start = ray.Start;
@@ -280,9 +286,9 @@ namespace Sandbox.VoxelFun
}
}
uint8 blockData = [Inline]GetBlock(walker);
Block blockData = [Inline]GetBlock(walker);
if(blockData != 0)
if(blockData != Blocks.Air)
{
intersectionPosition = start + distance * dir;
@@ -299,7 +305,7 @@ namespace Sandbox.VoxelFun
* Gets the block at the specified coordinate.
* @remarks If the blocks chunk is not loaded it will be loaded from the disk.
*/
public void SetBlock(Int32_3 blockCoordinate, uint8 blockId)
public void SetBlock(Int32_3 blockCoordinate, Block block)
{
Int32_3 chunkCoordinate = ChunkCoordFromBlockCoord(blockCoordinate);
@@ -307,14 +313,14 @@ namespace Sandbox.VoxelFun
Int32_3 coordInChunk = BlockCoordInChunk(blockCoordinate);
chunk.SetBlock(coordInChunk, blockId);
chunk.SetBlock(coordInChunk, block);
}
/**
* Gets the block at the specified coordinate.
* @remarks If the blocks chunk is not loaded it will be loaded from the disk.
*/
public uint8 GetBlock(Int32_3 blockCoordinate)
public Block GetBlock(Int32_3 blockCoordinate)
{
Int32_3 chunkCoordinate = ChunkCoordFromBlockCoord(blockCoordinate);