示例#1
0
        public static GCombineInfo Combine(List <GCombineInfo> combines)
        {
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector2> uvs       = new List <Vector2>();
            List <Color32> colors    = new List <Color32>();
            List <int>     triangles = new List <int>();

            for (int i = 0; i < combines.Count; ++i)
            {
                GCombineInfo c      = combines[i];
                int          offset = vertices.Count;
                for (int j = 0; j < c.Triangles.Length; ++j)
                {
                    triangles.Add(offset + c.Triangles[j]);
                }

                for (int j = 0; j < c.Vertices.Length; ++j)
                {
                    vertices.Add(c.Transform.MultiplyPoint(c.Vertices[j]));
                }

                uvs.AddRange(c.UVs);
                colors.AddRange(c.Colors);
            }

            GCombineInfo result = new GCombineInfo();

            result.Vertices  = vertices.ToArray();
            result.UVs       = uvs.ToArray();
            result.Colors    = colors.ToArray();
            result.Triangles = triangles.ToArray();
            return(result);
        }
示例#2
0
        public static GCombineInfo Combine(GCombineInfo meshTemplate, List <Matrix4x4> transforms)
        {
            int vertexCount = meshTemplate.Vertices.Length * transforms.Count;

            Vector3[] vertices = new Vector3[vertexCount];
            Vector2[] uvs      = new Vector2[vertexCount];
            //Color32[] colors = new Color32[vertexCount];

            int trisIndexCount = meshTemplate.Triangles.Length * transforms.Count;

            int[] triangles = new int[trisIndexCount];

            int currentVertIndex = 0;
            int currentTrisIndex = 0;

            for (int i = 0; i < transforms.Count; ++i)
            {
                int offset = currentVertIndex;
                for (int j = 0; j < meshTemplate.Triangles.Length; ++j)
                {
                    triangles[currentTrisIndex] = offset + meshTemplate.Triangles[j];
                    currentTrisIndex           += 1;
                }

                for (int j = 0; j < meshTemplate.Vertices.Length; ++j)
                {
                    vertices[currentVertIndex] = transforms[i].MultiplyPoint(meshTemplate.Vertices[j]);
                    uvs[currentVertIndex]      = meshTemplate.UVs[j];
                    //colors[currentVertIndex] = meshTemplate.Colors[j];
                    currentVertIndex += 1;
                }
            }

            GCombineInfo result = new GCombineInfo();

            result.Vertices = vertices;
            result.UVs      = uvs;
            //result.Colors = colors;
            result.Triangles = triangles;
            return(result);
        }
        public void UpdateMesh(int prototypeIndex)
        {
            if (Foliage.Grasses == null)
            {
                return;
            }
            if (prototypeIndex < 0 || prototypeIndex >= Foliage.Grasses.Prototypes.Count)
            {
                return;
            }

            StripInstances(prototypeIndex);
            string key = GetPatchMeshName(Index, prototypeIndex);
            Mesh   m   = Foliage.TerrainData.FoliageData.GetMesh(key);

            if (m != null && Foliage.TerrainData.Foliage.GrassInstanceCount == 0)
            {
                Foliage.TerrainData.FoliageData.DeleteMesh(key);
                return;
            }
            else if (m == null)
            {
                m = new Mesh();
                m.MarkDynamic();
                m.name = key;
                Foliage.TerrainData.FoliageData.SetMesh(key, m);
            }

            GGrassPrototype prototype   = Foliage.Grasses.Prototypes[prototypeIndex];
            Mesh            baseMesh    = prototype.GetBaseMesh();
            Vector3         terrainSize = new Vector3(
                Foliage.TerrainData.Geometry.Width,
                Foliage.TerrainData.Geometry.Height,
                Foliage.TerrainData.Geometry.Length);

            GCombineInfo meshTemplate = new GCombineInfo(baseMesh);

            List <Matrix4x4> transforms = new List <Matrix4x4>();
            Rect             uvRange    = GetUvRange();

            for (int i = 0; i < Instances.Count; ++i)
            {
                GGrassInstance grass = Instances[i];
                if (grass.PrototypeIndex != prototypeIndex)
                {
                    continue;
                }
                if (!uvRange.Contains(new Vector2(grass.Position.x, grass.Position.z)))
                {
                    continue;
                }

                Matrix4x4 t = Matrix4x4.TRS(
                    new Vector3(grass.Position.x * terrainSize.x, grass.Position.y * terrainSize.y + prototype.PivotOffset, grass.Position.z * terrainSize.z),
                    grass.Rotation,
                    new Vector3(prototype.Size.x * grass.Scale.x, prototype.Size.y * grass.Scale.y, prototype.Size.z * grass.Scale.z));
                transforms.Add(t);
            }

            int vertexCount = meshTemplate.Vertices.Length * transforms.Count;

            if (vertexCount > 65000)
            {
                string warning = string.Format("Failed to batch grass meshes at patch {0}, prototypeIndex {1} due to vertices limit (batch: {2}, limit: 65000). Consider removing some instances or increase Patch Grid Size and try again!", Index.ToString("0"), prototypeIndex, vertexCount);
                Debug.LogWarning(warning);
            }

            GJobSystem.RunOnBackground(() =>
            {
                GCombineInfo result = GCombiner.Combine(meshTemplate, transforms);
                System.Action task  = () =>
                {
                    if (result.Vertices.Length == 0)
                    {
                        Foliage.TerrainData.FoliageData.DeleteMesh(key);
                    }
                    else
                    {
                        m.Clear();
                        m.vertices = result.Vertices;
                        m.uv       = result.UVs;
                        //m.colors32 = result.Colors;
                        m.triangles = result.Triangles;
                        m.RecalculateBounds();

                        //Reduce mesh storage space
                        m.colors32 = null;
                        m.normals  = null;
                        m.tangents = null;
                        m.uv2      = null;
                        //m.RecalculateNormals();
                        //m.RecalculateTangents();

                        GCommon.SetDirty(m);
                        //System.GC.Collect(); ==>This line will cause the editor to hang soooooo long!
                    }
                };

                if (result.Vertices.Length < 1000)
                {
                    GJobSystem.RunOnMainThread(task);
                }
                else
                {
                    GJobSystem.ScheduleOnMainThread(task, 0);
                }
            });
        }