OSDN Git Service

W.I.P. Heightmap, needs handling for permeable blocks
authormelchior <melchior@users.osdn.me>
Mon, 19 Oct 2020 01:50:53 +0000 (21:50 -0400)
committermelchior <melchior@users.osdn.me>
Mon, 19 Oct 2020 01:50:53 +0000 (21:50 -0400)
Automap.sln
Automap/Data/ColumnMeta.cs
Automap/Helpers.cs
Automap/Renderers/StandardRenderer.cs
Automap/Subsystems/AutomapSystem.cs
ShardProcessor/Program.cs
ShardProcessor/ShardProcessor.csproj

index 6555777..e2e2e86 100644 (file)
@@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 2012\r
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Automap", "Automap\Automap.csproj", "{0287E0DF-B785-40E8-BB50-2D684B45FC61}"\r
 EndProject\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardProcessor", "ShardProcessor\ShardProcessor.csproj", "{837EE90B-7C03-413B-B54D-B50B2ED1EC00}"\r
+EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|Any CPU = Debug|Any CPU\r
@@ -13,5 +15,9 @@ Global
                {0287E0DF-B785-40E8-BB50-2D684B45FC61}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
                {0287E0DF-B785-40E8-BB50-2D684B45FC61}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
                {0287E0DF-B785-40E8-BB50-2D684B45FC61}.Release|Any CPU.Build.0 = Release|Any CPU\r
+               {837EE90B-7C03-413B-B54D-B50B2ED1EC00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {837EE90B-7C03-413B-B54D-B50B2ED1EC00}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {837EE90B-7C03-413B-B54D-B50B2ED1EC00}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {837EE90B-7C03-413B-B54D-B50B2ED1EC00}.Release|Any CPU.Build.0 = Release|Any CPU\r
        EndGlobalSection\r
 EndGlobal\r
index f571df0..bdba0f7 100644 (file)
@@ -90,8 +90,7 @@ namespace Automap
                public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
 
                [ProtoMember(13)]
-               private ushort[] _flattened_HeightMap;
-
+               private ushort[] _flattened_HeightMap;                  
 
                /// <summary>
                /// Column Presense Bitmap
@@ -131,6 +130,18 @@ namespace Automap
                        this.YMax = mapChunk.YMax;
                }
 
+               internal void ResetMetadata(int mapSizeY )
+               {
+               if (this.ColumnPresense == null) { this.ColumnPresense = new BitArray((mapSizeY / this.ChunkSize), false); }            
+
+               //Start fresh...
+               HeightMap = new ushort[ChunkSize, ChunkSize]; 
+               RockRatio = new Dictionary<int, uint>(this.RockRatio.Count);
+               AirBlocks = 0;
+               NonAirBlocks = 0;
+               YMax = 0;
+               }
+
                [ProtoBeforeSerialization]
                private void PrepareData()
                {
index 4703379..52fd3f7 100644 (file)
@@ -161,27 +161,7 @@ namespace Automap
         }
 
 
-
-        /// <summary>
-        /// Chunk local index. Not block position!
-        /// </summary>
-        /// <remarks>Clamps to 5 bit ranges automagically</remarks>
-        public static int ChunkBlockIndicie16(int X_index, int Y_index, int Z_index)
-        {
-            return ((Y_index & 31) * 32 + (Z_index & 31)) * 32 + (X_index & 31);
-        }
-
-        /// <summary>
-        /// Chunk index converted from block position (in world)
-        /// </summary>
-        /// <returns>The block indicie.</returns>
-        /// <param name="blockPos">Block position.</param>
-        /// <remarks>Clamps to 5 bit ranges automagically</remarks>
-        public static int ChunkBlockIndicie16(BlockPos blockPos)
-        {
-            //Chunk masked
-            return ((blockPos.Y & 31) * 32 + (blockPos.Z & 31)) * 32 + (blockPos.X & 31);
-        }
+                      
     }
 }
 
index 1945e1d..3003546 100644 (file)
@@ -6,13 +6,12 @@ using Hjg.Pngcs;
 using Vintagestory.API.Client;
 using Vintagestory.API.Common;
 using Vintagestory.API.MathTools;
+using Vintagestory.Common;
 
 namespace Automap
 {
        public class StandardRenderer : AChunkRenderer
        {
-               
-
 
                /// <summary>
                /// Renders shards similar to the Default VS version, plus P.O.I. markings.
@@ -21,135 +20,129 @@ namespace Automap
                /// <param name="logger">Logger.</param>
                public StandardRenderer(ICoreClientAPI clientAPI, ILogger logger, bool seasonalColor) : base(clientAPI, logger, seasonalColor)
                {
-                       
+
                }
 
                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[]
-                       {
+               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) 
+                               {
+                               if (ownChunk.IsPacked( )) ownChunk.Unpack( );//Gah - probably done already by chunk processor
+                               }
+                               else 
+                               {
+                               Logger.Warning("CHUNK A.W.O.L. : X{0} Y{1} Z{2} - Missing slice FOR COLUMN", chunkPos.X, chunkY, chunkPos.Y);
+                               //return;
+                               }
+               }
+
+               // 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(this.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 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;
+               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!
 
-                               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];
-                                       }
-                               }
+               int localChunkY = localY / chunkSize;
+               if (localChunkY >= (chunksColumn.Length)) continue;//Out of range!
+               if (chunksColumn[localChunkY] == null) continue;//BIG Gaps!
 
