public Mesh CreateMeshFromVerts(Vector3[] vertsToCopy, Mesh mesh, List <int> pathSplitIds, Transform SpriteGO = null)
        {
            List <Vector3> resultsLocal                   = new List <Vector3>();
            List <int>     resultsTriIndexesLocal         = new List <int>();
            List <int>     resultsTriIndexesReversedLocal = new List <int>();
            List <Vector2> uvsLocal     = new List <Vector2>();
            List <Vector3> normalsLocal = new List <Vector3>();


            Sprite          spr             = null;
            Rect            rec             = new Rect();
            Vector3         bound           = Vector3.zero;
            TextureImporter textureImporter = new TextureImporter();

            if (SpriteGO != null && SpriteGO.GetComponent <SpriteRenderer>() && SpriteGO.GetComponent <SpriteRenderer>().sprite)
            {
                spr             = SpriteGO.GetComponent <SpriteRenderer>().sprite;
                rec             = spr.rect;
                bound           = SpriteGO.GetComponent <Renderer>().bounds.max - SpriteGO.GetComponent <Renderer>().bounds.min;
                textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;
            }

            List <PolygonPoint>       p2          = new List <PolygonPoint>();
            List <TriangulationPoint> extraPoints = new List <TriangulationPoint>();

            int i = 0;

            for (i = 0; i < vertsToCopy.Count(); i++)
            {
                if (i < pathSplitIds[0])
                {
                    p2.Add(new PolygonPoint(vertsToCopy[i].x, vertsToCopy[i].y));
                }
                else
                {
                    extraPoints.Add(new TriangulationPoint(vertsToCopy[i].x, vertsToCopy[i].y));
                }
            }

            Polygon _polygon = new Polygon(p2);

            // this is how to add more points
            _polygon.AddSteinerPoints(extraPoints);

            P2T.Triangulate(_polygon);

            if (spr == null)
            {
                bound = new Vector3((float)(_polygon.Bounds.MaxX - _polygon.Bounds.MinX), (float)(_polygon.Bounds.MaxY - _polygon.Bounds.MinY), 0);
            }

            int idx = 0;

            foreach (DelaunayTriangle triangle in _polygon.Triangles)
            {
                Vector3 v = new Vector3();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v = new Vector3((float)p.X, (float)p.Y, 0);
                    if (!resultsLocal.Contains(v))
                    {
                        resultsLocal.Add(v);
                        resultsTriIndexesLocal.Add(idx);



                        Vector2 newUv = new Vector2(((v.x - (float)_polygon.Bounds.MinX) / bound.x), ((v.y - (float)_polygon.Bounds.MinY) / bound.y));
                        if (spr != null)
                        {
                            newUv    = new Vector2((v.x / bound.x) + 0.5f, (v.y / bound.y) + 0.5f);
                            newUv.x *= rec.width / spr.texture.width;
                            newUv.y *= rec.height / spr.texture.height;

                            newUv.x += (rec.x) / spr.texture.width;
                            newUv.y += (rec.y) / spr.texture.height;


                            SpriteMetaData[] smdArray = textureImporter.spritesheet;
                            Vector2          pivot    = new Vector2(.0f, .0f);;

                            for (int k = 0; k < smdArray.Length; k++)
                            {
                                if (smdArray[k].name == spr.name)
                                {
                                    switch (smdArray[k].alignment)
                                    {
                                    case (0):
                                        smdArray[k].pivot = Vector2.zero;
                                        break;

                                    case (1):
                                        smdArray[k].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (2):
                                        smdArray[k].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (3):
                                        smdArray[k].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (4):
                                        smdArray[k].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                                        break;

                                    case (5):
                                        smdArray[k].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                                        break;

                                    case (6):
                                        smdArray[k].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (7):
                                        smdArray[k].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (8):
                                        smdArray[k].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (9):
                                        smdArray[k].pivot -= new Vector2(.5f, .5f);
                                        break;
                                    }
                                    pivot = smdArray[k].pivot;
                                }
                            }
                            if (textureImporter.spriteImportMode == SpriteImportMode.Single)
                            {
                                pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
                            }
                            newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
                            newUv.y += ((pivot.y) * rec.height) / spr.texture.height;
                        }

                        uvsLocal.Add(newUv);
                        normalsLocal.Add(new Vector3(0, 0, -1));
                        idx++;
                    }
                    else
                    {
                        resultsTriIndexesLocal.Add(resultsLocal.LastIndexOf(v));
                    }
                }
            }



            for (int j = resultsTriIndexesLocal.Count - 1; j >= 0; j--)
            {
                resultsTriIndexesReversedLocal.Add(resultsTriIndexesLocal[j]);
            }

            results.AddRange(resultsLocal);
            resultsTriIndexes.AddRange(resultsTriIndexesLocal);
            resultsTriIndexesReversed.AddRange(resultsTriIndexesReversedLocal);

            uvs.AddRange(uvsLocal);
            normals.AddRange(normalsLocal);

            resultsLocal.Clear();
            resultsTriIndexesLocal.Clear();
            resultsTriIndexesReversedLocal.Clear();
            uvsLocal.Clear();
            normalsLocal.Clear();

            finalVertices = results.ToArray();

            finalNormals = normals.ToArray();
            finalUvs     = uvs.ToArray();

            finalTriangles = resultsTriIndexesReversed.ToArray();

            mesh.vertices  = finalVertices;
            mesh.triangles = finalTriangles;
            mesh.uv        = finalUvs;
            mesh.normals   = finalNormals;
            mesh           = calculateMeshTangents(mesh);
            return(mesh);
        }
