chunbk face culling

This commit is contained in:
maxwes08
2025-09-22 10:56:55 +02:00
parent 81ef6d8a29
commit 9a61dfd74c
5 changed files with 118 additions and 4 deletions

View File

@@ -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
{
}
}

View File

@@ -10,6 +10,7 @@
private Dictionary<ushort, BlockData> _blockData;
private Blocks[] _blocks;
public Dictionary<Orientation, Chunk> Neighbors = new();
public Chunk(int x, int y)
{
@@ -89,7 +90,7 @@
( 0, 0, -1) // -Z
};
private void UpdateChunkMesh()
public void UpdateChunkMesh()
{
List<FaceData> faces = new List<FaceData>(Size * Size * Height / 2);
@@ -129,6 +130,21 @@
int ni = GetBlockIndex(nx, ny, nz);
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();
continue;
}

View File

@@ -15,6 +15,8 @@ namespace Voxel
private World _world;
public double lastClick = 0;
public readonly float mouseCooldown = 0.2f;
private int _blockIndex = 0;
private Blocks _selectedBlock = Blocks.Dirt;
public Player(World world, Vector3 startPos)
{
@@ -30,7 +32,7 @@ namespace Voxel
y += normal.Y;
z += normal.Z;
_world.SetBlock(x, y, z, Blocks.OakPlanks);
_world.SetBlock(x, y, z, _selectedBlock);
}
public void BreakBlock()
@@ -70,5 +72,22 @@ namespace Voxel
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);
}
}
}

View File

@@ -114,5 +114,17 @@ namespace Voxel
base.OnMouseUp(e);
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);
}
}
}

View File

@@ -1,5 +1,6 @@
using OpenTK.Mathematics;
using System.Collections.Generic;
using System.Drawing;
namespace Voxel
{
@@ -21,6 +22,22 @@ namespace Voxel
public void AddChunk(Chunk 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)
@@ -46,6 +63,18 @@ namespace Voxel
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)
{
int chunkX = worldX / Chunk.Size;
@@ -57,6 +86,39 @@ namespace Voxel
int localZ = worldZ % Chunk.Size;
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)