Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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;
        }