mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Blocks now represented by Objects instead of ints
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -361,15 +369,24 @@ 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;
|
||||
}
|
||||
|
||||
@@ -377,7 +394,7 @@ namespace Sandbox.VoxelFun
|
||||
{
|
||||
String chunkFileName = scope String(_chunkBasePath);
|
||||
chunkFileName.AppendF($"{chunk.Coordinate.X}_{chunk.Coordinate.Y}_{chunk.Coordinate.Z}.cdata");
|
||||
|
||||
|
||||
FileStream fs = scope FileStream();
|
||||
|
||||
fs.Open(chunkFileName, FileMode.Create, .Write);
|
||||
@@ -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--;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user