using System;
using System.Collections.Generic;
+//using System.Drawing;
+//using System.Drawing.Imaging;
+//using System.IO;
using System.Linq;
using Hjg.Pngcs;
{
public class StandardRenderer : AChunkRenderer
{
+ public const string Name = @"Standard";
/// <summary>
/// Renders shards similar to the Default VS version, plus P.O.I. markings.
/// <param name="logger">Logger.</param>
public StandardRenderer(ICoreClientAPI clientAPI, ILogger logger, bool seasonalColor) : base(clientAPI, logger, seasonalColor)
{
-
+
}
- public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta targetColMeta, ref ColumnsMetadata allCols, out uint pixelCount)
+ public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mapChunk, ColumnMeta targetColMeta, ref ColumnsMetadata allCols, out uint pixelCount)
{
pixelCount = 0;
BlockPos tmpPos = new BlockPos( );
}
}
- // Prefetch map chunks, in pattern
- var mapCornerChunks = new List<ColumnMeta>(3);
-
- var south_west = new Vec2i(chunkPos.X - 1, chunkPos.Y - 1);
- var west = new Vec2i(chunkPos.X - 1, chunkPos.Y);
- var south = new Vec2i(chunkPos.X, chunkPos.Y - 1);
+ // Prefetch map chunks, in pattern
+ var corner_pos = new Vec2i(chunkPos.X - 1, chunkPos.Y - 1);
+ var west_pos = new Vec2i(chunkPos.X, chunkPos.Y - 1);
+ var north_pos = new Vec2i(chunkPos.X - 1 , chunkPos.Y);
- bool nullSouthWest = false, nullSouth = false, nullWest = false;
+ uint missingRainmap = 0, missingHeightmap = 0;
+ ColumnMeta north, northWest, west;
/*
- For missing corners / cardinal heightmaps...
- make fake heightmap dummy
+ "Overlap" Heightmap for Slope (height) values; covers 1 whole + 2 chunk edges, and corner block,
+ substitute ZERO with Average Height....better than nothing even if its wrong?
*/
+ var overlapHeightmap = new ushort[chunkSize + 1, chunkSize + 1];
- if (allCols.Contains(south_west)) {
- mapCornerChunks.Add(allCols[south_west]);
- }
- else {
- nullSouthWest = true;
- mapCornerChunks.Add(targetColMeta);//Temporary!
+ //Ofset copy of Heightmap...copied to Bottom, Rightmost
+ for (int copyX = 0; copyX < chunkSize; copyX++)
+ {
+ for (int copyY = 0; copyY < chunkSize; copyY++) {
+ overlapHeightmap[copyX + 1, copyY + 1] = targetColMeta.HeightMap[copyX, copyY];
+ }
}
- if (allCols.Contains(south)) {
- mapCornerChunks.Add(allCols[south]);
+
+
+ if (allCols.Contains(corner_pos) && allCols[corner_pos].HeightMap != null) {
+ northWest = allCols[corner_pos];
+ overlapHeightmap[0, 0] = northWest.HeightMap[chunkSize - 1, chunkSize - 1];
}
else {
- nullSouth = true;
- mapCornerChunks.Add(targetColMeta);//Temporary!
- }
+ missingHeightmap++;
+ var cornerMC = ClientAPI.World.BlockAccessor.GetMapChunk(corner_pos);
+ if (cornerMC != null && cornerMC.RainHeightMap != null)
+ {
+ overlapHeightmap[0, 0] = cornerMC.RainHeight2DMap(chunkSize - 1, (chunkSize - 1));
+ } else missingRainmap++;
+ }
+
+ if (allCols.Contains(north_pos) && allCols[north_pos].HeightMap != null) {
+ north = allCols[north_pos];
- if (allCols.Contains(west)) {
- mapCornerChunks.Add(allCols[west]);
+ for (int northEdgeIndex = 0; northEdgeIndex < chunkSize; northEdgeIndex++)
+ {
+ overlapHeightmap[0, northEdgeIndex + 1 ] = north.HeightMap[ (chunkSize - 1), northEdgeIndex];
+ }
+ }
+ else {
+ missingHeightmap++;
+ var northMC = ClientAPI.World.BlockAccessor.GetMapChunk(north_pos);
+ if (northMC != null && northMC.RainHeightMap != null) {
+ for (int northEdgeIndex = 0; northEdgeIndex < chunkSize; northEdgeIndex++)
+ {
+ overlapHeightmap[0, northEdgeIndex + 1] = northMC.RainHeight2DMap((chunkSize - 1), northEdgeIndex);
+ }
+ } else missingRainmap++;
}
+
+ if (allCols.Contains(west_pos) && allCols[west_pos].HeightMap != null) {
+ west = allCols[west_pos];
+
+ for (int westEdgeIndex = 0; westEdgeIndex < chunkSize; westEdgeIndex++)
+ {
+ overlapHeightmap[westEdgeIndex + 1, 0] = west.HeightMap[westEdgeIndex, chunkSize - 1];
+ }
+ }
else {
- nullWest = true;
- mapCornerChunks.Add(targetColMeta);//Temporary!
+ missingHeightmap++;
+ var westMC = ClientAPI.World.BlockAccessor.GetMapChunk(west_pos);
+ if (westMC != null && westMC.RainHeightMap != null) {
+ for (int westEdgeIndex = 0; westEdgeIndex < chunkSize; westEdgeIndex++) {
+ overlapHeightmap[westEdgeIndex + 1, 0] = westMC.RainHeight2DMap(westEdgeIndex, chunkSize - 1);
}
+ } else missingRainmap++;
+ }
+
+ ushort avgOverlap_Y = ( ushort )overlapHeightmap.OfType<ushort>( ).Average((ushort sel) => sel == 0 ? targetColMeta.YMax : sel);
+ //TODO: Row - then - Column averaging at Edges?
+
+ #if DEBUG
+ var badHeightData = overlapHeightmap.OfType<ushort>( ).Count((ushort arg) => arg == 0);
+
+ if (badHeightData > 0)
+ Logger.VerboseDebug("H.M Zeros# {0} , Missing Rainmaps {1} Heightmaps {2}",badHeightData ,missingRainmap, missingHeightmap);
+
+ //RenderDebugBitmap(overlapHeightmap, chunkPos);
+ #endif
+
for (int pixelIndex = 0; pixelIndex < (chunkSize * chunkSize); pixelIndex++) {
+ /********* PIXEL RENDERING LOOP **********/
MapUtil.PosInt2d(pixelIndex, chunkSize, localpos);
int localX = localpos.X;
int localZ = localpos.Y;
int localChunkY = localY / chunkSize;
if (localChunkY >= (chunksColumn.Length)) continue;//Out of range!
- if (chunksColumn[localChunkY] == null) continue;//BIG Gaps!
- //if (mapCornerChunks.Any(chks => chks == null)) {
- //Logger.Warning("mapCornerChunks A.W.O.L. near : X{0} Y{1} Z{2} - ", localX, localY, localZ);
- //continue;
- //}
-
- float slopeBoost = 1;
- int leftTop, rightTop, leftBot;
-
- ColumnMeta leftTopMapChunk = targetColMeta;
- ColumnMeta rightTopMapChunk = targetColMeta;
- ColumnMeta leftBotMapChunk = targetColMeta;
-
- int topX = localX - 1;
- int botX = localX;
- int leftZ = localZ - 1;
- int rightZ = localZ;
-
- if (topX < 0 && leftZ < 0) {
- leftTopMapChunk = mapCornerChunks[0];
- rightTopMapChunk = mapCornerChunks[1];
- leftBotMapChunk = mapCornerChunks[2];
- }
- else {
- if (topX < 0) {
- leftTopMapChunk = mapCornerChunks[1];
- rightTopMapChunk = mapCornerChunks[1];
- }
- if (leftZ < 0) {
- leftTopMapChunk = mapCornerChunks[2];
- leftBotMapChunk = mapCornerChunks[2];
- }
+ if (chunksColumn[localChunkY] == null)
+ {
+ #if DEBUG
+ Logger.VerboseDebug("Gap in chunk-column at render time Chunk-Y:{0}", localChunkY);
+ #endif
+ continue;
}
- topX = GameMath.Mod(topX, chunkSize);
- leftZ = GameMath.Mod(leftZ, chunkSize);
-
- leftTop = nullSouthWest ? 0 : Math.Sign(localY - leftTopMapChunk.HeightMap[topX, leftZ]);
- rightTop = nullSouth ? 0 : Math.Sign(localY - rightTopMapChunk.HeightMap[topX, rightZ]);
- leftBot = nullWest ? 0 : Math.Sign(localY - leftBotMapChunk.HeightMap[botX, leftZ]);
+ float slopeBoost = 1f;
+ int northH, northWestH, westH;
- float slopeness = (leftTop + rightTop + leftBot);
+ int north_X = localX + 1;
+ int north_Z = localZ;
+ int west_X = localX;
+ int west_Z = localZ + 1;
+ int northWest_X = localX;
+ int northWest_Z = localZ;
+ bool edge = localX == 0 || localZ == 0;
+
+ northH = Math.Sign(localY - (overlapHeightmap[north_X, north_Z] == 0 ? localY : overlapHeightmap[north_X, north_Z]));
+ northWestH = Math.Sign(localY - (overlapHeightmap[northWest_X, northWest_Z] == 0 ? localY : overlapHeightmap[northWest_X, northWest_Z]));
+ westH = Math.Sign(localY - (overlapHeightmap[west_X, west_Z] == 0 ? localY : overlapHeightmap[west_X, west_Z]));
- if (slopeness > 0) slopeBoost = 1.2f;
- if (slopeness < 0) slopeBoost = 0.8f;
+ float slopeness = (northH + northWestH + westH);
+ float tolerance = edge ? 2.0f : 0f;
- slopeBoost -= 0.15f; //Slope boost value
+
+ if (slopeness > tolerance) slopeBoost = 1.2f;
+ if (slopeness < tolerance) slopeBoost = 0.8f;
+ if (Math.Abs(slopeness) <= float.Epsilon) slopeBoost = 1.0f;//Same height
+ //slopeBoost -= 0.15f; //Slope boost value
int blockId = chunksColumn[localChunkY].MaybeBlocks[MapUtil.Index3d(localX, (localY % chunkSize), localZ, chunkSize, chunkSize)];
this.PngWriter.End( );
}
+
+ /*
+ private void RenderDebugBitmap( ushort[ , ] heightmap, Vec2i chunkOrigin )
+ {
+ Bitmap mapBitmap = null;
+ Graphics gContext = null;
+ mapBitmap = new Bitmap(33, 33, PixelFormat.Format24bppRgb);
+ gContext = Graphics.FromImage(mapBitmap);
+
+ for (int x = 0; x <= chunkSize; x++) {
+ for (int y = 0; y <= chunkSize; y++) {
+ ushort heightCol = heightmap[x, y];
+ Color color= Color.FromArgb((byte)heightCol,( byte )heightCol,( byte )heightCol);
+ mapBitmap.SetPixel(x, y, color);
+ }
+ }
+
+ gContext.Flush(System.Drawing.Drawing2D.FlushIntention.Sync);
+
+ var fileName = Path.Combine( ClientAPI.GetOrCreateDataPath("Heightmaps"),$"offhm_{chunkOrigin.X}-{chunkOrigin.Y}.png");
+ mapBitmap.Save(fileName, ImageFormat.Png);
+
+ }
+ */
}
}
\ No newline at end of file