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); }
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); } }); }