chunbk face culling
This commit is contained in:
@@ -1,7 +1,12 @@
|
|||||||
namespace Voxel
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Voxel
|
||||||
{
|
{
|
||||||
public class BlockData
|
public class BlockData
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
Chunk.cs
18
Chunk.cs
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
private Dictionary<ushort, BlockData> _blockData;
|
private Dictionary<ushort, BlockData> _blockData;
|
||||||
private Blocks[] _blocks;
|
private Blocks[] _blocks;
|
||||||
|
public Dictionary<Orientation, Chunk> Neighbors = new();
|
||||||
|
|
||||||
public Chunk(int x, int y)
|
public Chunk(int x, int y)
|
||||||
{
|
{
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
( 0, 0, -1) // -Z
|
( 0, 0, -1) // -Z
|
||||||
};
|
};
|
||||||
|
|
||||||
private void UpdateChunkMesh()
|
public void UpdateChunkMesh()
|
||||||
{
|
{
|
||||||
List<FaceData> faces = new List<FaceData>(Size * Size * Height / 2);
|
List<FaceData> faces = new List<FaceData>(Size * Size * Height / 2);
|
||||||
|
|
||||||
@@ -129,6 +130,21 @@
|
|||||||
int ni = GetBlockIndex(nx, ny, nz);
|
int ni = GetBlockIndex(nx, ny, nz);
|
||||||
if (GetBlockIndex(nx, ny, nz) == -1)
|
if (GetBlockIndex(nx, ny, nz) == -1)
|
||||||
{
|
{
|
||||||
|
if (Neighbors.TryGetValue((Orientation)face, out Chunk neighbor) && neighbor != null)
|
||||||
|
{
|
||||||
|
int localX = nx;
|
||||||
|
int localZ = nz;
|
||||||
|
|
||||||
|
if (nx < 0) localX = nx + Size;
|
||||||
|
if (nx >= Size) localX = nx - Size;
|
||||||
|
|
||||||
|
if (nz < 0) localZ = nz + Size;
|
||||||
|
if (nz >= Size) localZ = nz - Size;
|
||||||
|
|
||||||
|
Blocks neighborBlock = neighbor.GetBlock(localX, y, localZ);
|
||||||
|
if (neighborBlock != Blocks.Air)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
AddFace();
|
AddFace();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
21
Player.cs
21
Player.cs
@@ -15,6 +15,8 @@ namespace Voxel
|
|||||||
private World _world;
|
private World _world;
|
||||||
public double lastClick = 0;
|
public double lastClick = 0;
|
||||||
public readonly float mouseCooldown = 0.2f;
|
public readonly float mouseCooldown = 0.2f;
|
||||||
|
private int _blockIndex = 0;
|
||||||
|
private Blocks _selectedBlock = Blocks.Dirt;
|
||||||
|
|
||||||
public Player(World world, Vector3 startPos)
|
public Player(World world, Vector3 startPos)
|
||||||
{
|
{
|
||||||
@@ -30,7 +32,7 @@ namespace Voxel
|
|||||||
y += normal.Y;
|
y += normal.Y;
|
||||||
z += normal.Z;
|
z += normal.Z;
|
||||||
|
|
||||||
_world.SetBlock(x, y, z, Blocks.OakPlanks);
|
_world.SetBlock(x, y, z, _selectedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BreakBlock()
|
public void BreakBlock()
|
||||||
@@ -70,5 +72,22 @@ namespace Voxel
|
|||||||
BreakBlock();
|
BreakBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SwitchBlock(bool inverted)
|
||||||
|
{
|
||||||
|
var keys = BlockDefinitions.Blocks.Keys.ToList();
|
||||||
|
|
||||||
|
if (inverted)
|
||||||
|
if (_blockIndex == 0)
|
||||||
|
_blockIndex = keys.Count -1;
|
||||||
|
else
|
||||||
|
_blockIndex -= 1;
|
||||||
|
else
|
||||||
|
_blockIndex += 1;
|
||||||
|
|
||||||
|
_blockIndex = _blockIndex % keys.Count;
|
||||||
|
_selectedBlock = keys[_blockIndex];
|
||||||
|
Console.WriteLine(_selectedBlock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
Window.cs
12
Window.cs
@@ -114,5 +114,17 @@ namespace Voxel
|
|||||||
base.OnMouseUp(e);
|
base.OnMouseUp(e);
|
||||||
Input.SetMouseButton(e.Button, false);
|
Input.SetMouseButton(e.Button, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseWheel(MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseWheel(e);
|
||||||
|
|
||||||
|
bool inverted = false;
|
||||||
|
|
||||||
|
if (e.OffsetY < 0)
|
||||||
|
inverted = true;
|
||||||
|
|
||||||
|
Player.SwitchBlock(inverted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
World.cs
62
World.cs
@@ -1,5 +1,6 @@
|
|||||||
using OpenTK.Mathematics;
|
using OpenTK.Mathematics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace Voxel
|
namespace Voxel
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,22 @@ namespace Voxel
|
|||||||
public void AddChunk(Chunk chunk)
|
public void AddChunk(Chunk chunk)
|
||||||
{
|
{
|
||||||
_chunks[(chunk.X, chunk.Y)] = chunk;
|
_chunks[(chunk.X, chunk.Y)] = chunk;
|
||||||
|
|
||||||
|
Dictionary<Orientation, Orientation> oppositeOrientation = new()
|
||||||
|
{
|
||||||
|
{Orientation.West, Orientation.East},
|
||||||
|
{Orientation.East, Orientation.West},
|
||||||
|
{Orientation.North, Orientation.South},
|
||||||
|
{Orientation.South, Orientation.North},
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var (orientation, neighbor) in GetChunkNeighbors(chunk))
|
||||||
|
{
|
||||||
|
neighbor.Neighbors[oppositeOrientation[orientation]] = chunk;
|
||||||
|
chunk.Neighbors[orientation] = neighbor;
|
||||||
|
neighbor.UpdateChunkMesh();
|
||||||
|
}
|
||||||
|
chunk.UpdateChunkMesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveChunk(int chunkX, int chunkZ)
|
public void RemoveChunk(int chunkX, int chunkZ)
|
||||||
@@ -46,6 +63,18 @@ namespace Voxel
|
|||||||
return chunk.GetBlock(localX, worldY, localZ);
|
return chunk.GetBlock(localX, worldY, localZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Orientation> GetEdgeOrientations(int localX, int localZ, int size)
|
||||||
|
{
|
||||||
|
var orientations = new List<Orientation>();
|
||||||
|
|
||||||
|
if (localX == 0) orientations.Add(Orientation.West);
|
||||||
|
if (localX == size - 1) orientations.Add(Orientation.East);
|
||||||
|
if (localZ == size - 1) orientations.Add(Orientation.South); // assuming Z+ is North
|
||||||
|
if (localZ == 0) orientations.Add(Orientation.North);
|
||||||
|
|
||||||
|
return orientations;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block)
|
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block)
|
||||||
{
|
{
|
||||||
int chunkX = worldX / Chunk.Size;
|
int chunkX = worldX / Chunk.Size;
|
||||||
@@ -57,6 +86,39 @@ namespace Voxel
|
|||||||
int localZ = worldZ % Chunk.Size;
|
int localZ = worldZ % Chunk.Size;
|
||||||
|
|
||||||
chunk.SetBlock(localX, worldY, localZ, block);
|
chunk.SetBlock(localX, worldY, localZ, block);
|
||||||
|
|
||||||
|
if (block == Blocks.Air && (localX == 15 || localX == 0) || (localZ == 15 || localZ == 0))
|
||||||
|
{
|
||||||
|
foreach (var orientation in GetEdgeOrientations(localX, localZ, Chunk.Size))
|
||||||
|
{
|
||||||
|
if (chunk.Neighbors.TryGetValue(orientation, out var neighbor) && neighbor != null)
|
||||||
|
{
|
||||||
|
neighbor.UpdateChunkMesh();
|
||||||
|
Console.WriteLine($"Updated neighbor at {orientation}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(Orientation orientation, Chunk neighbor)> GetChunkNeighbors(Chunk chunk)
|
||||||
|
{
|
||||||
|
Dictionary<Orientation, (int x, int y)> offsets = new()
|
||||||
|
{
|
||||||
|
{ Orientation.West, (1, 0) },
|
||||||
|
{ Orientation.East, (-1, 0) },
|
||||||
|
{ Orientation.North, (0, 1) },
|
||||||
|
{ Orientation.South, (0, -1) }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var kv in offsets)
|
||||||
|
{
|
||||||
|
int nx = chunk.X + kv.Value.x;
|
||||||
|
int ny = chunk.Y + kv.Value.y;
|
||||||
|
|
||||||
|
Chunk neighbor = GetChunk(nx, ny);
|
||||||
|
if (neighbor != null)
|
||||||
|
yield return (kv.Key, neighbor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public (bool success, Blocks block, int x, int y, int z, Vector3i normal) Raycast(Vector3 origin, Vector3 direction, float maxDistance)
|
public (bool success, Blocks block, int x, int y, int z, Vector3i normal) Raycast(Vector3 origin, Vector3 direction, float maxDistance)
|
||||||
|
|||||||
Reference in New Issue
Block a user