示例#1
0
    public Mesh GenerateMesh()
    {
        DebugUtil.StartStopwatch("GenerateMesh");

        Mesh mesh = new Mesh();

        mesh.name = m_name;
        Dictionary <int, Dictionary <DraggableMeshPoint, int> > smoothingGroups = new Dictionary <int, Dictionary <DraggableMeshPoint, int> >();
        List <Vector3> vertices = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();

        int[] triangles = new int[m_triangles.Count * 3];
        for (int i = 0; i < m_triangles.Count; i++)
        {
            if (!smoothingGroups.ContainsKey(m_triangles[i].m_smoothGroupIndex))
            {
                smoothingGroups.Add(m_triangles[i].m_smoothGroupIndex, new Dictionary <DraggableMeshPoint, int>());
            }
            for (int j = 0; j < m_triangles[i].m_points.Length; j++)
            {
                if (!smoothingGroups[m_triangles[i].m_smoothGroupIndex].ContainsKey(m_triangles[i].m_points[j]))
                {
                    // Add vertex to vertices and smoothing group dictionary
                    vertices.Add(m_triangles[i].m_points[j].transform.position);
                    uvs.Add(m_triangles[i].m_uvs[j]);
                    smoothingGroups[m_triangles[i].m_smoothGroupIndex].Add(m_triangles[i].m_points[j], vertices.Count - 1);
                    triangles[3 * i + j] = vertices.Count - 1;
                }
                else
                {
                    // Use the one that we already have
                    triangles[3 * i + j] = smoothingGroups[m_triangles[i].m_smoothGroupIndex][m_triangles[i].m_points[j]];
                }
            }
        }

        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangles;
        mesh.uv        = uvs.ToArray();
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();

        DebugUtil.EndStopwatch("GenerateMesh");
        return(mesh);
    }
示例#2
0
    private Vector2[] PackUVs(Dictionary <int, Vector2>[] uvs, int uvCount, float startScale, int triesLeft)
    {
        DebugUtil.StartStopwatch("UV Packing");

        Vector2[] combinedUvs = new Vector2[uvCount];

        if (triesLeft == 0)
        {
            Debug.LogWarning("No tries left for UV packing");
            return(combinedUvs);
        }

        Dictionary <int, Vector2>[] originalUVs = (Dictionary <int, Vector2>[])uvs.Clone();

        Rect[] rects      = new Rect[uvs.Length];
        Rect[] startRects = new Rect[uvs.Length];

        for (int i = 0; i < uvs.Length; i++)
        {
            Vector2 min  = new Vector2(9999, 9999);
            Vector2 max  = new Vector2(-9999, -9999);
            var     keys = new List <int>(uvs[i].Keys);
            foreach (var k in keys)
            {
                var uv = uvs[i][k];
                uv.Scale(new Vector2(startScale, startScale));

                if (uv.x < min.x)
                {
                    min.x = uv.x;
                }
                if (uv.y < min.y)
                {
                    min.y = uv.y;
                }

                if (uv.x > max.x)
                {
                    max.x = uv.x;
                }
                if (uv.y > max.y)
                {
                    max.y = uv.y;
                }

                uvs[i][k] = uv;
            }
            rects[i].min      = min;
            rects[i].max      = max;
            startRects[i].min = min;
            startRects[i].max = max;

            rects[i].position += new Vector2(0.01f, 0.01f) * i;
        }

        float stepSize      = 0.08f;
        bool  noOverlap     = false;
        int   iterations    = 0;
        int   maxIterations = 1000;

        while (!noOverlap && iterations < maxIterations)
        {
            noOverlap = true;
            iterations++;

            for (int i = 0; i < rects.Length; i++)
            {
                for (int k = 0; k < rects.Length; k++)
                {
                    if (k == i)
                    {
                        continue;
                    }

                    if (rects[i].Overlaps(rects[k]))
                    {
                        noOverlap = false;
                        // From k to i
                        Vector2 dif = rects[i].position - rects[k].position;

                        if (dif.sqrMagnitude > stepSize * stepSize)
                        {
                            dif = dif.normalized * stepSize;
                        }

                        Vector2 randOffset = Random.insideUnitCircle * 0.01f;
                        dif += randOffset;

                        if (dif.x < 0)
                        {
                            if (rects[i].xMin + dif.x < 0)
                            {
                                dif.x = 0 - rects[i].xMin;
                            }
                        }
                        else
                        {
                            if (rects[i].xMax + dif.x > 1.0)
                            {
                                dif.x = 1 - rects[i].xMax;
                            }
                        }
                        if (dif.y < 0)
                        {
                            if (rects[i].yMin + dif.y < 0)
                            {
                                dif.y = 0 - rects[i].yMin;
                            }
                        }
                        else
                        {
                            if (rects[i].yMax + dif.y > 1.0)
                            {
                                dif.y = 1 - rects[i].yMax;
                            }
                        }

                        rects[i].position += dif;
                    }
                }
            }
        }

        for (int i = 0; i < uvs.Length; i++)
        {
            foreach (var uv in uvs[i])
            {
                combinedUvs[uv.Key] = uv.Value + rects[i].position - startRects[i].position;
            }
        }


        DebugUtil.EndStopwatch("UV Packing");

        if (noOverlap)
        {
            Debug.Log("Succes packing UVs");
        }
        else
        {
            Debug.Log("Packing failed, retrying with smaller scale");
            combinedUvs = PackUVs(originalUVs, uvCount, startScale * 0.8f, triesLeft - 1);
        }

        return(combinedUvs);
    }
