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

Last change on this file since 351 was 351, checked in by alloc, 17 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.