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; }
/// <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 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); }
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(); } }
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); }