OSDN Git Service

change the way the metadata is exported, typos
[automap/automap.git] / Automap / Renderers / StandardRenderer.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 StandardRenderer : IChunkRenderer
13         {
14                 private readonly int chunkSize;
15
16
17                 /// <summary>
18                 /// Renders shards similar to the Default VS version, plus P.O.I. markings.
19                 /// </summary>
20                 /// <param name="clientAPI">Client API.</param>
21                 /// <param name="logger">Logger.</param>
22                 public StandardRenderer(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
33                         var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
34
35                         int topChunkY = mc.YMax / chunkSize;//Heywaitaminute -- this isn't a highest FEATURE, if Rainmap isn't accurate!
36
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                         // Prefetch map chunks, in pattern
44                         IMapChunk[] mapChunks = new IMapChunk[]
45                         {
46                         ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y - 1),
47                         ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X - 1, chunkPos.Y),
48                         ClientAPI.World.BlockAccessor.GetMapChunk(chunkPos.X, chunkPos.Y - 1)
49                         };
50
51                         //pre-create PNG line slices...
52                         ImageLine[] lines = Enumerable.Repeat(new object(), chunkSize).Select(l => new ImageLine(pngWriter.ImgInfo)).ToArray();
53
54                         for (int posIndex = 0; posIndex < (chunkSize * chunkSize); posIndex++)
55                         {
56                                 int mapY = mc.RainHeightMap[posIndex];
57                                 int localChunkY = mapY / chunkSize;
58                                 if (localChunkY >= (chunksColumn.Length)) continue;//Out of range!
59
60                                 MapUtil.PosInt2d(posIndex, chunkSize, localpos);
61                                 int localX = localpos.X;
62                                 int localZ = localpos.Y;
63
64                                 float b = 1;
65                                 int leftTop, rightTop, leftBot;
66
67                                 IMapChunk leftTopMapChunk = mc;
68                                 IMapChunk rightTopMapChunk = mc;
69                                 IMapChunk leftBotMapChunk = mc;
70
71                                 int topX = localX - 1;
72                                 int botX = localX;
73                                 int leftZ = localZ - 1;
74                                 int rightZ = localZ;
75
76                                 if (topX < 0 && leftZ < 0)
77                                 {
78                                         leftTopMapChunk = mapChunks[0];
79                                         rightTopMapChunk = mapChunks[1];
80                                         leftBotMapChunk = mapChunks[2];
81                                 }
82                                 else
83                                 {
84                                         if (topX < 0)
85                                         {
86                                                 leftTopMapChunk = mapChunks[1];
87                                                 rightTopMapChunk = mapChunks[1];
88                                         }
89                                         if (leftZ < 0)
90                                         {
91                                                 leftTopMapChunk = mapChunks[2];
92                                                 leftBotMapChunk = mapChunks[2];
93                                         }
94                                 }
95
96                                 topX = GameMath.Mod(topX, chunkSize);
97                                 leftZ = GameMath.Mod(leftZ, chunkSize);
98
99                                 leftTop = leftTopMapChunk == null ? 0 : Math.Sign(mapY - leftTopMapChunk.RainHeightMap[leftZ * chunkSize + topX]);
100                                 rightTop = rightTopMapChunk == null ? 0 : Math.Sign(mapY - rightTopMapChunk.RainHeightMap[rightZ * chunkSize + topX]);
101                                 leftBot = leftBotMapChunk == null ? 0 : Math.Sign(mapY - leftBotMapChunk.RainHeightMap[leftZ * chunkSize + botX]);
102
103                                 float slopeness = (leftTop + rightTop + leftBot);
104
105                                 if (slopeness > 0) b = 1.2f;
106                                 if (slopeness < 0) b = 0.8f;
107
108                                 b -= 0.15f; //Slope boost value 
109
110                                 if (chunksColumn[localChunkY] == null)
111                                 {
112
113                                         continue;
114                                 }
115
116                                 chunksColumn[localChunkY].Unpack();
117                                 int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localpos.X, mapY % chunkSize, localpos.Y, chunkSize, chunkSize)];
118
119                                 Block block = ClientAPI.World.Blocks[blockId];
120
121                                 tmpPos.Set(chunkSize * chunkPos.X + localpos.X, mapY, chunkSize * chunkPos.Y + localpos.Y);
122
123                                 int avgCol = block.GetColor(ClientAPI, tmpPos);
124                                 int rndCol = block.GetRandomColor(ClientAPI, tmpPos, BlockFacing.UP);
125                                 int col = ColorUtil.ColorOverlay(avgCol, rndCol, 0.125f);
126                                 var packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
127
128                                 int red = ColorUtil.ColorB(packedFormat);
129                                 int green = ColorUtil.ColorG(packedFormat);
130                                 int blue = ColorUtil.ColorR(packedFormat);
131
132
133                                 //============ POI Population =================
134                                 if (BlockID_Designators.ContainsKey(blockId))
135                                 {
136                                         var desig = BlockID_Designators[blockId];
137
138                                         if (desig.Enabled)
139                                         {
140                                                 red = desig.OverwriteColor.R;
141                                                 green = desig.OverwriteColor.G;
142                                                 blue = desig.OverwriteColor.B;
143                                         }
144                                 }
145
146                                 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
147
148                                 //chunkImage.SetPixel(localX, localZ, pixelColor);
149                                 pixelCount++;
150                         }
151
152                         for (int row = 0; row < pngWriter.ImgInfo.Rows; row++)
153                         {
154                                 pngWriter.WriteRow(lines[row], row);
155                         }
156
157                         pngWriter.End();
158                 }
159         }
160 }
161