Exemple #1
0
            public void From(WorkingMesh mesh)
            {
                m_name = mesh.name;

                m_vertices = ArrayToBytes(mesh.vertices);
                m_normals  = ArrayToBytes(mesh.normals);
                m_tangents = ArrayToBytes(mesh.tangents);
                m_uvs      = ArrayToBytes(mesh.uv);
                m_uvs2     = ArrayToBytes(mesh.uv2);
                m_uvs3     = ArrayToBytes(mesh.uv3);
                m_uvs4     = ArrayToBytes(mesh.uv4);
                m_colors   = ArrayToBytes(mesh.colors);
                m_indices  = new List <int[]>();
                for (int i = 0; i < mesh.subMeshCount; ++i)
                {
                    m_indices.Add(mesh.GetTriangles(i));
                }
            }
Exemple #2
0
        private void ConvertMesh(WorkingMesh mesh, DisposableList <WorkingMaterial> materials, TexturePacker.TextureAtlas atlas, string mainTextureName)
        {
            var uv      = mesh.uv;
            var updated = new bool[uv.Length];
            // Some meshes have submeshes that either aren't expected to render or are missing a material, so go ahead and skip
            int subMeshCount = Mathf.Min(mesh.subMeshCount, materials.Count);

            for (int mi = 0; mi < subMeshCount; ++mi)
            {
                int[] indices = mesh.GetTriangles(mi);
                foreach (var i in indices)
                {
                    if (updated[i] == false)
                    {
                        var uvCoord = uv[i];
                        var texture = materials[mi].GetTexture(mainTextureName);

                        if (texture == null || texture.GetGUID() == Guid.Empty)
                        {
                            // Sample at center of white texture to avoid sampling edge colors incorrectly
                            uvCoord.x = 0.5f;
                            uvCoord.y = 0.5f;
                        }
                        else
                        {
                            var uvOffset = atlas.GetUV(texture.GetGUID());

                            uvCoord.x = Mathf.Lerp(uvOffset.xMin, uvOffset.xMax, uvCoord.x);
                            uvCoord.y = Mathf.Lerp(uvOffset.yMin, uvOffset.yMax, uvCoord.y);
                        }

                        uv[i]      = uvCoord;
                        updated[i] = true;
                    }
                }
            }

            mesh.uv = uv;
        }
Exemple #3
0
        private WorkingMesh MakeFillHoleMesh(WorkingMesh source)
        {
            int          totalTris = 0;
            List <int[]> newTris   = new List <int[]>();

            for (int si = 0; si < source.subMeshCount; ++si)
            {
                List <int>        tris     = source.GetTriangles(si).ToList();
                List <Vector2Int> edgeList = GetEdgeList(tris);


                List <EdgeGroup> groups = new List <EdgeGroup>();
                for (int i = 0; i < edgeList.Count; ++i)
                {
                    EdgeGroup group = new EdgeGroup();
                    group.Begin = edgeList[i].x;
                    group.End   = edgeList[i].y;
                    group.EdgeList.Add(edgeList[i]);

                    groups.Add(group);
                }

                bool isFinish = false;

                while (isFinish == false)
                {
                    isFinish = true;

                    for (int gi1 = 0; gi1 < groups.Count; ++gi1)
                    {
                        for (int gi2 = gi1 + 1; gi2 < groups.Count; ++gi2)
                        {
                            EdgeGroup g1 = groups[gi1];
                            EdgeGroup g2 = groups[gi2];

                            if (g1.End == g2.Begin)
                            {
                                g1.End = g2.End;
                                g1.EdgeList.AddRange(g2.EdgeList);

                                groups[gi2] = groups[groups.Count - 1];
                                groups.RemoveAt(groups.Count - 1);

                                gi2     -= 1;
                                isFinish = false;
                            }
                            else if (g1.Begin == g2.End)
                            {
                                g2.End = g1.End;
                                g2.EdgeList.AddRange(g1.EdgeList);

                                groups[gi1] = groups[gi2];
                                groups[gi2] = groups[groups.Count - 1];
                                groups.RemoveAt(groups.Count - 1);

                                gi2     -= 1;
                                isFinish = false;
                            }
                        }
                    }
                }

                for (int gi = 0; gi < groups.Count; ++gi)
                {
                    EdgeGroup group = groups[gi];
                    for (int ei1 = 1; ei1 < group.EdgeList.Count - 1; ++ei1)
                    {
                        for (int ei2 = ei1 + 1; ei2 < group.EdgeList.Count; ++ei2)
                        {
                            if (group.EdgeList[ei1].x == group.EdgeList[ei2].y)
                            {
                                EdgeGroup ng = new EdgeGroup();
                                ng.Begin = group.EdgeList[ei1].x;
                                ng.End   = group.EdgeList[ei2].y;

                                for (int i = ei1; i <= ei2; ++i)
                                {
                                    ng.EdgeList.Add(group.EdgeList[i]);
                                }

                                for (int i = ei2; i >= ei1; --i)
                                {
                                    group.EdgeList.RemoveAt(i);
                                }

                                groups.Add(ng);

                                ei1 = 0; // goto first
                                break;
                            }
                        }
                    }
                }

                if (groups.Count == 0)
                {
                    continue;
                }

                groups.Sort((g1, g2) => { return(g2.EdgeList.Count - g1.EdgeList.Count); });

                //first group( longest group ) is outline.
                for (int i = 1; i < groups.Count; ++i)
                {
                    EdgeGroup group = groups[i];
                    for (int ei = 1; ei < group.EdgeList.Count - 1; ++ei)
                    {
                        tris.Add(group.Begin);
                        tris.Add(group.EdgeList[ei].y);
                        tris.Add(group.EdgeList[ei].x);
                    }
                }

                totalTris += tris.Count;
                newTris.Add(tris.ToArray());
            }

            WorkingMesh mesh = new WorkingMesh(Allocator.Persistent, source.vertexCount, totalTris, source.subMeshCount, 0);

            mesh.name     = source.name;
            mesh.vertices = source.vertices;
            mesh.normals  = source.normals;
            mesh.uv       = source.uv;

            for (int i = 0; i < newTris.Count; ++i)
            {
                mesh.SetTriangles(newTris[i], i);
            }

            return(mesh);
        }
