Automap (client) [VS plugin mod]
リビジョン | 4c7e775b917dcc5870dc939caae9a1dc6b7ac2b3 (tree) |
---|---|
日時 | 2021-05-17 07:40:57 |
作者 | melchior <melchior@user...> |
コミッター | melchior |
W.I.P. Improved slope shading
@@ -20,7 +20,7 @@ | ||
20 | 20 | <ConsolePause>false</ConsolePause> |
21 | 21 | <CustomCommands> |
22 | 22 | <CustomCommands> |
23 | - <Command type="AfterBuild" command="7z -tzip a ${ProjectName}_${ProjectConfig}.zip" workingdir="${TargetDir}" /> | |
23 | + <Command type="AfterBuild" command="7z a -tzip -x!*.zip -aoa ${ProjectName}_${ProjectConfig}.zip" workingdir="${TargetDir}" /> | |
24 | 24 | <Command type="AfterClean" command="rm -f *.zip" workingdir="${TargetDir}" /> |
25 | 25 | </CustomCommands> |
26 | 26 | </CustomCommands> |
@@ -149,6 +149,9 @@ namespace Automap | ||
149 | 149 | if (HeightMap != null) |
150 | 150 | { |
151 | 151 | _flattened_HeightMap = new ushort[ChunkSize * ChunkSize]; |
152 | + | |
153 | + //Buffer.BlockCopy(HeightMap, 0, _flattened_HeightMap, 0, HeightMap.Length * sizeof(ushort)); | |
154 | + | |
152 | 155 | int flatIndex = 0; |
153 | 156 | |
154 | 157 | for (byte col = 0; col < ChunkSize; col++) |
@@ -94,6 +94,11 @@ namespace Automap | ||
94 | 94 | return whichever; |
95 | 95 | } |
96 | 96 | |
97 | + public static ushort RainHeight2DMap(this IMapChunk mapChunk, int x, int y, int chunkSize = 32) | |
98 | + { | |
99 | + int index = y % chunkSize * chunkSize + x % chunkSize; | |
100 | + return mapChunk.RainHeightMap[index]; | |
101 | + } | |
97 | 102 | |
98 | 103 | |
99 | 104 | /// <summary> |
@@ -25,7 +25,7 @@ namespace Automap | ||
25 | 25 | |
26 | 26 | } |
27 | 27 | |
28 | - public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta targetColMeta, ref ColumnsMetadata allCols, out uint pixelCount) | |
28 | + public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mapChunk, ColumnMeta targetColMeta, ref ColumnsMetadata allCols, out uint pixelCount) | |
29 | 29 | { |
30 | 30 | pixelCount = 0; |
31 | 31 | BlockPos tmpPos = new BlockPos( ); |
@@ -50,46 +50,85 @@ namespace Automap | ||
50 | 50 | } |
51 | 51 | } |
52 | 52 | |
53 | - // Prefetch map chunks, in pattern | |
54 | - var mapCornerChunks = new List<ColumnMeta>(3); | |
55 | - | |
56 | - var south_west = new Vec2i(chunkPos.X - 1, chunkPos.Y - 1); | |
57 | - var west = new Vec2i(chunkPos.X - 1, chunkPos.Y); | |
58 | - var south = new Vec2i(chunkPos.X, chunkPos.Y - 1); | |
59 | - | |
60 | - bool nullSouthWest = false, nullSouth = false, nullWest = false; | |
53 | + // Prefetch map chunks, in pattern | |
54 | + var corner_pos = new Vec2i(chunkPos.X - 1, chunkPos.Y - 1); | |
55 | + var west_pos = new Vec2i(chunkPos.X - 1, chunkPos.Y); | |
56 | + var south_pos = new Vec2i(chunkPos.X, chunkPos.Y - 1); | |
57 | + | |
61 | 58 | |
59 | + ColumnMeta south, southWest, west; | |
62 | 60 | /* |
63 | - For missing corners / cardinal heightmaps... | |
64 | - make fake heightmap dummy | |
61 | + "Overlap" Heightmap for Slope (height) values; covers 1 whole + 2 chunk edges, and corner block, | |
62 | + substitute ZERO with Average Height....better than nothing even if its wrong? | |
65 | 63 | */ |
64 | + var overlapHeightmap = new ushort[chunkSize + 1, chunkSize + 1]; | |
66 | 65 | |
67 | - if (allCols.Contains(south_west)) { | |
68 | - mapCornerChunks.Add(allCols[south_west]); | |
69 | - } | |
70 | - else { | |
71 | - nullSouthWest = true; | |
72 | - mapCornerChunks.Add(targetColMeta);//Temporary! | |
66 | + //Ofset copy of Heightmap... | |
67 | + for (int copyX = 0; copyX < chunkSize; copyX++) | |
68 | + { | |
69 | + for (int copyY = 0; copyY < chunkSize; copyY++) { | |
70 | + overlapHeightmap[copyX + 1, copyY] = targetColMeta.HeightMap[copyX, copyY]; | |
71 | + } | |
73 | 72 | } |
74 | 73 | |
75 | - if (allCols.Contains(south)) { | |
76 | - mapCornerChunks.Add(allCols[south]); | |
74 | + | |
75 | + | |
76 | + if (allCols.Contains(corner_pos) && allCols[corner_pos].HeightMap != null) { | |
77 | + southWest = allCols[corner_pos]; | |
78 | + overlapHeightmap[0, 32] = southWest.HeightMap[0, chunkSize - 1]; | |
77 | 79 | } |
78 | 80 | else { |
79 | - nullSouth = true; | |
80 | - mapCornerChunks.Add(targetColMeta);//Temporary! | |
81 | + var cornerMC = ClientAPI.World.BlockAccessor.GetMapChunk(corner_pos); | |
82 | + if (cornerMC != null && cornerMC.RainHeightMap != null) | |
83 | + { | |
84 | + overlapHeightmap[0, 32] = cornerMC.RainHeight2DMap(0, (chunkSize - 1) ); | |
85 | + } | |
81 | 86 | } |
87 | + | |
88 | + if (allCols.Contains(south_pos) && allCols[south_pos].HeightMap != null) { | |
89 | + south = allCols[south_pos]; | |
82 | 90 | |
83 | - if (allCols.Contains(west)) { | |
84 | - mapCornerChunks.Add(allCols[west]); | |
91 | + for (int southEdgeIndex = 0; southEdgeIndex < chunkSize; southEdgeIndex++) | |
92 | + { | |
93 | + overlapHeightmap[32, southEdgeIndex + 1] = south.HeightMap[0, southEdgeIndex]; | |
94 | + } | |
95 | + } | |
96 | + else { | |
97 | + var southMC = ClientAPI.World.BlockAccessor.GetMapChunk(south_pos); | |
98 | + if (southMC != null && southMC.RainHeightMap != null) { | |
99 | + for (int southEdgeIndex = 0; southEdgeIndex < chunkSize; southEdgeIndex++) | |
100 | + { | |
101 | + overlapHeightmap[32, southEdgeIndex] = southMC.RainHeight2DMap(0, southEdgeIndex); | |
102 | + } | |
103 | + } | |
85 | 104 | } |
105 | + | |
106 | + if (allCols.Contains(west_pos) && allCols[west_pos].HeightMap != null) { | |
107 | + west = allCols[west_pos]; | |
108 | + | |
109 | + for (int westEdgeIndex = 0; westEdgeIndex < chunkSize; westEdgeIndex++) | |
110 | + { | |
111 | + overlapHeightmap[westEdgeIndex, 0] = west.HeightMap[westEdgeIndex, chunkSize - 1]; | |
112 | + } | |
113 | + } | |
86 | 114 | else { |
87 | - nullWest = true; | |
88 | - mapCornerChunks.Add(targetColMeta);//Temporary! | |
115 | + var westMC = ClientAPI.World.BlockAccessor.GetMapChunk(south_pos); | |
116 | + if (westMC != null && westMC.RainHeightMap != null) { | |
117 | + for (int westEdgeIndex = 0; westEdgeIndex < chunkSize; westEdgeIndex++) { | |
118 | + overlapHeightmap[westEdgeIndex, 0] = westMC.RainHeight2DMap(westEdgeIndex, chunkSize - 1); | |
119 | + } | |
120 | + } | |
89 | 121 | } |
122 | + | |
123 | + var avgOverlap_Y = overlapHeightmap.OfType<ushort>( ).Average((ushort sel) => sel == 0 ? targetColMeta.YMax : sel); | |
124 | + //TODO: Row - then - Column averaging at Edges? | |
125 | + | |
126 | + // if (height == 0) height = ( ushort )avgOverlap_Y; | |
127 | + | |
90 | 128 | |
91 | 129 | |
92 | 130 | for (int pixelIndex = 0; pixelIndex < (chunkSize * chunkSize); pixelIndex++) { |
131 | + /********* PIXEL RENDERING LOOP **********/ | |
93 | 132 | MapUtil.PosInt2d(pixelIndex, chunkSize, localpos); |
94 | 133 | int localX = localpos.X; |
95 | 134 | int localZ = localpos.Y; |
@@ -97,57 +136,40 @@ namespace Automap | ||
97 | 136 | |
98 | 137 | int localChunkY = localY / chunkSize; |
99 | 138 | if (localChunkY >= (chunksColumn.Length)) continue;//Out of range! |
100 | - if (chunksColumn[localChunkY] == null) continue;//BIG Gaps! | |
139 | + if (chunksColumn[localChunkY] == null) | |
140 | + { | |
141 | + #if DEBUG | |
142 | + Logger.VerboseDebug("Gap in chunk-column at render time Chunk-Y:{0}", localChunkY); | |
143 | + #endif | |
144 | + continue; | |
145 | + } | |
146 | + | |
101 | 147 | //if (mapCornerChunks.Any(chks => chks == null)) { |
102 | 148 | //Logger.Warning("mapCornerChunks A.W.O.L. near : X{0} Y{1} Z{2} - ", localX, localY, localZ); |
103 | 149 | //continue; |
104 | 150 | //} |
105 | 151 | |
106 | 152 | float slopeBoost = 1f; |
107 | - int leftTop, rightTop, leftBot; | |
153 | + int leftTop, rightTop, leftBot; | |
108 | 154 | |
109 | - ColumnMeta leftTopMapChunk = targetColMeta; | |
110 | - ColumnMeta rightTopMapChunk = targetColMeta; | |
111 | - ColumnMeta leftBotMapChunk = targetColMeta; | |
155 | + int topX = localX; | |
156 | + int botX = localX + 1; | |
157 | + int leftZ = localZ + 1; | |
158 | + int rightZ = localZ; | |
112 | 159 | |
113 | - int topX = localX - 1; | |
114 | - int botX = localX; | |
115 | - int leftZ = localZ - 1; | |
116 | - int rightZ = localZ; | |
117 | - | |
118 | - if (topX < 0 && leftZ < 0) { | |
119 | - leftTopMapChunk = mapCornerChunks[0]; | |
120 | - rightTopMapChunk = mapCornerChunks[1]; | |
121 | - leftBotMapChunk = mapCornerChunks[2]; | |
122 | - } | |
123 | - else { | |
124 | - if (topX < 0) { | |
125 | - leftTopMapChunk = mapCornerChunks[1]; | |
126 | - rightTopMapChunk = mapCornerChunks[1]; | |
127 | - } | |
128 | - if (leftZ < 0) { | |
129 | - leftTopMapChunk = mapCornerChunks[2]; | |
130 | - leftBotMapChunk = mapCornerChunks[2]; | |
131 | - } | |
132 | - } | |
133 | - | |
134 | - topX = GameMath.Mod(topX, chunkSize); | |
135 | - leftZ = GameMath.Mod(leftZ, chunkSize); | |
160 | + topX = GameMath.Mod(topX, chunkSize + 1); | |
161 | + leftZ = GameMath.Mod(leftZ, chunkSize + 1); | |
136 | 162 | |
137 | - leftTop = nullSouthWest ? 0 : Math.Sign(localY - leftTopMapChunk.HeightMap[topX, leftZ]); | |
138 | - rightTop = nullSouth ? 0 : Math.Sign(localY - rightTopMapChunk.HeightMap[topX, rightZ]); | |
139 | - leftBot = nullWest ? 0 : Math.Sign(localY - leftBotMapChunk.HeightMap[botX, leftZ]); | |
163 | + leftTop = Math.Sign(localY - overlapHeightmap[topX, leftZ]); | |
164 | + rightTop = Math.Sign(localY - overlapHeightmap[topX, rightZ]); | |
165 | + leftBot = Math.Sign(localY - overlapHeightmap[botX, leftZ]); | |
140 | 166 | |
141 | 167 | float slopeness = (leftTop + rightTop + leftBot); |
142 | 168 | |
143 | 169 | if (slopeness > 0) slopeBoost = 1.2f; |
144 | 170 | if (slopeness < 0) slopeBoost = 0.8f; |
145 | 171 | if (Math.Abs(slopeness) <= float.Epsilon) slopeBoost = 1.0f;//Same height |
146 | - //slopeBoost -= 0.15f; //Slope boost value | |
147 | - | |
148 | - //FIXME: disable slopes on edges...for now | |
149 | - if (localX == 0 || localX == 31) slopeBoost= 1.0f; | |
150 | - if (localZ == 0 || localZ == 31) slopeBoost= 1.0f; | |
172 | + //slopeBoost -= 0.15f; //Slope boost value | |
151 | 173 | |
152 | 174 | int blockId = chunksColumn[localChunkY].MaybeBlocks[MapUtil.Index3d(localX, (localY % chunkSize), localZ, chunkSize, chunkSize)]; |
153 | 175 |
@@ -4,10 +4,10 @@ | ||
4 | 4 | "description" : "Automap; Generates a static HTML5 map dynamically, with P.O.I. Tracking & more.", |
5 | 5 | "authors": ["Melchior","VeryGoodDog"], |
6 | 6 | "contributors":["VeryGoodDog"], |
7 | - "version": "0.1.5", | |
7 | + "version": "0.1.6", | |
8 | 8 | "side":"Client", |
9 | 9 | "dependencies": { |
10 | - "game": "1.14.0" | |
10 | + "game": "1.14.10" | |
11 | 11 | }, |
12 | 12 | "website": "http://nowebsite.nope" |
13 | 13 | } |
\ No newline at end of file |