refactor: extract shared ChunkMath.FloorDiv helper
This commit is contained in:
13
Core/ChunkMath.cs
Normal file
13
Core/ChunkMath.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace VoxelEngine.Core;
|
||||||
|
|
||||||
|
internal static class ChunkMath
|
||||||
|
{
|
||||||
|
// Floor division: floors toward negative infinity (not toward zero like C#'s /).
|
||||||
|
// Required for correct world-coord -> chunk-index mapping for negative coordinates.
|
||||||
|
internal static int FloorDiv(int value, int size)
|
||||||
|
{
|
||||||
|
int q = value / size;
|
||||||
|
if (value % size != 0 && value < 0) q--;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,9 +20,9 @@ public sealed class Player
|
|||||||
{
|
{
|
||||||
Vector3 p = this.Position;
|
Vector3 p = this.Position;
|
||||||
return new Vector3i(
|
return new Vector3i(
|
||||||
Player.FloorDiv((int)MathF.Floor(p.X), VoxelChunk.Size),
|
ChunkMath.FloorDiv((int)MathF.Floor(p.X), VoxelChunk.Size),
|
||||||
Player.FloorDiv((int)MathF.Floor(p.Y), VoxelChunk.Size),
|
ChunkMath.FloorDiv((int)MathF.Floor(p.Y), VoxelChunk.Size),
|
||||||
Player.FloorDiv((int)MathF.Floor(p.Z), VoxelChunk.Size));
|
ChunkMath.FloorDiv((int)MathF.Floor(p.Z), VoxelChunk.Size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,11 +35,4 @@ public sealed class Player
|
|||||||
public void Move(Vector3 delta) => this.Camera.Move(delta);
|
public void Move(Vector3 delta) => this.Camera.Move(delta);
|
||||||
|
|
||||||
public void AddRotation(float yawDelta, float pitchDelta) => this.Camera.AddRotation(yawDelta, pitchDelta);
|
public void AddRotation(float yawDelta, float pitchDelta) => this.Camera.AddRotation(yawDelta, pitchDelta);
|
||||||
|
|
||||||
private static int FloorDiv(int value, int size)
|
|
||||||
{
|
|
||||||
int q = value / size;
|
|
||||||
if (value % size != 0 && value < 0) q--;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using OpenTK.Mathematics;
|
using OpenTK.Mathematics;
|
||||||
|
using VoxelEngine.Core;
|
||||||
using VoxelEngine.World.Blocks;
|
using VoxelEngine.World.Blocks;
|
||||||
using VoxelEngine.World.Persistence;
|
using VoxelEngine.World.Persistence;
|
||||||
|
|
||||||
namespace VoxelEngine.World;
|
namespace VoxelEngine.World;
|
||||||
|
|
||||||
public sealed class World : IWorld, IEnumerable<KeyValuePair<Vector3i, Chunk.Chunk>>
|
public sealed class World(BlockRegistry registry, IChunkModificationStore modStore)
|
||||||
|
: IWorld, IEnumerable<KeyValuePair<Vector3i, Chunk.Chunk>>
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Vector3i, Chunk.Chunk> _chunks = new();
|
private readonly Dictionary<Vector3i, Chunk.Chunk> _chunks = new();
|
||||||
private readonly BlockRegistry _registry;
|
|
||||||
|
|
||||||
public IChunkModificationStore ModificationStore { get; }
|
public IChunkModificationStore ModificationStore { get; } = modStore;
|
||||||
|
|
||||||
public World(BlockRegistry registry, IChunkModificationStore modStore)
|
|
||||||
{
|
|
||||||
this._registry = registry;
|
|
||||||
this.ModificationStore = modStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetChunk(Vector3i chunkPos, Chunk.Chunk chunk) => this._chunks[chunkPos] = chunk;
|
public void SetChunk(Vector3i chunkPos, Chunk.Chunk chunk) => this._chunks[chunkPos] = chunk;
|
||||||
|
|
||||||
@@ -27,25 +22,25 @@ public sealed class World : IWorld, IEnumerable<KeyValuePair<Vector3i, Chunk.Chu
|
|||||||
public IBlock GetBlock(int worldX, int worldY, int worldZ)
|
public IBlock GetBlock(int worldX, int worldY, int worldZ)
|
||||||
{
|
{
|
||||||
Vector3i chunkPos = new(
|
Vector3i chunkPos = new(
|
||||||
World.FloorDiv(worldX, Chunk.Chunk.Size),
|
ChunkMath.FloorDiv(worldX, Chunk.Chunk.Size),
|
||||||
World.FloorDiv(worldY, Chunk.Chunk.Size),
|
ChunkMath.FloorDiv(worldY, Chunk.Chunk.Size),
|
||||||
World.FloorDiv(worldZ, Chunk.Chunk.Size));
|
ChunkMath.FloorDiv(worldZ, Chunk.Chunk.Size));
|
||||||
|
|
||||||
Chunk.Chunk? chunk = this.GetChunk(chunkPos);
|
Chunk.Chunk? chunk = this.GetChunk(chunkPos);
|
||||||
if (chunk == null) return this._registry.Air;
|
if (chunk == null) return registry.Air;
|
||||||
|
|
||||||
int localX = worldX - chunkPos.X * Chunk.Chunk.Size;
|
int localX = worldX - chunkPos.X * Chunk.Chunk.Size;
|
||||||
int localY = worldY - chunkPos.Y * Chunk.Chunk.Size;
|
int localY = worldY - chunkPos.Y * Chunk.Chunk.Size;
|
||||||
int localZ = worldZ - chunkPos.Z * Chunk.Chunk.Size;
|
int localZ = worldZ - chunkPos.Z * Chunk.Chunk.Size;
|
||||||
return this._registry.Get(chunk[localX, localY, localZ]);
|
return registry.Get(chunk[localX, localY, localZ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetBlock(int worldX, int worldY, int worldZ, ushort blockId)
|
public bool SetBlock(int worldX, int worldY, int worldZ, ushort blockId)
|
||||||
{
|
{
|
||||||
Vector3i chunkPos = new(
|
Vector3i chunkPos = new(
|
||||||
World.FloorDiv(worldX, Chunk.Chunk.Size),
|
ChunkMath.FloorDiv(worldX, Chunk.Chunk.Size),
|
||||||
World.FloorDiv(worldY, Chunk.Chunk.Size),
|
ChunkMath.FloorDiv(worldY, Chunk.Chunk.Size),
|
||||||
World.FloorDiv(worldZ, Chunk.Chunk.Size));
|
ChunkMath.FloorDiv(worldZ, Chunk.Chunk.Size));
|
||||||
|
|
||||||
Chunk.Chunk? chunk = this.GetChunk(chunkPos);
|
Chunk.Chunk? chunk = this.GetChunk(chunkPos);
|
||||||
|
|
||||||
@@ -65,13 +60,6 @@ public sealed class World : IWorld, IEnumerable<KeyValuePair<Vector3i, Chunk.Chu
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int FloorDiv(int value, int size)
|
|
||||||
{
|
|
||||||
int q = value / size;
|
|
||||||
if (value % size != 0 && value < 0) q--;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<Vector3i, Chunk.Chunk>> GetEnumerator() => this._chunks.GetEnumerator();
|
public IEnumerator<KeyValuePair<Vector3i, Chunk.Chunk>> GetEnumerator() => this._chunks.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
|||||||
Reference in New Issue
Block a user