Пример #1
0
        public void Initialize(char symbol, int index, ArchitectureStyle style)
        {
            if (symbol == 'e')
            {
                return;
            }

            IResultSet resultSet = Repository.List("facade_item").Filter("style", style.name).Filter("symbol", symbol + "").Filter("index", index + "");

            if (resultSet.Count() == 0)
            {
                throw new Exception("model not found (style: " + style.name + ", element: " + symbol + index + ")");
            }

            _model = resultSet.Get(0);

            if (_model == null)
            {
                throw new Exception("invalid model (style: " + style.name + ", element: " + symbol + index + ")");
            }

            CacheMetadata();

            _invalid = false;
        }
Пример #2
0
        static Pattern <T> ParsePattern <T> (string patternString, ArchitectureStyle architectureStyle) where T : IPatternItem, new()
        {
            StringReader reader = new StringReader(patternString);

            List <string> lines = new List <string> ();
            string        line;

            while ((line = reader.ReadLine()) != null)
            {
                line = line.Trim();
                if (line.Length == 0)
                {
                    continue;
                }
                lines.Add(line);
            }

            int         numberOfLines   = lines.Count;
            int         numberOfColumns = -1;
            Pattern <T> pattern         = null;

            for (int y = 0; y < numberOfLines; y++)
            {
                string[] columns = Regex.Split(lines [y], @"\s+");

                if (numberOfColumns == -1)
                {
                    numberOfColumns = columns.Length;
                }
                else if (numberOfColumns != columns.Length)
                {
                    throw new Exception("different column sizes in pattern matrix");
                }

                if (pattern == null)
                {
                    pattern = new Pattern <T> (numberOfColumns, numberOfLines, architectureStyle);
                }

                for (int x = 0; x < numberOfColumns; x++)
                {
                    string elementString = columns [x];

                    if (elementString.Length < 2)
                    {
                        throw new Exception("invalid element: " + elementString);
                    }

                    char symbol = elementString [0];
                    int  index  = int.Parse(elementString.Substring(1));

                    pattern.SetElement(x, y, symbol, index);
                }
            }

            return(pattern);
        }
Пример #3
0
 public Allotment(int x, int y, int width, int depth, int widthInTiles, int depthInTiles, Direction[] freeFaces, ArchitectureStyle architectureStyle)
 {
     this.x                 = x;
     this.y                 = y;
     this.width             = width;
     this.depth             = depth;
     this.widthInTiles      = widthInTiles;
     this.depthInTiles      = depthInTiles;
     this.freeFaces         = freeFaces;
     this.architectureStyle = architectureStyle;
 }
Пример #4
0
        public Pattern(int width, int height, ArchitectureStyle architectureStyle)
        {
            _width             = width;
            _height            = height;
            _items             = new T[_height][];
            _architectureStyle = architectureStyle;

            for (int i = 0; i < _height; i++)
            {
                _items [i] = new T[_width];
            }
        }
Пример #5
0
 public Facade(Direction direction, int width, int height, int widthInTiles, int heightInTiles, ArchitectureStyle architecturalStyle, Pattern <FacadeItem> elementsPattern, Pattern <FacadeItem> detailsPattern, Pattern <FacadeOperation> operationsPattern)
 {
     this.direction         = direction;
     this.width             = width;
     this.height            = height;
     this.widthInTiles      = widthInTiles;
     this.heightInTiles     = heightInTiles;
     this.architectureStyle = architecturalStyle;
     this.elementsPattern   = elementsPattern;
     this.detailsPattern    = detailsPattern;
     this.operationsPattern = operationsPattern;
 }
