6 using Vintagestory.API.Client;
7 using Vintagestory.API.Common;
8 using Vintagestory.API.MathTools;
12 public class AlternateRenderer : IChunkRenderer
14 private readonly int chunkSize;
18 /// V.G.D:'s Alternative renderer
20 /// <param name="clientAPI">Client API.</param>
21 /// <param name="logger">Logger.</param>
22 public AlternateRenderer(ICoreClientAPI clientAPI, ILogger logger) : base(clientAPI, logger)
24 chunkSize = ClientAPI.World.BlockAccessor.ChunkSize;
27 public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta metaData, PngWriter pngWriter, out uint pixelCount)
30 BlockPos tmpPos = new BlockPos();
31 Vec2i localpos = new Vec2i();
32 var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
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++)
39 chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
40 //What to do if chunk is a void? invalid?
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++)
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;
53 MapUtil.PosInt2d(posIndex, chunkSize, localpos);
54 int localX = localpos.X;
55 int localZ = localpos.Y;
57 chunksColumn[localChunkY].Unpack();
58 int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, currY % chunkSize, localZ, chunkSize, chunkSize)];
60 Block block = ClientAPI.World.Blocks[blockId];
62 tmpPos.Set(chunkSize * chunkPos.X + localX, currY, chunkSize * chunkPos.Y + localZ);
68 //============ POI Population =================
69 if (BlockID_Designators.ContainsKey(blockId))
71 var desig = BlockID_Designators[blockId];
72 red = desig.OverwriteColor.R;
73 green = desig.OverwriteColor.G;
74 blue = desig.OverwriteColor.B;
77 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
81 float b = GetSlope(localX, localZ, allMapYs);
83 int col = block.GetColor(ClientAPI, tmpPos);
84 int packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
86 red = ColorUtil.ColorB(packedFormat);
87 green = ColorUtil.ColorG(packedFormat);
88 blue = ColorUtil.ColorR(packedFormat);
89 ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
91 //chunkImage.SetPixel(localX, localZ, pixelColor);
95 for (int row = 0; row < pngWriter.ImgInfo.Rows; row++)
97 pngWriter.WriteRow(lines[row], row);
103 private float GetSlope(int x, int y, ushort[] heightMap)
105 int baseY = heightMap[MapUtil.Index2d(x, y, chunkSize)];
107 // check bounds. i hate this.
111 locIndex = MapUtil.Index2d(x - 1, y, chunkSize);
112 runningY += (baseY - heightMap[locIndex]);
114 if (x < chunkSize - 1)
116 locIndex = MapUtil.Index2d(x + 1, y, chunkSize);
117 runningY += (baseY - heightMap[locIndex]);
121 locIndex = MapUtil.Index2d(x, y - 1, chunkSize);
122 runningY += (baseY - heightMap[locIndex]);
124 if (y < chunkSize - 1)
126 locIndex = MapUtil.Index2d(x, y + 1, chunkSize);
127 runningY += (baseY - heightMap[locIndex]);
129 runningY /= 4; // average now
130 runningY /= 5; // idk