Exemple #4
0
        private WorkingMesh MakeBorder(WorkingMesh source, Heightmap heightmap, int borderCount)
        {
            List <Vector3> vertices    = source.vertices.ToList();
            List <Vector3> normals     = source.normals.ToList();
            List <Vector2> uvs         = source.uv.ToList();
            List <int[]>   subMeshTris = new List <int[]>();

            int maxTris = 0;

            for (int si = 0; si < source.subMeshCount; ++si)
            {
                List <int>          tris         = source.GetTriangles(si).ToList();
                List <Vector2Int>   edges        = GetEdgeList(tris);
                HashSet <int>       vertexIndces = new HashSet <int>();
                List <BorderVertex> edgeVertices = new List <BorderVertex>();

                for (int ei = 0; ei < edges.Count; ++ei)
                {
                    vertexIndces.Add(edges[ei].x);
                    vertexIndces.Add(edges[ei].y);
                }

                List <BorderVertex> borderVertices = GenerateBorderVertices(heightmap, borderCount);

                //calculate closest vertex from border vertices.
                for (int i = 0; i < borderVertices.Count; ++i)
                {
                    float        closestDistance = Single.MaxValue;
                    BorderVertex v = borderVertices[i];
                    foreach (var index in vertexIndces)
                    {
                        Vector3 pos  = vertices[index];
                        float   dist = Vector3.SqrMagnitude(pos - borderVertices[i].Pos);
                        if (dist < closestDistance)
                        {
                            closestDistance = dist;
                            v.ClosestIndex  = index;
                        }
                    }

                    borderVertices[i] = v;
                }

                //generate tris
                int startAddIndex = vertices.Count;
                for (int bi = 0; bi < borderVertices.Count; ++bi)
                {
                    int next = (bi == borderVertices.Count - 1) ? 0 : bi + 1;

                    tris.Add(bi + startAddIndex);
                    tris.Add(borderVertices[bi].ClosestIndex);
                    tris.Add(next + startAddIndex);

                    Vector2 uv;
                    uv.x = (borderVertices[bi].Pos.x - heightmap.Offset.x) / heightmap.Size.x;
                    uv.y = (borderVertices[bi].Pos.z - heightmap.Offset.z) / heightmap.Size.z;
                    vertices.Add(borderVertices[bi].Pos);

                    if (m_hlod.UseNormal)
                    {
                        normals.Add(Vector3.up);
                    }
                    else
                    {
                        normals.Add(heightmap.GetInterpolatedNormal(uv.x, uv.y));
                    }

                    uvs.Add(uv);

                    if (borderVertices[bi].ClosestIndex == borderVertices[next].ClosestIndex)
                    {
                        continue;
                    }

                    tris.Add(borderVertices[bi].ClosestIndex);
                    tris.Add(borderVertices[next].ClosestIndex);
                    tris.Add(next + startAddIndex);
                }

                maxTris += tris.Count;
                subMeshTris.Add(tris.ToArray());
            }

            WorkingMesh mesh = new WorkingMesh(Allocator.Persistent, vertices.Count, maxTris, subMeshTris.Count, 0);

            mesh.name     = source.name;
            mesh.vertices = vertices.ToArray();
            mesh.normals  = normals.ToArray();
            mesh.uv       = uvs.ToArray();

            for (int i = 0; i < subMeshTris.Count; ++i)
            {
                mesh.SetTriangles(subMeshTris[i], i);
            }

            return(mesh);
        }
