source: binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs @ 351

Last change on this file since 351 was 351, checked in by alloc, 9 months ago

Fixed game version compatibility of GamePrefs
Code style cleanup (mostly argument names)

File size: 7.6 KB
Line 
1using System;
2using System.IO;
3using AllocsFixes.FileCache;
4using Unity.Collections;
5using UnityEngine;
6using UnityEngine.Profiling;
7
8namespace AllocsFixes.MapRendering {
9        public class MapRenderBlockBuffer {
10                private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT, false);
11                private readonly MapTileCache cache;
12                private readonly NativeArray<int> emptyImageData;
13                private readonly Texture2D zoomBuffer = new Texture2D (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, Constants.DEFAULT_TEX_FORMAT, false);
14                private readonly int zoomLevel;
15                private readonly string folderBase;
16               
17                private Vector2i currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
18                private string currentBlockMapFolder = string.Empty;
19
20                public MapRenderBlockBuffer (int _level, MapTileCache _cache) {
21                        zoomLevel = _level;
22                        cache = _cache;
23                        folderBase = Constants.MAP_DIRECTORY + "/" + zoomLevel + "/";
24
25                        {
26                                // Initialize empty tile data
27                                Color nullColor = new Color (0, 0, 0, 0);
28                                for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
29                                        for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
30                                                blockMap.SetPixel (x, y, nullColor);
31                                        }
32                                }
33
34                                NativeArray<int> blockMapData = blockMap.GetRawTextureData<int> ();
35                                emptyImageData = new NativeArray<int> (blockMapData.Length, Allocator.Persistent,
36                                        NativeArrayOptions.UninitializedMemory);
37                                blockMapData.CopyTo (emptyImageData);
38                        }
39                }
40
41                public TextureFormat FormatSelf {
42                        get { return blockMap.format; }
43                }
44
45                public void ResetBlock () {
46                        currentBlockMapFolder = string.Empty;
47                        currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
48                        cache.ResetTile (zoomLevel);
49                }
50
51                public void SaveBlock () {
52                        Profiler.BeginSample ("SaveBlock");
53                        try {
54                                saveTextureToFile ();
55                        } catch (Exception e) {
56                                Log.Warning ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
57                        }
58                        Profiler.EndSample ();
59                }
60
61                public bool LoadBlock (Vector2i _block) {
62                        Profiler.BeginSample ("LoadBlock");
63                        lock (blockMap) {
64                                if (currentBlockMapPos != _block) {
65                                        Profiler.BeginSample ("LoadBlock.Strings");
66                                        string folder;
67                                        if (currentBlockMapPos.x != _block.x) {
68                                                folder = folderBase + _block.x + '/';
69
70                                                Profiler.BeginSample ("LoadBlock.Directory");
71                                                Directory.CreateDirectory (folder);
72                                                Profiler.EndSample ();
73                                        } else {
74                                                folder = currentBlockMapFolder;
75                                        }
76
77                                        string fileName = folder + _block.y + ".png";
78                                        Profiler.EndSample ();
79                                       
80                                        SaveBlock ();
81                                        loadTextureFromFile (fileName);
82
83                                        currentBlockMapFolder = folder;
84                                        currentBlockMapPos = _block;
85
86                                        Profiler.EndSample ();
87                                        return true;
88                                }
89                        }
90
91                        Profiler.EndSample ();
92                        return false;
93                }
94
95                public void SetPart (Vector2i _offset, int _partSize, Color32[] _pixels) {
96                        if (_offset.x + _partSize > Constants.MAP_BLOCK_SIZE || _offset.y + _partSize > Constants.MAP_BLOCK_SIZE) {
97                                Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
98                                        zoomLevel, _offset, _partSize, _pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
99                                return;
100                        }
101
102                        Profiler.BeginSample ("SetPart");
103                        blockMap.SetPixels32 (_offset.x, _offset.y, _partSize, _partSize, _pixels);
104                        Profiler.EndSample ();
105                }
106
107                public Color32[] GetHalfScaled () {
108                        Profiler.BeginSample ("HalfScaled.ResizeBuffer");
109                        zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
110                        Profiler.EndSample ();
111
112                        Profiler.BeginSample ("HalfScaled.CopyPixels");
113                        if (blockMap.format == zoomBuffer.format) {
114                                Profiler.BeginSample ("Native");
115                                NativeArray<byte> dataSrc = blockMap.GetRawTextureData<byte> ();
116                                NativeArray<byte> dataZoom = zoomBuffer.GetRawTextureData<byte> ();
117                                dataSrc.CopyTo (dataZoom);
118                                Profiler.EndSample ();
119                        } else {
120                                Profiler.BeginSample ("GetSetPixels");
121                                zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
122                                Profiler.EndSample ();
123                        }
124                        Profiler.EndSample ();
125
126                        Profiler.BeginSample ("HalfScaled.Scale");
127                        TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
128                        Profiler.EndSample ();
129
130                        Profiler.BeginSample ("HalfScaled.Return");
131                        Color32[] result = zoomBuffer.GetPixels32 ();
132                        Profiler.EndSample ();
133
134                        return result;
135                }
136
137                public void SetPartNative (Vector2i _offset, int _partSize, NativeArray<int> _pixels) {
138                        if (_offset.x + _partSize > Constants.MAP_BLOCK_SIZE || _offset.y + _partSize > Constants.MAP_BLOCK_SIZE) {
139                                Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
140                                        zoomLevel, _offset, _partSize, _pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
141                                return;
142                        }
143
144                        Profiler.BeginSample ("SetPartNative");
145                        NativeArray<int> destData = blockMap.GetRawTextureData<int> ();
146                       
147                        for (int y = 0; y < _partSize; y++) {
148                                int srcLineStartIdx = _partSize * y;
149                                int destLineStartIdx = blockMap.width * (_offset.y + y) + _offset.x;
150                                for (int x = 0; x < _partSize; x++) {
151                                        destData [destLineStartIdx + x] = _pixels [srcLineStartIdx + x];
152                                }
153                        }
154                        Profiler.EndSample ();
155                }
156
157                public NativeArray<int> GetHalfScaledNative () {
158                        Profiler.BeginSample ("HalfScaledNative.ResizeBuffer");
159                        if (zoomBuffer.format != blockMap.format || zoomBuffer.height != Constants.MAP_BLOCK_SIZE / 2 || zoomBuffer.width != Constants.MAP_BLOCK_SIZE / 2) {
160                                zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, blockMap.format, false);
161                        }
162                        Profiler.EndSample ();
163
164                        Profiler.BeginSample ("HalfScaledNative.Scale");
165                        ScaleNative (blockMap, zoomBuffer);
166                        Profiler.EndSample ();
167
168                        return zoomBuffer.GetRawTextureData<int> ();
169                }
170               
171                private static void ScaleNative (Texture2D _sourceTex, Texture2D _targetTex) {
172                        NativeArray<int> srcData = _sourceTex.GetRawTextureData<int> ();
173                        NativeArray<int> targetData = _targetTex.GetRawTextureData<int> ();
174                       
175                        int oldWidth = _sourceTex.width;
176                        int oldHeight = _sourceTex.height;
177                        int newWidth = _targetTex.width;
178                        int newHeight = _targetTex.height;
179                       
180                        float ratioX = ((float) oldWidth) / newWidth;
181                        float ratioY = ((float) oldHeight) / newHeight;
182
183                        for (var y = 0; y < newHeight; y++) {
184                                var oldLineStart = (int) (ratioY * y) * oldWidth;
185                                var newLineStart = y * newWidth;
186                                for (var x = 0; x < newWidth; x++) {
187                                        targetData [newLineStart + x] = srcData [(int) (oldLineStart + ratioX * x)];
188                                }
189                        }
190                }
191
192                private void loadTextureFromFile (string _fileName) {
193                        Profiler.BeginSample ("LoadTexture");
194
195                        Profiler.BeginSample ("LoadFile");
196                        byte[] array = cache.LoadTile (zoomLevel, _fileName);
197                        Profiler.EndSample ();
198
199                        Profiler.BeginSample ("LoadImage");
200                        if (array != null && blockMap.LoadImage (array) && blockMap.height == Constants.MAP_BLOCK_SIZE &&
201                            blockMap.width == Constants.MAP_BLOCK_SIZE) {
202                                Profiler.EndSample ();
203
204                                Profiler.EndSample ();
205                                return;
206                        }
207                        Profiler.EndSample ();
208
209                        if (array != null) {
210                                Log.Error ("Map image tile " + _fileName + " has been corrupted, recreating tile");
211                        }
212
213                        if (blockMap.format != Constants.DEFAULT_TEX_FORMAT || blockMap.height != Constants.MAP_BLOCK_SIZE ||
214                            blockMap.width != Constants.MAP_BLOCK_SIZE) {
215                                blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT,
216                                        false);
217                        }
218
219                        blockMap.LoadRawTextureData (emptyImageData);
220
221                        Profiler.EndSample ();
222                }
223
224                private void saveTextureToFile () {
225                        Profiler.BeginSample ("EncodePNG");
226                        byte[] array = blockMap.EncodeToPNG ();
227                        Profiler.EndSample ();
228
229                        cache.SaveTile (zoomLevel, array);
230                }
231        }
232}
Note: See TracBrowser for help on using the repository browser.