Пример #6
0
    public override void Execute(List <Allotment> allotments)
    {
        _buildings = new List <Building> ();
        foreach (Allotment allotment in allotments)
        {
            ArchitectureStyle architectureStyle = allotment.architectureStyle;

            int heightInTiles = UnityEngine.Random.Range(architectureStyle.minHeight, architectureStyle.maxHeight + 1);
            int height        = heightInTiles * architectureStyle.tileHeight;

            int widthInTiles = allotment.widthInTiles - architectureStyle.spacing;
            int width        = widthInTiles * architectureStyle.tileWidth;
            int depthInTiles = allotment.depthInTiles - architectureStyle.spacing;
            int depth        = depthInTiles * architectureStyle.tileWidth;

            Facade[] facades = new Facade[allotment.freeFaces.Length];
            int      i       = 0;
            foreach (Direction freeFace in allotment.freeFaces)
            {
                int longitude;
                int longitudeInTiles;

                if (freeFace == Direction.BACK || freeFace == Direction.FRONT)
                {
                    longitude        = width;
                    longitudeInTiles = widthInTiles;
                }
                else
                {
                    longitude        = depth;
                    longitudeInTiles = depthInTiles;
                }

                Pattern <FacadeItem>      elementsPattern = architectureStyle.randomElementsPattern.Stretch(longitudeInTiles, heightInTiles);
                Pattern <FacadeItem>      detailsPattern  = architectureStyle.randomDetailsPattern.Stretch(longitudeInTiles, heightInTiles);
                Pattern <FacadeOperation> operationsPattern;
                if (architectureStyle.usesOperations)
                {
                    operationsPattern = architectureStyle.randomOperationsPattern.Stretch(longitudeInTiles, heightInTiles);
                }
                else
                {
                    operationsPattern = null;
                }
                PatternEvaluator.Evaluate(elementsPattern, detailsPattern, operationsPattern, architectureStyle);

                facades [i++] = new Facade(freeFace, longitude, height, longitudeInTiles, heightInTiles, architectureStyle, elementsPattern, detailsPattern, operationsPattern);
            }

            _buildings.Add(new Building(allotment.x, allotment.y, width, height, depth, widthInTiles, heightInTiles, depthInTiles, facades, architectureStyle));
        }
    }
Пример #7
0
 public static Pattern <T>[] ParsePatterns <T> (TextAsset patternsFile, ArchitectureStyle architectureStyle) where T : IPatternItem, new()
 {
     string[]      patternsStrings = Regex.Split(patternsFile.text, @"\-");
     Pattern <T>[] patterns        = new Pattern <T> [patternsStrings.Length];
     for (int i = 0; i < patterns.Length; i++)
     {
         string patternString = patternsStrings [i].Trim();
         if (patternString.Length == 0)
         {
             continue;
         }
         patterns [i] = ParsePattern <T> (patternString, architectureStyle);
     }
     return(patterns);
 }
Пример #8
0
    public Building(int x, int y, int width, int height, int depth, int widthInTiles, int heightInTiles, int depthInTiles, Facade[] facades, ArchitectureStyle architecturalStyle)
    {
        this.x                 = x;
        this.y                 = y;
        this.width             = width;
        this.height            = height;
        this.depth             = depth;
        this.widthInTiles      = widthInTiles;
        this.heightInTiles     = heightInTiles;
        this.depthInTiles      = depthInTiles;
        this.architectureStyle = architecturalStyle;

        for (int i = 0; i < facades.Length; i++)
        {
            _facades.Add(facades [i].direction, facades [i]);
        }
    }
Пример #9
0
 public void Initialize(char symbol, int index, ArchitectureStyle architectureStyle)
 {
     this._symbol = symbol;
     this._index  = index;
 }
