private ImageTexture[] loadMaterialTextures(ai.Material material, ai.TextureType type, TextureType textureType) { ImageTexture[] textures = new ImageTexture[material.GetMaterialTextureCount(type)]; for (int i = 0; i < textures.Length; i++) { ai.TextureSlot slot; material.GetMaterialTexture(type, i, out slot); string path = directory + slot.FilePath; ImageTexture texture; ImageTexture loaded = loadedTextures.Find(x => x.path == path); if (loaded != null) { texture = loaded; } else { texture = new ImageTexture(gl, path, textureType); loadedTextures.Add(texture); Console.WriteLine($"Texture file path: {path}"); } textures[i] = texture; } return(textures); }
List <Texture> loadMaterialTextures(Assimp.Material mat, Assimp.TextureType type, string typeName) { List <Texture> textures = new List <Texture>(); for (int i = 0; i < mat.GetMaterialTextureCount(type); i++) { bool skip = false; TextureSlot textureSlot; mat.GetMaterialTexture(type, i, out textureSlot); for (int j = 0; j < texturesLoaded.Count; j++) { if (texturesLoaded[j].path.CompareTo(textureSlot.FilePath) == 0) { skip = true; textures.Add(texturesLoaded[j]); break; } } if (!skip) { Texture texture = new Texture(); texture.id = TextureFromFile(textureSlot.FilePath, directory); texture.type = typeName; texture.path = textureSlot.FilePath; textures.Add(texture); texturesLoaded.Add(texture); } } return(textures); }
/// <summary> /// Helper method, used to transfer information from Material to ClientMaterial /// </summary> /// <param name="mat"> the source Material </param> /// <param name="myMat"> the destination ClientMaterial </param> protected void ApplyMaterial(Material mat, ClientMaterial myMat) { if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; if (mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex)) { ShaderResourceView temp; myMat.setDiffuseTexture(temp = CreateTexture(Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileName(tex.FilePath)))); myMat.setTexCount(temp == null ? 0 : 1); } else { myMat.setDiffuseTexture(null); myMat.setTexCount(1); } } // copies over all the material properties to the struct // sets the diffuse color Color4 color = new Color4(.4f, .4f, .4f, 1.0f); // default is light grey if (mat.HasColorDiffuse) { myMat.setDiffuse(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setDiffuse(color.Red, color.Green, color.Blue, color.Alpha); } // sets the specular color color = new Color4(0.1f, 0.1f, 0.1f, 1.0f); // default is non-specular if (mat.HasColorSpecular) { myMat.setSpecular(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setSpecular(color.Red, color.Green, color.Blue, color.Alpha); } // sets the ambient color color = new Color4(.3f, .3f, .3f, 1.0f); // default is dark grey if (mat.HasColorAmbient) { myMat.setAmbient(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setAmbient(color.Red, color.Green, color.Blue, color.Alpha); } // sets the emissive color color = new Color4(0, 0, 0, 1.0f); // default is black if (mat.HasColorEmissive) { myMat.setEmissive(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A); } else { myMat.setEmissive(color.Red, color.Green, color.Blue, color.Alpha); } // sets the shininess float shininess = 1; // default is 1 if (mat.HasShininess) { myMat.setShininess(mat.Shininess); } else { myMat.setShininess(shininess); } // sets the opacity float opacity = 1; // default is 1 if (mat.HasOpacity) { myMat.setOpacity(mat.Opacity); } else { myMat.setOpacity(mat.Opacity); } }
public override Node3D LoadAnimNode(string path) { if (NormBlank == null) { NormBlank = new Texture.Texture2D("data/tex/normblank.png", Texture.LoadMethod.Single, false); DiffBlank = new Texture.Texture2D("data/tex/diffblank.png", Texture.LoadMethod.Single, false); SpecBlank = new Texture.Texture2D("data/tex/specblank.png", Texture.LoadMethod.Single, false); } AnimEntity3D root = new AnimEntity3D(); string file = path; AssimpContext e = new Assimp.AssimpContext(); Assimp.Configs.NormalSmoothingAngleConfig c1 = new Assimp.Configs.NormalSmoothingAngleConfig(75); e.SetConfig(c1); Console.WriteLine("Impporting:" + file); Assimp.Scene s = null; try { s = e.ImportFile(file, PostProcessSteps.OptimizeMeshes | PostProcessSteps.OptimizeGraph | PostProcessSteps.FindInvalidData | PostProcessSteps.FindDegenerates | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | PostProcessSteps.CalculateTangentSpace); } catch (AssimpException ae) { Console.WriteLine(ae); Console.WriteLine("Failed to import"); Environment.Exit(-1); } Console.WriteLine("Imported."); Dictionary <string, Mesh3D> ml = new Dictionary <string, Mesh3D>(); List <Mesh3D> ml2 = new List <Mesh3D>(); Console.WriteLine("animCount:" + s.AnimationCount); Matrix4x4 tf = s.RootNode.Transform; tf.Inverse(); root.GlobalInverse = ToTK(tf); Dictionary <uint, List <VertexWeight> > boneToWeight = new Dictionary <uint, List <VertexWeight> >(); root.Animator = new Animation.Animator(); if (s.AnimationCount > 0) { Console.WriteLine("Processing animations."); root.Animator.InitAssImp(s, root); Console.WriteLine("Processed."); _ta = root.Animator; } Dictionary <uint, List <VertexWeight> > vertToBoneWeight = new Dictionary <uint, List <VertexWeight> >(); //s.Animations[0].NodeAnimationChannels[0]. //s.Animations[0].anim // root.Animator.InitAssImp(model); List <Vivid.Data.Vertex> _vertices = new List <Vertex>(); List <Vivid.Data.Tri> _tris = new List <Tri>(); List <Vertex> ExtractVertices(Mesh m, Dictionary <uint, List <VertexWeight> > vtb) { List <Vertex> rl = new List <Vertex>(); for (int i = 0; i < m.VertexCount; i++) { Vector3D pos = m.HasVertices ? m.Vertices[i] : new Assimp.Vector3D(); Vector3D norm = m.HasNormals ? m.Normals[i] : new Assimp.Vector3D(); Vector3D tan = m.HasTangentBasis ? m.Tangents[i] : new Assimp.Vector3D(); Vector3D bi = m.HasTangentBasis ? m.BiTangents[i] : new Assimp.Vector3D(); Vertex nv = new Vertex { Pos = new OpenTK.Vector3(pos.X, pos.Y, pos.Z), Norm = new OpenTK.Vector3(norm.X, norm.Y, norm.Z), Tan = new OpenTK.Vector3(tan.X, tan.Y, tan.Z), BiNorm = new OpenTK.Vector3(bi.X, bi.Y, bi.Z) }; if (m.HasTextureCoords(0)) { Vector3D coord = m.TextureCoordinateChannels[0][i]; nv.UV = new OpenTK.Vector2(coord.X, 1 - coord.Y); } float[] weights = vtb[(uint)i].Select(w => w.Weight).ToArray(); byte[] boneIndices = vtb[(uint)i].Select(w => (byte)w.VertexID).ToArray(); nv.Weight = weights.First(); nv.BoneIndices = new int[4]; nv.BoneIndices[0] = boneIndices[0]; if (boneIndices.Length > 1) { nv.BoneIndices[1] = boneIndices[1]; } if (boneIndices.Length > 2) { nv.BoneIndices[2] = boneIndices[2]; } if (boneIndices.Length > 3) { nv.BoneIndices[3] = boneIndices[3]; } rl.Add(nv); } return(rl); } root.Mesh = new Mesh3D(); foreach (Mesh m in s.Meshes) { ExtractBoneWeightsFromMesh(m, vertToBoneWeight); Mesh3D.Subset sub = new Vivid.Data.Mesh3D.Subset { VertexCount = m.VertexCount, VertexStart = _vertices.Count, FaceStart = _tris.Count, FaceCount = m.FaceCount }; root.Mesh.Subs.Add(sub); List <Vertex> verts = ExtractVertices(m, vertToBoneWeight); _vertices.AddRange(verts); List <short> indices = m.GetIndices().Select(i => (short)(i + (uint)sub.VertexStart)).ToList(); for (int i = 0; i < indices.Count; i += 3) { Tri t = new Tri { V0 = indices[i], V1 = indices[i + 2], v2 = indices[i + 1] }; _tris.Add(t); } } root.Mesh.VertexData = _vertices.ToArray(); root.Mesh.TriData = _tris.ToArray(); root.Mesh.FinalAnim(); root.Renderer = new Visuals.VRMultiPassAnim(); root.Meshes.Add(root.Mesh.Clone()); root.Meshes[0].FinalAnim(); Material.Material3D m1 = new Material.Material3D { ColorMap = DiffBlank, NormalMap = NormBlank, SpecularMap = SpecBlank }; root.Mesh.Material = m1; root.Meshes[0].Material = root.Mesh.Material; Assimp.Material mat = s.Materials[0]; TextureSlot t1; int sc = mat.GetMaterialTextureCount(TextureType.Unknown); Console.WriteLine("SC:" + sc); if (mat.HasColorDiffuse) { m1.Diff = CTV(mat.ColorDiffuse); } if (mat.HasColorSpecular) { m1.Spec = CTV(mat.ColorSpecular); // Console.WriteLine("Spec:" + vm.Spec); } if (mat.HasShininess) { //vm.Shine = 0.3f+ mat.Shininess; // Console.WriteLine("Shine:" + vm.Shine); } //Console.WriteLine("Spec:" + vm.Spec); //for(int ic = 0; ic < sc; ic++) ///{ if (sc > 0) { TextureSlot tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; m1.SpecularMap = new Texture.Texture2D(IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) { TextureSlot ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; Console.WriteLine("Norm:" + ntt.FilePath); m1.NormalMap = new Texture.Texture2D(IPath + "/" + ntt.FilePath, Vivid.Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; Console.WriteLine("DiffTex:" + t1.FilePath); if (t1.FilePath != null) { try { // Console.Write("t1:" + t1.FilePath); m1.ColorMap = new Texture.Texture2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); if (File.Exists(IPath + "norm" + t1.FilePath)) { // vm.TNorm = new Texture.VTex2D(IPath + "norm" + // t1.FilePath,Texture.LoadMethod.Single, false); // Console.WriteLine("TexLoaded"); } } catch { } } if (true) { if (new FileInfo(t1.FilePath).Exists == true) { // var tex = App.AppSal.CreateTex2D(); // tex.Path = t1.FilePath; // tex.Load(); //m2.DiffuseMap = tex; } } } //r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.A2, s.Transform.A3, s.Transform.A4, s.Transform.B1, s.Transform.B2, s.Transform.B3, s.Transform.B4, s.Transform.C1, s.Transform.C2, s.Transform.C3, s.Transform.C4, s.Transform.D1, s.Transform.D2, s.Transform.D3, s.Transform.D4); root.LocalTurn = new OpenTK.Matrix4(s.RootNode.Transform.A1, s.RootNode.Transform.B1, s.RootNode.Transform.C1, s.RootNode.Transform.D1, s.RootNode.Transform.A2, s.RootNode.Transform.B2, s.RootNode.Transform.C2, s.RootNode.Transform.D2, s.RootNode.Transform.A3, s.RootNode.Transform.B3, s.RootNode.Transform.C3, s.RootNode.Transform.D3, s.RootNode.Transform.A4, s.RootNode.Transform.B4, s.RootNode.Transform.C4, s.RootNode.Transform.D4); root.LocalTurn = ToTK(s.RootNode.Children[0].Transform); OpenTK.Matrix4 lt = root.LocalTurn; root.LocalTurn = lt.ClearTranslation(); root.LocalTurn = root.LocalTurn.ClearScale(); root.LocalPos = lt.ExtractTranslation(); root.LocalScale = lt.ExtractScale(); root.AnimName = "Run"; return(root); /* * foreach (var m in s.Meshes) * { * Console.WriteLine("M:" + m.Name + " Bones:" + m.BoneCount); * Console.WriteLine("AA:" + m.HasMeshAnimationAttachments); * * var vm = new Material.Material3D(); * vm.TCol = DiffBlank; * vm.TNorm = NormBlank; * vm.TSpec = SpecBlank; * var m2 = new VMesh(m.GetIndices().Length, m.VertexCount); * ml2.Add(m2); * // ml.Add(m.Name, m2); * for (int b = 0; b < m.BoneCount; b++) * { * uint index = 0; * string name = m.Bones[b].Name; * } * m2.Mat = vm; * // root.AddMesh(m2); * m2.Name = m.Name; * var mat = s.Materials[m.MaterialIndex]; * TextureSlot t1; * * var sc = mat.GetMaterialTextureCount(TextureType.Unknown); * Console.WriteLine("SC:" + sc); * if (mat.HasColorDiffuse) * { * vm.Diff = CTV(mat.ColorDiffuse); * } * if (mat.HasColorSpecular) * { * vm.Spec = CTV(mat.ColorSpecular); * Console.WriteLine("Spec:" + vm.Spec); * } * if (mat.HasShininess) * { * //vm.Shine = 0.3f+ mat.Shininess; * Console.WriteLine("Shine:" + vm.Shine); * } * * Console.WriteLine("Spec:" + vm.Spec); * //for(int ic = 0; ic < sc; ic++) * ///{ * if (sc > 0) * { * var tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; * vm.TSpec = new Texture.VTex2D(IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false); * } * * if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) * { * var ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; * Console.WriteLine("Norm:" + ntt.FilePath); * vm.TNorm = new Texture.VTex2D(IPath + "/" + ntt.FilePath, Fusion3D.Texture.LoadMethod.Single, false); * } * * if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) * { * t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; * Console.WriteLine("DiffTex:" + t1.FilePath); * * if (t1.FilePath != null) * { * try * { * // Console.Write("t1:" + t1.FilePath); * vm.TCol = new Texture.VTex2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); * if (File.Exists(IPath + "norm" + t1.FilePath)) * { * // vm.TNorm = new Texture.VTex2D(IPath + "norm" + * // t1.FilePath,Texture.LoadMethod.Single, false); * * // Console.WriteLine("TexLoaded"); * } * } * catch * { * } * } * if (true) * { * if (new FileInfo(t1.FilePath).Exists == true) * { * // var tex = App.AppSal.CreateTex2D(); * // tex.Path = t1.FilePath; * // tex.Load(); * //m2.DiffuseMap = tex; * } * } * } * * ExtractBoneWeightsFromMesh(m, vertToBoneWeight); * * for (int i = 0; i < m2.NumVertices; i++) * { * var v = m.Vertices[i];// * new Vector3D(15, 15, 15); * var n = m.Normals[i]; * var t = m.TextureCoordinateChannels[0]; * Vector3D tan, bi; * if (m.Tangents != null && m.Tangents.Count > 0) * { * tan = m.Tangents[i]; * bi = m.BiTangents[i]; * } * else * { * tan = new Vector3D(0, 0, 0); * bi = new Vector3D(0, 0, 0); * } * if (t.Count() == 0) * { * m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(new Vector3D(0, 0, 0))); * } * else * { * var tv = t[i]; * tv.Y = 1.0f - tv.Y; * m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(tv)); * } * * var weights = vertToBoneWeight[(uint)i].Select(w => w.Weight).ToArray(); * var boneIndices = vertToBoneWeight[(uint)i].Select(w => (byte)w.VertexID).ToArray(); * * m2.SetVertexBone(i, weights.First(), boneIndices); * * //var v = new PosNormalTexTanSkinned(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3(), weights.First(), boneIndices); * //verts.Add(v); * } * int[] id = m.GetIndices(); * int fi = 0; * uint[] nd = new uint[id.Length]; * for (int i = 0; i < id.Length; i += 3) * { * //Tri t = new Tri(); * //t.V0 = (int)nd[i]; * // t.V1 = (int)nd[i + 1]; * // t.v2 = (int)nd[i + 2]; * * // nd[i] = (uint)id[i]; * m2.SetTri(i / 3, (int)id[i], (int)id[i + 1], (int)id[i + 2]); * } * * m2.Indices = nd; * //m2.Scale(AssImpImport.ScaleX, AssImpImport.ScaleY, AssImpImport.ScaleZ); * m2.Final(); * } * * ProcessNode(root, s.RootNode, ml2); * * foreach (var ac in root.Clips) * { * Console.WriteLine("Anims:" + ac); * } * root.AnimName = "Run"; * /* * while (true) * { * } */ return(root as Node3D); }
public override Node3D LoadNode(string path) { if (NormBlank == null) { NormBlank = new Texture.Texture2D("data/tex/normblank.png", Texture.LoadMethod.Single, false); DiffBlank = new Texture.Texture2D("data/tex/diffblank.png", Texture.LoadMethod.Single, false); SpecBlank = new Texture.Texture2D("data/tex/specblank.png", Texture.LoadMethod.Single, false); } string ip = path; int ic = ip.LastIndexOf("/"); if (ic < 1) { ic = ip.LastIndexOf("\\"); } if (ic > 0) { IPath = ip.Substring(0, ic); } Entity3D root = new Entity3D(); string file = path; AssimpContext e = new Assimp.AssimpContext(); Assimp.Configs.NormalSmoothingAngleConfig c1 = new Assimp.Configs.NormalSmoothingAngleConfig(75); e.SetConfig(c1); Console.WriteLine("Impporting:" + file); Assimp.Scene s = null; try { s = e.ImportFile(file, PostProcessSteps.OptimizeGraph | PostProcessSteps.FindInvalidData | PostProcessSteps.FindDegenerates | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals | PostProcessSteps.FixInFacingNormals | PostProcessSteps.GenerateSmoothNormals); if (s.HasAnimations) { return(LoadAnimNode(path)); } } catch (AssimpException ae) { Console.WriteLine(ae); Console.WriteLine("Failed to import"); Environment.Exit(-1); } Console.WriteLine("Imported."); Dictionary <string, Mesh3D> ml = new Dictionary <string, Mesh3D>(); List <Mesh3D> ml2 = new List <Mesh3D>(); Console.WriteLine("animCount:" + s.AnimationCount); Matrix4x4 tf = s.RootNode.Transform; tf.Inverse(); root.GlobalInverse = ToTK(tf); Dictionary <uint, List <VertexWeight> > boneToWeight = new Dictionary <uint, List <VertexWeight> >(); //root.Animator = new Animation.Animator(); //s.Animations[0].NodeAnimationChannels[0]. //s.Animations[0].anim // root.Animator.InitAssImp(model); foreach (Mesh m in s.Meshes) { Console.WriteLine("M:" + m.Name + " Bones:" + m.BoneCount); Console.WriteLine("AA:" + m.HasMeshAnimationAttachments); Material.Material3D vm = new Material.Material3D { ColorMap = DiffBlank, NormalMap = NormBlank, SpecularMap = SpecBlank }; Mesh3D m2 = new Mesh3D(m.GetIndices().Length, m.VertexCount); ml2.Add(m2); // ml.Add(m.Name, m2); for (int b = 0; b < m.BoneCount; b++) { string name = m.Bones[b].Name; } m2.Material = vm; // root.AddMesh(m2); m2.Name = m.Name; Assimp.Material mat = s.Materials[m.MaterialIndex]; TextureSlot t1; int sc = mat.GetMaterialTextureCount(TextureType.Unknown); Console.WriteLine("SC:" + sc); if (mat.HasColorDiffuse) { vm.Diff = CTV(mat.ColorDiffuse); Console.WriteLine("Diff:" + vm.Diff); } if (mat.HasColorSpecular) { // vm.Spec = CTV ( mat.ColorSpecular ); Console.WriteLine("Spec:" + vm.Spec); } if (mat.HasShininess) { //vm.Shine = 0.3f+ mat.Shininess; Console.WriteLine("Shine:" + vm.Shine); } Console.WriteLine("Spec:" + vm.Spec); //for(int ic = 0; ic < sc; ic++) ///{ if (sc > 0) { TextureSlot tex2 = mat.GetMaterialTextures(TextureType.Unknown)[0]; // vm.SpecularMap = new Texture.Texture2D ( IPath + "/" + tex2.FilePath, Texture.LoadMethod.Single, false ); } if (mat.GetMaterialTextureCount(TextureType.Normals) > 0) { TextureSlot ntt = mat.GetMaterialTextures(TextureType.Normals)[0]; Console.WriteLine("Norm:" + ntt.FilePath); vm.NormalMap = new Texture.Texture2D(IPath + "/" + ntt.FilePath, Vivid.Texture.LoadMethod.Single, false); } if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0]; Console.WriteLine("DiffTex:" + t1.FilePath); if (t1.FilePath != null) { //Console.WriteLine ( "Tex:" + t1.FilePath ); // Console.Write("t1:" + t1.FilePath); vm.ColorMap = new Texture.Texture2D(IPath + "/" + t1.FilePath.Replace(".dds", ".png"), Texture.LoadMethod.Single, false); if (File.Exists(IPath + "/" + "norm_" + t1.FilePath)) { vm.NormalMap = new Texture.Texture2D(IPath + "/" + "norm_" + t1.FilePath, Texture.LoadMethod.Single, false); } } } for (int i = 0; i < m2.NumVertices; i++) { Vector3D v = m.Vertices[i];// * new Vector3D(15, 15, 15); Vector3D n = new Vector3D(0, 1, 0); if (m.Normals != null && m.Normals.Count > i) { n = m.Normals[i]; } List <Vector3D> t = m.TextureCoordinateChannels[0]; Vector3D tan, bi; if (m.Tangents != null && m.Tangents.Count > 0) { tan = m.Tangents[i]; bi = m.BiTangents[i]; } else { tan = new Vector3D(0, 0, 0); bi = new Vector3D(0, 0, 0); } if (t.Count() == 0) { m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(new Vector3D(0, 0, 0))); } else { Vector3D tv = t[i]; tv.Y = 1.0f - tv.Y; m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(tv)); } //var v = new PosNormalTexTanSkinned(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3(), weights.First(), boneIndices); //verts.Add(v); } int[] id = m.GetIndices(); uint[] nd = new uint[id.Length]; for (int i = 0; i < id.Length; i += 3) { //Tri t = new Tri(); //t.V0 = (int)nd[i]; // t.V1 = (int)nd[i + 1]; // t.v2 = (int)nd[i + 2]; // nd[i] = (uint)id[i]; if (i + 2 < id.Length) { m2.SetTri(i / 3, id[i], id[i + 1], id[i + 2]); } } m2.Indices = nd; //m2.Scale(AssImpImport.ScaleX, AssImpImport.ScaleY, AssImpImport.ScaleZ); //m2.GenerateTangents ( ); m2.Final(); } ProcessNode(root, s.RootNode, ml2); /* * while (true) * { * } */ return(root as Node3D); }
void ProcessMaterials(Scene scene, string directoryName, VertexMode mode) { for (int i = 0; i < scene.MaterialCount; i++) { Material mat = new Material(); Assimp.Material material = scene.Materials[i]; var diffuse = material.ColorDiffuse; mat.diffuse = new Vec3(diffuse.R, diffuse.G, diffuse.B); var specular = material.ColorSpecular; mat.specular = new Vec3(specular.R, specular.G, specular.B); var emissive = material.ColorEmissive; mat.emissive = new Vec3(emissive.R, emissive.G, emissive.B); float shininess = material.Shininess; mat.shininess = shininess; float shininessStrength = material.ShininessStrength; mat.specular.x *= shininessStrength; mat.specular.y *= shininessStrength; mat.specular.z *= shininessStrength; int numDiffuseMaps = material.GetMaterialTextureCount(TextureType.Diffuse); int numNormalMaps = material.GetMaterialTextureCount(TextureType.Normals); if (numDiffuseMaps > 0) { material.GetMaterialTexture(TextureType.Diffuse, 0, out var diffuseMapName); Console.WriteLine(diffuseMapName.FilePath); if (!File.Exists(diffuseMapName.FilePath) && (mode == VertexMode.TextureAndNormal || mode == VertexMode.TextureOnly)) { var a = new ModelWorkerEventArgs() { Args = diffuseMapName.FilePath, EventType = ModelWorkerEventArgs.EventArgsType.TextureNotExists, Context = directoryName }; this.OnActionCallback?.Invoke(this, a); diffuseMapName.FilePath = a.Args.Replace(directoryName, ""); } mat.diffuseMapName = diffuseMapName.FilePath; } if (numNormalMaps > 0) { material.GetMaterialTexture(TextureType.Normals, 0, out var normalMapName); Console.WriteLine(normalMapName.FilePath); if (!File.Exists(normalMapName.FilePath) && mode == VertexMode.TextureAndNormal) { var a = new ModelWorkerEventArgs() { Args = normalMapName.FilePath, EventType = ModelWorkerEventArgs.EventArgsType.TextureNotExists, Context = directoryName }; this.OnActionCallback?.Invoke(this, a); normalMapName.FilePath = a.Args.Replace(directoryName, ""); ; } mat.normalMapName = normalMapName.FilePath; } this._materials.Add(mat); } }
private void ApplyFixedFunctionMaterial(Mesh mesh, Material mat, bool textured, bool shaded) { shaded = shaded && (mesh == null || mesh.HasNormals); if (shaded) { GL.Enable(EnableCap.Lighting); } else { GL.Disable(EnableCap.Lighting); } var hasColors = mesh != null && mesh.HasVertexColors(0); if (hasColors) { GL.Enable(EnableCap.ColorMaterial); GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse); } else { GL.Disable(EnableCap.ColorMaterial); } // note: keep semantics of hasAlpha consistent with IsAlphaMaterial() var hasAlpha = false; var hasTexture = false; // note: keep this up-to-date with the code in UploadTextures() if (textured && mat.GetMaterialTextureCount(TextureType.Diffuse) > 0) { hasTexture = true; TextureSlot tex; mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); hasAlpha = hasAlpha || gtex.HasAlpha == Texture.AlphaState.HasAlpha; if(gtex.State == Texture.TextureState.GlTextureCreated) { GL.ActiveTexture(TextureUnit.Texture0); gtex.BindGlTexture(); GL.Enable(EnableCap.Texture2D); } else { GL.Disable(EnableCap.Texture2D); } } else { GL.Disable(EnableCap.Texture2D); } GL.Enable(EnableCap.Normalize); var alpha = 1.0f; if (mat.HasOpacity) { alpha = mat.Opacity; if (alpha < AlphaSuppressionThreshold) // suppress zero opacity, this is likely wrong input data { alpha = 1.0f; } } var color = new Color4(.8f, .8f, .8f, 1.0f); if (mat.HasColorDiffuse) { color = AssimpToOpenTk.FromColor(mat.ColorDiffuse); if (color.A < AlphaSuppressionThreshold) // s.a. { color.A = 1.0f; } } color.A *= alpha; hasAlpha = hasAlpha || color.A < 1.0f; if (shaded) { // if the material has a texture but the diffuse color texture is all black, // then heuristically assume that this is an import/export flaw and substitute // white. if (hasTexture && color.R < 1e-3f && color.G < 1e-3f && color.B < 1e-3f) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, Color4.White); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, color); } color = new Color4(0, 0, 0, 1.0f); if (mat.HasColorSpecular) { color = AssimpToOpenTk.FromColor(mat.ColorSpecular); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, color); color = new Color4(.2f, .2f, .2f, 1.0f); if (mat.HasColorAmbient) { color = AssimpToOpenTk.FromColor(mat.ColorAmbient); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Ambient, color); color = new Color4(0, 0, 0, 1.0f); if (mat.HasColorEmissive) { color = AssimpToOpenTk.FromColor(mat.ColorEmissive); } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, color); float shininess = 1; float strength = 1; if (mat.HasShininess) { shininess = mat.Shininess; } // todo: I don't even remember how shininess strength was supposed to be handled in assimp if (mat.HasShininessStrength) { strength = mat.ShininessStrength; } var exp = shininess*strength; if (exp >= 128.0f) // 128 is the maximum exponent as per the Gl spec { exp = 128.0f; } GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, exp); } else if (!hasColors) { GL.Color3(color.R, color.G, color.B); } if (hasAlpha) { GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.DepthMask(false); } else { GL.Disable(EnableCap.Blend); GL.DepthMask(true); } }
/// <summary> /// Check if a given assimp material requires alpha-blending for rendering /// </summary> /// <param name="material"></param> /// <returns></returns> public bool IsAlphaMaterial(Material material) { if (material.HasOpacity && IsTransparent(material.Opacity)) { return true; } // Also treat material as (potentially) semi-transparent if the alpha // components of any of the diffuse, specular, ambient and emissive // colors are non-1. It is not very well-defined how assimp handles // these values so better count them into transparency as well. // // Ignore color values with alpha=0, however. These are most likely // not intended to be fully transparent. if (material.HasColorDiffuse && IsTransparent(material.ColorDiffuse.A)) { return true; } if (material.HasColorSpecular && IsTransparent(material.ColorSpecular.A)) { return true; } if (material.HasColorAmbient && IsTransparent(material.ColorAmbient.A)) { return true; } if (material.HasColorEmissive && IsTransparent(material.ColorEmissive.A)) { return true; } if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; material.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); if(gtex.HasAlpha == Texture.AlphaState.HasAlpha) { return true; } } return false; }
/// <summary> /// Uploads all the textures required for a given material to VRAM (i.e. /// create the corresponding Gl objects). Textures that have been /// uploaded before are not attempted again. /// </summary> /// <param name="material"></param> /// <returns>Whether there were any new texture uploads</returns> public bool UploadTextures(Material material) { Debug.Assert(material != null); var any = false; // note: keep this up to date with the code in ApplyFixedFunctionMaterial if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0) { TextureSlot tex; material.GetMaterialTexture(TextureType.Diffuse, 0, out tex); var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath); if (gtex.State == Texture.TextureState.WinFormsImageCreated) { gtex.Upload(); any = true; } else if (gtex.ReconfigureUploadedTextureRequested) { gtex.ReconfigureUploadedTexture(); } } return any; }
void WriteTextureStack (Material mat, TextureType type, BinaryWriter writer, Dictionary<string,string> textures) { var count = mat.GetMaterialTextureCount(type); writer.Write(count); for (var i = 0; i < count; i++) { TextureSlot slot; mat.GetMaterialTexture(type, i, out slot); if (slot.Mapping != TextureMapping.FromUV) throw new ContentException("Unsupported texture mapping type, textures must be UV-mapped."); if (!textures.ContainsKey(slot.FilePath)) { textures.Add(slot.FilePath, Path.GetFileNameWithoutExtension(slot.FilePath)); } writer.Write(textures[slot.FilePath]); writer.Write(slot.UVIndex); writer.Write(slot.BlendFactor); writer.Write((int)slot.Operation); writer.Write(slot.WrapModeU == TextureWrapMode.Wrap); writer.Write(slot.WrapModeV == TextureWrapMode.Wrap); } }