示例#1
0
        internal void Internal_UpdateMeshLOD0()
        {
            Mesh meshLod0 = GetMesh(0);

            UpdateMesh(meshLod0, subDivTree);
            MeshFilterComponent.sharedMesh   = meshLod0;
            MeshColliderComponent.sharedMesh = meshLod0;
            GCommon.SetDirty(meshLod0);
        }
 public void DeleteMesh(Vector3Int key)
 {
     if (Meshes.ContainsKey(key))
     {
         Mesh m = Meshes[key];
         if (m != null)
         {
             GUtilities.DestroyObject(m);
         }
         Meshes.Remove(key);
         GCommon.SetDirty(this);
     }
 }
 public void DeleteMesh(string key)
 {
     if (GeneratedMeshes.ContainsKey(key))
     {
         Mesh m = GeneratedMeshes[key];
         if (m != null)
         {
             GUtilities.DestroyObject(m);
         }
         GeneratedMeshes.Remove(key);
         GCommon.SetDirty(this);
     }
 }
 public void SetMesh(string key, Mesh mesh)
 {
     if (GeneratedMeshes.ContainsKey(key))
     {
         Mesh oldMesh = GeneratedMeshes[key];
         if (oldMesh != null)
         {
             GUtilities.DestroyObject(oldMesh);
         }
         GeneratedMeshes.Remove(key);
     }
     GCommon.TryAddObjectToAsset(mesh, this);
     GeneratedMeshes.Add(key, mesh);
     GCommon.SetDirty(this);
 }
        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);
                }
            });
        }