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 public class BlockData
{ {
} }
} }

View File

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

View File

@@ -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);
}
} }
} }

View File

@@ -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);
}
} }
} }

View File

@@ -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)