Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions InfiniMap.Test/ChunkMapTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Linq;
using NUnit.Framework;

namespace InfiniMap.Test
{
[TestFixture]
public class ChunkMapTests
{
[Test]
public void TestChunksWithin()
{
var map = new Map2D<int>(1, 1);

map[0, 0] = 1; // 0,0
map[1, 1] = 2; // 1,1
map[2, 2] = 3; // 2,2
map[3, 3] = 4; // 3,3

map[-1, -1] = -1; //-1,-1
map[-2, -2] = -2; // -2,-2
map[-3, -3] = -3; // -3,-3
map[-4, -4] = -4; // -4,-4

var chunks = map.ChunksWithin(-4, -4, 4, 4, false);
Assert.That(chunks.Count() == 8);
}
}
}
1 change: 1 addition & 0 deletions InfiniMap.Test/InfiniMap.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChunkMapTests.cs" />
<Compile Include="SpaceTests.cs" />
<Compile Include="TestHelpers.cs" />
<Compile Include="MapTests2D.cs" />
Expand Down
71 changes: 34 additions & 37 deletions InfiniMap/ChunkMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,57 +235,54 @@ protected virtual IEnumerable<Tuple<WorldSpace, Chunk<T>>> ChunksWithin(long x0,
/// A list of pairs, containing the starting coordinates of the chunk, plus the chunk itself
/// as: (WorldSpace,Chunk{T})
/// </returns>
protected virtual IEnumerable<Tuple<WorldSpace, Chunk<T>>> ChunksWithin(WorldSpace begin, WorldSpace end, bool createIfNull)
protected virtual IEnumerable<Tuple<WorldSpace, Chunk<T>>> ChunksWithin(WorldSpace begin, WorldSpace end,
bool createIfNull)
{
var xPoints = new List<long>();
var yPoints = new List<long>();
var zPoints = new List<long>();
var c0 = TranslateWorldToChunk(begin);
var c1 = TranslateWorldToChunk(end);

var x0 = begin.X; var y0 = begin.Y; var z0 = begin.Z;
var x1 = end.X; var y1 = end.Y; var z1 = end.Z;
long x0 = c0.X * _chunkWidth;
long x1 = c1.X * _chunkWidth;

var xChunkLength = ((Math.Abs(x1) - Math.Abs(x0))/_chunkWidth) + 1;
var yChunkLength = ((Math.Abs(y1) - Math.Abs(y0))/_chunkHeight) + 1;
var zChunkLength = ((Math.Abs(z1) - Math.Abs(z0))/_chunkDepth) + 1;
long y0 = c0.Y * _chunkHeight;
long y1 = c1.Y * _chunkHeight;

for (int i = 0; i < xChunkLength; i++)
{
var x = (x0 + (_chunkWidth*i));
xPoints.Add(x);
}
long z0 = c0.Z * _chunkDepth;
long z1 = c1.Z * _chunkDepth;

for (int i = 0; i < yChunkLength; i++)
{
var y = (y0 + (_chunkHeight*i));
yPoints.Add(y);
}
//begin with origin block and step over worldspace in chunk sized steps yielding the chunk tuple.
var xyzPoints = Range(x0, x1, _chunkWidth)
.SelectMany(x => Range(y0, y1, _chunkHeight)
.SelectMany(y => Range(z0, z1, _chunkDepth)
.Select(z => new WorldSpace(x, y, z))))
.Select(point => Tuple.Create(point, GetChunk(point, createIfNull)))
.Where(c => c.Item2 != null);

for (int i = 0; i < zChunkLength; i++)
// Ensure chunk creation
return createIfNull ? xyzPoints.ToList() : xyzPoints;
}

private IEnumerable<long> Range(long from, long to, long step)
{
if (step <= 0L)
{
var z = (z0 + (_chunkDepth*i));
zPoints.Add(z);
throw new ArgumentOutOfRangeException(nameof(step), "Step size must be greater than zero.");
}

var xyPoints = xPoints.Zip(yPoints, (x, y) => new {x, y}).ToList();

IEnumerable<WorldSpace> xyzPoints;

if (xyPoints.Count > zPoints.Count)
if (from <= to)
{
// Special-case, probably a 2D slice, so we want to zip along the length of the xyPoints, not zPoints
xyzPoints = xyPoints.Select((pair, i) => new WorldSpace(pair.x, pair.y, zPoints.ElementAtOrDefault(i)));
for (long el = from; el <= to; el += step)
{
yield return el;
}
}
else
{
// Zip along the zPoints, if there is an xy value for that z point then use it, otherwise use 0
xyzPoints = zPoints.Select((z, i) => new WorldSpace(
xyPoints.ElementAtOrDefault(i) == null ? 0 : xyPoints[i].x,
xyPoints.ElementAtOrDefault(i) == null ? 0 : xyPoints[i].y,
z));
for (long el = from; el >= to; el -= step)
{
yield return el;
}
}

// Return (worldSpace, Chunk<T>)
return xyzPoints.Select(point => Tuple.Create(point, GetChunk(point, createIfNull)));
}

protected ChunkSpace TranslateWorldToChunk(WorldSpace worldSpace)
Expand Down