private static void WriteMaterial(ObjMaterial material, StreamWriter stream) { stream.WriteLine("newmtl {0}", material.Name); if (material.AmbientColor != null) { WriteColor("Ka", material.AmbientColor, stream); } if (material.DiffuseColor != null) { WriteColor("Kd", material.DiffuseColor, stream); } if (material.EmissiveColor != null) { WriteColor("Ke", material.EmissiveColor, stream); } if (material.SpecularColor != null) { WriteColor("Ks", material.SpecularColor, stream); } if (material.TransmissionColor != null) { WriteColor("Tf", material.TransmissionColor, stream); } stream.WriteLine("illum {0}", material.IlluminationModel); stream.Write("d"); if (material.IsHaloDissolve) { stream.Write(" -halo"); } stream.Write(' '); stream.WriteLine(material.DissolveFactor.ToString("F6", CultureInfo.InvariantCulture)); stream.Write("Ns "); stream.WriteLine(material.SpecularExponent.ToString("F6", CultureInfo.InvariantCulture)); stream.WriteLine("sharpness {0}", material.Sharpness); stream.Write("Ni "); stream.WriteLine(material.OpticalDensity.ToString("F6", CultureInfo.InvariantCulture)); stream.Write("map_aat "); if (material.IsAntiAliasingEnabled) { stream.WriteLine("on"); } else { stream.WriteLine("off"); } if (material.AmbientMap != null) { WriteMap("map_Ka", material.AmbientMap, stream); } if (material.DiffuseMap != null) { WriteMap("map_Kd", material.DiffuseMap, stream); } if (material.EmissiveMap != null) { WriteMap("map_Ke", material.EmissiveMap, stream); } if (material.SpecularMap != null) { WriteMap("map_Ks", material.SpecularMap, stream); } if (material.SpecularExponentMap != null) { WriteMap("map_Ns", material.SpecularExponentMap, stream); } if (material.DissolveMap != null) { WriteMap("map_d", material.DissolveMap, stream); } if (material.DecalMap != null) { WriteMap("decal", material.DecalMap, stream); } if (material.DispMap != null) { WriteMap("disp", material.DispMap, stream); } if (material.BumpMap != null) { WriteMap("bump", material.BumpMap, stream); } if (material.ReflectionMap.Sphere != null) { WriteMap("refl -type sphere", material.ReflectionMap.Sphere, stream); } if (material.ReflectionMap.CubeTop != null) { WriteMap("refl -type cube_top", material.ReflectionMap.CubeTop, stream); } if (material.ReflectionMap.CubeBottom != null) { WriteMap("refl -type cube_bottom", material.ReflectionMap.CubeBottom, stream); } if (material.ReflectionMap.CubeFront != null) { WriteMap("refl -type cube_front", material.ReflectionMap.CubeFront, stream); } if (material.ReflectionMap.CubeBack != null) { WriteMap("refl -type cube_back", material.ReflectionMap.CubeBack, stream); } if (material.ReflectionMap.CubeLeft != null) { WriteMap("refl -type cube_left", material.ReflectionMap.CubeLeft, stream); } if (material.ReflectionMap.CubeRight != null) { WriteMap("refl -type cube_right", material.ReflectionMap.CubeRight, stream); } }
public static ObjMaterialFile FromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } var mtl = new ObjMaterialFile(); ObjMaterial currentMaterial = null; foreach (var values in LineReader.Read(stream)) { switch (values[0].ToLowerInvariant()) { case "newmtl": if (values.Length < 2) { throw new InvalidDataException("A newmtl statement must specify a name."); } if (values.Length != 2) { throw new InvalidDataException("A newmtl statement has too many values."); } currentMaterial = new ObjMaterial { Name = values[1] }; mtl.Materials.Add(currentMaterial); break; case "ka": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.AmbientColor = ObjMaterialFileReader.ParseMaterialColor("Ka", values); break; case "kd": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.DiffuseColor = ObjMaterialFileReader.ParseMaterialColor("Kd", values); break; case "ke": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.EmissiveColor = ObjMaterialFileReader.ParseMaterialColor("Ke", values); break; case "ks": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.SpecularColor = ObjMaterialFileReader.ParseMaterialColor("Ks", values); break; case "tf": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.TransmissionColor = ObjMaterialFileReader.ParseMaterialColor("Tf", values); break; case "illum": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("An illum statement must specify an illumination model."); } if (values.Length != 2) { throw new InvalidDataException("An illum statement has too many values."); } currentMaterial.IlluminationModel = int.Parse(values[1], CultureInfo.InvariantCulture); break; case "d": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("A d statement must specify a factor."); } if (string.Equals(values[1], "-halo", StringComparison.OrdinalIgnoreCase)) { if (values.Length < 3) { throw new InvalidDataException("A d statement must specify a factor."); } if (values.Length != 3) { throw new InvalidDataException("A d statement has too many values."); } currentMaterial.IsHaloDissolve = true; currentMaterial.DissolveFactor = float.Parse(values[2], CultureInfo.InvariantCulture); } else { if (values.Length != 2) { throw new InvalidDataException("A d statement has too many values."); } currentMaterial.DissolveFactor = float.Parse(values[1], CultureInfo.InvariantCulture); } break; case "ns": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("A Ns statement must specify a specular exponent."); } if (values.Length != 2) { throw new InvalidDataException("A Ns statement has too many values."); } currentMaterial.SpecularExponent = float.Parse(values[1], CultureInfo.InvariantCulture); break; case "sharpness": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("A sharpness statement must specify a sharpness value."); } if (values.Length != 2) { throw new InvalidDataException("A sharpness statement has too many values."); } currentMaterial.Sharpness = int.Parse(values[1], CultureInfo.InvariantCulture); break; case "ni": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("A Ni statement must specify an optical density."); } if (values.Length != 2) { throw new InvalidDataException("A Ni statement has too many values."); } currentMaterial.OpticalDensity = float.Parse(values[1], CultureInfo.InvariantCulture); break; case "map_aat": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 2) { throw new InvalidDataException("A map_aat statement must specify a value."); } if (values.Length != 2) { throw new InvalidDataException("A map_aat statement has too many values."); } if (string.Equals(values[1], "on", StringComparison.OrdinalIgnoreCase)) { currentMaterial.IsAntiAliasingEnabled = true; } else if (string.Equals(values[1], "off", StringComparison.OrdinalIgnoreCase)) { currentMaterial.IsAntiAliasingEnabled = false; } else { throw new InvalidDataException("A map_aat statement must specify on or off."); } break; case "map_ka": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.AmbientMap = ObjMaterialFileReader.ParseMaterialMap("map_Ka", values); break; case "map_kd": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.DiffuseMap = ObjMaterialFileReader.ParseMaterialMap("map_Kd", values); break; case "map_ke": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.EmissiveMap = ObjMaterialFileReader.ParseMaterialMap("map_Ke", values); break; case "map_ks": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.SpecularMap = ObjMaterialFileReader.ParseMaterialMap("map_Ks", values); break; case "map_ns": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.SpecularExponentMap = ObjMaterialFileReader.ParseMaterialMap("map_Ns", values); break; case "map_d": case "map_tr": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.DissolveMap = ObjMaterialFileReader.ParseMaterialMap("map_d", values); break; case "decal": case "map_decal": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.DecalMap = ObjMaterialFileReader.ParseMaterialMap("decal", values); break; case "disp": case "map_disp": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.DispMap = ObjMaterialFileReader.ParseMaterialMap("disp", values); break; case "bump": case "map_bump": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } currentMaterial.BumpMap = ObjMaterialFileReader.ParseMaterialMap("bump", values); break; case "refl": case "map_refl": if (currentMaterial == null) { throw new InvalidDataException("The material name is not specified."); } if (values.Length < 4) { throw new InvalidDataException("A refl statement must specify a type and a file name."); } if (!string.Equals(values[1], "-type", StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("A refl statement must specify a type."); } switch (values[2].ToLowerInvariant()) { case "sphere": currentMaterial.ReflectionMap.Sphere = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_top": currentMaterial.ReflectionMap.CubeTop = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_bottom": currentMaterial.ReflectionMap.CubeBottom = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_front": currentMaterial.ReflectionMap.CubeFront = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_back": currentMaterial.ReflectionMap.CubeBack = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_left": currentMaterial.ReflectionMap.CubeLeft = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; case "cube_right": currentMaterial.ReflectionMap.CubeRight = ObjMaterialFileReader.ParseMaterialMap("refl", values); break; } break; } } return(mtl); }