Exemple #5
0
        public WorkingMesh CombineMesh(Allocator allocator, List <CombineInfo> infos)
        {
            //I didn't consider animation mesh combine.
            int verticesCount = 0;
            int normalCount   = 0;
            int tangentCount  = 0;
            int UV1Count      = 0;
            int UV2Count      = 0;
            int UV3Count      = 0;
            int UV4Count      = 0;
            int colorCount    = 0;

            int trianglesCount = 0;

            List <Dictionary <int, int> > remappers = new List <Dictionary <int, int> >(infos.Count);

            for (int i = 0; i < infos.Count; ++i)
            {
                int[] meshIndices = infos[i].Mesh.GetTriangles(infos[i].MeshIndex);
                Dictionary <int, int> remapper = CalculateMeshRemap(meshIndices);

                verticesCount += (infos[i].Mesh.vertices.Length > 0) ? remapper.Count : 0;
                normalCount   += (infos[i].Mesh.normals.Length > 0) ? remapper.Count : 0;
                tangentCount  += (infos[i].Mesh.tangents.Length > 0) ? remapper.Count : 0;
                UV1Count      += (infos[i].Mesh.uv.Length > 0) ? remapper.Count : 0;
                UV2Count      += (infos[i].Mesh.uv2.Length > 0) ? remapper.Count : 0;
                UV3Count      += (infos[i].Mesh.uv3.Length > 0) ? remapper.Count : 0;
                UV4Count      += (infos[i].Mesh.uv4.Length > 0) ? remapper.Count : 0;
                colorCount    += (infos[i].Mesh.colors.Length > 0) ? remapper.Count : 0;

                trianglesCount += meshIndices.Length;

                remappers.Add(remapper);
            }

            WorkingMesh combinedMesh = new WorkingMesh(allocator, verticesCount, trianglesCount, 1, 0);

            List <Vector3> vertices = new List <Vector3>(verticesCount);
            List <Vector3> normals  = new List <Vector3>(verticesCount);
            List <Vector4> tangents = new List <Vector4>(verticesCount);
            List <Vector2> uv1s     = new List <Vector2>(verticesCount);
            List <Vector2> uv2s     = new List <Vector2>(verticesCount);
            List <Vector2> uv3s     = new List <Vector2>(verticesCount);
            List <Vector2> uv4s     = new List <Vector2>(verticesCount);
            List <Color>   colors   = new List <Color>(colorCount);

            List <int> triangles = new List <int>(trianglesCount);

            for (int i = 0; i < infos.Count; ++i)
            {
                WorkingMesh           mesh     = infos[i].Mesh;
                Dictionary <int, int> remapper = remappers[i];
                int startIndex = vertices.Count;

                if (verticesCount > 0)
                {
                    FillBuffer(ref vertices, mesh.vertices, remapper, Vector3.zero);
                    for (int vi = startIndex; vi < vertices.Count; ++vi)
                    {
                        vertices[vi] = infos[i].Transform.MultiplyPoint(vertices[vi]);
                    }
                }

                if (normalCount > 0)
                {
                    FillBuffer(ref normals, mesh.normals, remapper, Vector3.up);
                    for (int ni = startIndex; ni < normals.Count; ++ni)
                    {
                        normals[ni] = infos[i].Transform.MultiplyVector(normals[ni]);
                    }
                }

                if (tangentCount > 0)
                {
                    FillBuffer(ref tangents, mesh.tangents, remapper, new Vector4(1, 0, 0, 1));
                    for (int ti = startIndex; ti < tangents.Count; ++ti)
                    {
                        Vector3 tanVec = new Vector3(tangents[ti].x, tangents[ti].y, tangents[ti].z);
                        tanVec = infos[i].Transform.MultiplyVector(tanVec);
                        Vector4 transTan = new Vector4(tanVec.x, tanVec.y, tanVec.z, tangents[ti].w);
                        tangents[ti] = transTan;
                    }
                }

                if (UV1Count > 0)
                {
                    FillBuffer(ref uv1s, mesh.uv, remapper, Vector2.zero);
                }
                if (UV2Count > 0)
                {
                    FillBuffer(ref uv2s, mesh.uv2, remapper, Vector2.zero);
                }
                if (UV3Count > 0)
                {
                    FillBuffer(ref uv3s, mesh.uv3, remapper, Vector2.zero);
                }
                if (UV4Count > 0)
                {
                    FillBuffer(ref uv4s, mesh.uv4, remapper, Vector2.zero);
                }
                if (colorCount > 0)
                {
                    FillBuffer(ref colors, mesh.colors, remapper, Color.white);
                }

                FillIndices(ref triangles, mesh.GetTriangles(infos[i].MeshIndex), remapper, startIndex);
            }

            combinedMesh.name     = "CombinedMesh";
            combinedMesh.vertices = vertices.ToArray();
            combinedMesh.normals  = normals.ToArray();
            combinedMesh.tangents = tangents.ToArray();
            combinedMesh.uv       = uv1s.ToArray();
            combinedMesh.uv2      = uv2s.ToArray();
            combinedMesh.uv3      = uv3s.ToArray();
            combinedMesh.uv4      = uv4s.ToArray();
            combinedMesh.colors   = colors.ToArray();

            combinedMesh.SetTriangles(triangles.ToArray(), 0);

            return(combinedMesh);
        }