public static void CombineMeshes(Queue<CombineInstance> items , byte area , InputGeometryCompiler compiler) { const int MaxTris = 65000; List<CombineInstance> combineInstancesPart = new List<CombineInstance>(); byte[] areas = NMGen.CreateAreaBuffer(MaxTris, area); while (items.Count != 0) { int vertCount = 0; while (items.Count > 0 && (vertCount + items.Peek().mesh.vertexCount < MaxTris)) { vertCount += items.Peek().mesh.vertexCount; combineInstancesPart.Add(items.Dequeue()); } Mesh meshPart = new Mesh(); meshPart.CombineMeshes(combineInstancesPart.ToArray(), true, true); compiler.AddTriangles(meshPart.vertices, meshPart.vertexCount , meshPart.triangles, areas, meshPart.triangles.Length / 3); Object.DestroyImmediate(meshPart); combineInstancesPart.Clear(); } }
public static void CombineMeshes(Queue <CombineInstance> items , byte area , InputGeometryCompiler compiler) { const int MaxTris = 65000; List <CombineInstance> combineInstancesPart = new List <CombineInstance>(); byte[] areas = NMGen.CreateAreaBuffer(MaxTris, area); while (items.Count != 0) { int vertCount = 0; while (items.Count > 0 && (vertCount + items.Peek().mesh.vertexCount < MaxTris)) { vertCount += items.Peek().mesh.vertexCount; combineInstancesPart.Add(items.Dequeue()); } Mesh meshPart = new Mesh(); meshPart.CombineMeshes(combineInstancesPart.ToArray(), true, true); UnityEngine.Vector3[] vs = meshPart.vertices; Vector3[] vvs = VectorHelper.ToVector3Array(ref vs); compiler.AddTriangles(vvs, meshPart.vertexCount , meshPart.triangles, areas, meshPart.triangles.Length / 3); Object.DestroyImmediate(meshPart); combineInstancesPart.Clear(); } }
private void Compile(InputBuildContext context) { context.info.compilerCount++; InputGeometryCompiler compiler = context.geomCompiler; List <Component> items = context.components; List <byte> areas = context.areas; for (int i = 0; i < items.Count; i++) { Component item = items[i]; if (item is Terrain) { Terrain terrain = (Terrain)item; if (terrain.terrainData != terrainData) { continue; } TriangleMesh mesh = TerrainUtil.TriangulateSurface(terrain, mResolution); byte[] lareas = NMGen.CreateAreaBuffer(mesh.triCount, areas[i]); if (compiler.AddTriangles(mesh, lareas)) { string msg = string.Format("Compiled the {0} terrain surface. Triangles: {1}" , terrain.name, mesh.triCount); context.Log(msg, this); } else { string msg = string.Format("Compiler rejected mesh for the {0} terrain.", terrain.name); context.LogError(msg, this); return; } if (includeTrees) { int before = compiler.TriCount; TerrainUtil.TriangluateTrees(terrain, areas[i], compiler); string msg = string.Format("Compiled the {0} terrain trees. Triangles: {1}" , terrain.name, compiler.TriCount - before); context.Log(msg, this); } break; } } }
private void CombineMeshes(Queue <MeshFilter> filters , byte area , InputGeometryCompiler compiler , ColliderHelper helper) { Queue <CombineInstance> combineInstances = new Queue <CombineInstance>(); while (filters.Count != 0) { MeshFilter filter = filters.Dequeue(); if (helper != null) { Collider collider = filter.GetComponent <Collider>(); if (collider) { CombineInstance ci; if (helper.Get(collider, out ci)) { combineInstances.Enqueue(ci); continue; } } } // Note: Null shared meshes were filtered out by the calling method. for (int subIndex = 0; subIndex < filter.sharedMesh.subMeshCount; ++subIndex) { CombineInstance combineInstance = new CombineInstance(); combineInstance.mesh = filter.sharedMesh; combineInstance.transform = filter.transform.localToWorldMatrix; combineInstance.subMeshIndex = subIndex; combineInstances.Enqueue(combineInstance); } } MeshUtil.CombineMeshes(combineInstances, area, compiler); }
public static void TriangluateTrees(Terrain terrain , byte area , InputGeometryCompiler compiler) { if (terrain == null || terrain.terrainData == null || compiler == null) { return; } TerrainData data = terrain.terrainData; // Note: This array may be loaded with nulls. // This is required to keep indices in sync. Mesh[] protoMeshes = new Mesh[data.treePrototypes.Length]; for (int i = 0; i < protoMeshes.Length; i++) { TreePrototype prototype = data.treePrototypes[i]; MeshFilter filter = prototype.prefab.GetComponent <MeshFilter>(); if (filter == null || filter.sharedMesh == null) { Debug.LogWarning(string.Format( "{0} : There is no mesh attached the {1} tree prototype." + "Trees based on this prototype will be ignored." , terrain.name , prototype.prefab.name)); protoMeshes[i] = null; } else { protoMeshes[i] = filter.sharedMesh; } } UnityEngine.Vector3 terrainPos = terrain.transform.position; UnityEngine.Vector3 terrainSize = terrain.terrainData.size; Queue <CombineInstance> combineInstances = new Queue <CombineInstance>(data.treeInstances.Length); foreach (TreeInstance tree in data.treeInstances) { if (protoMeshes[tree.prototypeIndex] == null) { // Prototype for this tree doesn't have a mesh. continue; } UnityEngine.Vector3 pos = tree.position; pos.x *= terrainSize.x; pos.y *= terrainSize.y; pos.z *= terrainSize.z; pos += terrainPos; UnityEngine.Vector3 scale = new UnityEngine.Vector3(tree.widthScale, tree.heightScale, tree.widthScale); CombineInstance ci = new CombineInstance(); ci.mesh = protoMeshes[tree.prototypeIndex]; ci.transform = Matrix4x4.TRS(pos, Quaternion.identity, scale); combineInstances.Enqueue(ci); } protoMeshes = null; if (combineInstances.Count == 0) { return; } MeshUtil.CombineMeshes(combineInstances, area, compiler); }
public static void TriangluateTrees(Terrain terrain , byte area , InputGeometryCompiler compiler) { if (terrain == null || terrain.terrainData == null || compiler == null) return; TerrainData data = terrain.terrainData; // Note: This array may be loaded with nulls. // This is required to keep indices in sync. Mesh[] protoMeshes = new Mesh[data.treePrototypes.Length]; for (int i = 0; i < protoMeshes.Length; i++) { TreePrototype prototype = data.treePrototypes[i]; MeshFilter filter = prototype.prefab.GetComponent<MeshFilter>(); if (filter == null || filter.sharedMesh == null) { Debug.LogWarning(string.Format( "{0} : There is no mesh attached the {1} tree prototype." + "Trees based on this prototype will be ignored." , terrain.name , prototype.prefab.name)); protoMeshes[i] = null; } else protoMeshes[i] = filter.sharedMesh; } Vector3 terrainPos = terrain.transform.position; Vector3 terrainSize = terrain.terrainData.size; Queue<CombineInstance> combineInstances = new Queue<CombineInstance>(data.treeInstances.Length); foreach (TreeInstance tree in data.treeInstances) { if (protoMeshes[tree.prototypeIndex] == null) // Prototype for this tree doesn't have a mesh. continue; Vector3 pos = tree.position; pos.x *= terrainSize.x; pos.y *= terrainSize.y; pos.z *= terrainSize.z; pos += terrainPos; Vector3 scale = new Vector3(tree.widthScale, tree.heightScale, tree.widthScale); CombineInstance ci = new CombineInstance(); ci.mesh = protoMeshes[tree.prototypeIndex]; ci.transform = Matrix4x4.TRS(pos, Quaternion.identity, scale); combineInstances.Enqueue(ci); } protoMeshes = null; if (combineInstances.Count == 0) return; MeshUtil.CombineMeshes(combineInstances, area, compiler); }
private void Compile(InputBuildContext context) { context.info.compilerCount++; ColliderHelper colliderHelper = (colocationOption == MeshColocationOption.Collider) ? new ColliderHelper() : null; InputGeometryCompiler compiler = context.geomCompiler; List <Component> master = new List <Component>(context.components); List <byte> areas = new List <byte>(context.areas); Queue <MeshFilter> filters = new Queue <MeshFilter>(); int count = 0; int ignored = 0; while (master.Count > 0) { byte area = 0; for (int i = master.Count - 1; i >= 0; i--) { Component item = master[i]; if (item is MeshFilter) { MeshFilter filter = (MeshFilter)item; if (filter.sharedMesh == null) { ignored++; areas.RemoveAt(i); master.RemoveAt(i); } else { if (filters.Count == 0) { area = areas[i]; } if (areas[i] == area) { count++; filters.Enqueue(filter); areas.RemoveAt(i); master.RemoveAt(i); } } } else { areas.RemoveAt(i); master.RemoveAt(i); } } if (filters.Count > 0) { CombineMeshes(filters, area, compiler, colliderHelper); } } if (colliderHelper != null) { colliderHelper.Dispose(); } if (ignored > 0) { string msg = string.Format("{0}: Ignored {1} MeshFilters with a null mesh." , name, ignored); context.Log(msg, this); } context.Log(string.Format("{0}: Compiled {1} MeshFilters.", name, count), this); }