private static void UnifyPrototypes(ref TerrainLayer[] basePrototypes, ref float[,,] baseData, ref TerrainLayer[] addPrototypes, ref float[,,] addData) /// Makes both datas prototypes arrays equal, and the layers arrays relevant to prototypes (empty arrays) /// Safe per-channel blend could be performed after this operation { //guard if prototypes have not been changed if (ArrayTools.MatchExactly(basePrototypes, addPrototypes)) { return; } //creating array of unified prototypes List <TerrainLayer> unifiedPrototypes = new List <TerrainLayer>(); unifiedPrototypes.AddRange(basePrototypes); //do not change the base prototypes order for (int p = 0; p < addPrototypes.Length; p++) { if (!unifiedPrototypes.Contains(addPrototypes[p])) { unifiedPrototypes.Add(addPrototypes[p]); } } //lut to convert prototypes indexes Dictionary <int, int> baseToUnifiedIndex = new Dictionary <int, int>(); Dictionary <int, int> addToUnifiedIndex = new Dictionary <int, int>(); for (int p = 0; p < basePrototypes.Length; p++) { baseToUnifiedIndex.Add(p, unifiedPrototypes.IndexOf(basePrototypes[p])); //should be 1,2,3,4,5, but doing this in case unified prototypes gather will be optimized } for (int p = 0; p < addPrototypes.Length; p++) { addToUnifiedIndex.Add(p, unifiedPrototypes.IndexOf(addPrototypes[p])); } //re-creating base data { float[,,] newBaseData = new float[baseData.GetLength(0), baseData.GetLength(1), unifiedPrototypes.Count]; int baseDataLayers = baseData.GetLength(2); for (int i = 0; i < baseDataLayers; i++) { ArrayTools.CopyLayer(baseData, newBaseData, i, baseToUnifiedIndex[i]); } baseData = newBaseData; } //re-creating add data { float[,,] newAddData = new float[addData.GetLength(0), addData.GetLength(1), unifiedPrototypes.Count]; int addDataLayers = addData.GetLength(2); for (int i = 0; i < addDataLayers; i++) { ArrayTools.CopyLayer(addData, newAddData, i, addToUnifiedIndex[i]); } addData = newAddData; } //saving prototypes basePrototypes = unifiedPrototypes.ToArray(); addPrototypes = unifiedPrototypes.ToArray(); }