Пример #1
0
 static public int CompareByZReverse(TriFace a, TriFace b)
 {
     if (a.vc.z == b.vc.z)
     {
         return(0);
     }
     return((a.vc.z < b.vc.z) ? 1 : -1);
 }
Пример #2
0
 static public int CompareByZ(TriFace a, TriFace b)
 {
     if (a.vc.z == b.vc.z)
     {
         return(0);
     }
     return((a.vc.z < b.vc.z) ? -1 : 1);
 }
        private int?FindAdjacentFace(int vertexAIndex, int vertexBIndex, List <int> nGonTriFaces, int currentTriFaceIndex)
        {
            foreach (int triFaceIndex in nGonTriFaces)
            {
                if (triFaceIndex == currentTriFaceIndex)
                {
                    continue;
                }

                TriFace triangle = TriFaces[triFaceIndex];
                if ((triangle.A == vertexAIndex || triangle.B == vertexAIndex || triangle.C == vertexAIndex) &&
                    (triangle.A == vertexBIndex || triangle.B == vertexBIndex || triangle.C == vertexBIndex))
                {
                    return(triFaceIndex);
                }
            }
            return(null);
        }
        public Dictionary <int, List <int> > TriFacesGroupedByVertex()
        {
            Dictionary <int, List <int> > vertToFaces = new Dictionary <int, List <int> >();

            for (int i = 0; i < TriFaces.Count; i++)
            {
                TriFace triangle = TriFaces[i];

                if (vertToFaces.ContainsKey(triangle.A))
                {
                    vertToFaces[triangle.A].Add(i);
                }
                else
                {
                    vertToFaces.Add(triangle.A, new List <int> {
                        i
                    });
                }

                if (vertToFaces.ContainsKey(triangle.B))
                {
                    vertToFaces[triangle.B].Add(i);
                }
                else
                {
                    vertToFaces.Add(triangle.B, new List <int> {
                        i
                    });
                }

                if (vertToFaces.ContainsKey(triangle.C))
                {
                    vertToFaces[triangle.C].Add(i);
                }
                else
                {
                    vertToFaces.Add(triangle.C, new List <int> {
                        i
                    });
                }
            }

            return(vertToFaces);
        }
