X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=Automap%2FRenderers%2FStandardRenderer.cs;h=415f488ae458db83dcadae18fe87d34ca9fa791b;hb=508336c58ad6f456d1ea4f2c93834f0a96a93d1d;hp=3dd9578afac9d81724aa38926b187705b3883ded;hpb=9c9a3ab6f9674b2aae267da5d9350f17a25602c0;p=automap%2Fautomap.git diff --git a/Automap/Renderers/StandardRenderer.cs b/Automap/Renderers/StandardRenderer.cs index 3dd9578..415f488 100644 --- a/Automap/Renderers/StandardRenderer.cs +++ b/Automap/Renderers/StandardRenderer.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +//using System.Drawing; +//using System.Drawing.Imaging; +//using System.IO; using System.Linq; using Hjg.Pngcs; @@ -25,7 +28,7 @@ namespace Automap } - 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( ); @@ -50,46 +53,96 @@ namespace Automap } } - // Prefetch map chunks, in pattern - var mapCornerChunks = new List(3); + // 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); - 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); - - 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( ).Average((ushort sel) => sel == 0 ? targetColMeta.YMax : sel); + //TODO: Row - then - Column averaging at Edges? + + #if DEBUG + var badHeightData = overlapHeightmap.OfType( ).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; @@ -97,57 +150,37 @@ namespace Automap 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; - //} + if (chunksColumn[localChunkY] == null) + { + #if DEBUG + Logger.VerboseDebug("Gap in chunk-column at render time Chunk-Y:{0}", localChunkY); + #endif + continue; + } float slopeBoost = 1f; - 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]; - } - } + int northH, northWestH, westH; + + 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])); - 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 slopeness = (northH + northWestH + westH); + float tolerance = edge ? 2.0f : 0f; - float slopeness = (leftTop + rightTop + leftBot); - if (slopeness > 0) slopeBoost = 1.2f; - if (slopeness < 0) slopeBoost = 0.8f; + 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 - - //FIXME: disable slopes on edges...for now - if (localX == 0 || localX == 31) slopeBoost= 1.0f; - if (localZ == 0 || localZ == 31) slopeBoost= 1.0f; + //slopeBoost -= 0.15f; //Slope boost value int blockId = chunksColumn[localChunkY].MaybeBlocks[MapUtil.Index3d(localX, (localY % chunkSize), localZ, chunkSize, chunkSize)]; @@ -181,5 +214,29 @@ namespace Automap 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