Пример #10
0
    public override void Execute(BaseGrid grid, ArchitectureStyle[] allArchitectureStyles, int[] architectureStylesMap, List <Block> blocks)
    {
        _allotments = new List <Allotment> ();
        foreach (Block block in blocks)
        {
            List <Rect> allPossibleAreas = new List <Rect> ();
            foreach (ArchitectureStyle possibleArchitectureStyle in block.architectureStyles)
            {
                int    tileWidth     = possibleArchitectureStyle.tileWidth;
                Rect[] possibleAreas = Combinatorics.PossibleAreas(possibleArchitectureStyle.minWidth + possibleArchitectureStyle.spacing, possibleArchitectureStyle.maxWidth + possibleArchitectureStyle.spacing, possibleArchitectureStyle.minDepth + possibleArchitectureStyle.spacing, possibleArchitectureStyle.maxDepth + possibleArchitectureStyle.spacing);
                foreach (Rect possibleArea in possibleAreas)
                {
                    Rect area = new Rect(0, 0, possibleArea.width * tileWidth, possibleArea.height * tileWidth);
                    if (!allPossibleAreas.Contains(area))
                    {
                        allPossibleAreas.Add(area);
                    }
                }
            }

            List <Rect> allotmentAreas = new List <Rect> ();
            MaxRects    maxRects       = new MaxRects(block.width, block.depth);

            if (_tryToFitSmallerAllotmentsFirst)
            {
                // sort possible allotment areas by rectangle area
                allPossibleAreas.Sort(delegate(Rect r1, Rect r2)
                {
                    float a1 = (r1.width * r1.height);
                    float a2 = (r2.width * r2.height);
                    return(a1.CompareTo(a2));
                });
            }

            while (allPossibleAreas.Count > 0)
            {
                Rect possibleArea;
                if (_tryToFitSmallerAllotmentsFirst)
                {
                    possibleArea = allPossibleAreas [0];
                }
                else
                {
                    possibleArea = allPossibleAreas [UnityEngine.Random.Range(0, allPossibleAreas.Count)];
                }

                Rect allotmentArea = maxRects.Insert((int)possibleArea.width, (int)possibleArea.height, _allotmentFittingHeuristics);

                if (allotmentArea.width == 0 || allotmentArea.height == 0)
                {
                    allPossibleAreas.Remove(possibleArea);
                    continue;
                }

                allotmentAreas.Add(new Rect(allotmentArea.x, allotmentArea.y, allotmentArea.width, allotmentArea.height));
            }

            if (maxRects.Occupancy() < _minOccupancyRate)
            {
                string message = "block occupancy is less than minimum: " + maxRects.Occupancy();
                if (_abortInError)
                {
                    throw new Exception(message);
                }
                else
                {
                    Debug.LogWarning(message);
                }
            }

            int blockXStart = (int)block.center.x - block.width / 2;
            int blockZStart = (int)block.center.y - block.depth / 2;
            foreach (Rect allotmentArea in allotmentAreas)
            {
                ArchitectureStyle architectureStyle = FindSuitableArchitectureStyle(allotmentArea, block.architectureStyles);

                bool hasLeftNeighbour  = false;
                bool hasRightNeighbour = false;
                bool hasUpperNeighbour = false;
                bool hasLowerNeighbour = false;
                foreach (Rect neighbourAllotmentArea in allotmentAreas)
                {
                    if (neighbourAllotmentArea == allotmentArea)
                    {
                        continue;
                    }

                    if (neighbourAllotmentArea.xMax <= allotmentArea.xMin &&
                        ((neighbourAllotmentArea.yMin >= allotmentArea.yMin && neighbourAllotmentArea.yMin <= allotmentArea.yMax) ||
                         (neighbourAllotmentArea.yMax >= allotmentArea.yMin && neighbourAllotmentArea.yMax <= allotmentArea.yMax) ||
                         (allotmentArea.yMin >= neighbourAllotmentArea.yMin && allotmentArea.yMin <= neighbourAllotmentArea.yMax) ||
                         (allotmentArea.yMax >= neighbourAllotmentArea.yMin && allotmentArea.yMax <= neighbourAllotmentArea.yMax)))
                    {
                        hasLeftNeighbour = true;
                    }
                    else if (neighbourAllotmentArea.xMin >= allotmentArea.xMax &&
                             ((neighbourAllotmentArea.yMin >= allotmentArea.yMin && neighbourAllotmentArea.yMin <= allotmentArea.yMax) ||
                              (neighbourAllotmentArea.yMax >= allotmentArea.yMin && neighbourAllotmentArea.yMax <= allotmentArea.yMax) ||
                              (allotmentArea.yMin >= neighbourAllotmentArea.yMin && allotmentArea.yMin <= neighbourAllotmentArea.yMax) ||
                              (allotmentArea.yMax >= neighbourAllotmentArea.yMin && allotmentArea.yMax <= neighbourAllotmentArea.yMax)))
                    {
                        hasRightNeighbour = true;
                    }
                    else if (neighbourAllotmentArea.yMin >= allotmentArea.yMax &&
                             ((neighbourAllotmentArea.xMin >= allotmentArea.xMin && neighbourAllotmentArea.xMin <= allotmentArea.xMax) ||
                              (neighbourAllotmentArea.xMax >= allotmentArea.xMin && neighbourAllotmentArea.xMax <= allotmentArea.xMax) ||
                              (allotmentArea.xMin >= neighbourAllotmentArea.xMin && allotmentArea.xMin <= neighbourAllotmentArea.xMax) ||
                              (allotmentArea.xMax >= neighbourAllotmentArea.xMin && allotmentArea.xMax <= neighbourAllotmentArea.xMax)))
                    {
                        hasUpperNeighbour = true;
                    }
                    else if (neighbourAllotmentArea.yMax <= allotmentArea.yMin &&
                             ((neighbourAllotmentArea.xMin >= allotmentArea.xMin && neighbourAllotmentArea.xMin <= allotmentArea.xMax) ||
                              (neighbourAllotmentArea.xMax >= allotmentArea.xMin && neighbourAllotmentArea.xMax <= allotmentArea.xMax) ||
                              (allotmentArea.xMin >= neighbourAllotmentArea.xMin && allotmentArea.xMin <= neighbourAllotmentArea.xMax) ||
                              (allotmentArea.xMax >= neighbourAllotmentArea.xMin && allotmentArea.xMax <= neighbourAllotmentArea.xMax)))
                    {
                        hasLowerNeighbour = true;
                    }
                }

                if (hasLeftNeighbour && hasRightNeighbour && hasUpperNeighbour && hasLowerNeighbour)
                {
                    continue;
                }

                List <Direction> freeFaces = new List <Direction> ();

                if (!hasLowerNeighbour)
                {
                    freeFaces.Add(Direction.FRONT);
                }

                if (!hasUpperNeighbour)
                {
                    freeFaces.Add(Direction.BACK);
                }

                if (!hasLeftNeighbour)
                {
                    freeFaces.Add(Direction.LEFT);
                }

                if (!hasRightNeighbour)
                {
                    freeFaces.Add(Direction.RIGHT);
                }

                int widthInTiles = (int)allotmentArea.width / architectureStyle.tileWidth;
                int depthInTiles = (int)allotmentArea.height / architectureStyle.tileWidth;

                int spacing = architectureStyle.spacing * (architectureStyle.tileWidth / 2);

                _allotments.Add(new Allotment(blockXStart + (int)allotmentArea.x + spacing, blockZStart + (int)allotmentArea.y + spacing, (int)allotmentArea.width, (int)allotmentArea.height, widthInTiles, depthInTiles, freeFaces.ToArray(), architectureStyle));
            }
        }
    }
