public IEnumerable <MeshPrimitive> GetHeightPlanes() { float size = 0.5f; MeshPrimitive mesh = CreateEmptyTriangleMesh(); float y = -size; List <Vector3> positions = new List <Vector3> { new Vector3(-size, y, -size) , new Vector3(-size, y, size) , new Vector3(size, y, size) , new Vector3(size, y, -size) }; mesh.Positions = positions; mesh.Colors = positions.Select(n => new Vector4(1, 0, 0, 0)); mesh.Indices = new int[] { 0, 1, 3, 1, 2, 3 }; mesh.Normals = _meshService.ComputeNormals(positions, mesh.Indices.ToList()); yield return(mesh); //===================== mesh = CreateEmptyTriangleMesh(); y = 0; positions = new List <Vector3> { new Vector3(-size, y, -size) , new Vector3(-size, y, size) , new Vector3(size, y, size) , new Vector3(size, y, -size) }; mesh.Positions = positions; mesh.Colors = positions.Select(n => new Vector4(0, 1, 0, 0)); mesh.Indices = new int[] { 0, 1, 3, 1, 2, 3 }; mesh.Normals = _meshService.ComputeNormals(positions, mesh.Indices.ToList()); yield return(mesh); //===================== mesh = CreateEmptyTriangleMesh(); y = size; positions = new List <Vector3> { new Vector3(-size, y, -size) , new Vector3(-size, y, size) , new Vector3(size, y, size) , new Vector3(size, y, -size) }; mesh.Positions = positions; mesh.Colors = positions.Select(n => new Vector4(0, 0, 1, 0)); mesh.Indices = new int[] { 0, 1, 3, 1, 2, 3 }; mesh.Normals = _meshService.ComputeNormals(positions, mesh.Indices.ToList()); yield return(mesh); }
/// <summary> /// Generate normal texture from height map. /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateNormalMap(HeightMap heightMap, string outputDirectory, string fileName = "normalmap.png") { List <Vector3> normals = _meshService.ComputeNormals(heightMap).ToList(); using (Image <Bgra32> outputImage = new Image <Bgra32>(heightMap.Width, heightMap.Height)) { for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); Vector3 norm = normals[index]; Bgra32 color = FromVec3NormalToColor(norm); outputImage[i, j] = color; } } outputImage.Save(System.IO.Path.Combine(outputDirectory, fileName)); } TextureInfo normal = new TextureInfo(System.IO.Path.Combine(outputDirectory, fileName), TextureImageFormat.image_jpeg, heightMap.Width, heightMap.Height); return(normal); }
public ModelRoot CreateTerrainMesh(HeightMap heightMap, GenOptions options = GenOptions.None, Matrix4x4 vectorTransform = default) { Triangulation triangulation = default; if (options.HasFlag(GenOptions.BoxedBaseElevation0)) { triangulation = _meshService.GenerateTriangleMesh_Boxed(heightMap, BoxBaseThickness.FixedElevation, 0); } else if (options.HasFlag(GenOptions.BoxedBaseElevationMin)) { triangulation = _meshService.GenerateTriangleMesh_Boxed(heightMap, BoxBaseThickness.FromMinimumPoint, 5); } else { triangulation = _meshService.TriangulateHeightMap(heightMap); } // create a basic scene var model = CreateNewModel(); var rnode = model.LogicalScenes.First()?.FindNode(n => n.Name == TERRAIN_NODE_NAME); var rmesh = rnode.Mesh = model.CreateMesh(TERRAIN_MESH_NAME); var material = model.CreateMaterial("Default") .WithPBRMetallicRoughness() .WithDoubleSide(true); var indexedTriangulation = new IndexedTriangulation(triangulation, vectorTransform); // create mesh primitive var primitive = rmesh.CreatePrimitive() .WithVertexAccessor("POSITION", indexedTriangulation.Positions); if (options.HasFlag(GenOptions.Normals)) { var normals = _meshService.ComputeNormals(indexedTriangulation.Positions, indexedTriangulation.Indices); primitive = primitive.WithVertexAccessor("NORMAL", normals.ToList()); } primitive = primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indexedTriangulation.Indices) .WithMaterial(material); return(model); }
/// <summary> /// Generate normal texture from height map. /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateNormalMap(HeightMap heightMap, string outputDirectory, string fileName = "normalmap.png") { List <Vector3> normals = _meshService.ComputeNormals(heightMap).ToList(); #if NETSTANDARD using (Image <Bgra32> outputImage = new Image <Bgra32>(heightMap.Width, heightMap.Height)) { for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); Vector3 norm = normals[index]; Bgra32 color = FromVec3NormalToColor(norm); outputImage[i, j] = color; } } outputImage.Save(System.IO.Path.Combine(outputDirectory, fileName)); } #elif NETFULL using (var dbm = new DirectBitmap(heightMap.Width, heightMap.Height)) { for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); Vector3 norm = normals[index]; Color color = FromVec3NormalToColor(norm); dbm.SetPixel(i, j, color); } } dbm.Bitmap.Save(Path.Combine(outputDirectory, fileName), ImageFormat.Png); } #endif TextureInfo normal = new TextureInfo(System.IO.Path.Combine(outputDirectory, fileName), TextureImageFormat.image_jpeg, heightMap.Width, heightMap.Height); return(normal); }