OSDN Git Service

Split Renderers (W.I.P.)
[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                 chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
39                 //What to do if chunk is a void? invalid?
40                 }
41
42                 //pre-create PNG line slices...
43                 ImageLine[ ] lines = Enumerable.Repeat(new object( ), chunkSize).Select(l => new ImageLine(pngWriter.ImgInfo)).ToArray( );
44                 ushort[ ] allMapYs = mc.RainHeightMap;
45                 for (int posIndex = 0; posIndex < (chunkSize * chunkSize); posIndex++) {
46                 int currY = allMapYs[posIndex];
47                 int localChunkY = currY / chunkSize;
48                 if (localChunkY >= (chunksColumn.Length)) continue; //Out of range!
49                 if (chunksColumn[localChunkY] == null) continue;
50
51                 MapUtil.PosInt2d(posIndex, chunkSize, localpos);
52                 int localX = localpos.X;
53                 int localZ = localpos.Y;
54
55                 chunksColumn[localChunkY].Unpack( );
56                 int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, currY % chunkSize, localZ, chunkSize, chunkSize)];
57
58                 Block block = ClientAPI.World.Blocks[blockId];
59
60                 tmpPos.Set(chunkSize * chunkPos.X + localX, currY, chunkSize * chunkPos.Y + localZ);
61
62                 int red;
63                 int green;
64                 int blue;
65
66                 //============ POI Population =================
67                 if (BlockID_Designators.ContainsKey(blockId)) {
68                 var desig = BlockID_Designators[blockId];
69                 red = desig.OverwriteColor.R;
70                 green = desig.OverwriteColor.G;
71                 blue = desig.OverwriteColor.B;
72
73                 
74                 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
75                 continue;
76                 }
77
78                 float b = GetSlope(localX, localZ, allMapYs);
79
80                 int col = block.GetColor(ClientAPI, tmpPos);
81                 int packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
82
83                 red = ColorUtil.ColorB(packedFormat);
84                 green = ColorUtil.ColorG(packedFormat);
85                 blue = ColorUtil.ColorR(packedFormat);
86                 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
87
88                 //chunkImage.SetPixel(localX, localZ, pixelColor);
89                 pixelCount++;
90                 }
91
92                 for (int row = 0; row < pngWriter.ImgInfo.Rows; row++) {
93                 pngWriter.WriteRow(lines[row], row);
94                 }
95
96                 pngWriter.End( );
97                 }
98
99                 private float GetSlope(int x, int y, ushort[ ] heightMap)
100                 {
101                 int baseY = heightMap[MapUtil.Index2d(x, y, chunkSize)];
102                 float runningY = 0;
103                 // check bounds. i hate this.
104                 int locIndex;
105                 if (x > 0) {
106                 locIndex = MapUtil.Index2d(x - 1, y, chunkSize);
107                 runningY += (baseY - heightMap[locIndex]);
108                 }
109                 if (x < chunkSize - 1) {
110                 locIndex = MapUtil.Index2d(x + 1, y, chunkSize);
111                 runningY += (baseY - heightMap[locIndex]);
112                 }
113                 if (y > 0) {
114                 locIndex = MapUtil.Index2d(x, y - 1, chunkSize);
115                 runningY += (baseY - heightMap[locIndex]);
116                 }
117                 if (y < chunkSize - 1) {
118                 locIndex = MapUtil.Index2d(x, y + 1, chunkSize);
119                 runningY += (baseY - heightMap[locIndex]);
120                 }
121                 runningY /= 4; // average now
122                 runningY /= 5; // idk
123                 return 1 + runningY;
124                 }
125         }
126 }
127