OSDN Git Service

W.I.P. Heightmap, needs handling for permeable blocks
[automap/automap.git] / Automap / Renderers / StandardRenderer.cs
index 3ee4c7f..3003546 100644 (file)
@@ -6,156 +6,143 @@ using Hjg.Pngcs;
 using Vintagestory.API.Client;
 using Vintagestory.API.Common;
 using Vintagestory.API.MathTools;
+using Vintagestory.Common;
 
 namespace Automap
 {
-       public class StandardRenderer : IChunkRenderer
+       public class StandardRenderer : AChunkRenderer
        {
-               private readonly int chunkSize;
-
 
                /// <summary>
                /// Renders shards similar to the Default VS version, plus P.O.I. markings.
                /// </summary>
                /// <param name="clientAPI">Client API.</param>
                /// <param name="logger">Logger.</param>
-               public StandardRenderer(ICoreClientAPI clientAPI, ILogger logger) : base(clientAPI, logger)
+               public StandardRenderer(ICoreClientAPI clientAPI, ILogger logger, bool seasonalColor) : base(clientAPI, logger, seasonalColor)
                {
-                       chunkSize = ClientAPI.World.BlockAccessor.ChunkSize;
+
                }
 
-               public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta metaData, PngWriter pngWriter, out uint pixelCount)
+               public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta metaData, out uint pixelCount)
                {
-                       pixelCount = 0;
-                       BlockPos tmpPos = new BlockPos();
-                       Vec2i localpos = new Vec2i();
+               pixelCount = 0;
+               BlockPos tmpPos = new BlockPos( );
+               Vec2i localpos = new Vec2i( );
 
-                       var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
+               var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
 
-                       int topChunkY = mc.YMax / chunkSize;//Heywaitaminute -- this isn't a highest FEATURE, if Rainmap isn't accurate!
+               //pre-create PNG line slices...
+               ImageLine[ ] lines = Enumerable.Repeat(new object( ), chunkSize).Select(l => new ImageLine(this.PngWriter.ImgInfo)).ToArray( );
 
-                       for (int chunkY = 0; chunkY <= topChunkY; chunkY++)
-                       {
-                               chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
-                               //What to do if chunk is a void? invalid?
-                       }
+               int topChunkY = metaData.YMax / chunkSize;
 
-                       // Prefetch map chunks, in pattern
-                       IMapChunk[] mapChunks = new IMapChunk[]
-                       {
-                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y - 1),
-                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y),
-                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X, chunkPos.Y - 1)
-                       };
-
-                       //pre-create PNG line slices...
-                       ImageLine[] lines = Enumerable.Repeat(new object(), chunkSize).Select(l => new ImageLine(pngWriter.ImgInfo)).ToArray();
-
-                       for (int posIndex = 0; posIndex < (chunkSize * chunkSize); posIndex++)
-                       {
-                               int mapY = mc.RainHeightMap[posIndex];
-                               int localChunkY = mapY / chunkSize;
-                               if (localChunkY >= (chunksColumn.Length)) continue;//Out of range!
-
-                               MapUtil.PosInt2d(posIndex, chunkSize, localpos);
-                               int localX = localpos.X;
-                               int localZ = localpos.Y;
-
-                               float b = 1;
-                               int leftTop, rightTop, leftBot;
-
-                               IMapChunk leftTopMapChunk = mc;
-                               IMapChunk rightTopMapChunk = mc;
-                               IMapChunk leftBotMapChunk = mc;
-
-                               int topX = localX - 1;
-                               int botX = localX;
-                               int leftZ = localZ - 1;
-                               int rightZ = localZ;
-
-                               if (topX < 0 && leftZ < 0)
+               for (int chunkY = 0; chunkY <= topChunkY; chunkY++) 
+               {
+                       chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
+                       WorldChunk ownChunk = chunksColumn[chunkY] as WorldChunk;
+                       if (ownChunk != null) 
                                {
-                                       leftTopMapChunk = mapChunks[0];
-                                       rightTopMapChunk = mapChunks[1];
-                                       leftBotMapChunk = mapChunks[2];
+                               if (ownChunk.IsPacked( )) ownChunk.Unpack( );//Gah - probably done already by chunk processor
                                }
-                               else
+                               else 
                                {
-                                       if (topX < 0)
-                                       {
-                                               leftTopMapChunk = mapChunks[1];
-                                               rightTopMapChunk = mapChunks[1];
-                                       }
-                                       if (leftZ < 0)
-                                       {
-                                               leftTopMapChunk = mapChunks[2];
-                                               leftBotMapChunk = mapChunks[2];
-                                       }
+                               Logger.Warning("CHUNK A.W.O.L. : X{0} Y{1} Z{2} - Missing slice FOR COLUMN", chunkPos.X, chunkY, chunkPos.Y);
+                               //return;
                                }
+               }
 
-                               topX = GameMath.Mod(topX, chunkSize);
-                               leftZ = GameMath.Mod(leftZ, chunkSize);
-
-                               leftTop = leftTopMapChunk == null ? 0 : Math.Sign(mapY - leftTopMapChunk.RainHeightMap[leftZ * chunkSize + topX]);
-                               rightTop = rightTopMapChunk == null ? 0 : Math.Sign(mapY - rightTopMapChunk.RainHeightMap[rightZ * chunkSize + topX]);
-                               leftBot = leftBotMapChunk == null ? 0 : Math.Sign(mapY - leftBotMapChunk.RainHeightMap[leftZ * chunkSize + botX]);
-
-                               float slopeness = (leftTop + rightTop + leftBot);
-
-                               if (slopeness > 0) b = 1.2f;
-                               if (slopeness < 0) b = 0.8f;
-
-                               b -= 0.15f; //Slope boost value 
+               // Prefetch map chunks, in pattern
+               IMapChunk[ ] mapChunks = new IMapChunk[ ]
+               {
+                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y - 1),
+                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y),
+                       ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X, chunkPos.Y - 1)
+               };
+               
+
+               for (int pixelIndex = 0; pixelIndex < (chunkSize * chunkSize); pixelIndex++) {
+               MapUtil.PosInt2d(pixelIndex, chunkSize, localpos);
+               int localX = localpos.X;
+               int localZ = localpos.Y;
+               ushort localY = metaData.HeightMap[localX, localZ];//mc.RainHeightMap[posIndex];//NOPE NOPE NOPE, RAINMAP IS CRAP. USE IT NOT!
+
+               int localChunkY = localY / chunkSize;
+               if (localChunkY >= (chunksColumn.Length)) continue;//Out of range!
+               if (chunksColumn[localChunkY] == null) continue;//BIG Gaps!
+
+               float slopeBoost = 1;
+               int leftTop, rightTop, leftBot;
+
+               IMapChunk leftTopMapChunk = mc;
+               IMapChunk rightTopMapChunk = mc;
+               IMapChunk leftBotMapChunk = mc;
+
+               int topX = localX - 1;
+               int botX = localX;
+               int leftZ = localZ - 1;
+               int rightZ = localZ;
+
+               if (topX < 0 && leftZ < 0) {
+               leftTopMapChunk = mapChunks[0];
+               rightTopMapChunk = mapChunks[1];
+               leftBotMapChunk = mapChunks[2];
+               }
+               else {
+               if (topX < 0) {
+               leftTopMapChunk = mapChunks[1];
+               rightTopMapChunk = mapChunks[1];
+               }
+               if (leftZ < 0) {
+               leftTopMapChunk = mapChunks[2];
+               leftBotMapChunk = mapChunks[2];
+               }
+               }
 
-                               if (chunksColumn[localChunkY] == null)
-                               {
+               topX = GameMath.Mod(topX, chunkSize);
+               leftZ = GameMath.Mod(leftZ, chunkSize);
 
-                                       continue;
-                               }
+               leftTop = leftTopMapChunk == null ? 0 : Math.Sign(localY - leftTopMapChunk.RainHeightMap[leftZ * chunkSize + topX]);
+               rightTop = rightTopMapChunk == null ? 0 : Math.Sign(localY - rightTopMapChunk.RainHeightMap[rightZ * chunkSize + topX]);
+               leftBot = leftBotMapChunk == null ? 0 : Math.Sign(localY - leftBotMapChunk.RainHeightMap[leftZ * chunkSize + botX]);
 
-                               chunksColumn[localChunkY].Unpack();
-                               int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localpos.X, mapY % chunkSize, localpos.Y, chunkSize, chunkSize)];
+               float slopeness = (leftTop + rightTop + leftBot);
 