예제 #2
0
        GameObject GenerateProvinceRegionSurface(int provinceIndex, int regionIndex, Material material)
        {
            Region region = provinces [provinceIndex].regions [regionIndex];

            Polygon poly = new Polygon(region.latlon);

            // Antarctica, Saskatchewan (Canada), British Columbia (Canada), Krasnoyarsk (Russia) - special cases due to its geometry
            if (provinceIndex == 218 || provinceIndex == 220 || provinceIndex == 224 || provinceIndex == 3423)
            {
                float step = 5;
                List <TriangulationPoint> steinerPoints = new List <TriangulationPoint>();
                for (double x = region.minMaxLat.x + step / 2; x < region.minMaxLat.y - step / 2; x += step)
                {
                    for (double y = region.minMaxLon.x + step / 2; y < region.minMaxLon.y - step / 2; y += step)
                    {
                        if (region.ContainsPoint(x, y))
                        {
                            steinerPoints.Add(new TriangulationPoint(x, y));
                        }
                    }
                }
                poly.AddSteinerPoints(steinerPoints);
            }
            P2T.Triangulate(poly);

            int flip1, flip2;

            if (_earthInvertedMode)
            {
                flip1 = 2; flip2 = 1;
            }
            else
            {
                flip1 = 1; flip2 = 2;
            }
            Vector3[] revisedSurfPoints = new Vector3[poly.Triangles.Count * 3];
            for (int k = 0; k < poly.Triangles.Count; k++)
            {
                DelaunayTriangle dt = poly.Triangles[k];
                revisedSurfPoints[k * 3]         = GetSpherePointFromLatLon(dt.Points[0].X, dt.Points[0].Y);
                revisedSurfPoints[k * 3 + flip1] = GetSpherePointFromLatLon(dt.Points[1].X, dt.Points[1].Y);
                revisedSurfPoints[k * 3 + flip2] = GetSpherePointFromLatLon(dt.Points[2].X, dt.Points[2].Y);
            }

            int revIndex = revisedSurfPoints.Length - 1;

            // Generate surface mesh
            int    cacheIndex    = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex);
            string cacheIndexSTR = cacheIndex.ToString();
            // Deletes potential residual surface
            Transform t = surfacesLayer.transform.FindChild(cacheIndexSTR);

            if (t != null)
            {
                DestroyImmediate(t.gameObject);
            }
            GameObject surf = Drawing.CreateSurface(cacheIndexSTR, revisedSurfPoints, revIndex, material);

            surf.transform.SetParent(transform, false);
            surf.transform.localPosition = MiscVector.Vector3zero;
            if (_earthInvertedMode)
            {
                surf.transform.localScale = MiscVector.Vector3one * 0.998f;
            }
            if (surfaces.ContainsKey(cacheIndex))
            {
                surfaces.Remove(cacheIndex);
            }
            surfaces.Add(cacheIndex, surf);
            return(surf);
        }
        public void CreateMesh(Vector2[] vertsToCopy, Transform transform, int triangleIndex)
        {
            List <Vector3> resultsLocal                   = new List <Vector3>();
            List <int>     resultsTriIndexesLocal         = new List <int>();
            List <int>     resultsTriIndexesReversedLocal = new List <int>();
            List <Vector2> uvsLocal     = new List <Vector2>();
            List <Vector3> normalsLocal = new List <Vector3>();


            Sprite  spr   = transform.GetComponent <SpriteRenderer>().sprite;
            Rect    rec   = spr.rect;
            Vector3 bound = transform.GetComponent <Renderer>().bounds.max - transform.GetComponent <Renderer>().bounds.min;

            TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;

            List <PolygonPoint> p2 = new List <PolygonPoint>();

            if (triangleIndex > 0)
            {
                vertsToCopy = CreateSubVertPoints(spr.bounds, vertsToCopy.ToList(), triangleIndex).ToArray();
            }

            int i = 0;

            for (i = 0; i < vertsToCopy.Count(); i++)
            {
                p2.Add(new PolygonPoint(vertsToCopy[i].x, vertsToCopy[i].y));
            }

            Polygon _polygon = new Polygon(p2);

            if (triangleIndex > 0)
            {
                List <TriangulationPoint> triPoints = GenerateGridPoints(spr.bounds, triangleIndex, _polygon);
                _polygon.AddSteinerPoints(triPoints);
            }

            P2T.Triangulate(_polygon);


            int idx = 0;

            foreach (DelaunayTriangle triangle in _polygon.Triangles)
            {
                Vector3 v = new Vector3();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v = new Vector3((float)p.X, (float)p.Y, 0);
                    if (!resultsLocal.Contains(v))
                    {
                        resultsLocal.Add(v);
                        resultsTriIndexesLocal.Add(idx);

                        Vector2 newUv = new Vector2((v.x / bound.x) + 0.5f, (v.y / bound.y) + 0.5f);

                        newUv.x *= rec.width / spr.texture.width;
                        newUv.y *= rec.height / spr.texture.height;

                        newUv.x += (rec.x) / spr.texture.width;
                        newUv.y += (rec.y) / spr.texture.height;

                        SpriteMetaData[] smdArray = textureImporter.spritesheet;
                        Vector2          pivot    = new Vector2(.0f, .0f);;

                        for (int k = 0; k < smdArray.Length; k++)
                        {
                            if (smdArray[k].name == spr.name)
                            {
                                switch (smdArray[k].alignment)
                                {
                                case (0):
                                    smdArray[k].pivot = Vector2.zero;
                                    break;

                                case (1):
                                    smdArray[k].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (2):
                                    smdArray[k].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (3):
                                    smdArray[k].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (4):
                                    smdArray[k].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                                    break;

                                case (5):
                                    smdArray[k].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                                    break;

                                case (6):
                                    smdArray[k].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (7):
                                    smdArray[k].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (8):
                                    smdArray[k].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (9):
                                    smdArray[k].pivot -= new Vector2(.5f, .5f);
                                    break;
                                }
                                pivot = smdArray[k].pivot;
                            }
                        }
                        if (textureImporter.spriteImportMode == SpriteImportMode.Single)
                        {
                            pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
                        }
                        newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
                        newUv.y += ((pivot.y) * rec.height) / spr.texture.height;


                        uvsLocal.Add(newUv);
                        normalsLocal.Add(new Vector3(0, 0, -1));
                        idx++;
                    }
                    else
                    {
                        resultsTriIndexesLocal.Add(resultsLocal.LastIndexOf(v));
                    }
                }
            }



            for (int j = resultsTriIndexesLocal.Count - 1; j >= 0; j--)
            {
                resultsTriIndexesReversedLocal.Add(resultsTriIndexesLocal[j]);
            }

            results.AddRange(resultsLocal);
            resultsTriIndexes.AddRange(resultsTriIndexesLocal);
            resultsTriIndexesReversed.AddRange(resultsTriIndexesReversedLocal);
            uvs.AddRange(uvsLocal);
            normals.AddRange(normalsLocal);

            resultsLocal.Clear();
            resultsTriIndexesLocal.Clear();
            resultsTriIndexesReversedLocal.Clear();
            uvsLocal.Clear();
            normalsLocal.Clear();

            finalVertices = results.ToArray();

            finalNormals = normals.ToArray();
            finalUvs     = uvs.ToArray();

            finalTriangles = resultsTriIndexesReversed.ToArray();
        }
