Beispiel #1
0
        /// <summary>
        /// 読み込み
        /// </summary>
        static public MMLParser Load(string fileName)
        {
            XmlSerializer sr  = new XmlSerializer(typeof(MMLParser));
            TextReader    tr  = new StreamReader(fileName);
            MMLParser     doc = (MMLParser)(sr.Deserialize(tr));

            tr.Close();

            // パラメータのサイズを求める
            if (doc.Materials.Count > 0)
            {
                int size = 0;
                foreach (var p in doc.Materials[0].Params)
                {
                    if (p.Value.GetType() == typeof(MaterialParamValue <float>))
                    {
                        size += 4;
                    }
                    else if (p.Value.GetType() == typeof(MaterialParamValue <Color4>))
                    {
                        size += 4 * 4;
                    }
                }
                doc.ParamSize = size;
            }

            return(doc);
        }
Beispiel #2
0
        /// <summary>
        /// 保存
        /// </summary>
        static public void Save(string fileName, Model model)
        {
            var serializer = new MMLParser();
            // モデルのパスを相対パスで設定
            Uri    u1           = new Uri(System.IO.Path.GetDirectoryName(fileName) + "/");
            Uri    u2           = new Uri(model.FilePath);
            string relativePath = u1.MakeRelativeUri(u2).ToString();

            serializer.ModelPath = relativePath;
            // マテリアル
            serializer.materials_ = new List <MMLMaterial>(model.MaterialNum);
            for (int i = 0; i < model.MaterialNum; i++)
            {
                var mat = new MMLMaterial();
                mat.Name     = model.Materials[i].Name;
                mat.Params   = new List <MaterialParam>(model.Materials[i].userParams_);
                mat.Textures = new List <TextureFileParam>(model.Materials[i].textureFileParams_);
                serializer.materials_.Add(mat);
            }

            XmlSerializer sw = new XmlSerializer(typeof(MMLParser));
            TextWriter    tw = new StreamWriter(fileName);

            sw.Serialize(tw, serializer);
            tw.Close();
        }
Beispiel #3
0
        /// <summary>
        /// 初期化
        /// </summary>
        public void Initialize(string fileName, float scaling = 1.0f, bool calcTangent = false)
        {
            string ext = System.IO.Path.GetExtension(fileName).ToLower();

            switch (ext)
            {
            case ".ksmdl":
                LoadFromksmdl(this, fileName);
                break;

            case ".obj":
                LoadFromObj(this, fileName, scaling, calcTangent);
                break;

            case ".mml":
                MMLParser p = MMLParser.Load(fileName);
                // 絶対パスにする
                string path = null;
                if (System.IO.Path.IsPathRooted(p.ModelPath))
                {
                    path = p.ModelPath;
                }
                else
                {
                    path = System.IO.Path.GetDirectoryName(fileName) + "\\" + p.ModelPath;
                }
                string modelExt = System.IO.Path.GetExtension(p.ModelPath).ToLower();
                switch (modelExt)
                {
                case ".obj":
                    LoadFromObj(this, path, scaling, calcTangent, p);
                    break;
                }
                break;
            }
        }
Beispiel #4
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);
                }
            }
        }
Beispiel #5
0
        static void LoadFromObj(Model model, string fileName, float scaling = 1.0f, bool calcTangent = false, MMLParser mml = null)
        {
            string baseDir = Path.GetDirectoryName(fileName);
            string mtlPath = baseDir + "/" + Path.GetFileNameWithoutExtension(fileName) + ".mtl";
            var    loader  = new Ext.ObjFileLoader();

            loader.Load(fileName, calcTangent);
            loader.LoadMaterials(mtlPath);
            MeshLoad(model, loader, fileName, scaling, mml);
        }