OSDN Git Service

改行位置調整
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / pmd / xml / Xml2PmdLoader.java
1 /*\r
2  * xml loader\r
3  *\r
4  * License : The MIT License\r
5  * Copyright(c) 2010 MikuToga Partners\r
6  */\r
7 \r
8 package jp.sourceforge.mikutoga.pmd.xml;\r
9 \r
10 import java.awt.Color;\r
11 import java.io.IOException;\r
12 import java.util.ArrayList;\r
13 import java.util.HashMap;\r
14 import java.util.LinkedList;\r
15 import java.util.List;\r
16 import java.util.Map;\r
17 import javax.xml.parsers.DocumentBuilder;\r
18 import jp.sourceforge.mikutoga.corelib.I18nText;\r
19 import jp.sourceforge.mikutoga.corelib.ListUtil;\r
20 import jp.sourceforge.mikutoga.pmd.BoneGroup;\r
21 import jp.sourceforge.mikutoga.pmd.BoneInfo;\r
22 import jp.sourceforge.mikutoga.pmd.BoneType;\r
23 import jp.sourceforge.mikutoga.pmd.Deg3d;\r
24 import jp.sourceforge.mikutoga.pmd.DynamicsInfo;\r
25 import jp.sourceforge.mikutoga.pmd.IKChain;\r
26 import jp.sourceforge.mikutoga.pmd.JointInfo;\r
27 import jp.sourceforge.mikutoga.pmd.Material;\r
28 import jp.sourceforge.mikutoga.pmd.MorphPart;\r
29 import jp.sourceforge.mikutoga.pmd.MorphType;\r
30 import jp.sourceforge.mikutoga.pmd.MorphVertex;\r
31 import jp.sourceforge.mikutoga.pmd.PmdModel;\r
32 import jp.sourceforge.mikutoga.pmd.Pos2d;\r
33 import jp.sourceforge.mikutoga.pmd.Pos3d;\r
34 import jp.sourceforge.mikutoga.pmd.Rad3d;\r
35 import jp.sourceforge.mikutoga.pmd.RigidBehaviorType;\r
36 import jp.sourceforge.mikutoga.pmd.RigidGroup;\r
37 import jp.sourceforge.mikutoga.pmd.RigidInfo;\r
38 import jp.sourceforge.mikutoga.pmd.RigidShape;\r
39 import jp.sourceforge.mikutoga.pmd.RigidShapeType;\r
40 import jp.sourceforge.mikutoga.pmd.ShadeInfo;\r
41 import jp.sourceforge.mikutoga.pmd.Surface;\r
42 import jp.sourceforge.mikutoga.pmd.ToonMap;\r
43 import jp.sourceforge.mikutoga.pmd.TripletRange;\r
44 import jp.sourceforge.mikutoga.pmd.Vec3d;\r
45 import jp.sourceforge.mikutoga.pmd.Vertex;\r
46 import jp.sourceforge.mikutoga.xml.DomUtils;\r
47 import jp.sourceforge.mikutoga.xml.TogaXmlException;\r
48 import org.w3c.dom.Document;\r
49 import org.w3c.dom.Element;\r
50 import org.w3c.dom.Node;\r
51 import org.w3c.dom.NodeList;\r
52 import org.xml.sax.InputSource;\r
53 import org.xml.sax.SAXException;\r
54 \r
55 /**\r
56  * XML形式でのモデルファイルを読み込む。\r
57  */\r
58 public class Xml2PmdLoader {\r
59 \r
60     private final DocumentBuilder builder;\r
61 \r
62     private PmdModel model;\r
63 \r
64     private final Map<String, Integer> toonIdxMap =\r
65             new HashMap<String, Integer>();\r
66     private final Map<String, BoneInfo> boneMap =\r
67             new HashMap<String, BoneInfo>();\r
68     private final Map<String, Vertex> vertexMap =\r
69             new HashMap<String, Vertex>();\r
70     private final Map<String, List<Surface>> surfaceGroupMap =\r
71             new HashMap<String, List<Surface>>();\r
72     private final Map<String, RigidInfo> rigidMap =\r
73             new HashMap<String, RigidInfo>();\r
74     private final Map<String, RigidGroup> rigidGroupMap =\r
75             new HashMap<String, RigidGroup>();\r
76 \r
77 \r
78     /**\r
79      * コンストラクタ。\r
80      * @param builder ビルダ\r
81      */\r
82     public Xml2PmdLoader(DocumentBuilder builder){\r
83         super();\r
84         this.builder = builder;\r
85         return;\r
86     }\r
87 \r
88     /**\r
89      * 要素からxsd:string型属性値を読み取る。\r
90      * @param elem 要素\r
91      * @param attrName 属性名\r
92      * @return 文字列\r
93      * @throws TogaXmlException 属性値が見つからなかった。\r
94      */\r
95     private static String getStringAttr(Element elem, String attrName)\r
96             throws TogaXmlException{\r
97         return DomUtils.getStringAttr(elem, attrName);\r
98     }\r
99 \r
100     /**\r
101      * 要素からxsd:boolean型属性値を読み取る。\r
102      * @param elem 要素\r
103      * @param attrName 属性名\r
104      * @return 真ならtrue\r
105      * @throws TogaXmlException 属性値が見つからなかった。\r
106      */\r
107     private static boolean getBooleanAttr(Element elem, String attrName)\r
108             throws TogaXmlException{\r
109         return DomUtils.getBooleanAttr(elem, attrName);\r
110     }\r
111 \r
112     /**\r
113      * 要素からxsd:integer型属性値を読み取る。\r
114      * @param elem 要素\r
115      * @param attrName 属性名\r
116      * @return int値\r
117      * @throws TogaXmlException 属性値が見つからなかった。\r
118      */\r
119     private static int getIntegerAttr(Element elem, String attrName)\r
120             throws TogaXmlException{\r
121         return DomUtils.getIntegerAttr(elem, attrName);\r
122     }\r
123 \r
124     /**\r
125      * 要素からxsd:float型属性値を読み取る。\r
126      * @param elem 要素\r
127      * @param attrName 属性名\r
128      * @return float値\r
129      * @throws TogaXmlException 属性値が見つからなかった。\r
130      */\r
131     private static float getFloatAttr(Element elem, String attrName)\r
132             throws TogaXmlException{\r
133         return DomUtils.getFloatAttr(elem, attrName);\r
134     }\r
135 \r
136     /**\r
137      * 要素から日本語Windows用ファイル名を属性値として読み取る。\r
138      * 念のため文字U+00A5は文字U-005Cに変換される。\r
139      * @param elem 要素\r
140      * @param attrName 属性名\r
141      * @return ファイル名\r
142      * @throws TogaXmlException 属性値が見つからなかった。\r
143      */\r
144     private static String getSjisFileNameAttr(Element elem, String attrName)\r
145             throws TogaXmlException{\r
146         return DomUtils.getSjisFileNameAttr(elem, attrName);\r
147     }\r
148 \r
149     /**\r
150      * 指定された名前の子要素を1つだけ返す。\r
151      * @param parent 親要素\r
152      * @param tagName 子要素名\r
153      * @return 子要素\r
154      * @throws TogaXmlException 1つも見つからなかった\r
155      */\r
156     private static Element getChild(Element parent, String tagName)\r
157             throws TogaXmlException{\r
158         return DomUtils.getChild(parent, tagName);\r
159     }\r
160 \r
161     /**\r
162      * 親要素が指定された名前の子要素を持つか判定する。\r
163      * @param parent 親要素\r
164      * @param tagName 子要素名\r
165      * @return 指定名の子要素が存在すればtrue\r
166      */\r
167     private static boolean hasChild(Element parent, String tagName){\r
168         return DomUtils.hasChild(parent, tagName);\r
169     }\r
170 \r
171     /**\r
172      * 指定された名前の子要素のforeachを返す。\r
173      * @param parent 親要素\r
174      * @param childTag 子要素名\r
175      * @return 子要素のforeach\r
176      */\r
177     private static Iterable<Element> eachChild(Element parent,\r
178                                                     String childTag){\r
179         return DomUtils.getEachChild(parent, childTag);\r
180     }\r
181 \r
182     /**\r
183      * グローバル名を取得する。\r
184      * 元要素のname属性及びi18nNameタグを持つ子要素が検索対象\r
185      * @param parent 元要素\r
186      * @return グローバル名。なければnull\r
187      */\r
188     private static String getGlobalName(Element parent){\r
189         NodeList nodeList = parent.getElementsByTagName("i18nName");\r
190         int length = nodeList.getLength();\r
191         for(int idx = 0; idx < length; idx++){\r
192             Node i18nNameNode = nodeList.item(idx);\r
193             Element i18nNameElem = (Element)i18nNameNode;\r
194             String lang = i18nNameElem.getAttribute("lang");\r
195             if(lang == null || lang.length() <= 0) continue;\r
196             if(lang.equals("en")){\r
197                 String name = i18nNameElem.getAttribute("name");\r
198                 return name;\r
199             }\r
200         }\r
201         return null;\r
202     }\r
203 \r
204     /**\r
205      * brタグで区切られた文字列内容(Mixed content)を改行付き文字列に変換する。\r
206      * brタグはその出現回数だけ\nに変換される。\r
207      * 生文字列コンテンツ中の\n,\rは削除される。\r
208      * 改行文字以外のホワイトスペースは保持される。\r
209      * @param parent br要素及び文字列コンテンツを含む要素\r
210      * @return 変換された文字列\r
211      */\r
212     private static String getBRedContent(Element parent){\r
213         StringBuilder result = new StringBuilder();\r
214 \r
215         for(Node node = parent.getFirstChild();\r
216             node != null;\r
217             node = node.getNextSibling() ){\r
218 \r
219             switch(node.getNodeType()){\r
220             case Node.ELEMENT_NODE:\r
221                 Element elem = (Element) node;\r
222                 if("br".equals(elem.getTagName())){\r
223                     result.append('\n');\r
224                 }\r
225                 break;\r
226             case Node.TEXT_NODE:\r
227             case Node.CDATA_SECTION_NODE:\r
228                 String content = node.getTextContent();\r
229                 content = content.replace("\r", "");\r
230                 content = content.replace("\n", "");\r
231                 result.append(content);\r
232                 break;\r
233             default:\r
234                 break;\r
235             }\r
236         }\r
237 \r
238         return result.toString();\r
239     }\r
240 \r
241     /**\r
242      * 多言語名を取得する。\r
243      * @param baseElement 元要素\r
244      * @param text 多言語名\r
245      * @throws TogaXmlException あるべき属性が存在しない。\r
246      */\r
247     private static void buildI18nName(Element baseElement, I18nText text)\r
248             throws TogaXmlException{\r
249         String primaryText;\r
250         primaryText = getStringAttr(baseElement, "name");\r
251         text.setPrimaryText(primaryText);\r
252 \r
253         for(Element i18nNameElem : eachChild(baseElement, "i18nName")){\r
254             String lang = getStringAttr(i18nNameElem, "lang");\r
255             String name = getStringAttr(i18nNameElem, "name");\r
256             if("en".equals(lang)){\r
257                 text.setGlobalText(name);\r
258             }else{\r
259                 text.setText(lang, text);\r
260             }\r
261         }\r
262 \r
263         return;\r
264     }\r
265 \r
266     /**\r
267      * XMLのパースを開始する。\r
268      * @param source XML入力\r
269      * @return モデルデータ\r
270      * @throws SAXException 構文エラー\r
271      * @throws IOException 入力エラー\r
272      * @throws TogaXmlException 構文エラー\r
273      */\r
274     public PmdModel parse(InputSource source)\r
275             throws SAXException, IOException, TogaXmlException{\r
276         Document document = this.builder.parse(source);\r
277 \r
278         this.model = new PmdModel();\r
279 \r
280         Element pmdModelElem = document.getDocumentElement();\r
281 \r
282         buildBasicInfo(pmdModelElem);\r
283 \r
284         buildBoneList(pmdModelElem);\r
285         buildVertexList(pmdModelElem);\r
286         buildSurfaceList(pmdModelElem);\r
287 \r
288         buildToonMap(pmdModelElem);\r
289         buildMaterialList(pmdModelElem);\r
290         buildIkChainList(pmdModelElem);\r
291         buildMorphList(pmdModelElem);\r
292         buildBoneGroupList(pmdModelElem);\r
293 \r
294         buildRigidList(pmdModelElem);\r
295         buildRigidGroupList(pmdModelElem);\r
296         resolveThroughRigidGroup(pmdModelElem);\r
297 \r
298         buildJointList(pmdModelElem);\r
299 \r
300         return this.model;\r
301     }\r
302 \r
303     private void buildBasicInfo(Element pmdModelElem)\r
304             throws TogaXmlException{\r
305         String primaryName = getStringAttr(pmdModelElem, "name");\r
306         String globalName = getGlobalName(pmdModelElem);\r
307 \r
308         I18nText modelName = this.model.getModelName();\r
309         modelName.setPrimaryText(primaryName);\r
310         modelName.setGlobalText(globalName);\r
311 \r
312         String primaryDescription = null;\r
313         String globalDescription = null;\r
314         for(Element descriptionElem :\r
315             eachChild(pmdModelElem, "description")){\r
316             String descriptionText = getBRedContent(descriptionElem);\r
317             if( ! descriptionElem.hasAttribute("lang") ){\r
318                 primaryDescription = descriptionText;\r
319             }else{\r
320                 String lang = getStringAttr(descriptionElem, "lang");\r
321                 if(lang.equals("ja")){\r
322                     primaryDescription = descriptionText;\r
323                 }else if(lang.equals("en")){\r
324                     globalDescription = descriptionText;\r
325                 }\r
326             }\r
327         }\r
328 \r
329         I18nText description = this.model.getDescription();\r
330         description.setPrimaryText(primaryDescription);\r
331         description.setGlobalText(globalDescription);\r
332 \r
333         return;\r
334     }\r
335 \r
336     private void buildToonMap(Element pmdModelElem)\r
337             throws TogaXmlException{\r
338         ToonMap toonMap = this.model.getToonMap();\r
339 \r
340         Element toonMapElem = getChild(pmdModelElem, "toonMap");\r
341 \r
342         for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){\r
343             String toonFileId = getStringAttr(toonDefElem, "toonFileId");\r
344             int toonIndex = getIntegerAttr(toonDefElem, "index");\r
345             String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");\r
346 \r
347             toonMap.setIndexedToon(toonIndex, toonFile);\r
348             this.toonIdxMap.put(toonFileId, toonIndex);\r
349         }\r
350 \r
351         return;\r
352     }\r
353 \r
354     private void buildBoneList(Element pmdModelElem)\r
355             throws TogaXmlException{\r
356         Element boneListElem = getChild(pmdModelElem, "boneList");\r
357 \r
358         List<BoneInfo> boneList = this.model.getBoneList();\r
359 \r
360         for(Element boneElem : eachChild(boneListElem, "bone")){\r
361             BoneInfo boneInfo = new BoneInfo();\r
362             boneList.add(boneInfo);\r
363 \r
364             I18nText boneName = boneInfo.getBoneName();\r
365             buildI18nName(boneElem, boneName);\r
366 \r
367             String boneType = getStringAttr(boneElem, "type");\r
368             BoneType type = BoneType.valueOf(boneType);\r
369             boneInfo.setBoneType(type);\r
370 \r
371             String boneId = getStringAttr(boneElem, "boneId");\r
372             this.boneMap.put(boneId, boneInfo);\r
373 \r
374             Element positionElem = getChild(boneElem, "position");\r
375             float xPos = getFloatAttr(positionElem, "x");\r
376             float yPos = getFloatAttr(positionElem, "y");\r
377             float zPos = getFloatAttr(positionElem, "z");\r
378             Pos3d position = boneInfo.getPosition();\r
379             position.setXPos(xPos);\r
380             position.setYPos(yPos);\r
381             position.setZPos(zPos);\r
382         }\r
383 \r
384         ListUtil.assignIndexedSerial(boneList);\r
385 \r
386         int serial = 0;\r
387         for(Element boneElem : eachChild(boneListElem, "bone")){\r
388             BoneInfo boneInfo = boneList.get(serial++);\r
389 \r
390             if(hasChild(boneElem, "ikBone")){\r
391                 Element ikBoneElem = getChild(boneElem, "ikBone");\r
392                 String ikBoneId = getStringAttr(ikBoneElem, "boneIdRef");\r
393                 BoneInfo ikBone = this.boneMap.get(ikBoneId);\r
394                 boneInfo.setIKBone(ikBone);\r
395             }else if(hasChild(boneElem, "rotationRatio")){\r
396                 Element ikBoneElem = getChild(boneElem, "rotationRatio");\r
397                 int ratio = getIntegerAttr(ikBoneElem, "ratio");\r
398                 boneInfo.setRotationRatio(ratio);\r
399             }\r
400 \r
401             Element boneChainElem = getChild(boneElem, "boneChain");\r
402             if(boneChainElem.hasAttribute("prevBoneIdRef")){\r
403                 String prevId = getStringAttr(boneChainElem, "prevBoneIdRef");\r
404                 BoneInfo prevBone = this.boneMap.get(prevId);\r
405                 boneInfo.setPrevBone(prevBone);\r
406             }\r
407             if(boneChainElem.hasAttribute("nextBoneIdRef")){\r
408                 String nextId = getStringAttr(boneChainElem, "nextBoneIdRef");\r
409                 BoneInfo nextBone = this.boneMap.get(nextId);\r
410                 boneInfo.setNextBone(nextBone);\r
411             }\r
412         }\r
413 \r
414         return;\r
415     }\r
416 \r
417     private void buildVertexList(Element pmdModelElem)\r
418             throws TogaXmlException{\r
419         Element vertexListElem = getChild(pmdModelElem, "vertexList");\r
420 \r
421         List<Vertex> vertexList = this.model.getVertexList();\r
422 \r
423         for(Element vertexElem : eachChild(vertexListElem, "vertex")){\r
424             Vertex vertex = new Vertex();\r
425             vertexList.add(vertex);\r
426 \r
427             String vertexId = getStringAttr(vertexElem, "vtxId");\r
428             this.vertexMap.put(vertexId, vertex);\r
429 \r
430             boolean showEdge = getBooleanAttr(vertexElem, "showEdge");\r
431             vertex.setEdgeAppearance(showEdge);\r
432 \r
433             float xVal;\r
434             float yVal;\r
435             float zVal;\r
436 \r
437             Element positionElem = getChild(vertexElem, "position");\r
438             xVal = getFloatAttr(positionElem, "x");\r
439             yVal = getFloatAttr(positionElem, "y");\r
440             zVal = getFloatAttr(positionElem, "z");\r
441             Pos3d position = vertex.getPosition();\r
442             position.setXPos(xVal);\r
443             position.setYPos(yVal);\r
444             position.setZPos(zVal);\r
445 \r
446             Element normalElem = getChild(vertexElem, "normal");\r
447             xVal = getFloatAttr(normalElem, "x");\r
448             yVal = getFloatAttr(normalElem, "y");\r
449             zVal = getFloatAttr(normalElem, "z");\r
450             Vec3d normal = vertex.getNormal();\r
451             normal.setXVal(xVal);\r
452             normal.setYVal(yVal);\r
453             normal.setZVal(zVal);\r
454 \r
455             Element uvElem = getChild(vertexElem, "uvMap");\r
456             float uVal = getFloatAttr(uvElem, "u");\r
457             float vVal = getFloatAttr(uvElem, "v");\r
458             Pos2d uv = vertex.getUVPosition();\r
459             uv.setXPos(uVal);\r
460             uv.setYPos(vVal);\r
461 \r
462             Element skinningElem = getChild(vertexElem, "skinning");\r
463             String boneId1 = getStringAttr(skinningElem, "boneIdRef1");\r
464             String boneId2 = getStringAttr(skinningElem, "boneIdRef2");\r
465             int weight = getIntegerAttr(skinningElem, "weightBalance");\r
466             BoneInfo boneA = this.boneMap.get(boneId1);\r
467             BoneInfo boneB = this.boneMap.get(boneId2);\r
468             vertex.setBonePair(boneA, boneB);\r
469             vertex.setWeightA(weight);\r
470         }\r
471 \r
472         ListUtil.assignIndexedSerial(vertexList);\r
473 \r
474         return;\r
475     }\r
476 \r
477     private void buildSurfaceList(Element pmdModelElem)\r
478             throws TogaXmlException{\r
479         Element surfaceGroupListElem =\r
480                 getChild(pmdModelElem, "surfaceGroupList");\r
481 \r
482         for(Element surfaceGroupElem :\r
483             eachChild(surfaceGroupListElem, "surfaceGroup") ){\r
484 \r
485             String groupId =\r
486                     getStringAttr(surfaceGroupElem, "surfaceGroupId");\r
487             List<Surface> surfaceList = buildSurface(surfaceGroupElem);\r
488 \r
489             this.surfaceGroupMap.put(groupId, surfaceList);\r
490         }\r
491     }\r
492 \r
493     private List<Surface> buildSurface(Element surfaceGroupElem)\r
494             throws TogaXmlException{\r
495         List<Surface> result = new ArrayList<Surface>();\r
496 \r
497         for(Element surfaceElem : eachChild(surfaceGroupElem, "surface")){\r
498             Surface surface = new Surface();\r
499             result.add(surface);\r
500 \r
501             String id1 = getStringAttr(surfaceElem, "vtxIdRef1");\r
502             String id2 = getStringAttr(surfaceElem, "vtxIdRef2");\r
503             String id3 = getStringAttr(surfaceElem, "vtxIdRef3");\r
504 \r
505             Vertex vertex1 = this.vertexMap.get(id1);\r
506             Vertex vertex2 = this.vertexMap.get(id2);\r
507             Vertex vertex3 = this.vertexMap.get(id3);\r
508 \r
509             surface.setTriangle(vertex1, vertex2, vertex3);\r
510         }\r
511 \r
512         return result;\r
513     }\r
514 \r
515     private void buildMaterialList(Element pmdModelElem)\r
516             throws TogaXmlException{\r
517         Element materialListElem =\r
518                 getChild(pmdModelElem, "materialList");\r
519 \r
520         List<Surface> surfaceList = this.model.getSurfaceList();\r
521         List<Material> materialList = this.model.getMaterialList();\r
522 \r
523         for(Element materialElem : eachChild(materialListElem, "material")){\r
524             Material material = new Material();\r
525             materialList.add(material);\r
526 \r
527             material.getShadeInfo().setToonMap(this.model.getToonMap());\r
528 \r
529             String surfaceGroupId =\r
530                     getStringAttr(materialElem, "surfaceGroupIdRef");\r
531             List<Surface> surfaceGroup =\r
532                     this.surfaceGroupMap.get(surfaceGroupId);\r
533             surfaceList.addAll(surfaceGroup);\r
534             material.getSurfaceList().addAll(surfaceGroup);\r
535 \r
536             boolean hasEdge = getBooleanAttr(materialElem, "showEdge");\r
537             material.setEdgeAppearance(hasEdge);\r
538 \r
539             ShadeInfo shadeInfo = material.getShadeInfo();\r
540 \r
541             int toonIdx;\r
542             if(hasChild(materialElem, "toon")){\r
543                 Element toonElem = getChild(materialElem, "toon");\r
544                 String toonId = getStringAttr(toonElem, "toonFileIdRef");\r
545                 toonIdx = this.toonIdxMap.get(toonId);\r
546             }else{\r
547                 toonIdx = 255;\r
548             }\r
549             shadeInfo.setToonIndex(toonIdx);\r
550 \r
551             if(hasChild(materialElem, "textureFile")){\r
552                 Element textureFileElem =\r
553                         getChild(materialElem, "textureFile");\r
554                 String textureFile =\r
555                         getSjisFileNameAttr(textureFileElem, "winFileName");\r
556                 shadeInfo.setTextureFileName(textureFile);\r
557             }\r
558 \r
559             if(hasChild(materialElem, "spheremapFile")){\r
560                 Element spheremapFileElem =\r
561                         getChild(materialElem, "spheremapFile");\r
562                 String spheremapFile =\r
563                         getSjisFileNameAttr(spheremapFileElem, "winFileName");\r
564                 shadeInfo.setSpheremapFileName(spheremapFile);\r
565             }\r
566 \r
567             float red;\r
568             float green;\r
569             float blue;\r
570 \r
571             Element diffuseElem = getChild(materialElem, "diffuse");\r
572             red   = getFloatAttr(diffuseElem, "r");\r
573             green = getFloatAttr(diffuseElem, "g");\r
574             blue  = getFloatAttr(diffuseElem, "b");\r
575             float alpha = getFloatAttr(diffuseElem, "alpha");\r
576             Color diffuse = new Color(red, green, blue, alpha);\r
577             material.setDiffuseColor(diffuse);\r
578 \r
579             Element specularElem = getChild(materialElem, "specular");\r
580             red   = getFloatAttr(specularElem, "r");\r
581             green = getFloatAttr(specularElem, "g");\r
582             blue  = getFloatAttr(specularElem, "b");\r
583             float shininess = getFloatAttr(specularElem, "shininess");\r
584             Color specular = new Color(red, green, blue);\r
585             material.setSpecularColor(specular);\r
586             material.setShininess(shininess);\r
587 \r
588             Element ambientElem = getChild(materialElem, "ambient");\r
589             red   = getFloatAttr(ambientElem, "r");\r
590             green = getFloatAttr(ambientElem, "g");\r
591             blue  = getFloatAttr(ambientElem, "b");\r
592             Color ambient = new Color(red, green, blue);\r
593             material.setAmbientColor(ambient);\r
594         }\r
595 \r
596         return;\r
597     }\r
598 \r
599     private void buildIkChainList(Element pmdModelElem)\r
600             throws TogaXmlException{\r
601         Element ikChainListElem =\r
602                 getChild(pmdModelElem, "ikChainList");\r
603 \r
604         List<IKChain> ikChainList = this.model.getIKChainList();\r
605 \r
606         for(Element ikChainElem : eachChild(ikChainListElem, "ikChain")){\r
607             IKChain ikChain = new IKChain();\r
608             ikChainList.add(ikChain);\r
609 \r
610             String ikBoneIdRef = getStringAttr(ikChainElem, "ikBoneIdRef");\r
611             int rucursiveDepth =\r
612                     getIntegerAttr(ikChainElem, "recursiveDepth");\r
613             float weight = getFloatAttr(ikChainElem, "weight");\r
614 \r
615             BoneInfo ikBone = this.boneMap.get(ikBoneIdRef);\r
616             ikChain.setIkBone(ikBone);\r
617             ikChain.setIKDepth(rucursiveDepth);\r
618             ikChain.setIKWeight(weight);\r
619 \r
620             List<BoneInfo> chainList = ikChain.getChainedBoneList();\r
621 \r
622             for(Element orderElem : eachChild(ikChainElem, "chainOrder")){\r
623                 String boneIdRef = getStringAttr(orderElem, "boneIdRef");\r
624                 BoneInfo chaindBone = this.boneMap.get(boneIdRef);\r
625                 chainList.add(chaindBone);\r
626             }\r
627         }\r
628 \r
629         return;\r
630     }\r
631 \r
632     private void buildMorphList(Element pmdModelElem)\r
633             throws TogaXmlException{\r
634         Element morphListElem =\r
635                 getChild(pmdModelElem, "morphList");\r
636 \r
637         Map<MorphType, List<MorphPart>> morphMap = this.model.getMorphMap();\r
638 \r
639         for(Element morphElem : eachChild(morphListElem, "morph")){\r
640             MorphPart morphPart = new MorphPart();\r
641 \r
642             I18nText name = morphPart.getMorphName();\r
643             buildI18nName(morphElem, name);\r
644 \r
645             String type = getStringAttr(morphElem, "type");\r
646             MorphType morphType = MorphType.valueOf(type);\r
647             morphPart.setMorphType(morphType);\r
648 \r
649             List<MorphVertex> morphVertexList =\r
650                     morphPart.getMorphVertexList();\r
651 \r
652             for(Element morphVertexElem\r
653                     : eachChild(morphElem, "morphVertex")){\r
654                 String vtxIdRef = getStringAttr(morphVertexElem, "vtxIdRef");\r
655                 Vertex baseVertex = this.vertexMap.get(vtxIdRef);\r
656                 float xOff = getFloatAttr(morphVertexElem, "xOff");\r
657                 float yOff = getFloatAttr(morphVertexElem, "yOff");\r
658                 float zOff = getFloatAttr(morphVertexElem, "zOff");\r
659 \r
660                 MorphVertex morphVertex = new MorphVertex();\r
661                 morphVertex.setBaseVertex(baseVertex);\r
662                 Pos3d position = morphVertex.getOffset();\r
663                 position.setXPos(xOff);\r
664                 position.setYPos(yOff);\r
665                 position.setZPos(zOff);\r
666 \r
667                 morphVertexList.add(morphVertex);\r
668             }\r
669 \r
670             morphMap.get(morphType).add(morphPart);\r
671         }\r
672 \r
673         List<MorphPart> serialList = new LinkedList<MorphPart>();\r
674         MorphPart baseDummy = new MorphPart();\r
675         serialList.add(baseDummy);\r
676         for(MorphPart part : morphMap.get(MorphType.EYEBROW)){\r
677             serialList.add(part);\r
678         }\r
679         for(MorphPart part : morphMap.get(MorphType.EYE)){\r
680             serialList.add(part);\r
681         }\r
682         for(MorphPart part : morphMap.get(MorphType.LIP)){\r
683             serialList.add(part);\r
684         }\r
685         for(MorphPart part : morphMap.get(MorphType.EXTRA)){\r
686             serialList.add(part);\r
687         }\r
688         ListUtil.assignIndexedSerial(serialList);\r
689 \r
690         return;\r
691     }\r
692 \r
693     private void buildBoneGroupList(Element pmdModelElem)\r
694             throws TogaXmlException{\r
695         Element boneGroupListElem =\r
696                 getChild(pmdModelElem, "boneGroupList");\r
697 \r
698         List<BoneGroup> boneGroupList = this.model.getBoneGroupList();\r
699         BoneGroup defaultGroup = new BoneGroup();\r
700         boneGroupList.add(defaultGroup);\r
701 \r
702         for(Element boneGroupElem\r
703                 : eachChild(boneGroupListElem, "boneGroup")){\r
704             BoneGroup group = new BoneGroup();\r
705             boneGroupList.add(group);\r
706 \r
707             I18nText name = group.getGroupName();\r
708             buildI18nName(boneGroupElem, name);\r
709 \r
710             for(Element boneGroupMemberElem\r
711                     : eachChild(boneGroupElem, "boneGroupMember")){\r
712                 String boneIdRef =\r
713                         getStringAttr(boneGroupMemberElem, "boneIdRef");\r
714                 BoneInfo bone = this.boneMap.get(boneIdRef);\r
715                 group.getBoneList().add(bone);\r
716             }\r
717         }\r
718 \r
719         ListUtil.assignIndexedSerial(boneGroupList);\r
720 \r
721         return;\r
722     }\r
723 \r
724     private void buildRigidList(Element pmdModelElem)\r
725             throws TogaXmlException{\r
726         Element rigidListElem =\r
727                 getChild(pmdModelElem, "rigidList");\r
728 \r
729         List<RigidInfo> rigidList = this.model.getRigidList();\r
730 \r
731         for(Element rigidElem : eachChild(rigidListElem, "rigid")){\r
732             RigidInfo rigid = new RigidInfo();\r
733             rigidList.add(rigid);\r
734 \r
735             I18nText name = rigid.getRigidName();\r
736             buildI18nName(rigidElem, name);\r
737 \r
738             String behavior = getStringAttr(rigidElem, "behavior");\r
739             RigidBehaviorType type = RigidBehaviorType.valueOf(behavior);\r
740             rigid.setBehaviorType(type);\r
741 \r
742             String rigidId = getStringAttr(rigidElem, "rigidId");\r
743             this.rigidMap.put(rigidId, rigid);\r
744 \r
745             Element linkedBoneElem = getChild(rigidElem, "linkedBone");\r
746             String boneIdRef = getStringAttr(linkedBoneElem, "boneIdRef");\r
747             BoneInfo linkedBone = this.boneMap.get(boneIdRef);\r
748             rigid.setLinkedBone(linkedBone);\r
749 \r
750             RigidShape rigidShape = rigid.getRigidShape();\r
751             if(hasChild(rigidElem, "rigidShapeSphere")){\r
752                 Element shapeElem =\r
753                         getChild(rigidElem, "rigidShapeSphere");\r
754                 float radius = getFloatAttr(shapeElem, "radius");\r
755                 rigidShape.setShapeType(RigidShapeType.SPHERE);\r
756                 rigidShape.setRadius(radius);\r
757             }\r
758             if(hasChild(rigidElem, "rigidShapeBox")){\r
759                 Element shapeElem =\r
760                         getChild(rigidElem, "rigidShapeBox");\r
761                 float width  = getFloatAttr(shapeElem, "width");\r
762                 float height = getFloatAttr(shapeElem, "height");\r
763                 float depth  = getFloatAttr(shapeElem, "depth");\r
764                 rigidShape.setShapeType(RigidShapeType.BOX);\r
765                 rigidShape.setWidth(width);\r
766                 rigidShape.setHeight(height);\r
767                 rigidShape.setDepth(depth);\r
768             }\r
769             if(hasChild(rigidElem, "rigidShapeCapsule")){\r
770                 Element shapeElem =\r
771                         getChild(rigidElem, "rigidShapeCapsule");\r
772                 float height = getFloatAttr(shapeElem, "height");\r
773                 float radius = getFloatAttr(shapeElem, "radius");\r
774                 rigidShape.setShapeType(RigidShapeType.CAPSULE);\r
775                 rigidShape.setHeight(height);\r
776                 rigidShape.setRadius(radius);\r
777             }\r
778 \r
779             float xVal;\r
780             float yVal;\r
781             float zVal;\r
782 \r
783             Element positionElem = getChild(rigidElem, "position");\r
784             xVal = getFloatAttr(positionElem, "x");\r
785             yVal = getFloatAttr(positionElem, "y");\r
786             zVal = getFloatAttr(positionElem, "z");\r
787             Pos3d position = rigid.getPosition();\r
788             position.setXPos(xVal);\r
789             position.setYPos(yVal);\r
790             position.setZPos(zVal);\r
791 \r
792             Element radRotationElem = getChild(rigidElem, "radRotation");\r
793             xVal = getFloatAttr(radRotationElem, "xRad");\r
794             yVal = getFloatAttr(radRotationElem, "yRad");\r
795             zVal = getFloatAttr(radRotationElem, "zRad");\r
796             Rad3d rotation = rigid.getRotation();\r
797             rotation.setXRad(xVal);\r
798             rotation.setYRad(yVal);\r
799             rotation.setZRad(zVal);\r
800 \r
801             Element dynamicsElem = getChild(rigidElem, "dynamics");\r
802             float mass = getFloatAttr(dynamicsElem, "mass");\r
803             float dampingPosition =\r
804                     getFloatAttr(dynamicsElem, "dampingPosition");\r
805             float dampingRotation =\r
806                     getFloatAttr(dynamicsElem, "dampingRotation");\r
807             float restitution = getFloatAttr(dynamicsElem, "restitution");\r
808             float friction = getFloatAttr(dynamicsElem, "friction");\r
809             DynamicsInfo dynamics = rigid.getDynamicsInfo();\r
810             dynamics.setMass(mass);\r
811             dynamics.setDampingPosition(dampingPosition);\r
812             dynamics.setDampingRotation(dampingRotation);\r
813             dynamics.setRestitution(restitution);\r
814             dynamics.setFriction(friction);\r
815         }\r
816 \r
817         ListUtil.assignIndexedSerial(rigidList);\r
818 \r
819         return;\r
820     }\r
821 \r
822     private void buildRigidGroupList(Element pmdModelElem)\r
823             throws TogaXmlException{\r
824         Element rigidGroupListElem =\r
825                 getChild(pmdModelElem, "rigidGroupList");\r
826 \r
827         List<RigidGroup> groupList = this.model.getRigidGroupList();\r
828 \r
829         for(Element rigidGroupElem\r
830                 : eachChild(rigidGroupListElem, "rigidGroup")){\r
831             RigidGroup rigidGroup = new RigidGroup();\r
832             groupList.add(rigidGroup);\r
833 \r
834             String rigidGroupId =\r
835                     getStringAttr(rigidGroupElem, "rigidGroupId");\r
836             this.rigidGroupMap.put(rigidGroupId, rigidGroup);\r
837 \r
838             for(Element memberElem\r
839                     : eachChild(rigidGroupElem, "rigidGroupMember")){\r
840                 String rigidIdRef = getStringAttr(memberElem, "rigidIdRef");\r
841                 RigidInfo rigid = this.rigidMap.get(rigidIdRef);\r
842                 rigidGroup.getRigidList().add(rigid);\r
843                 rigid.setRigidGroup(rigidGroup);\r
844             }\r
845         }\r
846 \r
847         while(groupList.size() < 16){\r
848             RigidGroup rigidGroup = new RigidGroup();\r
849             groupList.add(rigidGroup);\r
850         }\r
851 \r
852         ListUtil.assignIndexedSerial(groupList);\r
853 \r
854         return;\r
855     }\r
856 \r
857     private void resolveThroughRigidGroup(Element pmdModelElem)\r
858             throws TogaXmlException{\r
859         Element rigidListElem =\r
860                 getChild(pmdModelElem, "rigidList");\r
861 \r
862         List<RigidInfo> rigidList = this.model.getRigidList();\r
863 \r
864         int serialNum = 0;\r
865         for(Element rigidElem : eachChild(rigidListElem, "rigid")){\r
866             RigidInfo rigid = rigidList.get(serialNum++);\r
867             for(Element groupElem\r
868                     : eachChild(rigidElem, "throughRigidGroup")){\r
869                 String groupId = getStringAttr(groupElem, "rigidGroupIdRef");\r
870                 RigidGroup group = this.rigidGroupMap.get(groupId);\r
871                 rigid.getThroughGroupColl().add(group);\r
872             }\r
873         }\r
874 \r
875         return;\r
876     }\r
877 \r
878     private void buildJointList(Element pmdModelElem)\r
879             throws TogaXmlException{\r
880         Element jointListElem =\r
881                 getChild(pmdModelElem, "jointList");\r
882 \r
883         List<JointInfo> jointList = this.model.getJointList();\r
884 \r
885         for(Element jointElem : eachChild(jointListElem, "joint")){\r
886             JointInfo joint = new JointInfo();\r
887             jointList.add(joint);\r
888 \r
889             I18nText name = joint.getJointName();\r
890             buildI18nName(jointElem, name);\r
891 \r
892             Element rigidPairElem = getChild(jointElem, "jointedRigidPair");\r
893             String rigidIdRef1 = getStringAttr(rigidPairElem, "rigidIdRef1");\r
894             String rigidIdRef2 = getStringAttr(rigidPairElem, "rigidIdRef2");\r
895             RigidInfo rigid1 = this.rigidMap.get(rigidIdRef1);\r
896             RigidInfo rigid2 = this.rigidMap.get(rigidIdRef2);\r
897             joint.setRigidPair(rigid1, rigid2);\r
898 \r
899             float xVal;\r
900             float yVal;\r
901             float zVal;\r
902             float xFrom;\r
903             float xTo;\r
904             float yFrom;\r
905             float yTo;\r
906             float zFrom;\r
907             float zTo;\r
908 \r
909             Pos3d position = joint.getPosition();\r
910             Element positionElem = getChild(jointElem, "position");\r
911             xVal = getFloatAttr(positionElem, "x");\r
912             yVal = getFloatAttr(positionElem, "y");\r
913             zVal = getFloatAttr(positionElem, "z");\r
914             position.setXPos(xVal);\r
915             position.setYPos(yVal);\r
916             position.setZPos(zVal);\r
917 \r
918             TripletRange limitPosition = joint.getPositionRange();\r
919             Element limitPositionElem = getChild(jointElem, "limitPosition");\r
920             xFrom = getFloatAttr(limitPositionElem, "xFrom");\r
921             xTo   = getFloatAttr(limitPositionElem, "xTo");\r
922             yFrom = getFloatAttr(limitPositionElem, "yFrom");\r
923             yTo   = getFloatAttr(limitPositionElem, "yTo");\r
924             zFrom = getFloatAttr(limitPositionElem, "zFrom");\r
925             zTo   = getFloatAttr(limitPositionElem, "zTo");\r
926             limitPosition.setXRange(xFrom, xTo);\r
927             limitPosition.setYRange(yFrom, yTo);\r
928             limitPosition.setZRange(zFrom, zTo);\r
929 \r
930             Rad3d rotation = joint.getRotation();\r
931             Element rotationElem = getChild(jointElem, "radRotation");\r
932             xVal = getFloatAttr(rotationElem, "xRad");\r
933             yVal = getFloatAttr(rotationElem, "yRad");\r
934             zVal = getFloatAttr(rotationElem, "zRad");\r
935             rotation.setXRad(xVal);\r
936             rotation.setYRad(yVal);\r
937             rotation.setZRad(zVal);\r
938 \r
939             TripletRange limitRotation = joint.getRotationRange();\r
940             Element limitRotationElem = getChild(jointElem, "limitRotation");\r
941             xFrom = getFloatAttr(limitRotationElem, "xFrom");\r
942             xTo   = getFloatAttr(limitRotationElem, "xTo");\r
943             yFrom = getFloatAttr(limitRotationElem, "yFrom");\r
944             yTo   = getFloatAttr(limitRotationElem, "yTo");\r
945             zFrom = getFloatAttr(limitRotationElem, "zFrom");\r
946             zTo   = getFloatAttr(limitRotationElem, "zTo");\r
947             limitRotation.setXRange(xFrom, xTo);\r
948             limitRotation.setYRange(yFrom, yTo);\r
949             limitRotation.setZRange(zFrom, zTo);\r
950 \r
951             Pos3d elasticPosition = joint.getElasticPosition();\r
952             Element elasticPositionElem =\r
953                     getChild(jointElem, "elasticPosition");\r
954             xVal = getFloatAttr(elasticPositionElem, "x");\r
955             yVal = getFloatAttr(elasticPositionElem, "y");\r
956             zVal = getFloatAttr(elasticPositionElem, "z");\r
957             elasticPosition.setXPos(xVal);\r
958             elasticPosition.setYPos(yVal);\r
959             elasticPosition.setZPos(zVal);\r
960 \r
961             Deg3d elasticRotation = joint.getElasticRotation();\r
962             Element elasticRotationElem =\r
963                     getChild(jointElem, "elasticRotation");\r
964             xVal = getFloatAttr(elasticRotationElem, "xDeg");\r
965             yVal = getFloatAttr(elasticRotationElem, "yDeg");\r
966             zVal = getFloatAttr(elasticRotationElem, "zDeg");\r
967             elasticRotation.setXDeg(xVal);\r
968             elasticRotation.setYDeg(yVal);\r
969             elasticRotation.setZDeg(zVal);\r
970         }\r
971 \r
972         return;\r
973     }\r
974 \r
975 }\r