예제 #4
0
        GameObject GenerateCountryRegionSurface(int countryIndex, int regionIndex, Material material, bool drawOutline)
        {
            Country country = countries[countryIndex];
            Region  region  = country.regions [regionIndex];

            Polygon poly = new Polygon(region.latlon);

            double maxTriangleSize = 10.0f;

            if (countryIndex == 6)               // Antarctica
            {
                maxTriangleSize = 9.0f;
            }
            if (Mathf.Abs(region.minMaxLat.x - region.minMaxLat.y) > maxTriangleSize ||
                Mathf.Abs(region.minMaxLon.x - region.minMaxLon.y) > maxTriangleSize)                // special case; needs steiner points to reduce the size of triangles
            {
                double step = maxTriangleSize / 2;
                List <TriangulationPoint> steinerPoints = new List <TriangulationPoint>();
                for (double x = region.minMaxLat.x + step / 2; x < region.minMaxLat.y - step / 2; x += step)
                {
                    for (double y = region.minMaxLon.x + step / 2; y < region.minMaxLon.y - step / 2; y += step)
                    {
                        if (ContainsPoint2D(region.latlon, x, y))
                        {
                            steinerPoints.Add(new TriangulationPoint(x, y));
                        }
                    }
                }
                poly.AddSteinerPoints(steinerPoints);
            }

            P2T.Triangulate(poly);

            int flip1, flip2;

            flip1 = 1; flip2 = 2;
            Vector3[] revisedSurfPoints = new Vector3[poly.Triangles.Count * 3];
            for (int k = 0; k < poly.Triangles.Count; k++)
            {
                DelaunayTriangle dt = poly.Triangles[k];
                revisedSurfPoints[k * 3]         = GetSpherePointFromLatLon2(dt.Points[0].X, dt.Points[0].Y);
                revisedSurfPoints[k * 3 + flip1] = GetSpherePointFromLatLon2(dt.Points[1].X, dt.Points[1].Y);
                revisedSurfPoints[k * 3 + flip2] = GetSpherePointFromLatLon2(dt.Points[2].X, dt.Points[2].Y);
            }
            int revIndex = revisedSurfPoints.Length - 1;

            // Generate surface mesh
            int       cacheIndex    = GetCacheIndexForCountryRegion(countryIndex, regionIndex);
            string    cacheIndexSTR = cacheIndex.ToString();
            Transform t             = surfacesLayer.transform.FindChild(cacheIndexSTR);

            if (t != null)
            {
                DestroyImmediate(t.gameObject);
            }
            GameObject surf = Drawing.CreateSurface(cacheIndexSTR, revisedSurfPoints, revIndex, material);

            surf.transform.SetParent(surfacesLayer.transform, false);
            surf.transform.localPosition = MiscVector.Vector3zero;
            surf.transform.localRotation = Quaternion.Euler(MiscVector.Vector3zero);
            if (surfaces.ContainsKey(cacheIndex))
            {
                surfaces.Remove(cacheIndex);
            }
            surfaces.Add(cacheIndex, surf);

            // draw outline
            if (drawOutline)
            {
                DrawCountryRegionOutline(region, surf);
            }
            return(surf);
        }