-                               Block block = ClientAPI.World.Blocks[blockId];
+               if (slopeness > 0) slopeBoost = 1.2f;
+               if (slopeness < 0) slopeBoost = 0.8f;
 
-                               tmpPos.Set(chunkSize * chunkPos.X + localpos.X, mapY, chunkSize * chunkPos.Y + localpos.Y);
+               slopeBoost -= 0.15f; //Slope boost value 
 
-                               int avgCol = block.GetColor(ClientAPI, tmpPos);
-                               int rndCol = block.GetRandomColor(ClientAPI, tmpPos, BlockFacing.UP);
-                               int col = ColorUtil.ColorOverlay(avgCol, rndCol, 0.125f);
-                               var packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
+               int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, (localY % chunkSize), localZ, chunkSize, chunkSize)];
 
-                               int red = ColorUtil.ColorB(packedFormat);
-                               int green = ColorUtil.ColorG(packedFormat);
-                               int blue = ColorUtil.ColorR(packedFormat);
+               Block block = ClientAPI.World.Blocks[blockId];
 
+               tmpPos.Set(chunkSize * chunkPos.X + localpos.X, localY, chunkSize * chunkPos.Y + localpos.Y);
 
-                               //============ POI Population =================
-                               if (BlockID_Designators.ContainsKey(blockId))
-                               {
-                                       var desig = BlockID_Designators[blockId];
-
-                                       if (desig.Enabled)
-                                       {
-                                               red = desig.OverwriteColor.R;
-                                               green = desig.OverwriteColor.G;
-                                               blue = desig.OverwriteColor.B;
-                                       }
-                               }
+               int red = 0, green = 0, blue = 0;
 
-                               ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
+               ExtractBlockColor(tmpPos, block, slopeBoost, out red, out green, out blue);
 
-                               //chunkImage.SetPixel(localX, localZ, pixelColor);
-                               pixelCount++;
-                       }
+               //============ POI Population =================
+               if (BlockID_Designators.ContainsKey(blockId)) {
+               var desig = BlockID_Designators[blockId];
 
-                       for (int row = 0; row < pngWriter.ImgInfo.Rows; row++)
+                       if (desig.Enabled) 
                        {
-                               pngWriter.WriteRow(lines[row], row);
+                       red = desig.OverwriteColor.R;
+                       green = desig.OverwriteColor.G;
+                       blue = desig.OverwriteColor.B;
                        }
+               }
 
-                       pngWriter.End();
+               ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
+               pixelCount++;
+               }
+
+               for (int row = 0; row < this.PngWriter.ImgInfo.Rows; row++) {
+               this.PngWriter.WriteRow(lines[row], row);
                }
-       }
-}
 
+               this.PngWriter.End( );
+               }
+       }
+}
\ No newline at end of file