示例#3
0
    public void Unwrap(ref List <MeshManager.Triangle> triangles)
    {
        DebugUtil.StartStopwatch("Unwrap");

        List <Vector3> vertices;
        List <Vector3> normals;
        Dictionary <int, Dictionary <DraggableMeshPoint, int> > smoothingGroups;

        GetVertices(triangles, out vertices, out normals, out smoothingGroups);

        // 6 faces
        Dictionary <int, Vector2>[] uvs = new Dictionary <int, Vector2> [6];
        for (int i = 0; i < uvs.Length; i++)
        {
            uvs[i] = new Dictionary <int, Vector2>();
        }
        Vector3 min, max;

        //float minF, maxF;
        GetBoundingBox(vertices, out min, out max);
        //GetBoundingBox(vertices, out minF, out maxF);

        for (int i = 0; i < vertices.Count; i++)
        {
            Vector3 vec = vertices[i] - min;
            vec.x /= (max.x - min.x);
            vec.y /= (max.y - min.y);
            vec.z /= (max.z - min.z);

            float[] ang = new float[6];

            ang[0] = Vector3.Angle(Vector3.right, normals[i]);      //+x
            ang[1] = Vector3.Angle(Vector3.left, normals[i]);       //-x
            ang[2] = Vector3.Angle(Vector3.up, normals[i]);         //+y
            ang[3] = Vector3.Angle(Vector3.down, normals[i]);       //-y
            ang[4] = Vector3.Angle(Vector3.forward, normals[i]);    //+z
            ang[5] = Vector3.Angle(Vector3.back, normals[i]);       //-z

            int   minIndex = 0;
            float minVal   = 9999.0f;
            for (int k = 0; k < ang.Length; k++)
            {
                if (ang[k] < minVal)
                {
                    minVal   = ang[k];
                    minIndex = k;
                }
            }

            Vector2 uv;

            switch (minIndex)
            {
            default:
            case 0:
                uv.x = vec.z;
                uv.y = vec.y;
                break;

            case 1:
                uv.x = 1.0f - vec.z;
                uv.y = vec.y;
                break;

            case 2:
                uv.x = vec.x;
                uv.y = vec.z;
                break;

            case 3:
                uv.x = vec.x;
                uv.y = 1.0f - vec.z;
                break;

            case 4:
                uv.x = 1.0f - vec.x;
                uv.y = vec.y;
                break;

            case 5:
                uv.x = vec.x;
                uv.y = vec.y;
                break;
            }

            uvs[minIndex][i] = uv;
        }

        // Pack UVs
        var combinedUvs = PackUVs(uvs, vertices.Capacity, 0.3f);

        // Update triangles with uvs
        foreach (var triangle in triangles)
        {
            for (int i = 0; i < triangle.m_points.Length; i++)
            {
                int index = smoothingGroups[triangle.m_smoothGroupIndex][triangle.m_points[i]];
                triangle.m_uvs[i] = combinedUvs[index];
            }
        }

        DebugUtil.EndStopwatch("Unwrap");
    }