Exemplo n.º 1
0
        public void Break(Vector2 position)
        {
            var area = Area;

            Debug.Log(area);
            if (area > MinBreakArea)
            {
                var calc = new VoronoiCalculator();
                var clip = new VoronoiClipper();

                var sites = new Vector2[3];

                for (int i = 0; i < sites.Length; i++)
                {
                    var dist  = Mathf.Abs(NormalizedRandom(0.0f, 1.0f / 2.0f));
                    var angle = 2.0f * Mathf.PI * Random.value;

                    sites[i] = position + new Vector2(
                        dist * Mathf.Cos(angle),
                        dist * Mathf.Sin(angle));
                }

                var diagram = calc.CalculateDiagram(sites);

                var clipped = new List <Vector2>();

                for (int i = 0; i < sites.Length; i++)
                {
                    clip.ClipSite(diagram, Polygon, i, ref clipped);

                    if (clipped.Count > 0)
                    {
                        var newGo = Instantiate(gameObject, transform.parent);

                        newGo.transform.localPosition = transform.localPosition;
                        newGo.transform.localRotation = transform.localRotation;

                        var bs = newGo.GetComponent <BreakableSurface>();

                        bs.Thickness = Thickness;
                        bs.Polygon.Clear();
                        bs.Polygon.AddRange(clipped);

                        var childArea = bs.Area;

                        var rb = bs.GetComponent <Rigidbody>();

                        rb.mass = Rigidbody.mass * (childArea / area);
                    }
                }

                gameObject.SetActive(false);
                Destroy(gameObject);
            }
        }
Exemplo n.º 2
0
    // calcula o diagrama de voronoi                                                      link para a implementação utilizada: https://github.com/OskarSigvardsson/unity-delaunay
    // serve mais para ser usar a triangulação de delaunay do resultado do diagrama
    public void BuildVoronoi()
    {
        var points2d = Graham.GetPointVectorList();

        GK.VoronoiCalculator voronoiCalculator = new GK.VoronoiCalculator();
        Diagram = voronoiCalculator.CalculateDiagram(Graham.GetPointVectorList());

        //var extends = Map.GetComponent<MeshFilter>().mesh.bounds.size;
        //extends.Scale(Map.transform.localScale);

        VoronoiMesh = CreateVoronoiMesh(Diagram);


        BuildGraph();
    }
Exemplo n.º 3
0
    public void GenerateCity()
    {
        // use our seed for generation
        Random.State currentRNGState = Random.state;
        Random.InitState(citySeed);

        myCity                 = new City();
        myCity.thisCity        = new GameObject("NewCity");
        myCity.cityNoiseOffset = new Vector2(Random.Range(-10000, 10000), Random.Range(-10000, 10000));

        GK.VoronoiDiagram cityDiagram = new GK.VoronoiDiagram();
        //generate points
        List <Vector2> points = CreateCityPoint(myCity.cityNoiseOffset);// calulate voroni fracture sites

        //calculate city
        cityDiagram = new GK.VoronoiCalculator().CalculateDiagram(points);//calculate vorino diagram (ie roads seperating suburbs) using out sites

        //bounding
        List <Vector2> Polygon = new List <Vector2>();

        Polygon.Add(new Vector2(0, 0));
        Polygon.Add(new Vector2(citySize.x, 0));
        Polygon.Add(new Vector2(citySize.x, citySize.y));
        Polygon.Add(new Vector2(0, citySize.y));


        List <Vector2> clippedSite = new List <Vector2>();

        for (int siteIndex = 0; siteIndex < cityDiagram.Sites.Count; siteIndex++)
        {
            new GK.VoronoiClipper().ClipSite(cityDiagram, Polygon, siteIndex, ref clippedSite);// clip each of our suburbs

            if (clippedSite.Count > 0)
            {
                // assign and create a suburb object

                Suburb newSuburb = new Suburb();
                myCity.suburbs.Add(newSuburb);

                newSuburb.thisSuburb   = new GameObject("Suburb");
                newSuburb.sitePosition = cityDiagram.Sites[siteIndex];
                newSuburb.thisSuburb.transform.position = new Vector3(newSuburb.sitePosition.x, 0, newSuburb.sitePosition.y);
                newSuburb.thisSuburb.transform.SetParent(myCity.thisCity.transform);
                newSuburb.borders = new List <Vector2>(clippedSite);

                float xCoord     = myCity.cityNoiseOffset.x + newSuburb.sitePosition.x / citySize.x * noiseScale;
                float yCoord     = myCity.cityNoiseOffset.x + newSuburb.sitePosition.y / citySize.y * noiseScale;
                float noiseValue = curve.Evaluate(Mathf.PerlinNoise(xCoord, yCoord));
                for (int i = 0; i < curve.keys.Length; i++)//set which type of suburb will be generated bassed off our noise weight at the suburbs position
                {
                    if (noiseValue == curve.keys[i].value)
                    {
                        switch (i)
                        {
                        case 0:
                        {
                            newSuburb.suburbType = residentialSettings;
                            break;
                        }

                        case 1:
                        {
                            newSuburb.suburbType = urbanSettings;
                            break;
                        }

                        default:
                        {
                            newSuburb.suburbType = citySettings;
                            break;
                        }
                        }
                    }
                }

                newSuburb.seed = Random.Range(int.MinValue, int.MaxValue);
            }
        }
        Random.state = currentRNGState;
    }
