public ModelLoader(Device device, TextureLoadHandler textureLoadHandler) { _device = device; _textureLoadHandler = textureLoadHandler; _importer = new AssimpImporter(); _importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); }
public static AssetMesh[] LoadAsset(string path, string assetRoot) { var importer = new AssimpImporter(); var scene = importer.ImportFile(path, PostProcessSteps.PreTransformVertices | PostProcessSteps.Triangulate | PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.FlipUVs); var textures = scene.Meshes.Select(mesh => scene.Materials[mesh.MaterialIndex].GetTexture(TextureType.Diffuse, 0)); var vertices = scene.Meshes.Select(mesh => mesh.Vertices .Zip(mesh.Normals.Zip(mesh.GetTextureCoords(0), (normal, uv) => new { normal, uv }), (pos, normalUv) => new VertexPositionNormalTexture(VectorUtils.Convert(pos), VectorUtils.Convert(normalUv.normal), VectorUtils.ToVec2(VectorUtils.Convert(normalUv.uv))))); var indices = scene.Meshes.Select(mesh => mesh.GetIndices()); //Debug.Assert(vertices.All(x => x.All(y => y.TextureCoordinate.X < 1 && y.TextureCoordinate.Y < 1))); return vertices.Zip(indices.Zip(textures, (i, t) => new {i, t}), (v, it) => new AssetMesh { Vertices = v.ToArray(), Indices = it.i.ToArray(), Texture = !string.IsNullOrWhiteSpace(it.t.FilePath) ? new AssetTexture { Path = it.t.FilePath } : Option<AssetTexture>.None }).ToArray(); }
public static MeshResource Load(string filePath) { AssimpImporter importer = new AssimpImporter(); importer.SetConfig(new NormalizeVertexComponentsConfig(true)); importer.SetConfig(new MultithreadingConfig(-1)); LogStream logStream = new LogStream(delegate(String msg, String userdata) { Log.Message(msg); Log.Message(userdata); }); importer.AttachLogStream(logStream); Assimp.Scene model = importer.ImportFile(filePath, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.FlipUVs); MeshResource meshResource = new MeshResource(); meshResource.Materials = model.Materials.Select(m => (BaseMaterial)new TexturedMaterial(m, Directory.GetParent(filePath).FullName)).ToList(); foreach (var modelMesh in model.Meshes) { EntityBuffer buffer = new EntityBuffer(); List<ushort> indices = new List<ushort>(); List<Vertex> vertices = new List<Vertex>(); Vector3D[] texCoords = modelMesh.HasTextureCoords(0) ? modelMesh.GetTextureCoords(0) : null; foreach (var face in modelMesh.Faces) { for (int i = 0; i < face.IndexCount; i++) { indices.Add((ushort)face.Indices[i]); } } var material = model.Materials[modelMesh.MaterialIndex]; TexturedMaterial texMat = new TexturedMaterial(material, Directory.GetParent(filePath).FullName); for (int i = 0; i < modelMesh.VertexCount; i++) { var vertex = modelMesh.Vertices[i]; var texCoord = texCoords[i]; var normal = modelMesh.Normals[i]; vertices.Add(new Vertex(new Position3(vertex.X, vertex.Y, vertex.Z), new Position2(texCoord.X, texCoord.Y), new Position3(normal.X, normal.Y, normal.Z))); } buffer.SetVertices(vertices, indices); Mesh mesh = new Mesh(buffer); meshResource.Meshes.Add(modelMesh.MaterialIndex, mesh); } importer.Dispose(); return meshResource; }
public static Mesh LoadModel(string filename) { Mesh mesh = new Mesh(); AssimpImporter importer = new AssimpImporter(); if(!importer.IsImportFormatSupported(Path.GetExtension(filename))) { throw new ArgumentException("Model format " + Path.GetExtension(filename) + " is not supported! Cannot load {1}", "filename"); } var min = new Vector3(float.MaxValue); var max = new Vector3(float.MinValue); Scene model = importer.ImportFile(filename, PostProcessPreset.TargetRealTimeFast); for(int j = 0; j < model.MeshCount; j++) { Assimp.Mesh m = model.Meshes[j]; Vector3[] positions = new Vector3[m.VertexCount]; Vector2[] textureCoords = new Vector2[m.VertexCount]; Vector3[] normals = new Vector3[m.VertexCount]; Vector3[] tangents = new Vector3[m.VertexCount]; for(var i = 0; i < m.VertexCount; i++) { Vector3 pos = m.HasVertices ? Util.ToVector3(m.Vertices[i]) : new Vector3(); Vector3 t = m.HasTextureCoords(0) ? Util.ToVector3(m.GetTextureCoords(0)[i]) : new Vector3(); Vector3 normal = m.HasNormals ? Util.ToVector3(m.Normals[i]) : new Vector3(); Vector3 tangent = m.HasTangentBasis ? Util.ToVector3(m.Tangents[i]) : new Vector3(); min = Vector3.Min(min, pos); max = Vector3.Max(max, pos); positions[i] = pos; textureCoords[i] = new Vector2(t.X, -t.Y); normals[i] = normal; tangents[i] = tangent; } int[] indices = m.GetIntIndices(); mesh.AddVertices(positions, textureCoords, normals, indices); } mesh.Complete(); return mesh; }
static List<Model> ConvertBIN(string filenameIN, string filenameOUT) { AssimpImporter importer = new AssimpImporter (); //Initialize Assimp.NET List<Model> models = SceneToCustom (importer.ImportFile (filenameIN)); //Import file and set it up for a serializeable struct BinaryFormatter serializer = new BinaryFormatter (); //Initialize the serializer int index = 0; foreach (Model model in models) { Stream outwrite = File.OpenWrite (Path.Combine (Path.GetDirectoryName (filenameOUT), index.ToString () + Path.GetFileName (filenameOUT))); //Create output file serializer.Serialize (outwrite, model); //Do the magic, data serialized to xml file outwrite.Close (); //Close and dispose stream outwrite.Dispose (); index++; } return models; }
/// <summary> /// Ucitavanje podataka o sceni iz odgovarajuceg fajla. /// </summary> private void LoadScene() { // Instanciranje klase za ucitavanje podataka o sceni. AssimpImporter importer = new AssimpImporter(); // Definisanje callback delegata za belezenje poruka u toku ucitavanja podataka o sceni. LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); importer.AttachLogStream(logstream); // Ucitavanje podataka o sceni iz odgovarajuceg fajla. m_scene = importer.ImportFile(Path.Combine(m_scenePath, m_sceneFileName), PostProcessPreset.TargetRealTimeMaximumQuality); // Oslobadjanje resursa koriscenih za ucitavanje podataka o sceni. importer.Dispose(); }
public override VSceneNode LoadNode(string path) { VSceneEntity root = new VSceneEntity(); string file = path; var e = new Assimp.AssimpImporter(); var c1 = new Assimp.Configs.NormalSmoothingAngleConfig(45); e.SetConfig(c1); var s = e.ImportFile(file, PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.Triangulate | PostProcessSteps.GenerateNormals); Dictionary <string, VMesh> ml = new Dictionary <string, VMesh>(); List <VMesh> ml2 = new List <VMesh>(); foreach (var m in s.Meshes) { var vm = new Material.VMaterial(); var m2 = new VMesh(m.VertexCount, m.GetIntIndices().Length); ml2.Add(m2); // ml.Add(m.Name, m2); m2.Mat = vm; // root.AddMesh(m2); m2.Name = m.Name; var mat = s.Materials[m.MaterialIndex]; TextureSlot t1; if (mat.GetTextureCount(TextureType.Diffuse) > 0) { t1 = mat.GetTextures(TextureType.Diffuse)[0]; if (t1.FilePath != null) { vm.TCol = new Texture.VTex2D(IPath + t1.FilePath, Texture.LoadMethod.Single); Console.WriteLine("TexLoaded"); } if (true) { if (new FileInfo(t1.FilePath).Exists == true) { // var tex = App.AppSal.CreateTex2D(); // tex.Path = t1.FilePath; // tex.Load(); //m2.DiffuseMap = tex; } } } for (int i = 0; i < m2.NumVertices; i++) { var v = m.Vertices[i]; var n = m.Normals[i]; var t = m.GetTextureCoords(0); Vector3D tan, bi; if (m.Tangents != null) { tan = m.Tangents[i]; bi = m.BiTangents[i]; } else { tan = new Vector3D(0, 0, 0); bi = new Vector3D(0, 0, 0); } if (t != null) { m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(t[i])); } else { m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(new Vector3D(0, 0, 0))); } } int[] id = m.GetIntIndices(); int fi = 0; uint[] nd = new uint[id.Length]; for (int i = 0; i < id.Length; i++) { nd[i] = (uint)id[i]; } m2.Indices = nd; m2.Final(); } ProcessNode(root, s.RootNode, ml2); return(root as VSceneNode); }
private ContentCompilerResult CompileFromFileInternal(string fileName, ModelCompilerOptions compilerOptions) { logger = new Logger(); var result = new ContentCompilerResult() { Logger = logger }; modelFilePath = fileName; modelDirectory = Path.GetDirectoryName(modelFilePath); // Preload AssimpLibrary if not already loaded if (!AssimpLibrary.Instance.LibraryLoaded) { var rootPath = Path.GetDirectoryName(typeof(AssimpLibrary).Assembly.Location); AssimpLibrary.Instance.LoadLibrary(Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath32Bit), Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath64Bit)); } var importer = new AssimpImporter(); //importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); // Steps for Direct3D, should we make this configurable? var steps = PostProcessSteps.FlipUVs | PostProcessSteps.FlipWindingOrder | PostProcessSteps.MakeLeftHanded; // Setup quality switch (compilerOptions.Quality) { case ModelRealTimeQuality.Low: steps |= PostProcessPreset.TargetRealTimeFast; break; case ModelRealTimeQuality.Maximum: steps |= PostProcessPreset.TargetRealTimeMaximumQuality; break; default: steps |= PostProcessPreset.TargetRealTimeQuality; break; } scene = importer.ImportFile(fileName, steps); model = new ModelData(); ProcessScene(); result.IsContentGenerated = true; result.ModelData = model; return result; }
public SkinnedModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipTexY = false) { // initialize collections _subsets = new List<MeshGeometry.Subset>(); _vertices = new List<PosNormalTexTanSkinned>(); _indices = new List<short>(); DiffuseMapSRV = new List<ShaderResourceView>(); NormalMapSRV = new List<ShaderResourceView>(); Materials = new List<Material>(); var importer = new AssimpImporter(); #if DEBUG importer.AttachLogStream(new ConsoleLogStream()); importer.VerboseLoggingEnabled = true; #endif var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace ); // Load animation data Animator = new SceneAnimator(); Animator.Init(model); // create our vertex-to-boneweights lookup var vertToBoneWeight = new Dictionary<uint, List<VertexWeight>>(); // create bounding box extents _min = new Vector3(float.MaxValue); _max = new Vector3(float.MinValue); foreach (var mesh in model.Meshes) { ExtractBoneWeightsFromMesh(mesh, vertToBoneWeight); var subset = new MeshGeometry.Subset { VertexCount = mesh.VertexCount, VertexStart = _vertices.Count, FaceStart = _indices.Count / 3, FaceCount = mesh.FaceCount }; _subsets.Add(subset); var verts = ExtractVertices(mesh, vertToBoneWeight, flipTexY); _vertices.AddRange(verts); // extract indices and shift them to the proper offset into the combined vertex buffer var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList(); _indices.AddRange(indices); // extract materials var mat = model.Materials[mesh.MaterialIndex]; var material = mat.ToMaterial(); Materials.Add(material); // extract material textures var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath; if (!string.IsNullOrEmpty(diffusePath)) { DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath))); } var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath; if (!string.IsNullOrEmpty(normalPath)) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } else { // for models created without a normal map baked, we'll check for a texture with the same // filename as the diffure texture, and _nmap suffixed // this lets us add our own normal maps easily var normalExt = Path.GetExtension(diffusePath); normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt; if (File.Exists(Path.Combine(texturePath, normalPath))) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } } } BoundingBox = new BoundingBox(_min, _max); _modelMesh = new MeshGeometry(); _modelMesh.SetSubsetTable(_subsets); _modelMesh.SetVertices(device, _vertices); _modelMesh.SetIndices(device, _indices); }
/// <summary> Формат dae. (collada) </summary> public void ExportCollada() { if (!MakePayment("8", "Payment for PrintAhead collada print")) { MessageBox.Show("Payment was failed!"); return; } var fiName = string.Empty; var daeName = string.Empty; string newDirectory = string.Empty; using (var ofd = new FolderDialogEx()) { if (ofd.ShowDialog(Handle) != DialogResult.OK) return; if (ofd.SelectedFolder[0] == ProgramCore.Project.ProjectPath) { MessageBox.Show("Can't export file to project directory.", "Warning"); return; } newDirectory = Path.Combine(ofd.SelectedFolder[0], "SmoothedModelTextures"); FolderEx.CreateDirectory(newDirectory); daeName = Path.Combine(newDirectory, ProgramCore.Project.ProjectName + ".dae"); fiName = Path.Combine(newDirectory, ProgramCore.Project.ProjectName + ".obj"); } //var tempScale = 5f; var realScale = ctrlRenderControl.headMeshesController.RenderMesh.RealScale; if (ProgramCore.PluginMode) { var scale = 1f; switch (ProgramCore.Project.ManType) { case ManType.Male: scale = ctrlRenderControl.headMeshesController.SetSize(29.9421043f); // подгонка размера break; case ManType.Female: scale = ctrlRenderControl.headMeshesController.SetSize(29.3064537f); // подгонка размера break; case ManType.Child: scale = ctrlRenderControl.headMeshesController.SetSize(25.6209984f); // подгонка размера break; } //tempScale = ProgramCore.MainForm.ctrlRenderControl.headMeshesController.RenderMesh.MorphScale; //ProgramCore.MainForm.ctrlRenderControl.headMeshesController.RenderMesh.MorphScale /= scale; realScale /= scale; } if (ProgramCore.Project != null) { ctrlRenderControl.pickingController.SelectedMeshes.Clear(); ProgramCore.Project.ToStream(); } var morphK = float.IsNaN(ProgramCore.Project.MorphingScale) ? 0.9f : ProgramCore.Project.MorphingScale; ProgramCore.MainForm.ctrlRenderControl.DoMorth(morphK); // чтобы не потерять Smoothing Process.Start("http://www.shapeways.com/"); var meshInfos = new List<MeshInfo>(); foreach (var part in ctrlRenderControl.headMeshesController.RenderMesh.Parts) meshInfos.Add(new MeshInfo(part)); MeshInfo.FindCenter(meshInfos, "Меши бошки до экспорта frmMain::ExportCollada()"); ProgramCore.EchoToLog(String.Format("realScale frmMain::ExportCollada(): {0}", realScale), EchoMessageType.Information); ObjSaver.ExportMergedModel(fiName, ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes, ProgramCore.MainForm.ctrlRenderControl.pickingController.AccesoryMeshes, meshInfos, realScale, true, true); var importer = new AssimpImporter(); importer.ConvertFromFileToFile(fiName, daeName, "collada"); if (ProgramCore.Project.FrontImage != null) ProgramCore.Project.FrontImage.Save(Path.Combine(newDirectory, "tempHaarImage.jpg")); if (ProgramCore.Project.ProfileImage != null) ProgramCore.Project.ProfileImage.Save(Path.Combine(newDirectory, "ProfileImage.jpg")); File.Delete(fiName); var mtlName = Path.Combine(newDirectory, ProgramCore.Project.ProjectName + ".mtl"); if (File.Exists(mtlName)) File.Delete(mtlName); using (var zip = new ZipFile()) { zip.AddFiles(Directory.GetFiles(newDirectory), false, ""); foreach (var dir in Directory.GetDirectories(newDirectory)) { var files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories); foreach (var file in files) { if (!zip.ContainsEntry((new FileInfo(file)).Name)) zip.AddFile(file, ""); } } zip.Save(Path.Combine(newDirectory, ProgramCore.Project.ProjectName + ".zip")); } //if (ProgramCore.PluginMode) // ProgramCore.MainForm.ctrlRenderControl.headMeshesController.RenderMesh.MorphScale = tempScale; MessageBox.Show("Color 3D export finished!", "Done"); }
/// <summary> Формат stl 5$</summary> public void Export3DPrint() { if (!MakePayment("5", "Payment for PrintAhead stl print")) { MessageBox.Show("Payment was failed!"); return; } var fiName = string.Empty; var stlName = string.Empty; using (var ofd = new FolderDialogEx()) { if (ofd.ShowDialog(Handle) != DialogResult.OK) return; stlName = Path.Combine(ofd.SelectedFolder[0], ProgramCore.Project.ProjectName + ".stl"); fiName = Path.Combine(ofd.SelectedFolder[0], ProgramCore.Project.ProjectName + ".obj"); } if (ProgramCore.Project != null) { ctrlRenderControl.pickingController.SelectedMeshes.Clear(); ProgramCore.Project.ToStream(); } var meshInfos = new List<MeshInfo>(); foreach (var part in ctrlRenderControl.headMeshesController.RenderMesh.Parts) meshInfos.Add(new MeshInfo(part)); ObjSaver.ExportMergedModel(fiName, ProgramCore.MainForm.ctrlRenderControl.pickingController.HairMeshes, ProgramCore.MainForm.ctrlRenderControl.pickingController.AccesoryMeshes, meshInfos, ctrlRenderControl.headMeshesController.RenderMesh.RealScale); var importer = new AssimpImporter(); importer.ConvertFromFileToFile(fiName, stlName, "stl"); }
private Scene LoadDaeScene(String path) { Scene scene; using (var importer = new AssimpImporter()) { importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality); } return scene; }
static List<Model> ConvertProtoBUF(string filenameIN, string filenameOUT) { AssimpImporter importer = new AssimpImporter (); //Initialize Assimp.NET List<Model> models = SceneToCustom (importer.ImportFile (filenameIN)); //Import file and set it up for a serializeable struct int index = 0; foreach (Model model in models) { using (Stream outwrite = File.Create(Path.Combine (Path.GetDirectoryName (filenameOUT), index.ToString () + Path.GetFileName (filenameOUT)))) { //Create output file Serializer.Serialize (outwrite, model); //Do the magic, data serialized to xml file } index++; } return models; }
public static Mesh CreateFromFile(string filePath, bool rotateYZ = false, bool convertToLeftHanded = false, float scale = 1) { Func<Assimp.Vector3D, Vector3> _MakeVector3 = v => new Vector3(v.X, v.Y, v.Z); Func<Assimp.Vector3D, Vector2> _MakeTexCoord = v => { var x = v.X; while (x > 1) x -= 1; while (x < 0) x += 1; var y = v.Y; while (y > 1) y -= 1; while (y < 0) y += 1; return new Vector2(x, y); }; using (var importer = new AssimpImporter()) { if (Config.LoadMeshPrintLog) { LogStream logStream = new LogStream((msg, data) => { Console.WriteLine(string.Format("Assimp: {0}", msg)); }); importer.AttachLogStream(logStream); } PostProcessSteps options = PostProcessSteps.None; if(Config.LoadMeshComputeTangent) options |= PostProcessSteps.CalculateTangentSpace; if(convertToLeftHanded) options |= PostProcessSteps.MakeLeftHanded; var scene = importer.ImportFile(filePath, options); if (!scene.HasMeshes) return null; var builder = new MeshBuilder(); Matrix mat = Matrix.Identity; if(rotateYZ) mat = Matrix.RotationX(-MathUtil.PiOverTwo); foreach (var aiMesh in scene.Meshes) { builder.BeginSubmesh(); for (int i = 0; i < aiMesh.VertexCount; ++i) { var v = new MeshVertex(); v.Position = _MakeVector3(aiMesh.Vertices[i]) * scale; v.Position = Vector3.TransformCoordinate(v.Position, mat); if (aiMesh.HasNormals) { v.Normal = _MakeVector3(aiMesh.Normals[i]); v.Normal = Vector3.TransformNormal(v.Normal, mat); } if (aiMesh.HasTangentBasis) { v.Tangent = _MakeVector3(aiMesh.Tangents[i]); v.Tangent = Vector3.TransformNormal(v.Tangent, mat); } if (aiMesh.HasTextureCoords(0)) { var texCoords = aiMesh.GetTextureCoords(0); v.TexCoord = _MakeTexCoord(texCoords[i]); } builder.Vertex(v); } //aiMesh.GetIntIndices().ToList().ForEach(builder.Index); for (int i = 0; i < aiMesh.FaceCount; ++i) { var face = aiMesh.Faces[i]; for (int j = 1; j < face.IndexCount - 1;++j ) { builder.Index((uint) face.Indices[0]); builder.Index((uint) face.Indices[j]); builder.Index((uint) face.Indices[j+1]); } } //if (scene.HasMaterials) //{ // var folder = System.IO.Path.GetDirectoryName(filePath); // var materialIndex = aiMesh.MaterialIndex; // if (materialIndex >= 0 && materialIndex < scene.Materials.Length) // { // var material = scene.Materials[materialIndex]; // var textures = material.GetTextures(TextureType.Diffuse); // if (textures != null) // { // builder.Texture(0, System.IO.Path.Combine(folder, textures[0].FilePath)); // } // textures = material.GetTextures(TextureType.Ambient); // if (textures != null) // builder.Texture(1, System.IO.Path.Combine(folder, textures[0].FilePath)); // textures = material.GetTextures(TextureType.Specular); // if (textures != null) // builder.Texture(2, System.IO.Path.Combine(folder, textures[0].FilePath)); // } //} builder.EndSubmesh(); } return builder.Complete(); } }
private void LoadModel(Device device, String fileName) { PostProcessSteps flags = PostProcessSteps.Triangulate | PostProcessSteps.OptimizeMeshes | PostProcessSteps.GenerateUVCoords | PostProcessSteps.FixInFacingNormals | PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateSmoothNormals; using (AssimpImporter importer = new AssimpImporter()) { Console.WriteLine("Loading model " + fileName); var data = importer.ImportFile(fileName, flags); foreach (var mesh in data.Meshes) { List<Vertex> geometry = new List<Vertex>(mesh.FaceCount * 3); String meshName = data.Materials[mesh.MaterialIndex].Name; //Console.WriteLine("Loading mesh " + meshName); if (!mesh.HasTextureCoords(0)) { Console.WriteLine("INFO: Mesh has no UV's. This is perfectly fine if the material does not use textures."); } foreach (var face in mesh.Faces) { for (int t = 0; t < face.IndexCount; ++t) { if (!mesh.HasTextureCoords(0)) { geometry.Add(new Vertex(mesh.Vertices[face.Indices[t]], mesh.Normals[face.Indices[t]], new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), new Vector3D(0, 0, 0))); } else { geometry.Add(new Vertex(mesh.Vertices[face.Indices[t]], mesh.Normals[face.Indices[t]], mesh.Tangents[face.Indices[t]], mesh.BiTangents[face.Indices[t]], mesh.GetTextureCoords(0)[face.Indices[t]])); } } } meshes.Add(new Mesh(device, meshName, geometry)); } } }
public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath) { _subsets = new List<MeshGeometry.Subset>(); _vertices = new List<PosNormalTexTan>(); _indices = new List<short>(); DiffuseMapSRV = new List<ShaderResourceView>(); NormalMapSRV = new List<ShaderResourceView>(); Materials = new List<Material>(); _modelMesh = new MeshGeometry(); var importer = new AssimpImporter(); if (!importer.IsImportFormatSupported(Path.GetExtension(filename))) { throw new ArgumentException("Model format " + Path.GetExtension(filename) + " is not supported! Cannot load {1}", "filename"); } #if DEBUG importer.AttachLogStream(new ConsoleLogStream()); importer.VerboseLoggingEnabled = true; #endif var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace); var min = new Vector3(float.MaxValue); var max = new Vector3(float.MinValue); var verts = new List<PosNormalTexTan>(); foreach (var mesh in model.Meshes) { var subset = new MeshGeometry.Subset { VertexCount = mesh.VertexCount, VertexStart = _vertices.Count, FaceStart = _indices.Count / 3, FaceCount = mesh.FaceCount }; _subsets.Add(subset); // bounding box corners for (var i = 0; i < mesh.VertexCount; i++) { var pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3(); min = Vector3.Minimize(min, pos); max = Vector3.Maximize(max, pos); var norm = mesh.HasNormals ? mesh.Normals[i] : new Vector3D(); var texC = mesh.HasTextureCoords(0) ? mesh.GetTextureCoords(0)[i] : new Vector3D(); var tan = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D(); var v = new PosNormalTexTan(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3()); verts.Add(v); } _vertices.AddRange(verts); var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList(); _indices.AddRange(indices); var mat = model.Materials[mesh.MaterialIndex]; var material = mat.ToMaterial(); Materials.Add(material); var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath; if (Path.GetExtension(diffusePath) == ".tga") { // DirectX doesn't like to load tgas, so you will need to convert them to pngs yourself with an image editor diffusePath = diffusePath.Replace(".tga", ".png"); } if (!string.IsNullOrEmpty(diffusePath)) { DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath))); } var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath; if (!string.IsNullOrEmpty(normalPath)) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } else { var normalExt = Path.GetExtension(diffusePath); normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt; NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } } BoundingBox = new BoundingBox(min, max); _modelMesh.SetSubsetTable(_subsets); _modelMesh.SetVertices(device, _vertices); _modelMesh.SetIndices(device, _indices); }