-                               topX = GameMath.Mod(topX, chunkSize);
-                               leftZ = GameMath.Mod(leftZ, chunkSize);
+               float slopeBoost = 1;
+               int leftTop, rightTop, leftBot;
 
-                               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]);
+               IMapChunk leftTopMapChunk = mc;
+               IMapChunk rightTopMapChunk = mc;
+               IMapChunk leftBotMapChunk = mc;
 
-                               float slopeness = (leftTop + rightTop + leftBot);
+               int topX = localX - 1;
+               int botX = localX;
+               int leftZ = localZ - 1;
+               int rightZ = localZ;
 
-                               if (slopeness > 0) slopeBoost = 1.2f;
-                               if (slopeness < 0) slopeBoost = 0.8f;
+               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];
+               }
+               }
 
-                               slopeBoost -= 0.15f; //Slope boost value 
+               topX = GameMath.Mod(topX, chunkSize);
+               leftZ = GameMath.Mod(leftZ, chunkSize);
 
-                               if (chunksColumn[localChunkY] == null)
-                               {
+               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]);
 
-                                       continue;
-                               }
+               float slopeness = (leftTop + rightTop + leftBot);
 
-                               chunksColumn[localChunkY].Unpack();
-                               int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localpos.X, mapY % chunkSize, localpos.Y, chunkSize, chunkSize)];
+               if (slopeness > 0) slopeBoost = 1.2f;
+               if (slopeness < 0) slopeBoost = 0.8f;
 
-                               Block block = ClientAPI.World.Blocks[blockId];
+               slopeBoost -= 0.15f; //Slope boost value 
 
-                               tmpPos.Set(chunkSize * chunkPos.X + localpos.X, mapY, chunkSize * chunkPos.Y + localpos.Y);
+               int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, (localY % chunkSize), localZ, chunkSize, chunkSize)];
 
-                               int red, green, blue;
+               Block block = ClientAPI.World.Blocks[blockId];
 
-                               ExtractBlockColor(tmpPos, block, slopeBoost, out red, out green, out blue);
+               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 < this.PngWriter.ImgInfo.Rows; row++)
+                       if (desig.Enabled) 
                        {
-                               this.PngWriter.WriteRow(lines[row], row);
+                       red = desig.OverwriteColor.R;
+                       green = desig.OverwriteColor.G;
+                       blue = desig.OverwriteColor.B;
                        }
+               }
 
-                       this.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
index 11b573a..3420e4d 100644 (file)
@@ -235,11 +235,11 @@ namespace Automap
                                                {
                                                        columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem);
                                                        #if DEBUG
-                                                       Logger.VerboseDebug("Un-painted chun shard: ({0}) ", mostActiveCol.Key);
+                                                       Logger.VerboseDebug("Un-painted chunk shard: ({0}) ", mostActiveCol.Key);
                                                        #endif
                                                }
                                        }
-                                       //Cleanup persisted Metadata...
+                                       //Cleanup in-memory Metadata...
                                        chunkTopMetadata.ClearMetadata();
                                }
 
@@ -537,9 +537,16 @@ namespace Automap
                /// <param name="chunkMeta">Chunk metadata</param>
                private void ProcessChunkBlocks(Vec2i key, IMapChunk mapChunk, ref ColumnMeta chunkMeta)
                {
+                       int targetChunkY = mapChunk.YMax / chunkSize;//Surface ish... 
+                       byte chunkTally = 0;
 
-                       int targetChunkY = mapChunk.YMax / chunkSize;//Surface ... 
-                       for (; targetChunkY > 0; targetChunkY--)
+               #if DEBUG
+               Logger.VerboseDebug("Start col @ X{0} Y{1} Z{2} !", key.X, targetChunkY, key.Y);
+               #endif
+
+               chunkMeta.ResetMetadata(ClientAPI.World.BlockAccessor.MapSizeY);
+
+               for (; targetChunkY > 0; targetChunkY--)
                        {
                                WorldChunk worldChunk = ClientAPI.World.BlockAccessor.GetChunk(key.X, targetChunkY, key.Y) as WorldChunk;
 
@@ -575,70 +582,64 @@ namespace Automap
                                        }
                                }
 
-                               //NOTE: Temporary; remove - replace later
-                               if (chunkMeta.ColumnPresense == null) { chunkMeta.ColumnPresense = new BitArray((ClientAPI.World.BlockAccessor.MapSizeY / chunkSize), false); }
-                               chunkMeta.ColumnPresense[targetChunkY] = true;
-
                                /********************* Chunk/Column BLOCKs scanning ****************/
                                //Heightmap, Stats, block tally
 
                                int X_index, Y_index, Z_index;
 
