/// <summary> /// マテリアルの読み込み /// </summary> public void LoadMaterials(String fileName) { CultureInfo ci = new CultureInfo("en-US", false); try { using (StreamReader sr = new StreamReader(fileName)) { bool end = false; MaterialObject currentObj = null; while (!end) { if (sr.EndOfStream) { end = true; continue; } String line = sr.ReadLine().Trim(); if (line.StartsWith("#")) { continue; } if (line.Length < 1) { continue; } if (line.StartsWith("newmtl ")) { var tokens = line.Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries); currentObj = new MaterialObject(); currentObj.ID = tokens[1]; m_materialList.Add(currentObj); } if (line.StartsWith("map_Kd ")) { var tokens = line.Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries); String texture = tokens[1]; if (!m_textureList.ContainsKey(texture)) { m_textureList.Add(texture, texture); } currentObj.textureID.Add(texture); } if (line.StartsWith("map_bump ")) { var tokens = line.Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries); String texture = tokens[1]; if (!m_textureList.ContainsKey(texture)) { m_textureList.Add(texture, texture); } currentObj.textureID.Add(texture); } } } } catch (IOException e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } }
/// <summary> /// LoaderからMeshを生成する /// </summary> static void MeshLoad(Model model, Ext.MeshLoader loader, string fileName, float scaling, MMLParser mml) { model.FilePath = fileName; string baseDir = Path.GetDirectoryName(fileName); int numVertices = loader.m_Vertices.Count; int numIndices = loader.m_Indices.Count; // 頂点バッファ int elemNum; uint shaderAttr; if (loader.m_Vertices[0].GetType().Name == "MyVertex") { elemNum = 8; shaderAttr = (uint)(Shader.VertexAttr.POSITION | Shader.VertexAttr.NORMAL | Shader.VertexAttr.TEXCOORD0); } else { elemNum = 14; shaderAttr = (uint)(Shader.VertexAttr.POSITION | Shader.VertexAttr.NORMAL | Shader.VertexAttr.TEXCOORD0 | Shader.VertexAttr.TANGENT | Shader.VertexAttr.BITANGENT); } int stride = elemNum * sizeof(System.Single); int vertex_size = stride * numVertices; var vertices = new DataStream(vertex_size, true, true); foreach (var vertex in loader.m_Vertices) { vertices.Write(new Vector3(vertex.x * scaling, vertex.y * scaling, vertex.z * scaling)); vertices.Write(new Vector3(vertex.nx, vertex.ny, vertex.nz)); vertices.Write(new Vector2(vertex.u, vertex.v)); var bv = vertex as Ext.MyVertexBump; if (bv != null) { vertices.Write(new Vector3(bv.tx, bv.ty, bv.tz)); vertices.Write(new Vector3(bv.btx, bv.bty, bv.btz)); } } vertices.Position = 0; VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = vertices, data_size = vertex_size, stride = stride }; model.vertexBuffer_ = new VertexBuffer(desc); vertices.Close(); // インデックスバッファ int index_size = 4 * numIndices; var indices = new DataStream(index_size, true, true); foreach (var index in loader.m_Indices) { indices.Write(index); } indices.Position = 0; model.indexBuffer_ = new IndexBuffer(indices, index_size); indices.Close(); model.indexNum_ = numIndices; // 以下マテリアル関係 { // テクスチャ Dictionary <string, string> textureList = loader.m_textureList; if (mml != null) { textureList = new Dictionary <string, string>(); foreach (var m in mml.Materials) { foreach (var t in m.Textures) { if (t.Path != null && t.Path != "") { textureList[t.Path] = t.Path; } } } } int texNum = textureList.Count; if (texNum > 0) { model.textures_ = new List <Texture>(texNum); } var textureDict = new Dictionary <string, int>(); model.textureDict_ = new Dictionary <int, string>(); int currentIdx = 0; foreach (var v in textureList) { try { string path = v.Value.Replace("file:///", ""); path = System.IO.Path.IsPathRooted(path) ? path : baseDir + "/" + path; model.textures_.Add(new Texture(path)); textureDict[v.Key] = currentIdx; model.textureDict_[currentIdx] = v.Key; currentIdx++; } catch { Console.WriteLine("テクスチャの読み込みに失敗しました."); } } // マテリアル List <Ext.MaterialObject> materialList = loader.m_materialList; if (mml != null) { materialList = new List <Ext.MaterialObject>(); // TODO:名前解決したほうがいい? foreach (var m in mml.Materials) { var mat = new Ext.MaterialObject(); mat.ID = m.Name; mat.textureID = new List <string>(); foreach (var s in m.Textures) { if (s.Path != null && s.Path != "") { mat.textureID.Add(s.Path); } } materialList.Add(mat); } } int material_num = materialList.Count; Material.ksMaterialStruct[] material_struct_list = new Material.ksMaterialStruct[material_num]; for (int i = 0; i < material_num; i++) { if (materialList[i].textureID.Count > 0) { // テクスチャあり material_struct_list[i].m_Type = (int)Material.MaterialType.TEXTURE_ONLY; material_struct_list[i].m_texID.Initialize(); for (int j = 0; j < materialList[i].textureID.Count; j++) { var t = materialList[i].textureID[j]; if (textureDict.ContainsKey(t)) { material_struct_list[i].m_texID[j] = textureDict[t]; } } } else { // テクスチャなし material_struct_list[i].m_Type = (int)Material.MaterialType.COLOR_ONLY; material_struct_list[i].color = new Color4(1.0f, 1.0f, 1.0f, 1.0f); } } // マテリアル実体 model.materials_ = new Material[material_num]; model.textureIdDict_ = new Dictionary <Material, Material.Index4>(); for (int i = 0; i < material_num; i++) { model.materials_[i] = new Material(model, ref material_struct_list[i], model.textures_); model.materials_[i].Name = materialList[i].ID; // 気持ち悪いので何とかしたいところ(ksmdlのサポートを切れば...) model.materials_[i].SetShader(ShaderManager.DefaultShader, shaderAttr); if (material_struct_list[i].m_Type == (int)Material.MaterialType.TEXTURE_ONLY) { model.textureIdDict_[model.materials_[i]] = material_struct_list[i].m_texID; } if (mml != null) { // パラメータ model.materials_[i].userParams_ = mml.Materials[i].Params; model.materials_[i].userParamSize_ = mml.ParamSize; } } // パラメータを持っていないデータを読んだ場合適当な値を生成しておく if (mml == null) { MaterialParamLoader mloader = new MaterialParamLoader(model.materials_); mloader.Load(null); } // マテリアルエディタ時は調整用パラメータを生成する if (AutoCreateMaterialUserParam) { for (int i = 0; i < material_num; i++) { model.materials_[i].InitializeTextureParams(ref material_struct_list[i]); } } // 1ノードで複数サブセットという形にしておく int subsetNum = loader.m_subsetList.Count; model.nodes_ = new Node[1]; model.nodes_[0] = new Node(subsetNum); for (int i = 0; i < loader.m_subsetList.Count; i++) { var subset = loader.m_subsetList[i]; int startIdx = subset.startIndex; int endIdx = subset.endIndex; model.nodes_[0].Subsets[i].startIndex = startIdx; model.nodes_[0].Subsets[i].endIndex = endIdx; model.nodes_[0].Subsets[i].materialIndex = materialList.FindIndex(0, c => c.ID == subset.material); } } }