Colladaからデータ取得
C#のLinqToXMLでColladaからデータを取ってみる
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Xml.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace WindowsFormsApplication1 { /// <summary> /// マテリアル情報 /// </summary> struct Material { public string MaterialName; public List<string> TextureFileName; public Vector4 DiffuseColor; public Vector4 AmbientColor; public Vector4 EmissionColor; public Vector4 SpecularColor; public float Shininess; public float RefractionIndex; } public partial class Form1 : Form { private Dictionary<string, string> m_ImageDictionary; private List<Material> m_MaterialList; public Form1() { m_ImageDictionary = new Dictionary<string, string>(); m_MaterialList = new List<Material>(); InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { openFileDialog1.InitialDirectory = @"D:\text\dae"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { string dae_filename = openFileDialog1.FileName; textBox1.Text = dae_filename; parseDAE(dae_filename); } } /// <summary> /// DAEを解釈 /// </summary> /// <param name="dae_filename"></param> private void parseDAE(string dae_filename) { var load_dae = XDocument.Load(@dae_filename); XNamespace ex = @"http://www.collada.org/2005/11/COLLADASchema"; // テクスチャ m_ImageDictionary = parseTexture(load_dae, ex); // マテリアル m_MaterialList = parseMaterialList(load_dae, ex); } /// <summary> /// テクスチャの連想配列作成 /// </summary> /// <param name="dae"></param> /// <param name="ex"></param> /// <returns></returns> private Dictionary<string, string> parseTexture(XDocument dae, XNamespace ex) { Dictionary<string, string> imageDictionary = new Dictionary<string, string>(); var query = from n in dae.Descendants(ex + "image") select n; foreach (var elem in query) { imageDictionary.Add(elem.Attribute("id").Value, elem.Value); } return imageDictionary; } /// <summary> /// マテリアルリスト /// </summary> /// <param name="dae"></param> /// <param name="ex"></param> /// <returns></returns> private List<Material> parseMaterialList(XDocument dae, XNamespace ex) { List<Material> materialList = new List<Material>(); var query = from n in dae.Descendants(ex + "effect") select n; foreach (var elem in query) { Material mat = new Material(); mat.TextureFileName = new List<string>(); // マテリアル名 mat.MaterialName = elem.Attribute("id").Value; // テクスチャ名(複数の場合あり) XElement el = elem; var q = from m in el.Descendants(ex + "surface") select m; foreach (var e in q) { string texname = m_ImageDictionary[e.Value]; mat.TextureFileName.Add(texname); } // diffuse mat.DiffuseColor = parseColor("diffuse", el, ex); // ambient mat.AmbientColor = parseColor("ambient", el, ex); // emission mat.EmissionColor = parseColor("emission", el, ex); // specular mat.SpecularColor = parseColor("specular", el, ex); // shininess mat.Shininess = parseParam("shiniess", el, ex); // refraction index mat.RefractionIndex = parseParam("index_of_refraction", el, ex); materialList.Add(mat); } return materialList; } /// <summary> /// library_effects内の色を解析 /// </summary> /// <param name="colorname"></param> /// <param name="element"></param> /// <param name="ex"></param> /// <returns></returns> private Vector4 parseColor(string colorname, XElement element, XNamespace ex) { var query = from m in element.Descendants(ex + colorname) select m; Vector4 color = new Vector4(); foreach (var e in query) { string col = e.Value; string[] array = col.Split(' '); if (array.Count() > 1) { color.X = float.Parse(array[0]); color.Y = float.Parse(array[1]); color.Z = float.Parse(array[2]); color.W = float.Parse(array[3]); } else { color.X = color.Y = color.Z = color.W = 1.0f; } } return color; } /// <summary> /// float解析 /// </summary> /// <param name="colorname"></param> /// <param name="element"></param> /// <param name="ex"></param> /// <returns></returns> private float parseParam(string paramname, XElement element, XNamespace ex) { var query = from m in element.Descendants(ex + paramname) select m; float param = 0.0f; foreach (var e in query) { string p = e.Value; if (p.Length > 0) { param = float.Parse(p); } } return param; } } }