Exemplo n.º 4
0
    //subdivide our suburb into blocks
    public void GenerateBlocks(float spacing, float deviation = 0, float alignmentRotation = 0)
    {
        //set our seed for the suburb
        Random.State currentRNGState = Random.state;
        Random.InitState(seed);

        float          minX = float.MaxValue, maxX = float.MinValue, minY = float.MaxValue, maxY = float.MinValue;
        Vector2        rotationPivot = new Vector2(0, 0);
        List <Vector2> shrunkBorders = new List <Vector2>(borders);
        List <Vector2> sites         = new List <Vector2>();

        // shrink our borders so our points arnt created to close to the edge, this will result in blocks that are to small
        shrunkBorders = CityTest.Shrink(shrunkBorders, spacing / 2);
        if (shrunkBorders.Count >= 3)
        {
            for (int i = 0; i < shrunkBorders.Count; i++)//find anchorPoint
            {
                if (shrunkBorders[i].x < rotationPivot.x)
                {
                    rotationPivot.x = shrunkBorders[i].x;
                }
                if (shrunkBorders[i].y < rotationPivot.y)
                {
                    rotationPivot.y = shrunkBorders[i].y;
                }
            }

            //find rotate boarders for alignment and find bounding volume
            for (int i = 0; i < shrunkBorders.Count; i++)
            {
                shrunkBorders[i] = shrunkBorders[i].RotateAroundPoint(rotationPivot, alignmentRotation);// Vector2.MoveTowards(shrunkBorders[i].RotateAroundPoint(rotationPivot, alignmentRotation), borderCenter, spacing/2);// spacing/2);
                if (shrunkBorders[i].x > maxX)
                {
                    maxX = shrunkBorders[i].x;
                }
                else if (shrunkBorders[i].x < minX)
                {
                    minX = shrunkBorders[i].x;
                }
                if (shrunkBorders[i].y > maxY)
                {
                    maxY = shrunkBorders[i].y;
                }
                else if (shrunkBorders[i].y < minY)
                {
                    minY = shrunkBorders[i].y;
                }
            }

            //triangulate out polygon so we can check if created points are within our poly
            GK.DelaunayTriangulation triangulation = new GK.DelaunayCalculator().CalculateTriangulation(shrunkBorders);

            float xCenterOffset = ((maxX - minX) % spacing) / 2;
            float yCenterOffset = ((maxY - minY) % spacing) / 2;
            for (float x = minX - xCenterOffset; x < maxX; x += spacing)
            {
                for (float y = minY - yCenterOffset; y < maxY; y += spacing)
                {
                    Vector2 newPoint = new Vector2(x + Random.Range(-deviation, deviation), y + Random.Range(-deviation, deviation)); // generate a points i a grid

                    for (int i = 0; i < triangulation.Triangles.Count; i += 3)                                                        // if the point is contained within our polygon
                    {
                        if (GK.Geom.PointInTriangle(newPoint,
                                                    triangulation.Vertices[triangulation.Triangles[i]],
                                                    triangulation.Vertices[triangulation.Triangles[i + 1]],
                                                    triangulation.Vertices[triangulation.Triangles[i + 2]]))
                        {
                            Vector2 rotatedPoint = newPoint.RotateAroundPoint(rotationPivot, -alignmentRotation);
                            sites.Add(rotatedPoint);// rotate our aligned point to its original rotation and add it to the block site list

                            break;
                        }
                    }
                }
            }
        }

        if (sites.Count >= 3)                                                                           // we can only create a diagram if we have more then 2 verts
        {
            GK.VoronoiDiagram blockVoronoiDiagram = new GK.VoronoiCalculator().CalculateDiagram(sites); // generate our streets and blocks in our suburb

            for (int i = 0; i < blockVoronoiDiagram.Sites.Count; i++)
            {
                List <Vector2> clippedSite = null;

                if (blockVoronoiDiagram.FirstEdgeBySite.Count > 0)                                      ////THIS IS NEEDED BECAUSE THE DIAGRAM CAN BE INVALID SOMETIMES
                {
                    new GK.VoronoiClipper().ClipSite(blockVoronoiDiagram, borders, i, ref clippedSite); // clip our block by our suburb

                    if (clippedSite.Count > 0)
                    {
                        Block newBlock = new Block();// create and assign the block
                        newBlock.borders       = new List <Vector2>(clippedSite);
                        newBlock.parentSuburb  = this;
                        newBlock.seed          = Random.Range(int.MinValue, int.MaxValue);
                        newBlock.blockPosition = blockVoronoiDiagram.Sites[i];

                        newBlock.thisBlock = new GameObject("Block");
                        newBlock.thisBlock.transform.SetParent(thisSuburb.transform);
                        newBlock.thisBlock.transform.localPosition = new Vector3(newBlock.blockPosition.x, 0, newBlock.blockPosition.y);
                        myBlocks.Add(newBlock);
                    }
                    else
                    {
                        Debug.LogError("SUBURB SITE AFTER CLIPPED WASNT VALID");
                    }
                }
                else////THIS IS NEEDED BECAUSE THE DIAGRAM CAN BE INVALID SOMETIMES if its not valid make the entire subrb a block
                {
                    Debug.LogWarning("SITE COULTNT BE CREATED BECASUE DIAGRAM DOESNT HAVE STARTING EDGES");
                    Block newBlock = new Block();
                    newBlock.borders       = new List <Vector2>(borders);
                    newBlock.parentSuburb  = this;
                    newBlock.seed          = Random.Range(int.MinValue, int.MaxValue);
                    newBlock.blockPosition = sitePosition;

                    newBlock.thisBlock = new GameObject("Block");
                    newBlock.thisBlock.transform.SetParent(thisSuburb.transform);
                    newBlock.thisBlock.transform.localPosition = new Vector3(newBlock.blockPosition.x, 0, newBlock.blockPosition.y);
                    myBlocks.Add(newBlock);
                    break;
                }
            }
        }
        else// if the suburb has less then 3 verts it cant be split so we make the entire suburb a block
        {
            Block newBlock = new Block();
            newBlock.borders       = new List <Vector2>(borders);
            newBlock.parentSuburb  = this;
            newBlock.seed          = Random.Range(int.MinValue, int.MaxValue);
            newBlock.blockPosition = sitePosition;

            newBlock.thisBlock = new GameObject("Block");
            newBlock.thisBlock.transform.SetParent(thisSuburb.transform);
            newBlock.thisBlock.transform.localPosition = new Vector3(newBlock.blockPosition.x, 0, newBlock.blockPosition.y);
            myBlocks.Add(newBlock);
        }
        Random.state = currentRNGState;
    }