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> /// Initialize our basic model /// </summary> /// <param name="device">Direct3D device for use</param> /// <param name="texMgr">Texture manager from which to load texture data</param> /// <param name="filename">Filename of the ASSIMP resource we would like to load (see ASSIMP documentation for supported formats)</param> /// <param name="texturePath">Texture path - base path for textures used by the ASSIMP model</param> public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath) { _subsets = new List<MeshGeometry.Subset>(); _vertices = new List<BasicEffectVertex>(); _indices = new List<ushort>(); DiffuseMapSRV = new List<ShaderResourceView>(); NormalMapSRV = new List<ShaderResourceView>(); Materials = new List<Lighting.Material>(); _modelMesh = new MeshGeometry(); var importer = new AssimpContext(); if (!importer.IsImportFormatSupported(Path.GetExtension(filename))) { throw new ArgumentException($"Model format {Path.GetExtension(filename)} is not supported! Cannot load {filename}", "Outside Engine"); } var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace); #if DEBUG var logStream = new ConsoleLogStream(); logStream.Attach(); #endif foreach (var mesh in model.Meshes) { // // Vertex processing // var verts = new List<BasicEffectVertex>(); var subset = new MeshGeometry.Subset { VertexCount = mesh.VertexCount, VertexStart = _vertices.Count, FaceStart = _indices.Count / 3, FaceCount = mesh.FaceCount }; _subsets.Add(subset); // TODO KAM: Process bounding box corners for (var i = 0; i < mesh.VertexCount; ++i) { Vector3 pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3(); var norml = mesh.HasNormals ? mesh.Normals[i].ToVector3() : new Vector3(); var texC = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i].ToVector3() : new Vector3(); var tan = mesh.HasTangentBasis ? mesh.Tangents[i].ToVector3() : new Vector3(); var v = new BasicEffectVertex(pos, norml, new Vector2(texC.X, texC.Y)); verts.Add(v); } _vertices.AddRange(verts); var indices = mesh.GetIndices().Select(i => (ushort)(i + (uint)subset.VertexStart)).ToList(); _indices.AddRange(indices); // // Material processing // var mat = model.Materials[mesh.MaterialIndex]; var material = mat.ToMaterial(); Materials.Add(material); TextureSlot diffuseSlot; mat.GetMaterialTexture(TextureType.Diffuse, 0, out diffuseSlot); var diffusePath = diffuseSlot.FilePath; if (Path.GetExtension(diffusePath) == ".tga") { throw new InvalidDataException("Cannot use TGA files for textures with DirectX. Sorry about that."); } if (!string.IsNullOrEmpty(diffusePath)) { DiffuseMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, diffusePath))); } TextureSlot normalSlot; mat.GetMaterialTexture(TextureType.Normals, 0, out normalSlot); var normalPath = normalSlot.FilePath; if (!string.IsNullOrEmpty(normalPath)) { NormalMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, normalPath))); } else { var normalExt = Path.GetExtension(diffusePath); normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt; NormalMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, normalPath))); } } _modelMesh.SetSubsetTable(_subsets); _modelMesh.SetVertices(device, _vertices); _modelMesh.SetIndices(device, _indices); }
private static BasicModel BuildFromMeshData(Device device, GeometryGenerator.MeshData mesh) { var ret = new BasicModel(); var subset = new MeshGeometry.Subset { FaceCount = mesh.Indices.Count / 3, FaceStart = 0, VertexCount = mesh.Vertices.Count, VertexStart = 0 }; ret._subsets.Add(subset); var max = new Vector3(float.MinValue); var min = new Vector3(float.MaxValue); foreach (var vertex in mesh.Vertices) { max = Vector3.Maximize(max, vertex.Position); min = Vector3.Minimize(min, vertex.Position); } ret.BoundingBox = new BoundingBox(min, max); ret._vertices.AddRange(mesh.Vertices.Select(v => new PosNormalTexTan(v.Position, v.Normal, v.TexC, v.TangentU)).ToList()); ret._indices.AddRange(mesh.Indices.Select(i => (short)i)); ret.Materials.Add(new Material { Ambient = Color.Gray, Diffuse = Color.White, Specular = new Color4(16, 1, 1, 1) }); ret.DiffuseMapSRV.Add(null); ret.NormalMapSRV.Add(null); ret._modelMesh.SetSubsetTable(ret._subsets); ret._modelMesh.SetVertices(device, ret._vertices); ret._modelMesh.SetIndices(device, ret._indices); return ret; }
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); }
public static BasicModel LoadFromTxtFile(Device device, string filename) { var vertices = new List<Basic32>(); var indices = new List<int>(); var vcount = 0; var tcount = 0; using (var reader = new StreamReader(filename)) { var input = reader.ReadLine(); if (input != null) // VertexCount: X vcount = Convert.ToInt32(input.Split(new[] { ':' })[1].Trim()); input = reader.ReadLine(); if (input != null) //TriangleCount: X tcount = Convert.ToInt32(input.Split(new[] { ':' })[1].Trim()); // skip ahead to the vertex data do { input = reader.ReadLine(); } while (input != null && !input.StartsWith("{")); // Get the vertices for (int i = 0; i < vcount; i++) { input = reader.ReadLine(); if (input != null) { var vals = input.Split(new[] { ' ' }); vertices.Add( new Basic32( new Vector3( Convert.ToSingle(vals[0].Trim()), Convert.ToSingle(vals[1].Trim()), Convert.ToSingle(vals[2].Trim())), new Vector3( Convert.ToSingle(vals[3].Trim()), Convert.ToSingle(vals[4].Trim()), Convert.ToSingle(vals[5].Trim())), new Vector2() ) ); } } // skip ahead to the index data do { input = reader.ReadLine(); } while (input != null && !input.StartsWith("{")); // Get the indices for (var i = 0; i < tcount; i++) { input = reader.ReadLine(); if (input == null) { break; } var m = input.Trim().Split(new[] { ' ' }); indices.Add(Convert.ToInt32(m[0].Trim())); indices.Add(Convert.ToInt32(m[1].Trim())); indices.Add(Convert.ToInt32(m[2].Trim())); } } var ret = new BasicModel(); var subset = new MeshGeometry.Subset { FaceCount = indices.Count / 3, FaceStart = 0, VertexCount = vertices.Count, VertexStart = 0 }; ret._subsets.Add(subset); var max = new Vector3(float.MinValue); var min = new Vector3(float.MaxValue); foreach (var vertex in vertices) { max = Vector3.Maximize(max, vertex.Position); min = Vector3.Minimize(min, vertex.Position); } ret.BoundingBox = new BoundingBox(min, max); ret._vertices.AddRange(vertices.Select(v => new PosNormalTexTan(v.Position, v.Normal, v.Tex, new Vector3(1, 0, 0))).ToList()); ret._indices.AddRange(indices.Select(i => (short)i)); ret.Materials.Add(new Material { Ambient = Color.Gray, Diffuse = Color.White, Specular = new Color4(16, 1, 1, 1) }); ret.DiffuseMapSRV.Add(null); ret.NormalMapSRV.Add(null); ret._modelMesh.SetSubsetTable(ret._subsets); ret._modelMesh.SetVertices(device, ret._vertices); ret._modelMesh.SetIndices(device, ret._indices); return ret; }