diff --git a/TrueCraft.API/Coordinates2D.cs b/TrueCraft.API/Coordinates2D.cs
index 196f758..943002a 100644
--- a/TrueCraft.API/Coordinates2D.cs
+++ b/TrueCraft.API/Coordinates2D.cs
@@ -250,6 +250,26 @@ namespace TrueCraft.API
///
public static readonly Coordinates2D Right = new Coordinates2D(1, 0);
+ ///
+ /// A trio of 3D coordinates facing to the east.
+ ///
+ public static readonly Coordinates2D East = new Coordinates2D(1, 0);
+
+ ///
+ /// A trio of 3D coordinates facing to the west.
+ ///
+ public static readonly Coordinates2D West = new Coordinates2D(-1, 0);
+
+ ///
+ /// A trio of 3D coordinates facing to the north.
+ ///
+ public static readonly Coordinates2D North = new Coordinates2D(0, -1);
+
+ ///
+ /// A trio of 3D coordinates facing to the south.
+ ///
+ public static readonly Coordinates2D South = new Coordinates2D(0, 1);
+
#endregion
///
diff --git a/TrueCraft.Client/Rendering/BlockRenderer.cs b/TrueCraft.Client/Rendering/BlockRenderer.cs
index 984cecf..5cdba07 100644
--- a/TrueCraft.Client/Rendering/BlockRenderer.cs
+++ b/TrueCraft.Client/Rendering/BlockRenderer.cs
@@ -51,7 +51,8 @@ namespace TrueCraft.Client.Rendering
for (int _side = 0; _side < 6; _side++)
{
var side = (CubeFace)_side;
- var quad = CreateQuad(side, offset, texture, textureIndex % texture.Length, indiciesOffset, out _indicies, color);
+ var quad = CreateQuad(side, offset, texture, textureIndex % texture.Length, indiciesOffset,
+ out _indicies, color);
Array.Copy(quad, 0, verticies, _side * 4, 4);
Array.Copy(_indicies, 0, indicies, _side * 6, 6);
textureIndex += 4;
@@ -59,8 +60,8 @@ namespace TrueCraft.Client.Rendering
return verticies;
}
- protected static VertexPositionNormalColorTexture[] CreateQuad(CubeFace face, Vector3 offset, Vector2[] texture, int textureOffset,
- int indiciesOffset, out int[] indicies, Color color)
+ protected static VertexPositionNormalColorTexture[] CreateQuad(CubeFace face, Vector3 offset,
+ Vector2[] texture, int textureOffset, int indiciesOffset, out int[] indicies, Color color)
{
indicies = new[] { 0, 1, 3, 1, 2, 3 };
for (int i = 0; i < indicies.Length; i++)
diff --git a/TrueCraft.Client/Rendering/ChunkRenderer.cs b/TrueCraft.Client/Rendering/ChunkRenderer.cs
index 34baa5a..097e5d6 100644
--- a/TrueCraft.Client/Rendering/ChunkRenderer.cs
+++ b/TrueCraft.Client/Rendering/ChunkRenderer.cs
@@ -39,12 +39,14 @@ namespace TrueCraft.Client.Rendering
}
}
+ private ReadOnlyWorld World { get; set; }
private TrueCraftGame Game { get; set; }
private IBlockRepository BlockRepository { get; set; }
- public ChunkRenderer(TrueCraftGame game, IBlockRepository blockRepository)
+ public ChunkRenderer(ReadOnlyWorld world, TrueCraftGame game, IBlockRepository blockRepository)
: base()
{
+ World = world;
BlockRepository = blockRepository;
Game = game;
}
@@ -59,10 +61,20 @@ namespace TrueCraft.Client.Rendering
Coordinates3D.West
};
+ private static readonly VisibleFaces[] AdjacentCoordFaces =
+ {
+ VisibleFaces.Bottom,
+ VisibleFaces.Top,
+ VisibleFaces.South,
+ VisibleFaces.North,
+ VisibleFaces.West,
+ VisibleFaces.East
+ };
+
protected override bool TryRender(ReadOnlyChunk item, out Mesh result)
{
var state = new RenderState();
- ProcessChunk(item, state);
+ ProcessChunk(World, item, state);
result = new ChunkMesh(item, Game, state.Verticies.ToArray(),
state.OpaqueIndicies.ToArray(), state.TransparentIndicies.ToArray());
@@ -70,15 +82,125 @@ namespace TrueCraft.Client.Rendering
return (result != null);
}
- private class RenderState
+ [Flags]
+ public enum VisibleFaces
{
- public readonly List Verticies = new List();
- public readonly List OpaqueIndicies = new List();
- public readonly List TransparentIndicies = new List();
- public readonly HashSet DrawableCoordinates = new HashSet();
+ None = 0,
+ North = 1,
+ South = 2,
+ East = 4,
+ West = 8,
+ Top = 16,
+ Bottom = 32,
+ All = North | South | East | West | Top | Bottom
}
- private void ProcessChunk(ReadOnlyChunk chunk, RenderState state)
+ private class RenderState
+ {
+ public readonly List Verticies
+ = new List();
+ public readonly List OpaqueIndicies = new List();
+ public readonly List TransparentIndicies = new List();
+ public readonly Dictionary DrawableCoordinates
+ = new Dictionary();
+ }
+
+ private void AddBottomBlock(Coordinates3D coords, RenderState state, ReadOnlyChunk chunk)
+ {
+ var desiredFaces = VisibleFaces.None;
+ if (coords.X == 0)
+ desiredFaces |= VisibleFaces.West;
+ else if (coords.X == Chunk.Width - 1)
+ desiredFaces |= VisibleFaces.East;
+ if (coords.Z == 0)
+ desiredFaces |= VisibleFaces.North;
+ else if (coords.Z == Chunk.Depth - 1)
+ desiredFaces |= VisibleFaces.South;
+ if (coords.Y == 0)
+ desiredFaces |= VisibleFaces.Bottom;
+ else if (coords.Y == Chunk.Depth - 1)
+ desiredFaces |= VisibleFaces.Top;
+
+ VisibleFaces faces;
+ state.DrawableCoordinates.TryGetValue(coords, out faces);
+ faces |= desiredFaces;
+ state.DrawableCoordinates[coords] = desiredFaces;
+ }
+
+ private void AddAdjacentBlocks(Coordinates3D coords, RenderState state, ReadOnlyChunk chunk)
+ {
+ // Add adjacent blocks
+ for (int i = 0; i < AdjacentCoordinates.Length; i++)
+ {
+ var next = coords + AdjacentCoordinates[i];
+ if (next.X < 0 || next.X >= Chunk.Width
+ || next.Y < 0 || next.Y >= Chunk.Height
+ || next.Z < 0 || next.Z >= Chunk.Depth)
+ {
+ continue;
+ }
+ if (chunk.GetBlockId(next) != 0)
+ {
+ VisibleFaces faces;
+ state.DrawableCoordinates.TryGetValue(next, out faces);
+ faces |= AdjacentCoordFaces[i];
+ state.DrawableCoordinates[next] = faces;
+ }
+ }
+ }
+
+ private void UpdateFacesFromAdjacent(Coordinates3D adjacent, ReadOnlyChunk chunk,
+ VisibleFaces mod, ref VisibleFaces faces)
+ {
+ if (chunk == null)
+ return;
+ var provider = BlockRepository.GetBlockProvider(chunk.GetBlockId(adjacent));
+ if (!provider.Opaque)
+ faces |= mod;
+ }
+
+ private void AddChunkBoundaryBlocks(Coordinates3D coords, RenderState state, ReadOnlyChunk chunk)
+ {
+ VisibleFaces faces;
+ if (!state.DrawableCoordinates.TryGetValue(coords, out faces))
+ faces = VisibleFaces.None;
+ VisibleFaces oldFaces = faces;
+
+ if (coords.X == 0)
+ {
+ var adjacent = coords;
+ adjacent.X = Chunk.Width - 1;
+ var nextChunk = World.GetChunk(chunk.Chunk.Coordinates + Coordinates2D.West);
+ UpdateFacesFromAdjacent(adjacent, nextChunk, VisibleFaces.West, ref faces);
+ }
+ else if (coords.X == Chunk.Width - 1)
+ {
+ var adjacent = coords;
+ adjacent.X = 0;
+ var nextChunk = World.GetChunk(chunk.Chunk.Coordinates + Coordinates2D.East);
+ UpdateFacesFromAdjacent(adjacent, nextChunk, VisibleFaces.East, ref faces);
+ }
+
+ if (coords.Z == 0)
+ {
+ var adjacent = coords;
+ adjacent.Z = Chunk.Depth - 1;
+ var nextChunk = World.GetChunk(chunk.Chunk.Coordinates + Coordinates2D.North);
+ UpdateFacesFromAdjacent(adjacent, nextChunk, VisibleFaces.North, ref faces);
+ }
+ else if (coords.Z == Chunk.Depth - 1)
+ {
+ var adjacent = coords;
+ adjacent.Z = 0;
+ var nextChunk = World.GetChunk(chunk.Chunk.Coordinates + Coordinates2D.South);
+ UpdateFacesFromAdjacent(adjacent, nextChunk, VisibleFaces.South, ref faces);
+ }
+
+ if (oldFaces != faces)
+ state.DrawableCoordinates[coords] = faces;
+ }
+
+ private void ProcessChunk(ReadOnlyWorld world, ReadOnlyChunk chunk, RenderState state)
{
state.Verticies.Clear();
state.OpaqueIndicies.Clear();
@@ -94,26 +216,16 @@ namespace TrueCraft.Client.Rendering
var coords = new Coordinates3D(x, y, z);
var id = chunk.GetBlockId(coords);
var provider = BlockRepository.GetBlockProvider(id);
- if (id != 0 && (coords.X == 0 || coords.X == Chunk.Width - 1
- || coords.Y == 0 || coords.Y == Chunk.Height - 1
- || coords.Z == 0 || coords.Z == Chunk.Depth - 1))
- {
- state.DrawableCoordinates.Add(coords);
- }
+ if (id != 0 && coords.Y == 0)
+ AddBottomBlock(coords, state, chunk);
if (!provider.Opaque)
+ AddAdjacentBlocks(coords, state, chunk);
+ else
{
- // Add adjacent blocks
- foreach (var a in AdjacentCoordinates)
+ if (coords.X == 0 || coords.X == Chunk.Width - 1 ||
+ coords.Z == 0 || coords.Z == Chunk.Depth - 1)
{
- var next = coords + a;
- if (next.X < 0 || next.X >= Chunk.Width
- || next.Y < 0 || next.Y >= Chunk.Height
- || next.Z < 0 || next.Z >= Chunk.Depth)
- {
- continue;
- }
- if (chunk.GetBlockId(next) != 0)
- state.DrawableCoordinates.Add(next);
+ AddChunkBoundaryBlocks(coords, state, chunk);
}
}
}
@@ -124,13 +236,14 @@ namespace TrueCraft.Client.Rendering
{
var coords = enumerator.Current;
enumerator.MoveNext();
+ var c = coords.Key;
var descriptor = new BlockDescriptor
{
- ID = chunk.GetBlockId(coords),
- Metadata = chunk.GetMetadata(coords),
- BlockLight = chunk.GetBlockLight(coords),
- SkyLight = chunk.GetSkyLight(coords),
- Coordinates = coords,
+ ID = chunk.GetBlockId(coords.Key),
+ Metadata = chunk.GetMetadata(coords.Key),
+ BlockLight = chunk.GetBlockLight(coords.Key),
+ SkyLight = chunk.GetSkyLight(coords.Key),
+ Coordinates = coords.Key,
Chunk = chunk.Chunk
};
var provider = BlockRepository.GetBlockProvider(descriptor.ID);
@@ -138,7 +251,7 @@ namespace TrueCraft.Client.Rendering
{
int[] i;
var v = BlockRenderer.RenderBlock(provider, descriptor,
- new Vector3(chunk.X * Chunk.Width + coords.X, coords.Y, chunk.Z * Chunk.Depth + coords.Z),
+ new Vector3(chunk.X * Chunk.Width + c.X, c.Y, chunk.Z * Chunk.Depth + c.Z),
state.Verticies.Count, out i);
state.Verticies.AddRange(v);
state.OpaqueIndicies.AddRange(i);
@@ -147,7 +260,7 @@ namespace TrueCraft.Client.Rendering
{
int[] i;
var v = BlockRenderer.RenderBlock(provider, descriptor,
- new Vector3(chunk.X * Chunk.Width + coords.X, coords.Y, chunk.Z * Chunk.Depth + coords.Z),
+ new Vector3(chunk.X * Chunk.Width + c.X, c.Y, chunk.Z * Chunk.Depth + c.Z),
state.Verticies.Count, out i);
state.Verticies.AddRange(v);
state.TransparentIndicies.AddRange(i);
diff --git a/TrueCraft.Client/TrueCraft.Client.csproj b/TrueCraft.Client/TrueCraft.Client.csproj
index e41111a..4a5fe6b 100644
--- a/TrueCraft.Client/TrueCraft.Client.csproj
+++ b/TrueCraft.Client/TrueCraft.Client.csproj
@@ -47,18 +47,15 @@
localhost TestUser
- v4.5
+ true
- v4.5
- v4.5
- v4.5
@@ -68,6 +65,9 @@
DEBUG;
true
+
+ false
+
..\lib\Ionic.Zip.Reduced.dll
@@ -190,7 +190,7 @@
PreserveNewest
- PreserveNewest
+ Always
PreserveNewest
diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs
index 4c34dda..9e1904d 100644
--- a/TrueCraft.Client/TrueCraftGame.cs
+++ b/TrueCraft.Client/TrueCraftGame.cs
@@ -78,7 +78,7 @@ namespace TrueCraft.Client
Interfaces = new List();
SpriteBatch = new SpriteBatch(GraphicsDevice);
base.Initialize(); // (calls LoadContent)
- ChunkConverter = new ChunkRenderer(this, Client.World.World.BlockRepository);
+ ChunkConverter = new ChunkRenderer(Client.World, this, Client.World.World.BlockRepository);
Client.ChunkLoaded += (sender, e) => ChunkConverter.Enqueue(e.Chunk);
//Client.ChunkModified += (sender, e) => ChunkConverter.Enqueue(e.Chunk, true);
ChunkConverter.MeshCompleted += ChunkConverter_MeshGenerated;
@@ -302,7 +302,7 @@ namespace TrueCraft.Client
Mouse.SetPosition(centerX, centerY);
var look = new Vector2((centerX - e.X), (centerY - e.Y))
- * (float)(GameTime.ElapsedGameTime.TotalSeconds * 70);
+ * (float)(GameTime.ElapsedGameTime.TotalSeconds * 90);
Client.Yaw += look.X;
Client.Pitch += look.Y;