OSDN Git Service

indentation
[automap/automap.git] / Automap / Renderers / AlternateRenderer.cs
1 using System;
2 using System.Linq;
3
4 using Hjg.Pngcs;
5
6 using Vintagestory.API.Client;
7 using Vintagestory.API.Common;
8 using Vintagestory.API.MathTools;
9
10 namespace Automap
11 {
12         public class AlternateRenderer : IChunkRenderer
13         {
14                 private readonly int chunkSize;
15
16
17                 /// <summary>
18                 /// V.G.D:'s Alternative renderer
19                 /// </summary>
20                 /// <param name="clientAPI">Client API.</param>
21                 /// <param name="logger">Logger.</param>
22                 public AlternateRenderer(ICoreClientAPI clientAPI, ILogger logger) : base(clientAPI, logger)
23                 {
24                         chunkSize = ClientAPI.World.BlockAccessor.ChunkSize;
25                 }
26
27                 public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta metaData, PngWriter pngWriter, out uint pixelCount)
28                 {
29                         pixelCount = 0;
30                         BlockPos tmpPos = new BlockPos();
31                         Vec2i localpos = new Vec2i();
32                         var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
33
34                         int topChunkY = mc.YMax / chunkSize;//Heywaitaminute -- this isn't a highest FEATURE, if Rainmap isn't accurate!
35                                                                                                 //Metadata of DateTime chunk was edited, chunk coords.,world-seed? Y-Max feature height
36                                                                                                 //Grab a chunk COLUMN... Topmost Y down...
37                         for (int chunkY = 0; chunkY <= topChunkY; chunkY++)
38                         {
39                                 chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
40                                 //What to do if chunk is a void? invalid?
41                         }
42
43                         //pre-create PNG line slices...
44                         ImageLine[] lines = Enumerable.Repeat(new object(), chunkSize).Select(l => new ImageLine(pngWriter.ImgInfo)).ToArray();
45                         ushort[] allMapYs = mc.RainHeightMap;
46                         for (int posIndex = 0; posIndex < (chunkSize * chunkSize); posIndex++)
47                         {
48                                 int currY = allMapYs[posIndex];
49                                 int localChunkY = currY / chunkSize;
50                                 if (localChunkY >= (chunksColumn.Length)) continue; //Out of range!
51                                 if (chunksColumn[localChunkY] == null) continue;
52
53                                 MapUtil.PosInt2d(posIndex, chunkSize, localpos);
54                                 int localX = localpos.X;
55                                 int localZ = localpos.Y;
56
57                                 chunksColumn[localChunkY].Unpack();
58                                 int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, currY % chunkSize, localZ, chunkSize, chunkSize)];
59
60                                 Block block = ClientAPI.World.Blocks[blockId];
61
62                                 tmpPos.Set(chunkSize * chunkPos.X + localX, currY, chunkSize * chunkPos.Y + localZ);
63
64                                 int red;
65                                 int green;
66                                 int blue;
67
68                                 //============ POI Population =================
69                                 if (BlockID_Designators.ContainsKey(blockId))
70                                 {
71                                         var desig = BlockID_Designators[blockId];
72                                         red = desig.OverwriteColor.R;
73                                         green = desig.OverwriteColor.G;
74                                         blue = desig.OverwriteColor.B;
75
76
77                                         ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
78                                         continue;
79                                 }
80
81                                 float b = GetSlope(localX, localZ, allMapYs);
82
83                                 int col = block.GetColor(ClientAPI, tmpPos);
84                                 int packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
85
86                                 red = ColorUtil.ColorB(packedFormat);
87                                 green = ColorUtil.ColorG(packedFormat);
88                                 blue = ColorUtil.ColorR(packedFormat);
89                                 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
90
91                                 //chunkImage.SetPixel(localX, localZ, pixelColor);
92                                 pixelCount++;
93                         }
94
95                         for (int row = 0; row < pngWriter.ImgInfo.Rows; row++)
96                         {
97                                 pngWriter.WriteRow(lines[row], row);
98                         }
99
100                         pngWriter.End();
101                 }
102
103                 private float GetSlope(int x, int y, ushort[] heightMap)
104                 {
105                         int baseY = heightMap[MapUtil.Index2d(x, y, chunkSize)];
106                         float runningY = 0;
107                         // check bounds. i hate this.
108                         int locIndex;
109                         if (x > 0)
110                         {
111                                 locIndex = MapUtil.Index2d(x - 1, y, chunkSize);
112                                 runningY += (baseY - heightMap[locIndex]);
113                         }
114                         if (x < chunkSize - 1)
115                         {
116                                 locIndex = MapUtil.Index2d(x + 1, y, chunkSize);
117                                 runningY += (baseY - heightMap[locIndex]);
118                         }
119                         if (y > 0)
120                         {
121                                 locIndex = MapUtil.Index2d(x, y - 1, chunkSize);
122                                 runningY += (baseY - heightMap[locIndex]);
123                         }
124                         if (y < chunkSize - 1)
125                         {
126                                 locIndex = MapUtil.Index2d(x, y + 1, chunkSize);
127                                 runningY += (baseY - heightMap[locIndex]);
128                         }
129                         runningY /= 4; // average now
130                         runningY /= 5; // idk
131                         return 1 + runningY;
132                 }
133         }
134 }
135