예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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);
                }
            }
        }