Пример #5
0
        protected override void OnPopulateMesh(VertexHelper vh)
        {
            var recttransform = gameObject.transform as RectTransform;
            var rect          = recttransform.rect;

            rect.xMin += margin.left;
            rect.xMax -= margin.right;
            rect.yMin += margin.bottom;
            rect.yMax -= margin.top;
            // Debug.Log("rect:" + rect.ToString() + "\ncenter:" + rect.center.ToString());

            if (sourceMesh == null)
            {
                PolulateQuad(vh, rect);
                return;
            }

            var meshsize = sourceMesh.bounds.size;

            // Calc scale
            var scale = Vector3.one;

            switch (scalingMode)
            {
            case ScalingMode.Stretch:
                scale.x = rect.width / meshsize.x;
                scale.y = rect.height / meshsize.y;
                scale.z = Mathf.Min(scale.x, scale.y);
                break;

            case ScalingMode.Fit:
                scale.x = rect.width / meshsize.x;
                scale.y = rect.height / meshsize.y;
                scale.x = Mathf.Min(scale.x, scale.y);
                scale.y = scale.x;
                scale.z = scale.x;
                break;

            case ScalingMode.NoScale:
                scale = Vector3.one;
                break;
            }

            float extraScaleZ = keepMeshZ? 1.0f : 0.0f;

            // Debug.Log("rect w:" + rect.width + ",h:" + rect.height);
            // Debug.Log("bounds:(w:" + meshsize.x + ",h:" + meshsize.y);
            // Debug.Log("scale:" + scale.ToString());

            // Calc offsets
            var meshcenter = keepMeshOrigin ? Vector3.zero : sourceMesh.bounds.center;

            var rectoffset = Vector3.zero;

            rectoffset.x = rect.center.x;
            rectoffset.y = rect.center.y;

            //
            vh.Clear();

            // Vertices
            var      vcount   = sourceMesh.vertexCount;
            UIVertex uiv      = UIVertex.simpleVert;
            var      uiverts  = new List <UIVertex>(vcount);
            var      vertposs = new List <Vector3>(vcount);

            for (int i = 0; i < vcount; i++)
            {
                var pos = sourceMesh.vertices[i] - meshcenter;
                pos.Scale(scale);
                pos += rectoffset;
                vertposs.Add(pos);

                pos.z       *= extraScaleZ;
                uiv.position = pos;
                uiv.normal   = sourceMesh.normals[i];
                uiv.tangent  = sourceMesh.tangents[i];
                if (useMeshVertexColor)
                {
                    uiv.color  = (i < sourceMesh.colors.Length) ? sourceMesh.colors[i] : Color.black;
                    uiv.color *= color;
                }
                else
                {
                    uiv.color = color;
                }
                uiv.uv0 = (i < sourceMesh.uv.Length) ? sourceMesh.uv[i] : Vector2.zero;
                uiv.uv1 = (i < sourceMesh.uv2.Length) ? sourceMesh.uv2[i] : Vector2.zero;
                uiv.uv2 = (i < sourceMesh.uv3.Length) ? sourceMesh.uv3[i] : Vector2.zero;
                uiv.uv3 = (i < sourceMesh.uv4.Length) ? sourceMesh.uv4[i] : Vector2.zero;
                uiverts.Add(uiv);
            }

            // Faces
            int tricount = sourceMesh.triangles.Length;
            var indices  = new List <int>(tricount);

            if (!removeBackFace && (sortTriangles == SortMode.None))
            {
                // No backface culling and z sort
                indices.AddRange(sourceMesh.triangles);
            }
            else
            {
                // Some mesh processing needed
                var faces   = new List <TriFace>(tricount / 3);
                var triface = new TriFace();

                if (removeBackFace)
                {
                    // Backface culling
                    for (int i = 0; i < tricount; i += 3)
                    {
                        int i0  = sourceMesh.triangles[i];
                        int i1  = sourceMesh.triangles[i + 1];
                        int i2  = sourceMesh.triangles[i + 2];
                        var v0  = vertposs[i0];
                        var v1  = vertposs[i1];
                        var v2  = vertposs[i2];
                        var v01 = v1 - v0;
                        var v02 = v2 - v0;
                        var n   = Vector3.Cross(v01, v02);
                        if (n.z < 0.0f)  // Front face normal is (0,0,-1)
                        {
                            triface.SetFace(i0, i1, i2);
                            triface.SetVertices(v0, v1, v2);
                            faces.Add(triface);
                        }
                    }
                }
                else
                {
                    // Use all triangles
                    for (int i = 0; i < tricount; i += 3)
                    {
                        triface.SetFace(
                            sourceMesh.triangles[i],
                            sourceMesh.triangles[i + 1],
                            sourceMesh.triangles[i + 2]
                            );
                        triface.SetVertices(
                            vertposs[triface.i0],
                            vertposs[triface.i1],
                            vertposs[triface.i2]
                            );
                        faces.Add(triface);
                    }
                }

                // Sorting. Camera's foward is (0,0,1)
                switch (sortTriangles)
                {
                case SortMode.Normal:
                    // Descending order
                    faces.Sort(TriFace.CompareByZReverse);
                    break;

                case SortMode.Reverse:
                    // Ascending order
                    faces.Sort(TriFace.CompareByZ);
                    break;
                    // case SortMode.None:
                    // default:
                    //     break;
                }

                // Add triangle
                foreach (var f in faces)
                {
                    indices.Add(f.i0);
                    indices.Add(f.i1);
                    indices.Add(f.i2);
                }
            }

            vh.AddUIVertexStream(uiverts, indices);
        }
