static void SaveMeshToFile(Mesh3d m, string name, string outfile) { StringBuilder materialb = new StringBuilder(); var mat = m.GetLodLevel(0).Material; var i3d = m.GetLodLevel(0).Info3d; var inst = m.GetInstance(0); string meshname = name + ".mesh3d"; string matname = name + ".material"; string rawfile = name + ".raw"; i3d.Manager.ReverseYUV(1); i3d.Manager.SaveRawWithTangents(outfile + "/" + rawfile); materialb.AppendLine(string.Format("diffuse {0} {1} {2}", ftos(mat.DiffuseColor.X), ftos(mat.DiffuseColor.Y), ftos(mat.DiffuseColor.Z))); materialb.AppendLine(string.Format("roughness {0}", ftos(mat.Roughness))); materialb.AppendLine(string.Format("metalness {0}", 0.2f)); materialb.AppendLine(); if (mat.NormalsTexture != null) { materialb.AppendLine("node"); materialb.AppendLine(string.Format("texture {0}", mat.NormalsTexture.FileName)); materialb.AppendLine("mix REPLACE"); materialb.AppendLine("target NORMAL"); materialb.AppendLine(); } if (mat.DiffuseTexture != null) { materialb.AppendLine("node"); materialb.AppendLine(string.Format("texture {0}", mat.DiffuseTexture.FileName)); materialb.AppendLine("mix REPLACE"); materialb.AppendLine("target DIFFUSE"); materialb.AppendLine("modifier LINEARIZE"); materialb.AppendLine(); } if (mat.BumpTexture != null) { materialb.AppendLine("node"); materialb.AppendLine(string.Format("texture {0}", mat.BumpTexture.FileName)); materialb.AppendLine("mix REPLACE"); materialb.AppendLine("target BUMP"); materialb.AppendLine(); } if (mat.RoughnessTexture != null) { materialb.AppendLine("node"); materialb.AppendLine(string.Format("texture {0}", mat.RoughnessTexture.FileName)); materialb.AppendLine("mix REPLACE"); materialb.AppendLine("target ROUGHNESS"); materialb.AppendLine(); } File.WriteAllText(outfile + "/" + matname, materialb.ToString()); StringBuilder meshb = new StringBuilder(); meshb.AppendLine("lodlevel"); meshb.AppendLine("start 0"); meshb.AppendLine("end 99999"); meshb.AppendLine(string.Format("info3d {0}", rawfile)); meshb.AppendLine(string.Format("material {0}", matname)); meshb.AppendLine(); meshb.AppendLine("instance"); meshb.AppendLine(string.Format("translate {0} {1} {2}", ftos(inst.Transformation.Position.R.X), ftos(inst.Transformation.Position.R.Y), ftos(inst.Transformation.Position.R.Z))); meshb.AppendLine(string.Format("scale {0} {1} {2}", ftos(inst.Transformation.ScaleValue.R.X), ftos(inst.Transformation.ScaleValue.R.Y), ftos(inst.Transformation.ScaleValue.R.Z))); meshb.AppendLine(string.Format("rotate {0} {1} {2} {3}", ftos(inst.Transformation.Orientation.R.X), ftos(inst.Transformation.Orientation.R.Y), ftos(inst.Transformation.Orientation.R.Z), ftos(inst.Transformation.Orientation.R.W))); File.WriteAllText(outfile + "/" + meshname, meshb.ToString()); }
private void LoadFromString(string[] lines) { Materials = new List <GenericMaterial>(); Meshes = new List <Mesh3d>(); Lights = new List <Light>(); Cameras = new List <Camera>(); var regx = new Regex("(.+?)[ ]+(.+)"); var currentMaterial = new GenericMaterial(Vector3.One); Light tempLight = null; GenericMaterial tempMaterial = null; Mesh3d tempMesh = null; Camera tempCamera = null; Action flush = () => { if (tempLight != null) { Lights.Add(tempLight); if (OnObjectFinish != null) { OnObjectFinish.Invoke(this, tempLight); } } if (tempMaterial != null) { Materials.Add(tempMaterial); if (OnObjectFinish != null) { OnObjectFinish.Invoke(this, tempMaterial); } } if (tempMesh != null) { Meshes.Add(tempMesh); if (OnObjectFinish != null) { OnObjectFinish.Invoke(this, tempMesh); } } if (tempCamera != null) { Cameras.Add(tempCamera); if (OnObjectFinish != null) { OnObjectFinish.Invoke(this, tempCamera); } } tempLight = null; tempMaterial = null; tempMesh = null; tempCamera = null; }; string vertexbuffer = ""; PhysicalBody physob = null; foreach (var l in lines) { if (l.StartsWith("//") || l.Trim().Length == 0) { continue; } var regout = regx.Match(l); if (!regout.Success) { throw new ArgumentException("Invalid line in scene string: " + l); } string command = regout.Groups[1].Value.Trim(); string data = regout.Groups[2].Value.Trim(); if (command.Length == 0 || data.Length == 0) { throw new ArgumentException("Invalid line in scene string: " + l); } switch (command) { // Mesh3d start case "mesh": { flush(); tempMesh = Mesh3d.Empty; tempMesh.AddInstance(new Mesh3dInstance(new TransformationManager(Vector3.Zero), data)); //tempMesh.Name = data; break; } case "usematerial": { tempMesh.AddLodLevel(null, Materials.First((a) => a.Name == data), 0, 999999); break; } case "scaleuv": { string[] literals = data.Split(' '); float x, y; if (!float.TryParse(literals[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out x)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out y)) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMesh.GetLodLevel(0).Info3d.Manager.ScaleUV(x, y); var obj = tempMesh.GetLodLevel(0).Info3d.Manager; tempMesh.GetLodLevel(0).SetInfo3d(new Object3dInfo(tempMesh.GetLodLevel(0).Info3d.Manager.Vertices)); tempMesh.GetLodLevel(0).Info3d.Manager = obj; break; } case "vbo": { vertexbuffer = data; ApplyVboIbo(tempMesh, vertexbuffer); vertexbuffer = ""; break; } case "physics": { var datas = data.Split(' '); if (datas[0] == "convexhull") { if (tempMesh == null) { throw new ArgumentException("Invalid line in scene string: " + l); } var shape = tempMesh.GetLodLevel(0).Info3d.Manager.GetConvexHull(); float mass; if (!float.TryParse(datas[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out mass)) { throw new ArgumentException("Invalid line in scene string: " + l); } physob = Game.World.Physics.CreateBody(mass, tempMesh.GetInstance(0), shape); } if (datas[0] == "boundingbox") { if (tempMesh == null) { throw new ArgumentException("Invalid line in scene string: " + l); } var shape = Physics.CreateBoundingBoxShape(tempMesh.GetLodLevel(0).Info3d.Manager); float mass; if (!float.TryParse(datas[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out mass)) { throw new ArgumentException("Invalid line in scene string: " + l); } physob = Game.World.Physics.CreateBody(mass, tempMesh.GetInstance(0), shape); } if (datas[0] == "accurate") { if (tempMesh == null) { throw new ArgumentException("Invalid line in scene string: " + l); } var shape = tempMesh.GetLodLevel(0).Info3d.Manager.GetAccurateCollisionShape(); float mass; if (!float.TryParse(datas[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out mass)) { throw new ArgumentException("Invalid line in scene string: " + l); } physob = Game.World.Physics.CreateBody(mass, tempMesh.GetInstance(0), shape); } if (datas[0] == "enable") { if (physob == null) { throw new ArgumentException("Invalid line in scene string: " + l); } physob.Enable(); } break; } case "translate": { string[] literals = data.Split(' '); if (literals.Length != 3) { throw new ArgumentException("Invalid line in scene string: " + l); } float x, y, z; if (!float.TryParse(literals[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out x)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out y)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out z)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (tempMesh != null) { tempMesh.GetInstance(0).Transformation.Translate(x, y, z); } if (tempCamera != null) { tempCamera.Transformation.Translate(x, y, z); } if (tempLight != null) { tempLight.Transformation.Translate(x, y, z); } break; } case "scale": { if (tempMesh == null) { throw new ArgumentException("Invalid line in scene string: " + l); } string[] literals = data.Split(' '); if (literals.Length != 3) { throw new ArgumentException("Invalid line in scene string: " + l); } float x, y, z; if (!float.TryParse(literals[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out x)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out y)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out z)) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMesh.GetInstance(0).Transformation.Scale(x, y, z); break; } case "rotate": { string[] literals = data.Split(' '); if (literals.Length < 3 || literals.Length > 4) { throw new ArgumentException("Invalid line in scene string: " + l); } float x, y, z; if (!float.TryParse(literals[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out x)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out y)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out z)) { throw new ArgumentException("Invalid line in scene string: " + l); } Quaternion rot = Quaternion.Identity; if (literals.Length == 3) { var rotx = Matrix3.CreateRotationX(MathHelper.DegreesToRadians(x)); var roty = Matrix3.CreateRotationY(MathHelper.DegreesToRadians(y)); var rotz = Matrix3.CreateRotationZ(MathHelper.DegreesToRadians(z)); rot = Quaternion.FromMatrix(rotx * roty * rotz); } if (literals.Length == 4) { float w; if (!float.TryParse(literals[3], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out w)) { throw new ArgumentException("Invalid line in scene string: " + l); } rot = new Quaternion(x, y, z, w); } if (tempMesh != null) { tempMesh.GetInstance(0).Transformation.Rotate(rot); } if (tempCamera != null) { tempCamera.Transformation.Rotate(rot); } if (tempLight != null) { tempLight.Transformation.Rotate(rot); } break; } // Mesh3d end Material start case "material": { flush(); tempMaterial = new GenericMaterial(Vector3.One); tempMaterial.Name = data; break; } case "type": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.Type = (GenericMaterial.MaterialType)Enum.Parse(typeof(GenericMaterial.MaterialType), data, true); break; } case "invertnormalmap": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } // tempMaterial.InvertNormalMap = data == "true" ? true : false; break; } case "transparency": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } //tempMaterial.SupportTransparency = data == "true" ? true : false; break; } case "normalmap": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.NormalsTexture = new Texture(Media.Get(data)); break; } case "bumpmap": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.BumpTexture = new Texture(Media.Get(data)); break; } case "roughnessmap": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.RoughnessTexture = new Texture(Media.Get(data)); break; } case "metalnessmap": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } // tempMaterial.MetalnessMap = new Texture(Media.Get(data)); break; } case "roughness": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } float f; if (!float.TryParse(data, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out f)) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.Roughness = f; break; } case "metalness": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } float f; if (!float.TryParse(data, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out f)) { throw new ArgumentException("Invalid line in scene string: " + l); } //tempMaterial.Metalness = f; break; } case "color": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } string[] literals = data.Split(' '); if (literals.Length != 3) { throw new ArgumentException("Invalid line in scene string: " + l); } float x, y, z; if (!float.TryParse(literals[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out x)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out y)) { throw new ArgumentException("Invalid line in scene string: " + l); } if (!float.TryParse(literals[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out z)) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.DiffuseColor = new Vector3(x, y, z); break; } case "texture": { if (tempMaterial == null) { throw new ArgumentException("Invalid line in scene string: " + l); } tempMaterial.DiffuseTexture = new Texture(Media.Get(data)); tempMaterial.SpecularTexture = tempMaterial.DiffuseTexture; //tempMaterial.Mode = GenericMaterial.DrawMode.TextureMultipleColor; break; } // Material end default: throw new ArgumentException("Invalid line in scene string: " + l); } } flush(); }