// Reads in all information of a facade public List <Rectangle> initializeNewFacade(InputFacade facade) { allCurrentFacadeRectangles = RegionFinder.findRectangles(facade.facadeLayoutName, facade.inputFacade.width, facade.inputFacade.height); float maxY = 0; float maxX = 0; foreach (Color c in allCurrentFacadeRectangles.Keys) { foreach (Rectangle r in allCurrentFacadeRectangles[c]) { maxX = Mathf.Max(maxX, r.toX); maxY = Mathf.Max(maxY, r.toY); } } buildingNameText.text = facade.gameObject.name; widthText.text = facade.getBuildingWidth().ToString(); heightText.text = facade.getBuildingHeight().ToString(); Vector3 previewScale = facadePreview.rectTransform.localScale; facadePreview.rectTransform.localScale = new Vector3(previewScale.y * facade.getBuildingWidth() / facade.getBuildingHeight(), previewScale.y, 1); layoutPreview.rectTransform.localScale = facadePreview.rectTransform.localScale; foreach (Color c in allCurrentFacadeRectangles.Keys) { Rectangle newRect = new Rectangle(); newRect.symbol = c; currentFacadeRectangles.Enqueue(newRect); } return(null); }
private void writeRepeatRule(Region r, string axis, InputFacade inputF) { string from = getRegionName(r, inputF.gameObject.name); string repeatRule = from + " -> repeat(" + axis + ")"; // If there already exists a rule if (hasRules.Contains(from)) { return; } hasRules.Add(from); List <Region> containedShapes = RegionManager.sortRegions(r.subregions, axis); // Try to find the repeat sequence to identify the repeating pattern in the repeat List <Region> repeatSequence = new List <Region>(); for (int i = 0; i < containedShapes.Count; i++) { repeatSequence.Add(containedShapes[i]); int repeatLength = repeatSequence.Count; // If the length of our sequence is not a divisor of the repeating region it cannot be what we are looking for if (containedShapes.Count % repeatLength != 0) { continue; } bool matches = true; // Iterate over the contained shapes and see if our pattern repeats for (int k = 0; k < containedShapes.Count / repeatLength; k++) { for (int j = 0; j < repeatLength; j++) { Region other = containedShapes[repeatLength * k + j]; if (!containedShapes[j].equalTerminals(other)) { matches = false; break; } } if (!matches) { break; } } // If we have found a matching pattern if (matches) { break; } } repeatRule += createShapeSplitString(repeatSequence, axis, inputF); writeToRuleFile(repeatRule); }
public void beginGeneration(Dictionary <Color, List <Rectangle> > rectangles, InputFacade inputF, StreamWriter sw) { fileDS = sw; if (!inputF.formattedCorrectly()) { Debug.LogError("Skipping " + inputF.gameObject.name); } else { // buildingName = inputF.gameObject.name; // currentFacade = inputF; // inputFacade = inputF.inputFacade; // facadeHeight = inputFacade.height; // facadeWidth = inputFacade.width; generateRules(rectangles, inputF); } }
// Clears all information of the current facade and initializes variables for the next // Returns true if there was a next facade, false if not private bool nextFacade() { nextFacadeIndex++; if (nextFacadeIndex <= facades.Length) { // Clear all information informationRects = new List <Rectangle>(); currentFacadeRectangles = new Queue <Rectangle>(); currentRectangle = null; // Initialize the new facade InputFacade iF = facades[nextFacadeIndex - 1].GetComponent <InputFacade>(); initializeNewFacade(iF); Texture2D layoutTex = readFacadeImage(Application.dataPath + iF.facadeLayoutName); facadePreview.sprite = Sprite.Create(iF.inputFacade, new Rect(0, 0, iF.inputFacade.width, iF.inputFacade.height), facadePreview.sprite.pivot); layoutPreview.sprite = Sprite.Create(layoutTex, new Rect(0, 0, layoutTex.width, layoutTex.height), facadePreview.sprite.pivot); // Go to the next facade index return(true); } return(false); }
private void writeDebugPicture(List <Rectangle> rectangles, InputFacade inputF) { Texture2D debugTex = new Texture2D(inputF.inputFacade.width, inputF.inputFacade.height); foreach (Rectangle rectangle in rectangles) { int width = rectangle.toX - rectangle.fromX; int height = rectangle.toY - rectangle.fromY; for (int x = 1; x < width; x++) { for (int y = 1; y < height; y++) { debugTex.SetPixel(rectangle.fromX + x, rectangle.fromY + y, rectangle.symbol); } } } File.WriteAllBytes(Application.dataPath + "/DebugPicture.png", debugTex.EncodeToPNG()); }
private void SaveGameBtn_Click(object sender, EventArgs e) { var fileDialog = new SaveFileDialog(); if (fileDialog.ShowDialog() == DialogResult.OK) { StreamWriter stream = null; try { stream = new StreamWriter(fileDialog.FileName); InputFacade.SaveGame(stream); } catch (SecurityException) { AddToTrackingLog(ProgramLocalization.GameSavingFailed); } finally { stream?.Close(); } } }
private void generateRules(Dictionary <Color, List <Rectangle> > rectangles, InputFacade inputF) { List <Region> repeatedRegions = null; List <Rectangle> terminalRegions = new List <Rectangle>(); foreach (Color c in rectangles.Keys) { int count = 0; foreach (Rectangle ret in rectangles[c]) { terminalRegions.Add(ret); count++; } } writeDebugPicture(terminalRegions, inputF); string buildingName = inputF.gameObject.name; splitFacade(repeatedRegions, terminalRegions, inputF); setTerminalNames(rectangles, buildingName); checkTerminalProtrusion(rectangles, buildingName); MaterialExtractor.extractMaterials(rectangles, inputF.inputFacade); }
// Creates and returns the string that defines the size and shapes of that the rule splits into public string createShapeSplitString(List <Region> shapes, string axis, InputFacade inputF) { string splitString = " {"; // Get width/height in pixels of the input facade depending on which axis we are working on int facadeLength = (axis == "X") ? inputF.inputFacade.width : inputF.inputFacade.height; // Get self defined height and length of building float buildingSize = (axis == "X") ? inputF.getBuildingWidth() : inputF.getBuildingHeight(); for (int i = 0; i < shapes.Count; i++) { Region subarea = shapes[i]; float size = (axis == "X") ? (subarea.toX - subarea.fromX) * 1f / facadeLength : (subarea.toY - subarea.fromY) * 1f / facadeLength; string shapeName = getRegionName(subarea, inputF.gameObject.name); string relative = (relativeRegions.Contains(shapeName)) ? "N" : ""; splitString += size * buildingSize + relative + ": " + shapeName; if (i < shapes.Count - 1) { splitString += " | "; } } splitString += "}"; return(splitString); }
private void splitFacade(List <Region> repeatedRegions, List <Rectangle> terminalRegions, InputFacade inputF) { string buildingName = inputF.gameObject.name; string startShape = buildingName + "Start"; // Create the initial decomposition rule to create 4 walls from a cube writeInitialRules(buildingName); Queue <Region> regionsToSplit = new Queue <Region>(); Region start = new Region(terminalRegions); regionNames.Add(start, startShape); regionsToSplit.Enqueue(start); while (regionsToSplit.Count > 0) { Region toSplit = regionsToSplit.Dequeue(); // If the current region is a terminal region then we should not split further if (toSplit.terminals.Count == 1 || hasRules.Contains(getRegionName(toSplit, buildingName))) { continue; } // Gets the list of areas that the region can be split into on x and y axes respectively List <Region> xSplits = RegionFinder.createSplitHorizontal(toSplit); List <Region> ySplits = RegionFinder.createSplitVertical(toSplit); List <Region> toEnqueue = new List <Region>(); // Choose the one with most contained elements if (xSplits == null && ySplits == null) { // No splits were able to be performed Debug.Assert(toSplit.terminals.Count == 1, "Unable to split non-terminal region. Terminating rule generation."); toSplit.debugPrintRegion(); return; } else if (xSplits != null && (ySplits == null || xSplits.Count >= ySplits.Count)) { // If the X-split is preferred createSplitRule(xSplits, repeatedRegions, "X", getRegionName(toSplit, buildingName), inputF); toEnqueue = xSplits; } else { // If the Y-split is preferred toEnqueue = createSplitRule(ySplits, repeatedRegions, "Y", getRegionName(toSplit, buildingName), inputF); toEnqueue = ySplits; } foreach (Region newRegion in toEnqueue) { regionsToSplit.Enqueue(newRegion); } fileDS.Flush(); } }
// Deducts and write a split rule given a split on an axis private List <Region> createSplitRule(List <Region> splits, List <Region> repeats, string axis, string regionName, InputFacade inputF) { List <Region> splitRepeats = new List <Region>(); List <Region> nonRepeats = new List <Region>(); // If this area already has a rule defined if (hasRules.Contains(regionName)) { return(splits); } repeats = RegionFinder.findRealRepeats(splits, axis); // Bad datastructure and complexity, should use other foreach (Region current in splits) { // Find the largest repeat-region that contains our current split region Region containedIn = null; if (repeats != null) { foreach (Region other in repeats) { // If the repeated region contains the split region and is greater than our current one if (other.containsRegion(current) && (containedIn == null || (other.terminals.Count > containedIn.terminals.Count))) { containedIn = other; other.subregions.Add(current); } } } if (containedIn == null) { nonRepeats.Add(current); } else if (!splitRepeats.Contains(containedIn)) { // If there was a repeated area that contains our split region and it was not already added splitRepeats.Add(containedIn); } } splits = new List <Region>(splitRepeats); splits.AddRange(nonRepeats); splits = RegionManager.sortRegions(splits, axis); foreach (Region region in splits) { setRegionName(region, inputF.gameObject.name); } foreach (Region repeatR in splitRepeats) { relativeRegions.Add(getRegionName(repeatR, inputF.gameObject.name)); } // Add case for just repeat later if (splits.Count > splitRepeats.Count) { string rule = regionName + " -> split(" + axis + ")"; rule += createShapeSplitString(splits, axis, inputF); writeToRuleFile(rule); hasRules.Add(regionName); } // Now we need to write the repeat rules, which regions are contained in the large repeat areas foreach (Region r in splitRepeats) { writeRepeatRule(r, axis, inputF); } return(splits); }
private void ResultProcessingTimer_Tick(object sender, EventArgs e) { UpdateClock(); InputFacade.ProcessQueueTick(); }
private void MovementBtn4_Click(object sender, EventArgs e) { InputFacade.SendChessboardMovement(ChessboardMovement.Vector2Minus); }
private void EndGameBtn_Click(object sender, EventArgs e) { InputFacade.EndGame(); }
private void StopTrackingBtn_Click(object sender, EventArgs e) { InputFacade.StopTracking(); }
private void RecalibrateBtn_Click(object sender, EventArgs e) { InputFacade.Recalibrate(); }