OSDN Git Service

SAX対応
[mikutoga/Pmd2XML.git] / src / main / java / jp / sfjp / mikutoga / pmd / model / xml / ExporterMaterial.java
1 /*
2  * material xml exporter
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.pmd.model.xml;
9
10 import java.awt.Color;
11 import java.io.IOException;
12 import java.util.List;
13 import jp.sfjp.mikutoga.corelib.I18nText;
14 import jp.sfjp.mikutoga.pmd.model.Material;
15 import jp.sfjp.mikutoga.pmd.model.PmdModel;
16 import jp.sfjp.mikutoga.pmd.model.ShadeInfo;
17 import jp.sfjp.mikutoga.pmd.model.ToonMap;
18 import jp.sfjp.mikutoga.xml.ProxyXmlExporter;
19
20 /**
21  * マテリアル設定のXMLエクスポーター。
22  */
23 class ExporterMaterial extends ProxyXmlExporter {
24
25     // sRGBカラー情報配列インデックス
26     private static final int IDX_RED   = 0;
27     private static final int IDX_GREEN = 1;
28     private static final int IDX_BLUE  = 2;
29     private static final int IDX_ALPHA = 3;
30
31
32     private final ExtraExporter exp;
33
34
35     /**
36      * コンストラクタ。
37      * @param delegate 委譲先
38      */
39     ExporterMaterial(PmdXmlExporter delegate) {
40         super(delegate);
41         this.exp = new ExtraExporter(delegate);
42         return;
43     }
44
45     /**
46      * マテリアル素材一覧を出力する。
47      * @param model モデルデータ
48      * @throws IOException 出力エラー
49      */
50     void putMaterialList(PmdModel model)
51             throws IOException{
52         ind().putSimpleSTag(PmdTag.MATERIAL_LIST.tag()).ln();
53
54         pushNest();
55         int ct = 0;
56         boolean dumped = false;
57         List<Material> materialList = model.getMaterialList();
58         for(Material material : materialList){
59             if( ! dumped ) ln();
60             putMaterial(material, ct++);
61             dumped = true;
62         }
63         popNest();
64
65         ind().putETag(PmdTag.MATERIAL_LIST.tag()).ln(2);
66
67         return;
68     }
69
70     /**
71      * マテリアル素材情報を出力する。
72      * @param material マテリアル素材
73      * @param no マテリアル通し番号
74      * @throws IOException 出力エラー
75      */
76     private void putMaterial(Material material, int no)
77             throws IOException{
78         I18nText name = material.getMaterialName();
79         String primary = name.getPrimaryText();
80         String local = name.getText();
81         if(local != null && local.length() > 0){
82             ind().putLineComment(local).ln();
83         }
84
85         ind().putOpenSTag(PmdTag.MATERIAL.tag()).sp();
86         if(primary != null && primary.length() > 0){
87             putAttr(PmdAttr.NAME.attr(), primary).sp();
88         }
89         String bool;
90         if(material.getEdgeAppearance()) bool = "true";
91         else                             bool = "false";
92         putAttr(PmdAttr.SHOW_EDGE.attr(), bool);
93         sp();
94         this.exp.putNumberedIdAttr(PmdAttr.SURFACE_GROUP_IDREF,
95                           ExtraExporter.PFX_SURFACEGROUP, no);
96         sp().putCloseSTag().ln();
97         pushNest();
98
99         this.exp.putI18nName(name);
100
101         putPhongShade(material);
102
103         ShadeInfo shade = material.getShadeInfo();
104
105         if(shade.isValidToonIndex()){
106             putToon(shade);
107         }
108
109         putShadeFile(shade);
110
111         popNest();
112         ind().putETag(PmdTag.MATERIAL.tag()).ln(2);
113
114         return;
115     }
116
117     /**
118      * フォンシェーディング情報を出力する。
119      * @param material マテリアル
120      * @throws IOException 出力エラー
121      */
122     private void putPhongShade(Material material)
123             throws IOException{
124         float[] rgba = null;
125
126         ind().putOpenSTag(PmdTag.DIFFUSE.tag()).sp();
127         Color diffuse = material.getDiffuseColor();
128         rgba = diffuse.getRGBComponents(rgba);
129         putTriColor(rgba);
130         putFloatAttr(PmdAttr.ALPHA.attr(), rgba[IDX_ALPHA]).sp();
131         putCloseEmpty().ln();
132
133         float shininess = material.getShininess();
134         ind().putOpenSTag(PmdTag.SPECULAR.tag()).sp();
135         Color specular = material.getSpecularColor();
136         rgba = specular.getRGBComponents(rgba);
137         putTriColor(rgba);
138         putFloatAttr(PmdAttr.SHININESS.attr(), shininess).sp();
139         putCloseEmpty().ln();
140
141         ind().putOpenSTag(PmdTag.AMBIENT.tag()).sp();
142         Color ambient = material.getAmbientColor();
143         rgba = ambient.getRGBComponents(rgba);
144         putTriColor(rgba);
145         putCloseEmpty().ln();
146
147         return;
148     }
149
150     /**
151      * 三原色属性を出力する。
152      * @param rgb カラー情報
153      * @throws IOException 出力エラー
154      */
155     private void putTriColor(float[] rgb)
156             throws IOException{
157         putFloatAttr(PmdAttr.R.attr(), rgb[IDX_RED]  ).sp();
158         putFloatAttr(PmdAttr.G.attr(), rgb[IDX_GREEN]).sp();
159         putFloatAttr(PmdAttr.B.attr(), rgb[IDX_BLUE] ).sp();
160
161         return;
162     }
163
164     /**
165      * マテリアルのトゥーン情報を出力する。
166      * @param shade シェーディング情報
167      * @throws IOException 出力エラー
168      */
169     private void putToon(ShadeInfo shade)
170             throws IOException{
171         ind().putOpenSTag(PmdTag.TOON.tag()).sp();
172
173         int toonIdx = shade.getToonIndex();
174         this.exp.putNumberedIdAttr(PmdAttr.TOONFILE_IDREF,
175                           ExtraExporter.PFX_TOONFILE, toonIdx);
176         sp();
177
178         putCloseEmpty();
179
180         String toonFileName = shade.getToonFileName();
181         if(toonFileName != null && toonFileName.length() > 0){
182             sp().putLineComment(toonFileName);
183         }
184         ln();
185
186         return;
187     }
188
189     /**
190      * シェーディングファイル情報を出力する。
191      * @param shade シェーディング情報
192      * @throws IOException 出力エラー
193      */
194     private void putShadeFile(ShadeInfo shade)
195             throws IOException{
196         String textureFileName   = shade.getTextureFileName();
197         String spheremapFileName = shade.getSpheremapFileName();
198
199         if(textureFileName != null && textureFileName.length() > 0){
200             ind().putOpenSTag(PmdTag.TEXTURE_FILE.tag()).sp();
201             putAttr(PmdAttr.WINFILE_NAME.attr(),
202                     textureFileName).sp();
203             putCloseEmpty().ln();
204         }
205
206         if(spheremapFileName != null && spheremapFileName.length() > 0){
207             ind().putOpenSTag(PmdTag.SPHEREMAP_FILE.tag()).sp();
208             putAttr(PmdAttr.WINFILE_NAME.attr(),
209                     spheremapFileName).sp();
210             putCloseEmpty().ln();
211         }
212
213         return;
214     }
215
216     /**
217      * トゥーンファイルマッピング情報を出力する。
218      * @param model モデルデータ
219      * @throws IOException 出力エラー
220      */
221     void putToonMap(PmdModel model)
222             throws IOException{
223         ind().putSimpleSTag(PmdTag.TOON_MAP.tag()).ln();
224         pushNest();
225
226         ToonMap map = model.getToonMap();
227         for(int index = 0; index < ToonMap.MAX_CUSTOM_TOON; index++){
228             ind();
229             putToonDef(map, index);
230             ln();
231         }
232
233         popNest();
234         ind().putETag(PmdTag.TOON_MAP.tag()).ln(2);
235         return;
236     }
237
238     /**
239      * 個別のトゥーンファイル情報を出力する。
240      * @param map トゥーンマップ
241      * @param index インデックス値
242      * @throws IOException 出力エラー
243      */
244     private void putToonDef(ToonMap map, int index)
245             throws IOException{
246         putOpenSTag(PmdTag.TOON_DEF.tag()).sp();
247         this.exp.putNumberedIdAttr(PmdAttr.TOONFILE_ID,
248                 ExtraExporter.PFX_TOONFILE, index);
249         sp();
250         putIntAttr(PmdAttr.INDEX.attr(), index).sp();
251         String toonFile = map.getIndexedToon(index);
252         putAttr(PmdAttr.WINFILE_NAME.attr(), toonFile).sp();
253         putCloseEmpty();
254         this.exp.putUnescapedComment(toonFile);
255         return;
256     }
257
258 }