/// <summary> /// Submesh grouping optimization /// </summary> /// <param name="meshArray">Mesh array</param> /// <param name="optimizedMesh">Optimized mesh result</param> /// <returns>Returns true if the mesh array was optimized</returns> public static bool OptimizeMeshes(IEnumerable <SubMeshContent> meshArray, out SubMeshContent optimizedMesh) { optimizedMesh = null; int?count = meshArray?.Count(); if (count == 1) { optimizedMesh = meshArray.First(); } else if (count > 1) { var firstMesh = meshArray.First(); string material = firstMesh.Material; Topology topology = firstMesh.Topology; VertexTypes vertexType = firstMesh.VertexType; bool isTextured = firstMesh.Textured; List <VertexData> verts = new List <VertexData>(); List <uint> idx = new List <uint>(); uint indexOffset = 0; foreach (var mesh in meshArray) { if (mesh.VertexType != vertexType || mesh.Topology != topology) { optimizedMesh = null; return(false); } if (mesh.Vertices.Length > 0) { verts.AddRange(mesh.Vertices); } if (mesh.Indices.Length > 0) { idx.AddRange(mesh.Indices.Select(i => i + indexOffset)); } indexOffset = (uint)verts.Count; } optimizedMesh = new SubMeshContent(topology, material, isTextured, false); optimizedMesh.SetVertices(verts); optimizedMesh.SetIndices(idx); } return(true); }
/// <summary> /// Generates a new model content from an height map /// </summary> /// <param name="contentFolder">Content folder</param> /// <param name="heightMap">Height map</param> /// <param name="textures">Texture list</param> /// <param name="cellSize">Cell size</param> /// <param name="cellHeight">Cell height</param> /// <returns>Returns a new model content</returns> public static ModelContent FromHeightmap(string contentFolder, string heightMap, IEnumerable <string> textures, float cellSize, float cellHeight) { ModelContent modelContent = new ModelContent(); string texureName = "texture"; string materialName = "material"; string geoName = "geometry"; ImageContent heightMapImage = new ImageContent() { Streams = ContentManager.FindContent(contentFolder, heightMap), }; ImageContent textureImage = new ImageContent() { Streams = ContentManager.FindContent(contentFolder, textures), }; MaterialContent material = MaterialContent.Default; material.DiffuseTexture = texureName; HeightMap hm = HeightMap.FromStream(heightMapImage.Stream, null); hm.BuildGeometry(cellSize, cellHeight, out var vertices, out var indices); SubMeshContent geo = new SubMeshContent(Topology.TriangleList, materialName, true, false); geo.SetVertices(vertices); geo.SetIndices(indices); modelContent.Images.Add(texureName, textureImage); modelContent.Materials.Add(materialName, material); modelContent.Geometry.Add(geoName, materialName, geo); return(modelContent); }
/// <summary> /// Generate model content from scratch /// </summary> /// <param name="topology">Topology</param> /// <param name="vertices">Vertex list</param> /// <param name="indices">Index list</param> /// <param name="material">Material</param> /// <returns>Returns new model content</returns> private static ModelContent Generate(Topology topology, IEnumerable <VertexData> vertices, IEnumerable <uint> indices, MaterialContent material = null) { ModelContent modelContent = new ModelContent(); if (material != null) { modelContent.Images.Import(ref material); modelContent.Materials.Add(ModelContent.DefaultMaterial, material); } var materialName = material != null ? ModelContent.DefaultMaterial : ModelContent.NoMaterial; var textured = modelContent.Materials[materialName].DiffuseTexture != null; SubMeshContent geo = new SubMeshContent(topology, materialName, textured, false); geo.SetVertices(vertices); geo.SetIndices(indices); modelContent.Geometry.Add(ModelContent.StaticMesh, material != null ? ModelContent.DefaultMaterial : ModelContent.NoMaterial, geo); modelContent.Optimize(); return(modelContent); }