Пример #1
0
        public void Execute(Plot plot, uint seed)
        {
            processPlots.Clear();
            plots.Clear();
            debug.Clear();

            int plotSize = plot.numberOfEdges;

            bool[] plotExternals = new bool[plotSize];
            for (int p = 0; p < plotSize; p++)
            {
                plotExternals[p] = true;
            }
            _parent = plot;
            ProcessPlot initialPlot = new ProcessPlot(_parent, obbFit.CreateSorted(plot.pointsV2));

            processPlots.Add(initialPlot);
            float initialArea = initialPlot.obbs[0].area;

            if (plot.splitSettings.autoArea)
            {
                FlatBounds pBounds = new FlatBounds();
                pBounds.Encapsulate(plot.getAllPointsV2);
                plot.splitSettings.minArea = Mathf.Min(pBounds.size.x, pBounds.size.y) * plot.splitSettings.autoAreaRatio;
                plot.splitSettings.maxArea = Mathf.Max(pBounds.size.x, pBounds.size.y) * plot.splitSettings.autoAreaRatio;
            }

            if (initialArea < plot.splitSettings.maxArea)// if the supplied plot is already small enough - return it
            {
                plots.Add(_parent);
                processPlots.Clear();
//                Debug.Log("Plot size (" + initialArea + ") below max area " + plot.splitSettings.maxArea);
                return;
            }

            rGen = new RandomGen(seed);

            int it = 0;

            while (processPlots.Count > 0)
            {
                ProcessPlot processPlot = processPlots[0];
                IPlot       currentPlot = processPlot.plot;
                processPlots.RemoveAt(0);
                Subplot[] newPlots = SplitPlot(processPlot);

                bool earlyTermination = newPlots[0] == null;
                if (newPlots[1] == null)
                {
                    earlyTermination = true;
                }
                if (rGen.output < plot.splitSettings.randomTerminationChance)
                {
                    earlyTermination = true;
                }
                Subplot      plotA = null, plotB = null;
                List <OBBox> obbsA = null;
                List <OBBox> obbsB = null;
                if (!earlyTermination)
                {
                    plotA = newPlots[0];
                    plotB = newPlots[1];

                    if (plotA.plotAccessPercentage < plot.splitSettings.minimumAccessLengthPercent)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotA.notes = "insufficient access";
                        }
                        earlyTermination = true;
                    }
                    if (plotB.plotAccessPercentage < plot.splitSettings.minimumAccessLengthPercent)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotB.notes = "insufficient access";
                        }
                        earlyTermination = true;
                    }
                    if (plotA.numberOfEdges < 4 && !plot.splitSettings.allowTrianglularPlots)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotA.notes = "triangular split";
                        }
                        earlyTermination = true;
                    }
                    if (plotB.numberOfEdges < 4 && !plot.splitSettings.allowTrianglularPlots)
                    {
                        plotB.notes      = "triangular split";
                        earlyTermination = true;
                    }

                    obbsA = obbFit.CreateSorted(plotA.pointsV2);
                    if (obbsA.Count == 0)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotA.notes = "no obb generated";
                        }
                        earlyTermination = true;
                    }
                    else if (obbsA[0].aspect < plot.splitSettings.minimumAspect)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotA.notes = "aspect issue";
                        }
                        earlyTermination = true;
                    }
                    else if (obbsA[0].area < plot.splitSettings.minArea)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotA.notes = "area smaller than minimum";
                        }
                        earlyTermination = true;
                    }

                    obbsB = obbFit.CreateSorted(plotB.pointsV2);
                    if (obbsB.Count == 0)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotB.notes = "no obb generated";
                        }
                        earlyTermination = true;
                    }
                    else if (obbsB[0].aspect < plot.splitSettings.minimumAspect)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotB.notes = "aspect issue";
                        }
                        earlyTermination = true;
                    }
                    else if (obbsB[0].area < plot.splitSettings.minArea)
                    {
                        if (plot.splitSettings.log)
                        {
                            plotB.notes = "area smaller than minimum";
                        }
                        earlyTermination = true;
                    }
                }

                if (earlyTermination)
                {
                    if (plotA != null && plotB != null)
                    {
                        if (plot.splitSettings.log)
                        {
                            currentPlot.notes = string.Format("plotA:{0}  plotB:{1}  {2}", plotA.notes, plotB.notes, processPlot);
                        }

                        if (plot.splitSettings.debug)//output debug info
                        {
                            DebugSplitInfo info = new DebugSplitInfo();
                            info.plot  = currentPlot;
                            info.plotA = plotA;
                            info.plotB = plotB;
                            debug.Add(info);
                        }
                    }
                    //figure on appropirate fallback
                    if (!processPlot.longSplit && plot.splitSettings.fallbackSecondaryDivision)//divide along the longer split
                    {
                        processPlot.longSplit = true;
                        processPlots.Insert(0, processPlot);
                    }
                    else
                    {
                        if (!processPlot.variationA && plot.splitSettings.fallbackVariations)//use a variation on the split
                        {
                            processPlot.variationA = true;
                            processPlots.Insert(0, processPlot);
                        }
                        else
                        {
                            if (!processPlot.variationB && plot.splitSettings.fallbackVariations)//use a variation on the split
                            {
                                processPlot.variationB = true;
                                processPlots.Insert(0, processPlot);
                            }
                            else
                            {
                                if (processPlot.obbs.Count > 1 && plot.splitSettings.fallbackAlternativeObb)//if there are other cut options - use them!
                                {
                                    processPlot.obbs.RemoveAt(0);
                                    processPlot.longSplit  = false;
                                    processPlot.variationA = false;
                                    processPlot.variationB = false;
                                    processPlots.Insert(0, processPlot);
                                }
                                else
                                {
                                    plots.Add(currentPlot);//termination - all allowable fallbacks used
                                }
                            }
                        }
                    }
                    continue;//next
                }

                OBBox obbA       = obbsA[0];
                OBBox obbB       = obbsB[0];
                bool  terminateA = obbA.area < plot.splitSettings.maxArea && rGen.output < 0.3f;
                if (!terminateA)
                {
                    processPlots.Add(new ProcessPlot(plotA, obbsA));
                }
                else
                {
                    if (plot.splitSettings.log)
                    {
                        plotA.notes = "small enough to end";
                    }
                    plots.Add(plotA);//termination
                }

                bool terminateB = obbB.area < plot.splitSettings.maxArea && rGen.output < 0.3f;
                if (!terminateB)
                {
                    processPlots.Add(new ProcessPlot(plotB, obbsB));
                }
                else
                {
                    if (plot.splitSettings.log)
                    {
                        plotB.notes = "small enough to end";
                    }
                    plots.Add(plotB);//termination
                }

                it++;
                if (it > 5000)
                {
                    UnityEngine.Profiling.Profiler.EndSample();
                    return;
                }
            }
//            Profiler.EndSample();
        }