// This is meant to identify noisy packs // storing and reading packs in json format can make certain packs wrong because of numerical precision errors // here we identify some of those packs and clear them from the memory // for each pack, we check if the shapes are overlapping // if shapes overlap then some numerical precision errors must have occured public bool IdentifyRemoveNoisyPack(string packFileName, int packID) { Pack pack = packEvol.ReadPack(packFileName, packID); GameObject[] shapes = packEvol.VisualizePack(pack, loadFromResources: false, keepRenderer: false); bool noisyPack = false; for (int i = 0; i < shapes.Length; i++) { // move shape out of box shapes[i].transform.position = new Vector3(100f, 100f, 100f); // check if the shape collides bool shapeCollide = gtPack.WillShapeCollide(shapes[i], pack.positions[i]); if (shapeCollide) { noisyPack = true; break; } // move shape back in shapes[i].transform.position = pack.positions[i]; } int shapesLength = shapes.Length; for (int i = 0; i < shapes.Length; i++) { UnityEngine.Object.DestroyImmediate(shapes[i]); } return(noisyPack); }
List <int> ShapeOrderMixedBFSDFS(Pack pack) { GameObject[] shapes = packEvol.VisualizePack(pack, loadFromResources: false, keepRenderer: false); int[,] shapeCon = BottomShapeMatrix(shapes); int shapesLength = shapes.Length; for (int i = 0; i < shapesLength; i++) { UnityEngine.Object.DestroyImmediate(shapes[i]); } List <int> shapesAlreadyAdded = new List <int>(); shapesAlreadyAdded.Add(pack.sources.Length); for (int i = 0; i < pack.sources.Length; i++) { // find all possible shapes that can be added next List <int> possibleShapesToAdd = new List <int>(); foreach (int shapeAlreadyAdded in shapesAlreadyAdded) { for (int j = 0; j < pack.sources.Length; j++) { if (shapeCon[j, shapeAlreadyAdded] == 1) { if (!possibleShapesToAdd.Contains(j) && !shapesAlreadyAdded.Contains(j)) { possibleShapesToAdd.Add(j); } } } } // chose one of the possible shapes and add it int shapeIndex = UnityEngine.Random.Range(0, possibleShapesToAdd.Count); shapesAlreadyAdded.Add(possibleShapesToAdd.ElementAt(shapeIndex)); } return(shapesAlreadyAdded); }
// Tighten and Connect the Pack public int[,] TightConPack(ref Pack pack) { PackEvolver packEvol = GetComponent <PackEvolver>(); GameObject[] shapes = packEvol.VisualizePack(pack, loadFromResources: false, keepRenderer: false); // An Adjagency matrix. The (n+1)th node represents the bottom int[,] shapeCon = new int[shapes.Length + 1, shapes.Length + 1]; for (int i = 0; i < shapes.Length; i++) { List <int> conBotIdx = GetConnectedNodes(shapes.Length, shapeCon); // unConBotIdx: unconnected to bottom index int unConBotIdx = -1; for (int j = 0; j < shapes.Length; j++) { if (!conBotIdx.Contains(j)) { unConBotIdx = j; break; } } Debug.Assert(unConBotIdx != -1, "Error in code as all nodes already connected to bottom"); // List of nodes that are connected to unConBotIdx List <int> unConBotIdxs = GetConnectedNodes(unConBotIdx, SubArray2D(shapeCon, 0, shapes.Length, 0, shapes.Length)); foreach (int idx in unConBotIdxs) { packEvol.SetLayerRecursively(shapes[idx], 11); } int minUnConBotIdx = -1; int minUnConBotVal = 100; int minUnConBotCon = -1; foreach (int idx in unConBotIdxs) { var temp = FindNextCon(shapes[idx], shapes.Length); if (temp.Item2 < minUnConBotVal) { minUnConBotIdx = idx; minUnConBotVal = temp.Item2; minUnConBotCon = temp.Item1; } } shapeCon[minUnConBotIdx, minUnConBotCon] = 1; shapeCon[minUnConBotCon, minUnConBotIdx] = 1; foreach (int idx in unConBotIdxs) { Vector3 temp = shapes[idx].transform.position; temp.y -= ((float)minUnConBotVal) * GRID_SIZE; shapes[idx].transform.position = temp; packEvol.SetLayerRecursively(shapes[idx], 0); } } int shapesLength = shapes.Length; for (int i = 0; i < shapesLength; i++) { pack.positions[i] = shapes[i].transform.position; UnityEngine.Object.DestroyImmediate(shapes[i]); } return(shapeCon); }