2 using System.Collections.Generic;
\r
3 using System.Drawing.Design;
\r
6 using System.Runtime.InteropServices;
\r
7 using System.ComponentModel;
\r
8 using System.Windows.Forms;
\r
9 using System.Windows.Forms.Design;
\r
11 namespace Tso2MqoGui
\r
13 public abstract class TSOGenerator
\r
16 private TSOGeneratorConfig config;
\r
17 protected MqoFile mqo;
\r
18 protected TSOFile tsoref;
\r
19 protected Dictionary<string, TSONode> nodes;
\r
20 protected List<TSOMesh> meshes;
\r
21 private ImportInfo ii;
\r
22 private BinaryWriter bw;
\r
23 protected Dictionary<string, MaterialInfo> materials;
\r
24 private Dictionary<string, TextureInfo> textures;
\r
26 public TSOGenerator(TSOGeneratorConfig config)
\r
28 this.config = config;
\r
31 public TSOFile LoadTSO(string file)
\r
33 TSOFile tso = new TSOFile(file);
\r
38 private bool SetCurrentDirectory(string dir)
\r
41 Environment.CurrentDirectory = dir;
\r
45 private bool DoLoadMQO(string mqo_file)
\r
48 mqo = new MqoFile();
\r
53 private bool DoLoadXml(string importinfo_file)
\r
56 ii = ImportInfo.Load(importinfo_file);
\r
59 materials = new Dictionary<string, MaterialInfo>();
\r
60 bool validmap = true;
\r
62 foreach (MqoMaterial i in mqo.Materials)
\r
64 MaterialInfo mi = new MaterialInfo(dir, i, ii.GetMaterial(i.name));
\r
65 validmap &= mi.Valid;
\r
66 materials.Add(i.name, mi);
\r
69 if (!validmap || config.ShowMaterials)
\r
72 throw new Exception("マテリアルの設定が無効です");
\r
74 FormMaterial dlg = new FormMaterial();
\r
75 dlg.materials = materials;
\r
77 if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
\r
82 textures = new Dictionary<string, TextureInfo>();
\r
84 foreach (MaterialInfo i in materials.Values)
\r
86 string name = Path.GetFileNameWithoutExtension(i.ColorTexture);
\r
88 if (!textures.ContainsKey(name))
\r
89 textures.Add(name, new TextureInfo(name, i.ColorTexture));
\r
91 name = Path.GetFileNameWithoutExtension(i.ShadeTexture);
\r
93 if (!textures.ContainsKey(name))
\r
94 textures.Add(name, new TextureInfo(name, i.ShadeTexture));
\r
100 private bool DoWriteHeader()
\r
102 bw.Write(0x314F5354);
\r
106 private bool DoWriteNodeNames()
\r
108 bw.Write(tsoref.nodes.Length);
\r
110 nodes = new Dictionary<string, TSONode>();
\r
112 foreach (TSONode i in tsoref.nodes)
\r
114 WriteString(bw, i.Name);
\r
115 nodes.Add(i.ShortName, i);
\r
121 private bool DoWriteNodeMatrices()
\r
123 bw.Write(tsoref.nodes.Length);
\r
125 foreach (TSONode i in tsoref.nodes)
\r
126 WriteMatrix(bw, i.Matrix);
\r
131 private bool DoWriteTextures()
\r
133 bw.Write(textures.Count);
\r
135 foreach (TextureInfo tex_info in textures.Values)
\r
137 string file = tex_info.file;
\r
138 string name = tex_info.name;
\r
140 string file_directory_name = Path.GetDirectoryName(file);
\r
141 string file_name = Path.GetFileName(file);
\r
143 WriteString(bw, name);
\r
144 WriteString(bw, "\"" + file_name + "\"");
\r
147 TSOTex tex = LoadTex(file);
\r
149 bw.Write(tex.Width);
\r
150 bw.Write(tex.Height);
\r
151 bw.Write(tex.Depth);
\r
152 bw.Write(tex.data, 0, tex.data.Length);
\r
154 ImportTextureInfo import_tex_info = new ImportTextureInfo(tex);
\r
155 ii.textures.Add(import_tex_info);
\r
157 // テクスチャが同じフォルダにない場合、コピーしておく
\r
158 if (file_directory_name != "" && file_directory_name.ToUpper() != dir.ToUpper())
\r
160 import_tex_info.File = Path.Combine(dir, file_name);
\r
161 File.Copy(file, import_tex_info.File, true);
\r
168 private bool DoWriteEffects()
\r
170 bw.Write(ii.effects.Count);
\r
172 foreach (ImportEffectInfo import_effect_info in ii.effects)
\r
174 string file = Path.Combine(dir, import_effect_info.Name);
\r
175 string[] code = File.ReadAllLines(file, Encoding.Default);
\r
177 WriteString(bw, import_effect_info.Name);
\r
178 bw.Write(code.Length);
\r
180 foreach (string line in code)
\r
181 WriteString(bw, line.Trim('\r', '\n'));
\r
187 private bool DoWriteMaterials()
\r
189 bw.Write(mqo.Materials.Count);
\r
191 foreach (MqoMaterial mat in mqo.Materials)
\r
193 MaterialInfo mat_info = materials[mat.name];
\r
194 string[] code = mat_info.GetCode();
\r
196 WriteString(bw, mat.name);
\r
197 WriteString(bw, "cgfxShader");
\r
198 bw.Write(code.Length);
\r
200 foreach (string line in code)
\r
201 WriteString(bw, line.Trim('\r', '\n'));
\r
203 ImportMaterialInfo import_mat_info = new ImportMaterialInfo();
\r
204 import_mat_info.Name = mat.name;
\r
205 import_mat_info.File = "cgfxShader";
\r
206 ii.materials.Add(import_mat_info);
\r
209 File.WriteAllLines(Path.Combine(dir, mat.name), code);
\r
215 private bool DoWriteMeshes()
\r
217 bw.Write(meshes.Count);
\r
219 foreach (TSOMesh mesh in meshes)
\r
221 WriteString(bw, mesh.Name);
\r
222 WriteMatrix(bw, mesh.Matrix);
\r
224 bw.Write(mesh.numsubs);
\r
226 foreach (TSOSubMesh sub in mesh.sub_meshes)
\r
228 bw.Write(sub.spec);
\r
229 bw.Write(sub.numbones);
\r
231 foreach (int i in sub.bones)
\r
234 bw.Write(sub.numvertices);
\r
236 foreach (Vertex v in sub.vertices)
\r
237 WriteVertex(bw, v);
\r
244 private bool DoOutput(string tsoout_file)
\r
246 //----- 出力処理 -----------------------------------------------
\r
247 ii.materials.Clear();
\r
248 ii.textures.Clear();
\r
250 using (FileStream fs = File.OpenWrite(tsoout_file))
\r
253 bw = new BinaryWriter(fs);
\r
256 DoWriteNodeNames();
\r
257 DoWriteNodeMatrices();
\r
260 DoWriteMaterials();
\r
261 DoGenerateMeshes();
\r
267 protected abstract bool DoGenerateMeshes();
\r
269 private bool DoSaveXml(string importinfo_file)
\r
272 ImportInfo.Save(importinfo_file, ii);
\r
276 protected virtual bool DoCleanup()
\r
288 System.GC.Collect();
\r
292 public void Generate(string mqo_file, string tsoref_file, string tsoout_file)
\r
294 string dir = Path.GetDirectoryName(mqo_file);
\r
295 string importinfo_file = Path.ChangeExtension(mqo_file, ".xml");
\r
299 if (!SetCurrentDirectory(dir)) return;
\r
300 if (!DoLoadMQO(mqo_file)) return;
\r
301 if (!DoLoadRefTSO(tsoref_file)) return;
\r
302 if (!DoLoadXml(importinfo_file)) return;
\r
303 if (!DoOutput(tsoout_file)) return;
\r
304 if (!DoSaveXml(importinfo_file)) return;
\r
312 protected abstract bool DoLoadRefTSO(string tsoref);
\r
315 public void WriteString(BinaryWriter bw, string s)
\r
317 byte[] b = Encoding.Default.GetBytes(s);
\r
322 public void WriteMatrix(BinaryWriter bw, Matrix44 m)
\r
324 bw.Write(m.M11); bw.Write(m.M12); bw.Write(m.M13); bw.Write(m.M14);
\r
325 bw.Write(m.M21); bw.Write(m.M22); bw.Write(m.M23); bw.Write(m.M24);
\r
326 bw.Write(m.M31); bw.Write(m.M32); bw.Write(m.M33); bw.Write(m.M34);
\r
327 bw.Write(m.M41); bw.Write(m.M42); bw.Write(m.M43); bw.Write(m.M44);
\r
330 public unsafe void WriteVertex(BinaryWriter bw, Vertex v)
\r
333 byte* idx = (byte*)(&idx0);
\r
334 List<int> idxs = new List<int>(4);
\r
335 List<float> wgts = new List<float>(4);
\r
337 if (v.Wgt.x > 0) { idxs.Add(idx[0]); wgts.Add(v.Wgt.x); }
\r
338 if (v.Wgt.y > 0) { idxs.Add(idx[1]); wgts.Add(v.Wgt.y); }
\r
339 if (v.Wgt.z > 0) { idxs.Add(idx[2]); wgts.Add(v.Wgt.z); }
\r
340 if (v.Wgt.w > 0) { idxs.Add(idx[3]); wgts.Add(v.Wgt.w); }
\r
342 bw.Write(v.Pos.X); bw.Write(v.Pos.Y); bw.Write(v.Pos.Z);
\r
343 bw.Write(v.Nrm.X); bw.Write(v.Nrm.Y); bw.Write(v.Nrm.Z);
\r
344 bw.Write(v.Tex.X); bw.Write(v.Tex.Y);
\r
346 bw.Write(wgts.Count);
\r
348 for (int i = 0, n = idxs.Count; i < n; ++i)
\r
356 public TSOTex LoadTex(string file)
\r
358 string ext = Path.GetExtension(file).ToUpper();
\r
363 case ".TGA": tex = LoadTarga(file); break;
\r
364 case ".BMP": tex = LoadBitmap(file); break;
\r
365 default: throw new Exception("Unsupported texture file: " + file);
\r
368 for (int i = 0, n = tex.data.Length; i < n; i += tex.Depth)
\r
370 byte b = tex.data[i + 0];
\r
371 tex.data[i + 0] = tex.data[i + 2];
\r
372 tex.data[i + 2] = b;
\r
378 public unsafe TSOTex LoadTarga(string file)
\r
380 using (FileStream fs = File.OpenRead(file))
\r
382 BinaryReader br = new BinaryReader(fs);
\r
383 TARGA_HEADER header;
\r
385 Marshal.Copy(br.ReadBytes(sizeof(TARGA_HEADER)), 0, (IntPtr)(&header), sizeof(TARGA_HEADER));
\r
387 if (header.imagetype != 0x02) throw new Exception("Invalid imagetype: " + file);
\r
388 if (header.depth != 24
\r
389 && header.depth != 32) throw new Exception("Invalid depth: " + file);
\r
391 TSOTex tex = new TSOTex();
\r
392 tex.depth = header.depth / 8;
\r
393 tex.width = header.width;
\r
394 tex.height = header.height;
\r
396 tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);
\r
402 public unsafe TSOTex LoadBitmap(string file)
\r
404 using (FileStream fs = File.OpenRead(file))
\r
406 BinaryReader br = new BinaryReader(fs);
\r
407 BITMAPFILEHEADER bfh;
\r
408 BITMAPINFOHEADER bih;
\r
410 Marshal.Copy(br.ReadBytes(sizeof(BITMAPFILEHEADER)), 0, (IntPtr)(&bfh), sizeof(BITMAPFILEHEADER));
\r
411 Marshal.Copy(br.ReadBytes(sizeof(BITMAPINFOHEADER)), 0, (IntPtr)(&bih), sizeof(BITMAPINFOHEADER));
\r
413 if (bfh.bfType != 0x4D42) throw new Exception("Invalid imagetype: " + file);
\r
414 if (bih.biBitCount != 24
\r
415 && bih.biBitCount != 32) throw new Exception("Invalid depth: " + file);
\r
417 TSOTex tex = new TSOTex();
\r
418 tex.depth = bih.biBitCount / 8;
\r
419 tex.width = bih.biWidth;
\r
420 tex.height = bih.biHeight;
\r
422 tex.data = br.ReadBytes(tex.width * tex.height * tex.depth);
\r
430 public class TSOGeneratorOneBone : TSOGenerator
\r
432 public Dictionary<string, string> ObjectBoneNames = new Dictionary<string, string>();
\r
434 public TSOGeneratorOneBone(TSOGeneratorConfig config)
\r
439 protected override bool DoLoadRefTSO(string tsoref_file)
\r
442 tsoref = LoadTSO(tsoref_file);
\r
446 protected override bool DoGenerateMeshes()
\r
448 meshes = new List<TSOMesh>();
\r
450 foreach (MqoObject obj in mqo.Objects)
\r
452 if (obj.name.ToLower() == "bone")
\r
455 Console.WriteLine("object:" + obj.name);
\r
458 Point3[] normal = new Point3[obj.vertices.Count];
\r
460 foreach (MqoFace face in obj.faces)
\r
462 Point3 v1 = Point3.Normalize(obj.vertices[face.b] - obj.vertices[face.a]);
\r
463 Point3 v2 = Point3.Normalize(obj.vertices[face.c] - obj.vertices[face.b]);
\r
464 Point3 n = Point3.Normalize(Point3.Cross(v1, v2));
\r
465 normal[face.a] -= n;
\r
466 normal[face.b] -= n;
\r
467 normal[face.c] -= n;
\r
470 for (int i = 0; i < normal.Length; ++i)
\r
471 normal[i] = Point3.Normalize(normal[i]);
\r
474 uint idx = 0x00000000;
\r
475 Point4 wgt = new Point4(1, 0, 0, 0);
\r
476 int[] bones = new int[1];
\r
480 bone = ObjectBoneNames[obj.name];
\r
482 catch (KeyNotFoundException)
\r
484 throw new KeyNotFoundException(string.Format("ボーン指定に誤りがあります。オブジェクト {0} にボーンを割り当てる必要があります。", obj.name));
\r
486 bones[0] = nodes[bone].ID;
\r
489 List<ushort> indices = new List<ushort>();
\r
490 VertexHeap<Vertex> vh = new VertexHeap<Vertex>();
\r
491 List<TSOSubMesh> subs = new List<TSOSubMesh>();
\r
493 Console.WriteLine(" vertices bone_indices");
\r
494 Console.WriteLine(" -------- ------------");
\r
496 for (int mtl = 0; mtl < materials.Count; ++mtl)
\r
500 foreach (MqoFace face in obj.faces)
\r
502 if (face.mtl != mtl)
\r
505 Vertex va = new Vertex(obj.vertices[face.a], wgt, idx, normal[face.a], new Point2(face.ta.x, 1 - face.ta.y));
\r
506 Vertex vb = new Vertex(obj.vertices[face.b], wgt, idx, normal[face.b], new Point2(face.tb.x, 1 - face.tb.y));
\r
507 Vertex vc = new Vertex(obj.vertices[face.c], wgt, idx, normal[face.c], new Point2(face.tc.x, 1 - face.tc.y));
\r
509 indices.Add(vh.Add(va));
\r
510 indices.Add(vh.Add(vc));
\r
511 indices.Add(vh.Add(vb));
\r
514 if (indices.Count == 0)
\r
518 ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());
\r
521 Vertex[] verts = vh.verts.ToArray();
\r
522 TSOSubMesh sub = new TSOSubMesh();
\r
524 sub.numbones = bones.Length;
\r
526 sub.numvertices = nidx.Length;
\r
527 sub.vertices = new Vertex[nidx.Length];
\r
529 for (int i = 0; i < nidx.Length; ++i)
\r
530 sub.vertices[i] = verts[nidx[i]];
\r
532 Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);
\r
538 TSOMesh mesh = new TSOMesh();
\r
539 mesh.name = obj.name;
\r
540 mesh.numsubs = subs.Count;
\r
541 mesh.sub_meshes = subs.ToArray();
\r
542 mesh.matrix = Matrix44.Identity;
\r
552 public unsafe class TSOGeneratorRefBone : TSOGenerator
\r
554 private List<Vertex> vlst;
\r
555 private PointCluster pc;
\r
557 public TSOGeneratorRefBone(TSOGeneratorConfig config)
\r
562 private void CreatePointCluster(TSOFile tso)
\r
564 vlst = new List<Vertex>();
\r
566 foreach (TSOMesh i in tso.meshes)
\r
567 foreach (TSOSubMesh j in i.sub_meshes)
\r
568 vlst.AddRange(j.vertices);
\r
570 pc = new PointCluster(vlst.Count);
\r
572 foreach (Vertex i in vlst)
\r
573 pc.Add(i.Pos.x, i.Pos.y, i.Pos.z);
\r
578 protected override bool DoLoadRefTSO(string tsoref_file)
\r
581 tsoref = LoadTSO(tsoref_file);
\r
583 foreach (TSOMesh mesh in tsoref.meshes)
\r
584 foreach (TSOSubMesh sub in mesh.sub_meshes)
\r
586 int[] bones = sub.bones;
\r
588 for (int k = 0, n = sub.numvertices; k < n; ++k)
\r
591 uint idx0 = sub.vertices[k].Idx;
\r
592 byte* idx = (byte*)(&idx0);
\r
593 idx[0] = (byte)bones[idx[0]];
\r
594 idx[1] = (byte)bones[idx[1]];
\r
595 idx[2] = (byte)bones[idx[2]];
\r
596 idx[3] = (byte)bones[idx[3]];
\r
597 sub.vertices[k].Idx = idx0;
\r
601 CreatePointCluster(tsoref);
\r
605 protected override bool DoGenerateMeshes()
\r
607 meshes = new List<TSOMesh>();
\r
609 foreach (MqoObject obj in mqo.Objects)
\r
611 if (obj.name.ToLower() == "bone")
\r
614 Console.WriteLine("object:" + obj.name);
\r
617 List<int> vref = new List<int>(obj.vertices.Count);
\r
619 foreach (Point3 j in obj.vertices)
\r
620 vref.Add(pc.NearestIndex(j.x, j.y, j.z));
\r
623 Point3[] normal = new Point3[obj.vertices.Count];
\r
625 foreach (MqoFace face in obj.faces)
\r
627 Point3 v1 = Point3.Normalize(obj.vertices[face.b] - obj.vertices[face.a]);
\r
628 Point3 v2 = Point3.Normalize(obj.vertices[face.c] - obj.vertices[face.b]);
\r
629 Point3 n = Point3.Normalize(Point3.Cross(v1, v2));
\r
631 normal[face.a] -= n;
\r
632 normal[face.b] -= n;
\r
633 normal[face.c] -= n;
\r
636 for (int j = 0; j < normal.Length; ++j)
\r
637 normal[j] = Point3.Normalize(normal[j]);
\r
640 List<int> faces1 = new List<int>();
\r
641 List<int> faces2 = new List<int>();
\r
642 //int[] bonecnv = new int[tsor.nodes.Length]; // ボーン変換テーブル
\r
643 VertexHeap<Vertex> vh = new VertexHeap<Vertex>();
\r
644 Vertex[] v = new Vertex[3];
\r
645 List<int> bones = new List<int>(16);
\r
646 List<ushort> indices = new List<ushort>();
\r
647 Dictionary<int, int> selected = new Dictionary<int, int>();
\r
648 Dictionary<int, int> work = new Dictionary<int, int>();
\r
649 List<TSOSubMesh> subs = new List<TSOSubMesh>();
\r
651 for (int j = 0, n = obj.faces.Count; j < n; ++j)
\r
655 Console.WriteLine(" vertices bone_indices");
\r
656 Console.WriteLine(" -------- ------------");
\r
658 while (faces1.Count > 0)
\r
660 int mtl = obj.faces[faces1[0]].mtl;
\r
666 foreach (int j in faces1)
\r
668 MqoFace f = obj.faces[j];
\r
676 v[0] = vlst[vref[f.a]];
\r
677 v[1] = vlst[vref[f.b]];
\r
678 v[2] = vlst[vref[f.c]];
\r
682 for (int k = 0; k < 3; ++k)
\r
685 UInt32 idx0 = vv.Idx;
\r
686 Point4 wgt0 = vv.Wgt;
\r
687 byte* idx = (byte*)(&idx0);
\r
688 float* wgt = (float*)(&wgt0);
\r
690 for (int l = 0; l < 4; ++l)
\r
692 if (wgt[l] <= float.Epsilon) continue;
\r
693 if (selected.ContainsKey(idx[l])) continue;
\r
695 if (!work.ContainsKey(idx[l]))
\r
696 work.Add(idx[l], 0);
\r
700 if (selected.Count + work.Count > 16)
\r
707 foreach (KeyValuePair<int, int> l in work)
\r
709 selected.Add(l.Key, selected.Count); // ボーンテーブルに追加
\r
714 Vertex va = new Vertex(obj.vertices[f.a], v[0].Wgt, v[0].Idx, normal[f.a], new Point2(f.ta.x, 1 - f.ta.y));
\r
715 Vertex vb = new Vertex(obj.vertices[f.b], v[1].Wgt, v[1].Idx, normal[f.b], new Point2(f.tb.x, 1 - f.tb.y));
\r
716 Vertex vc = new Vertex(obj.vertices[f.c], v[2].Wgt, v[2].Idx, normal[f.c], new Point2(f.tc.x, 1 - f.tc.y));
\r
718 indices.Add(vh.Add(va));
\r
719 indices.Add(vh.Add(vc));
\r
720 indices.Add(vh.Add(vb));
\r
724 ushort[] nidx = NvTriStrip.Optimize(indices.ToArray());
\r
727 Vertex[] verts = vh.verts.ToArray();
\r
729 for (int j = 0; j < verts.Length; ++j)
\r
731 uint idx0 = verts[j].Idx;
\r
732 byte* idx = (byte*)(&idx0);
\r
733 Point4 wgt0 = verts[j].Wgt;
\r
734 float* wgt = (float*)(&wgt0);
\r
736 for (int k = 0; k < 4; ++k)
\r
737 if (wgt[k] > float.Epsilon)
\r
738 idx[k] = (byte)selected[idx[k]];
\r
740 verts[j].Idx = idx0;
\r
744 TSOSubMesh sub = new TSOSubMesh();
\r
746 sub.numbones = bones.Count;
\r
747 sub.bones = bones.ToArray();
\r
748 sub.numvertices = nidx.Length;
\r
749 sub.vertices = new Vertex[nidx.Length];
\r
751 for (int j = 0; j < nidx.Length; ++j)
\r
752 sub.vertices[j] = verts[nidx[j]];
\r
754 Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length);
\r
759 List<int> t = faces1;
\r
766 TSOMesh mesh = new TSOMesh();
\r
767 mesh.name = obj.name;
\r
768 mesh.numsubs = subs.Count;
\r
769 mesh.sub_meshes = subs.ToArray();
\r
770 mesh.matrix = Matrix44.Identity;
\r
778 protected override bool DoCleanup()
\r
782 return base.DoCleanup();
\r
786 public class TextureInfo
\r
788 public string name;
\r
789 public string file;
\r
791 public TextureInfo(string name, string file)
\r
798 public class MaterialInfo
\r
804 //public Dictionary<string, string> parameters;
\r
806 public MaterialInfo(string path, MqoMaterial mat, ImportMaterialInfo import_mat_info)
\r
809 color_tex = mat.tex;
\r
811 if (import_mat_info != null)
\r
813 string file = Path.Combine(path, import_mat_info.Name);
\r
815 if (File.Exists(file))
\r
818 if (import_mat_info.ShadeTex != null)
\r
820 file = Path.Combine(path, import_mat_info.ShadeTex.File);
\r
822 if (File.Exists(file))
\r
832 return File.Exists(shader)
\r
833 && File.Exists(color_tex)
\r
834 && File.Exists(shade_tex);
\r
838 public string[] GetCode()
\r
840 TSOMaterialCode code = TSOMaterialCode.GenerateFromFile(shader);
\r
841 List<string> line = new List<string>();
\r
843 code.SetValue("ColorTex", Path.GetFileNameWithoutExtension(color_tex));
\r
844 code.SetValue("ShadeTex", Path.GetFileNameWithoutExtension(shade_tex));
\r
846 foreach (KeyValuePair<string, TSOParameter> i in code)
\r
847 line.Add(i.Value.ToString());
\r
849 return line.ToArray();
\r
852 public string Name { get { return name; } }
\r
854 [Editor(typeof(FileNameEditor), typeof(UITypeEditor))]
\r
855 [DisplayNameAttribute("シェーダー設定ファイル")]
\r
856 public string ShaderFile { get { return shader; } set { shader = value; } }
\r
858 [Editor(typeof(FileNameEditor), typeof(UITypeEditor))]
\r
859 [DisplayNameAttribute("テクスチャ:カラー")]
\r
860 public string ColorTexture { get { return color_tex; } set { color_tex = value; } }
\r
862 [Editor(typeof(FileNameEditor), typeof(UITypeEditor))]
\r
863 [DisplayNameAttribute("テクスチャ:シェーティング")]
\r
864 public string ShadeTexture { get { return shade_tex; } set { shade_tex = value; } }
\r