Пример #11
0
        public static void Evaluate(Pattern <FacadeItem> elementsPattern, Pattern <FacadeItem> detailsPattern, Pattern <FacadeOperation> operationsPattern, ArchitectureStyle architectureStyle)
        {
            if (elementsPattern.width != detailsPattern.width || (operationsPattern != null && elementsPattern.width != operationsPattern.width) ||
                elementsPattern.height != detailsPattern.height || (operationsPattern != null && elementsPattern.height != operationsPattern.height))
            {
                throw new Exception("patterns do not match in size");
            }

            int width  = elementsPattern.width;
            int height = elementsPattern.height;

            for (int y = 0; y < height; y++)
            {
                IModel previousElementModel = null;
                int    x2 = 0;
                for (int x1 = 0; x1 < width; x1++)
                {
                    FacadeItem element = elementsPattern.GetElement(x1, y);

                    if (element.invalid)
                    {
                        continue;
                    }

                    if (element.model != previousElementModel)
                    {
                        x2 = x1;
                    }

                    previousElementModel = element.model;

                    if (architectureStyle.groundFloor == GroundFloor.FIRST_FLOOR_FOOTER && y == height - 1)
                    {
                        element.BottomVariant();
                    }
                    else if (/*architectureStyle.header &&*/ y == 0)
                    {
                        element.TopVariant();
                    }

                    if (element.size > 1)
                    {
                        // pattern occurring outside its frequency (i.e.: occurrence of a 2 sized pattern in an odd frequency)
                        if ((x1 - x2) % element.size != 0)
                        {
                            element.Invalidate();
                            detailsPattern.SetElement(x1, y, 'e', 0);
                            continue;
                        }

                        // pattern overflowing other patterns
                        bool substituted = false;
                        for (int i = 1; i < element.size && (i + x1) < width; i++)
                        {
                            FacadeItem neighbourElement = elementsPattern.GetElement(x1 + i, y);
                            // cannot compare neighbour to possibly "transformed" element, so compare to previous element model
                            if (neighbourElement.model != previousElementModel)
                            {
                                elementsPattern.SetElement(x1, y, architectureStyle.defaultFacadeElementSymbol, architectureStyle.defaultFacadeElementIndex);
                                detailsPattern.SetElement(x1, y, architectureStyle.defaultFacadeDetailSymbol, architectureStyle.defaultFacadeDetailIndex);
                                substituted = true;
                                break;
                            }
                        }

                        if (substituted)
                        {
                            for (int i = 1; i < element.size && (i + x1) < width; i++)
                            {
                                elementsPattern.SetElement(x1 + i, y, architectureStyle.defaultFacadeElementSymbol, architectureStyle.defaultFacadeElementIndex);
                                detailsPattern.SetElement(x1 + i, y, architectureStyle.defaultFacadeDetailSymbol, architectureStyle.defaultFacadeDetailIndex);
                            }

                            continue;
                        }
                    }

                    // facade item overflowing the facade
                    if (x1 + element.size > width)
                    {
                        elementsPattern.SetElement(x1, y, architectureStyle.defaultFacadeElementSymbol, architectureStyle.defaultFacadeElementIndex);
                        detailsPattern.SetElement(x1, y, architectureStyle.defaultFacadeDetailSymbol, architectureStyle.defaultFacadeDetailIndex);
                        continue;
                    }

                    if (operationsPattern != null)
                    {
                        // facade item spreading among different elevation levels
                        FacadeOperation operation   = operationsPattern.GetElement(x1, y);
                        bool            substituted = false;
                        for (int i = 1; i < element.size && (i + x1) < width; i++)
                        {
                            FacadeOperation neighbourOperation = operationsPattern.GetElement(x1 + i, y);
                            if (neighbourOperation != operation)
                            {
                                elementsPattern.SetElement(x1, y, architectureStyle.defaultFacadeElementSymbol, architectureStyle.defaultFacadeElementIndex);
                                detailsPattern.SetElement(x1, y, architectureStyle.defaultFacadeDetailSymbol, architectureStyle.defaultFacadeDetailIndex);
                                substituted = true;
                            }
                        }

                        if (substituted)
                        {
                            for (int i = 1; i < element.size && (i + x1) < width; i++)
                            {
                                elementsPattern.SetElement(x1 + i, y, architectureStyle.defaultFacadeElementSymbol, architectureStyle.defaultFacadeElementIndex);
                                detailsPattern.SetElement(x1 + i, y, architectureStyle.defaultFacadeDetailSymbol, architectureStyle.defaultFacadeDetailIndex);
                            }
                            continue;
                        }
                    }

                    if (!element.allowsDetail)
                    {
                        detailsPattern.SetElement(x1, y, 'e', 0);
                    }
                }
            }
        }
    public override void Execute(BaseGrid grid, ArchitectureStyle[] allArchitectureStyles, int[] architectureStylesMap, List <Block> blocks)
    {
        _allotments = new List <Allotment> ();
        foreach (Block block in blocks)
        {
            ArchitectureStyle architectureStyle = block.randomArchitectureStyle;

            int blockWidthInTiles = block.width / architectureStyle.tileWidth;
            int blockDepthInTiles = block.depth / architectureStyle.tileWidth;

            int[][] possibleWidths = SubsetSum.Combinations(Enumerable.Range(architectureStyle.minWidth + architectureStyle.spacing, architectureStyle.maxWidth + architectureStyle.spacing).ToArray(), blockWidthInTiles);
            int[][] possibleDepths = SubsetSum.Combinations(Enumerable.Range(architectureStyle.minDepth + architectureStyle.spacing, architectureStyle.maxDepth + architectureStyle.spacing).ToArray(), blockDepthInTiles);

            int[] widths = possibleWidths [UnityEngine.Random.Range(0, possibleWidths.Length)];
            int[] depths = possibleDepths [UnityEngine.Random.Range(0, possibleDepths.Length)];

            int startX = (int)block.center.x - block.width / 2;
            int startZ = (int)block.center.y - block.depth / 2;

            int zOffset = 0;
            for (int z2 = 0; z2 < depths.Length; z2++)
            {
                int xOffset      = 0;
                int depthInTiles = depths [z2];
                int depth        = depthInTiles * architectureStyle.tileWidth;
                for (int x2 = 0; x2 < widths.Length; x2++)
                {
                    int widthInTiles = widths [x2];
                    int width        = widthInTiles * architectureStyle.tileWidth;

                    if ((z2 == 0 || z2 == depths.Length - 1) || (x2 == 0 || x2 == widths.Length - 1))
                    {
                        HashSet <Direction> freeFaces = new HashSet <Direction> ();

                        if (z2 == 0)
                        {
                            freeFaces.Add(Direction.FRONT);
                        }
                        else if (z2 == depths.Length - 1)
                        {
                            freeFaces.Add(Direction.BACK);
                        }

                        if (x2 == 0)
                        {
                            freeFaces.Add(Direction.LEFT);
                        }
                        else if (x2 == widths.Length - 1)
                        {
                            freeFaces.Add(Direction.RIGHT);
                        }

                        _allotments.Add(new Allotment(startX + xOffset, startZ + zOffset, width, depth, widthInTiles, depthInTiles, freeFaces.ToArray(), architectureStyle));
                    }

                    xOffset += width;
                }
                zOffset += depth;
            }
        }
    }