Пример #6
0
 public Tile(TriFace face, TileType type)
 {
     this.face = face;
     this.type = type;
 }
        public override void GenerateUVs()
        {
            for (int i = 0; i < Vertices.Count; i++)
            {
                Vertex vertex = Vertices[i];
                vertex.UV = new Vector2(0.5f + Mathf.Atan2(vertex.Position.z, vertex.Position.x) / (2f * Mathf.PI),
                                        0.5f + Mathf.Asin(vertex.Position.y) / Mathf.PI);
                Vertices[i] = vertex;
            }

            //detect...
            Dictionary <int, int> visited = new Dictionary <int, int>();
            int        vertexIndex        = Vertices.Count - 1;
            List <int> wrapped            = new List <int>();

            for (int i = 0; i < TriFaces.Count; i++)
            {
                Vector3 texA      = Vertices[TriFaces[i].A].UV;
                Vector3 texB      = Vertices[TriFaces[i].B].UV;
                Vector3 texC      = Vertices[TriFaces[i].C].UV;
                Vector3 texNormal = Vector3.Cross(texB - texA, texC - texA);
                if (texNormal.z > 0)
                {
                    wrapped.Add(i);
                }
            }

            //...and fix
            foreach (int i in wrapped)
            {
                int    ta = TriFaces[i].A;
                int    tb = TriFaces[i].B;
                int    tc = TriFaces[i].C;
                Vertex A  = Vertices[ta];
                Vertex B  = Vertices[tb];
                Vertex C  = Vertices[tc];

                if (A.UV.x < 0.25f)
                {
                    int tempA = ta;
                    if (!visited.TryGetValue(ta, out tempA))
                    {
                        A.UV.x += 1;
                        Vertices.Add(A);
                        vertexIndex++;
                        visited[ta] = vertexIndex;
                        tempA       = vertexIndex;
                    }
                    ta = tempA;
                }
                if (B.UV.x < 0.25f)
                {
                    int tempB = tb;
                    if (!visited.TryGetValue(tb, out tempB))
                    {
                        B.UV.x += 1;
                        Vertices.Add(B);
                        vertexIndex++;
                        visited[tb] = tempB = vertexIndex;
                    }
                    tb = tempB;
                }
                if (C.UV.x < 0.25f)
                {
                    int tempC = tc;
                    if (!visited.TryGetValue(tc, out tempC))
                    {
                        C.UV.x += 1;
                        Vertices.Add(C);
                        vertexIndex++;
                        visited[tc] = tempC = vertexIndex;
                    }
                    tc = tempC;
                }
                TriFaces[i] = new TriFace(ta, tb, tc);
            }

            //fix polar UVs
            Vertex north      = Vertices.Find(v => v.Position.y == 1);
            Vertex south      = Vertices.Find(v => v.Position.y == -1);
            int    northIndex = Vertices.IndexOf(north);
            int    southIndex = Vertices.IndexOf(south);

            vertexIndex = Vertices.Count - 1;
            for (int i = 0; i < TriFaces.Count; i++)
            {
                if (TriFaces[i].A == northIndex)
                {
                    Vertex B        = Vertices[TriFaces[i].B];
                    Vertex C        = Vertices[TriFaces[i].C];
                    Vertex newNorth = north;
                    newNorth.UV.x = (B.UV.x + C.UV.x) / 2;
                    vertexIndex++;
                    Vertices.Add(newNorth);
                    TriFaces[i] = new TriFace(vertexIndex, TriFaces[i].B, TriFaces[i].C);
                }
                else if (TriFaces[i].A == southIndex)
                {
                    Vertex B        = Vertices[TriFaces[i].B];
                    Vertex C        = Vertices[TriFaces[i].C];
                    Vertex newSouth = south;
                    vertexIndex++;
                    newSouth.UV.x = (B.UV.x + C.UV.x) / 2;
                    Vertices.Add(newSouth);
                    TriFaces[i] = new TriFace(vertexIndex, TriFaces[i].B, TriFaces[i].C);
                }
            }
        }
        public ProceduralIcosphere Truncated()
        {
            ProceduralIcosphere truncated = new ProceduralIcosphere();

            Dictionary <int, List <int> > triFacesGroupedByVertex = TriFacesGroupedByVertex();

            int originalVertexCount = Vertices.Count;
            //originalVertexCount = 2;

            List <Vertex> dualVertices = TriFaces.Select(t => new Vertex(t.Centroid(Vertices))).ToList();

            Dictionary <int, Vertex> midPointCache = new Dictionary <int, Vertex>();

            int hexCount  = 0;
            int pentCount = 0;

            //build new n-gons from each vertex in the original shape
            for (int vertexIndex = 0; vertexIndex < originalVertexCount; vertexIndex++)
            {
                List <int> vertexTriFaces = triFacesGroupedByVertex[vertexIndex];
                if (vertexTriFaces.Count == 6)
                {
                    hexCount++;
                }
                else
                {
                    pentCount++;
                }

                Vertex nGonCentreVertex = FindNgonCentre(vertexTriFaces, dualVertices);

                //for each of the TriFaces connected to this vertex
                for (int j = vertexTriFaces.Count - 1; j >= 0; j--)
                {
                    int triIndex = vertexTriFaces[j];

                    TriFace triangle = TriFaces[triIndex];

                    List <int> otherVerts = new List <int> {
                        triangle.A, triangle.B, triangle.C
                    };

                    //sort the triangle- ORIGINAL CODE TRANSCRIBED FROM RUST - DOESN'T WORK
                    //otherVerts.Remove(vertexIndex);
                    //TriFace sortedTriangle = new TriFace(vertexIndex, otherVerts[0], otherVerts[1]);

                    //ROTATE the triangle until the first elelemtn is the right one works
                    while (otherVerts[0] != vertexIndex)
                    {
                        int first = otherVerts[0];
                        otherVerts.RemoveAt(0);
                        otherVerts.Add(first);
                    }

                    TriFace sortedTriangle = new TriFace(otherVerts.ToArray());

                    Vertex newPoint   = dualVertices[triIndex];
                    Vertex midABPoint = GetMidPoint(sortedTriangle.A, sortedTriangle.B, vertexTriFaces, triIndex, newPoint, dualVertices, midPointCache);
                    Vertex midACPoint = GetMidPoint(sortedTriangle.A, sortedTriangle.C, vertexTriFaces, triIndex, newPoint, dualVertices, midPointCache);

                    int nGonCentreIndex = truncated.AddVertex(nGonCentreVertex);
                    int newPointIndex   = truncated.AddVertex(newPoint);
                    int midABIndex      = truncated.AddVertex(midABPoint);
                    int midACIndex      = truncated.AddVertex(midACPoint);

                    truncated.TriFaces.Add(new TriFace(newPointIndex, midACIndex, nGonCentreIndex));
                    truncated.TriFaces.Add(new TriFace(midABIndex, newPointIndex, nGonCentreIndex));
                }
            }
            Debug.Log($"Total hexagons: {hexCount}");
            Debug.Log($"Total pentagons: {pentCount}");

            return(truncated);
        }