-                               //Ensure ChunkData Metadata fields arn't null...due to being tossed out
-                               if (chunkMeta.HeightMap == null) { chunkMeta.HeightMap = new ushort[chunkSize, chunkSize]; }
-                               if (chunkMeta.RockRatio == null) { chunkMeta.RockRatio = new Dictionary<int, uint>(10); }
-
                                //First Chance fail-safe;
                                if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) {
                                Logger.VerboseDebug("WORLD chunk; Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", key.X, targetChunkY, key.Y);
+                               nullChunkCount++;
                                continue;
                                }               
 
-                               for (Y_index = 0; Y_index < chunkSize - 1; Y_index++)
+                               chunkMeta.ColumnPresense[targetChunkY] = true;
+                               chunkTally++;
+                               for (Y_index = 0; Y_index < chunkSize; Y_index++)
                                {
-                                       for (Z_index = 0; Z_index < chunkSize - 1; Z_index++)
+                                       for (Z_index = 0; Z_index < chunkSize; Z_index++)
                                        {
-                                               for (X_index = 0; X_index < chunkSize - 1; X_index++)
+                                               for (X_index = 0; X_index < chunkSize; X_index++) 
                                                {
-                                               /* Encode packed indicie
-                                               (y * chunksize + z) * chunksize + x
-                                               */
-                                               var indicie = Helpers.ChunkBlockIndicie16(X_index, Y_index, Z_index);
+                                               var indicie = MapUtil.Index3d(X_index, Y_index, Z_index, chunkSize, chunkSize);
 
                                                //'Last' Chance fail-safe;
                                                if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) {
                                                Logger.VerboseDebug("Processing Block: Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", X_index, Y_index, Z_index);
-                                               goto loop_bustout;;
+                                               nullChunkCount++;
+                                               goto loop_bustout; ;
                                                }
-                                               
+
                                                int aBlockId = worldChunk.Blocks[indicie];
 
-                                               if (aBlockId == 0)
-                                               {//Air
-                                                       chunkMeta.AirBlocks++;
-                                                       continue;
+                                               if (aBlockId == 0) {//Air
+                                               chunkMeta.AirBlocks++;
+                                               continue;
                                                }
 
-                                               if (RockIdCodes.ContainsKey(aBlockId))
-                                               {
-                                                       if (chunkMeta.RockRatio.ContainsKey(aBlockId))
-                                                               chunkMeta.RockRatio[aBlockId]++;
-                                                       else
-                                                               chunkMeta.RockRatio.Add(aBlockId, 1);
+                                               if (RockIdCodes.ContainsKey(aBlockId)) {
+                                               if (chunkMeta.RockRatio.ContainsKey(aBlockId))
+                                                       chunkMeta.RockRatio[aBlockId]++;
+                                               else
+                                                       chunkMeta.RockRatio.Add(aBlockId, 1);
                                                }
 
                                                chunkMeta.NonAirBlocks++;
 
-                                               //Heightmap 
-                                               if (chunkMeta.HeightMap[X_index, Z_index] == 0)
-                                               {
-                                               chunkMeta.HeightMap[X_index, Z_index] = (ushort) (Y_index + (targetChunkY * chunkSize));
-                                               }
+                                               ushort localHeight = ( ushort )(Y_index + (targetChunkY * chunkSize));
+                                               //Heightmap - Need to ignore Grass & Snow
+                                               if (localHeight > chunkMeta.HeightMap[X_index, Z_index]) 
+                                                       {
+                                                       chunkMeta.HeightMap[X_index, Z_index] = localHeight;
+                                                       if (localHeight > chunkMeta.YMax) chunkMeta.YMax = localHeight;
+                                                       }
                                                }
                                        }
                                }
                                loop_bustout:;
                        }
+                       Logger.VerboseDebug("COLUMN X{0} Z{1}: {2}, processed.", key.X , key.Y, chunkTally + 1);
                }
 
                private void UpdateEntityMetadata()
index 1db0de8..e9e5b6c 100644 (file)
@@ -4,9 +4,16 @@ namespace ShardProcessor
 {
        class MainClass
        {
+               /*
+                       -Process existing PNGs: Report/Dump contents of Chunk Metadata, as per current version
+                       -Extract contents of game's SQLLite map DB, INTO Automap type shards...
+                       -Other stuff? chunk fixing / validation?
+               */
                public static void Main(string[ ] args)
                {
-               Console.WriteLine("Hello World!");
+               Console.WriteLine("AUTOMAP Offline Shard processor v0.1");
+
+
                }
        }
 }
index 992af68..ba17e0f 100644 (file)
@@ -7,7 +7,7 @@
     <OutputType>Exe</OutputType>\r
     <RootNamespace>ShardProcessor</RootNamespace>\r
     <AssemblyName>ShardProcessor</AssemblyName>\r
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
+    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\r
   </PropertyGroup>\r
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
     <DebugSymbols>true</DebugSymbols>\r