4 * License : The MIT License
\r
5 * Copyright(c) 2010 MikuToga Partners
\r
8 package jp.sourceforge.mikutoga.pmd.xml;
\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
56 * XML形式でのモデルファイルを読み込む。
\r
58 public class Xml2PmdLoader {
\r
60 private final DocumentBuilder builder;
\r
62 private PmdModel model;
\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
80 * @param builder ビルダ
\r
82 public Xml2PmdLoader(DocumentBuilder builder){
\r
84 this.builder = builder;
\r
89 * 要素からxsd:string型属性値を読み取る。
\r
91 * @param attrName 属性名
\r
93 * @throw TogaXmlException 属性値が見つからなかった。
\r
95 private static String getStringAttr(Element elem, String attrName)
\r
96 throws TogaXmlException{
\r
97 return DomUtils.getStringAttr(elem, attrName);
\r
101 * 要素からxsd:boolean型属性値を読み取る。
\r
103 * @param attrName 属性名
\r
105 * @throw TogaXmlException 属性値が見つからなかった。
\r
107 private static boolean getBooleanAttr(Element elem, String attrName)
\r
108 throws TogaXmlException{
\r
109 return DomUtils.getBooleanAttr(elem, attrName);
\r
113 * 要素からxsd:integer型属性値を読み取る。
\r
115 * @param attrName 属性名
\r
117 * @throw TogaXmlException 属性値が見つからなかった。
\r
119 private static int getIntegerAttr(Element elem, String attrName)
\r
120 throws TogaXmlException{
\r
121 return DomUtils.getIntegerAttr(elem, attrName);
\r
125 * 要素からxsd:float型属性値を読み取る。
\r
127 * @param attrName 属性名
\r
129 * @throw TogaXmlException 属性値が見つからなかった。
\r
131 private static float getFloatAttr(Element elem, String attrName)
\r
132 throws TogaXmlException{
\r
133 return DomUtils.getFloatAttr(elem, attrName);
\r
137 * 要素から日本語Windows用ファイル名を属性値として読み取る。
\r
138 * 念のため文字U+00A5は文字U-005Cに変換される。
\r
140 * @param attrName 属性名
\r
142 * @throw TogaXmlException 属性値が見つからなかった。
\r
144 private static String getSjisFileNameAttr(Element elem, String attrName)
\r
145 throws TogaXmlException{
\r
146 return DomUtils.getSjisFileNameAttr(elem, attrName);
\r
150 * 指定された名前の子要素を1つだけ返す。
\r
151 * @param parent 親要素
\r
152 * @param tagName 子要素名
\r
154 * @throw TogaXmlException 1つも見つからなかった
\r
156 private static Element getChild(Element parent, String tagName)
\r
157 throws TogaXmlException{
\r
158 return DomUtils.getChild(parent, tagName);
\r
162 * 親要素が指定された名前の子要素を持つか判定する。
\r
163 * @param parent 親要素
\r
164 * @param tagName 子要素名
\r
165 * @return 指定名の子要素が存在すればtrue
\r
167 private static boolean hasChild(Element parent, String tagName){
\r
168 return DomUtils.hasChild(parent, tagName);
\r
172 * 指定された名前の子要素のforeachを返す。
\r
173 * @param parent 親要素
\r
174 * @param childTag 子要素名
\r
175 * @return 子要素のforeach
\r
177 private static Iterable<Element> eachChild(Element parent,
\r
179 return DomUtils.getEachChild(parent, childTag);
\r
182 private static String getGlobalName(Element parent){
\r
183 NodeList nodeList = parent.getElementsByTagName("i18nName");
\r
184 int length = nodeList.getLength();
\r
185 for(int idx = 0; idx < length; idx++){
\r
186 Node i18nNameNode = nodeList.item(idx);
\r
187 Element i18nNameElem = (Element)i18nNameNode;
\r
188 String lang = i18nNameElem.getAttribute("lang");
\r
189 if(lang == null || lang.length() <= 0) continue;
\r
190 if(lang.equals("en")){
\r
191 String name = i18nNameElem.getAttribute("name");
\r
199 * brタグで区切られた文字列内容(Mixed content)を改行付き文字列に変換する。
\r
200 * brタグはその出現回数だけ\nに変換される。
\r
201 * 生文字列コンテンツ中の\n,\rは削除される。
\r
202 * 改行文字以外のホワイトスペースは保持される。
\r
203 * @param parent br要素及び文字列コンテンツを含む要素
\r
206 private static String getBRedContent(Element parent){
\r
207 StringBuilder result = new StringBuilder();
\r
209 for(Node node = parent.getFirstChild();
\r
211 node = node.getNextSibling() ){
\r
213 switch(node.getNodeType()){
\r
214 case Node.ELEMENT_NODE:
\r
215 Element elem = (Element) node;
\r
216 if("br".equals(elem.getTagName())){
\r
217 result.append('\n');
\r
220 case Node.TEXT_NODE:
\r
221 case Node.CDATA_SECTION_NODE:
\r
222 String content = node.getTextContent();
\r
223 content = content.replace("\r", "");
\r
224 content = content.replace("\n", "");
\r
225 result.append(content);
\r
232 return result.toString();
\r
235 private static void buildI18nName(Element baseElement, I18nText text)
\r
236 throws TogaXmlException{
\r
237 String primaryText;
\r
238 primaryText = getStringAttr(baseElement, "name");
\r
239 text.setPrimaryText(primaryText);
\r
241 for(Element i18nNameElem : eachChild(baseElement, "i18nName")){
\r
242 String lang = getStringAttr(i18nNameElem, "lang");
\r
243 String name = getStringAttr(i18nNameElem, "name");
\r
244 if("en".equals(lang)){
\r
245 text.setGlobalText(name);
\r
247 text.setText(lang, text);
\r
254 public PmdModel parse(InputSource source)
\r
255 throws SAXException, IOException, TogaXmlException{
\r
256 Document document = this.builder.parse(source);
\r
258 this.model = new PmdModel();
\r
260 Element pmdModelElem = document.getDocumentElement();
\r
262 buildBasicInfo(pmdModelElem);
\r
264 buildBoneList(pmdModelElem);
\r
265 buildVertexList(pmdModelElem);
\r
266 buildSurfaceList(pmdModelElem);
\r
268 buildToonMap(pmdModelElem);
\r
269 buildMaterialList(pmdModelElem);
\r
270 buildIkChainList(pmdModelElem);
\r
271 buildMorphList(pmdModelElem);
\r
272 buildBoneGroupList(pmdModelElem);
\r
274 buildRigidList(pmdModelElem);
\r
275 buildRigidGroupList(pmdModelElem);
\r
276 resolveThroughRigidGroup(pmdModelElem);
\r
278 buildJointList(pmdModelElem);
\r
283 private void buildBasicInfo(Element pmdModelElem)
\r
284 throws TogaXmlException{
\r
285 String primaryName = getStringAttr(pmdModelElem, "name");
\r
286 String globalName = getGlobalName(pmdModelElem);
\r
288 I18nText modelName = this.model.getModelName();
\r
289 modelName.setPrimaryText(primaryName);
\r
290 modelName.setGlobalText(globalName);
\r
292 String primaryDescription = null;
\r
293 String globalDescription = null;
\r
294 for(Element descriptionElem :
\r
295 eachChild(pmdModelElem, "description")){
\r
296 String descriptionText = getBRedContent(descriptionElem);
\r
297 if( ! descriptionElem.hasAttribute("lang") ){
\r
298 primaryDescription = descriptionText;
\r
300 String lang = getStringAttr(descriptionElem, "lang");
\r
301 if(lang.equals("ja")){
\r
302 primaryDescription = descriptionText;
\r
303 }else if(lang.equals("en")){
\r
304 globalDescription = descriptionText;
\r
309 I18nText description = this.model.getDescription();
\r
310 description.setPrimaryText(primaryDescription);
\r
311 description.setGlobalText(globalDescription);
\r
316 private void buildToonMap(Element pmdModelElem)
\r
317 throws TogaXmlException{
\r
318 ToonMap toonMap = this.model.getToonMap();
\r
320 Element toonMapElem = getChild(pmdModelElem, "toonMap");
\r
322 for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){
\r
323 String toonFileId = getStringAttr(toonDefElem, "toonFileId");
\r
324 int toonIndex = getIntegerAttr(toonDefElem, "index");
\r
325 String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");
\r
327 toonMap.setIndexedToon(toonIndex, toonFile);
\r
328 this.toonIdxMap.put(toonFileId, toonIndex);
\r
334 private void buildBoneList(Element pmdModelElem)
\r
335 throws TogaXmlException{
\r
336 Element boneListElem = getChild(pmdModelElem, "boneList");
\r
338 List<BoneInfo> boneList = this.model.getBoneList();
\r
340 for(Element boneElem : eachChild(boneListElem, "bone")){
\r
341 BoneInfo boneInfo = new BoneInfo();
\r
342 boneList.add(boneInfo);
\r
344 I18nText boneName = boneInfo.getBoneName();
\r
345 buildI18nName(boneElem, boneName);
\r
347 String boneType = getStringAttr(boneElem, "type");
\r
348 BoneType type = BoneType.valueOf(boneType);
\r
349 boneInfo.setBoneType(type);
\r
351 String boneId = getStringAttr(boneElem, "boneId");
\r
352 this.boneMap.put(boneId, boneInfo);
\r
354 Element positionElem = getChild(boneElem, "position");
\r
355 float xPos = getFloatAttr(positionElem, "x");
\r
356 float yPos = getFloatAttr(positionElem, "y");
\r
357 float zPos = getFloatAttr(positionElem, "z");
\r
358 Pos3d position = boneInfo.getPosition();
\r
359 position.setXPos(xPos);
\r
360 position.setYPos(yPos);
\r
361 position.setZPos(zPos);
\r
364 ListUtil.assignIndexedSerial(boneList);
\r
367 for(Element boneElem : eachChild(boneListElem, "bone")){
\r
368 BoneInfo boneInfo = boneList.get(serial++);
\r
370 if(hasChild(boneElem, "ikBone")){
\r
371 Element ikBoneElem = getChild(boneElem, "ikBone");
\r
372 String ikBoneId = getStringAttr(ikBoneElem, "boneIdRef");
\r
373 BoneInfo ikBone = this.boneMap.get(ikBoneId);
\r
374 boneInfo.setIKBone(ikBone);
\r
375 }else if(hasChild(boneElem, "rotationRatio")){
\r
376 Element ikBoneElem = getChild(boneElem, "rotationRatio");
\r
377 int ratio = getIntegerAttr(ikBoneElem, "ratio");
\r
378 boneInfo.setRotationRatio(ratio);
\r
381 Element boneChainElem = getChild(boneElem, "boneChain");
\r
382 if(boneChainElem.hasAttribute("prevBoneIdRef")){
\r
383 String prevId = getStringAttr(boneChainElem, "prevBoneIdRef");
\r
384 BoneInfo prevBone = this.boneMap.get(prevId);
\r
385 boneInfo.setPrevBone(prevBone);
\r
387 if(boneChainElem.hasAttribute("nextBoneIdRef")){
\r
388 String nextId = getStringAttr(boneChainElem, "nextBoneIdRef");
\r
389 BoneInfo nextBone = this.boneMap.get(nextId);
\r
390 boneInfo.setNextBone(nextBone);
\r
397 private void buildVertexList(Element pmdModelElem)
\r
398 throws TogaXmlException{
\r
399 Element vertexListElem = getChild(pmdModelElem, "vertexList");
\r
401 List<Vertex> vertexList = this.model.getVertexList();
\r
403 for(Element vertexElem : eachChild(vertexListElem, "vertex")){
\r
404 Vertex vertex = new Vertex();
\r
405 vertexList.add(vertex);
\r
407 String vertexId = getStringAttr(vertexElem, "vtxId");
\r
408 this.vertexMap.put(vertexId, vertex);
\r
410 boolean showEdge = getBooleanAttr(vertexElem, "showEdge");
\r
411 vertex.setEdgeAppearance(showEdge);
\r
417 Element positionElem = getChild(vertexElem, "position");
\r
418 xVal = getFloatAttr(positionElem, "x");
\r
419 yVal = getFloatAttr(positionElem, "y");
\r
420 zVal = getFloatAttr(positionElem, "z");
\r
421 Pos3d position = vertex.getPosition();
\r
422 position.setXPos(xVal);
\r
423 position.setYPos(yVal);
\r
424 position.setZPos(zVal);
\r
426 Element normalElem = getChild(vertexElem, "normal");
\r
427 xVal = getFloatAttr(normalElem, "x");
\r
428 yVal = getFloatAttr(normalElem, "y");
\r
429 zVal = getFloatAttr(normalElem, "z");
\r
430 Vec3d normal = vertex.getNormal();
\r
431 normal.setXVal(xVal);
\r
432 normal.setYVal(yVal);
\r
433 normal.setZVal(zVal);
\r
435 Element uvElem = getChild(vertexElem, "uvMap");
\r
436 float uVal = getFloatAttr(uvElem, "u");
\r
437 float vVal = getFloatAttr(uvElem, "v");
\r
438 Pos2d uv = vertex.getUVPosition();
\r
442 Element skinningElem = getChild(vertexElem, "skinning");
\r
443 String boneId1 = getStringAttr(skinningElem, "boneIdRef1");
\r
444 String boneId2 = getStringAttr(skinningElem, "boneIdRef2");
\r
445 int weight = getIntegerAttr(skinningElem, "weightBalance");
\r
446 BoneInfo boneA = this.boneMap.get(boneId1);
\r
447 BoneInfo boneB = this.boneMap.get(boneId2);
\r
448 vertex.setBonePair(boneA, boneB);
\r
449 vertex.setWeightA(weight);
\r
452 ListUtil.assignIndexedSerial(vertexList);
\r
457 private void buildSurfaceList(Element pmdModelElem)
\r
458 throws TogaXmlException{
\r
459 Element surfaceGroupListElem =
\r
460 getChild(pmdModelElem, "surfaceGroupList");
\r
462 for(Element surfaceGroupElem :
\r
463 eachChild(surfaceGroupListElem, "surfaceGroup") ){
\r
465 String groupId = getStringAttr(surfaceGroupElem, "surfaceGroupId");
\r
466 List<Surface> surfaceList = buildSurface(surfaceGroupElem);
\r
468 this.surfaceGroupMap.put(groupId, surfaceList);
\r
472 private List<Surface> buildSurface(Element surfaceGroupElem)
\r
473 throws TogaXmlException{
\r
474 List<Surface> result = new ArrayList<Surface>();
\r
476 for(Element surfaceElem : eachChild(surfaceGroupElem, "surface")){
\r
477 Surface surface = new Surface();
\r
478 result.add(surface);
\r
480 String id1 = getStringAttr(surfaceElem, "vtxIdRef1");
\r
481 String id2 = getStringAttr(surfaceElem, "vtxIdRef2");
\r
482 String id3 = getStringAttr(surfaceElem, "vtxIdRef3");
\r
484 Vertex vertex1 = this.vertexMap.get(id1);
\r
485 Vertex vertex2 = this.vertexMap.get(id2);
\r
486 Vertex vertex3 = this.vertexMap.get(id3);
\r
488 surface.setTriangle(vertex1, vertex2, vertex3);
\r
494 private void buildMaterialList(Element pmdModelElem)
\r
495 throws TogaXmlException{
\r
496 Element materialListElem =
\r
497 getChild(pmdModelElem, "materialList");
\r
499 List<Surface> surfaceList = this.model.getSurfaceList();
\r
500 List<Material> materialList = this.model.getMaterialList();
\r
502 for(Element materialElem : eachChild(materialListElem, "material")){
\r
503 Material material = new Material();
\r
504 materialList.add(material);
\r
506 material.getShadeInfo().setToonMap(this.model.getToonMap());
\r
508 String surfaceGroupId =
\r
509 getStringAttr(materialElem, "surfaceGroupIdRef");
\r
510 List<Surface> surfaceGroup =
\r
511 this.surfaceGroupMap.get(surfaceGroupId);
\r
512 surfaceList.addAll(surfaceGroup);
\r
513 material.getSurfaceList().addAll(surfaceGroup);
\r
515 boolean hasEdge = getBooleanAttr(materialElem, "showEdge");
\r
516 material.setEdgeAppearance(hasEdge);
\r
518 ShadeInfo shadeInfo = material.getShadeInfo();
\r
521 if(hasChild(materialElem, "toon")){
\r
522 Element toonElem = getChild(materialElem, "toon");
\r
523 String toonId = getStringAttr(toonElem, "toonFileIdRef");
\r
524 toonIdx = this.toonIdxMap.get(toonId);
\r
528 shadeInfo.setToonIndex(toonIdx);
\r
530 if(hasChild(materialElem, "textureFile")){
\r
531 Element textureFileElem =
\r
532 getChild(materialElem, "textureFile");
\r
533 String textureFile =
\r
534 getSjisFileNameAttr(textureFileElem, "winFileName");
\r
535 shadeInfo.setTextureFileName(textureFile);
\r
538 if(hasChild(materialElem, "spheremapFile")){
\r
539 Element spheremapFileElem =
\r
540 getChild(materialElem, "spheremapFile");
\r
541 String spheremapFile =
\r
542 getSjisFileNameAttr(spheremapFileElem, "winFileName");
\r
543 shadeInfo.setSpheremapFileName(spheremapFile);
\r
550 Element diffuseElem = getChild(materialElem, "diffuse");
\r
551 red = getFloatAttr(diffuseElem, "r");
\r
552 green = getFloatAttr(diffuseElem, "g");
\r
553 blue = getFloatAttr(diffuseElem, "b");
\r
554 float alpha = getFloatAttr(diffuseElem, "alpha");
\r
555 Color diffuse = new Color(red, green, blue, alpha);
\r
556 material.setDiffuseColor(diffuse);
\r
558 Element specularElem = getChild(materialElem, "specular");
\r
559 red = getFloatAttr(specularElem, "r");
\r
560 green = getFloatAttr(specularElem, "g");
\r
561 blue = getFloatAttr(specularElem, "b");
\r
562 float shininess = getFloatAttr(specularElem, "shininess");
\r
563 Color specular = new Color(red, green, blue);
\r
564 material.setSpecularColor(specular);
\r
565 material.setShininess(shininess);
\r
567 Element ambientElem = getChild(materialElem, "ambient");
\r
568 red = getFloatAttr(ambientElem, "r");
\r
569 green = getFloatAttr(ambientElem, "g");
\r
570 blue = getFloatAttr(ambientElem, "b");
\r
571 Color ambient = new Color(red, green, blue);
\r
572 material.setAmbientColor(ambient);
\r
578 private void buildIkChainList(Element pmdModelElem)
\r
579 throws TogaXmlException{
\r
580 Element ikChainListElem =
\r
581 getChild(pmdModelElem, "ikChainList");
\r
583 List<IKChain> ikChainList = this.model.getIKChainList();
\r
585 for(Element ikChainElem : eachChild(ikChainListElem, "ikChain")){
\r
586 IKChain ikChain = new IKChain();
\r
587 ikChainList.add(ikChain);
\r
589 String ikBoneIdRef = getStringAttr(ikChainElem, "ikBoneIdRef");
\r
590 int rucursiveDepth = getIntegerAttr(ikChainElem, "recursiveDepth");
\r
591 float weight = getFloatAttr(ikChainElem, "weight");
\r
593 BoneInfo ikBone = this.boneMap.get(ikBoneIdRef);
\r
594 ikChain.setIkBone(ikBone);
\r
595 ikChain.setIKDepth(rucursiveDepth);
\r
596 ikChain.setIKWeight(weight);
\r
598 List<BoneInfo> chainList = ikChain.getChainedBoneList();
\r
600 for(Element orderElem : eachChild(ikChainElem, "chainOrder")){
\r
601 String boneIdRef = getStringAttr(orderElem, "boneIdRef");
\r
602 BoneInfo chaindBone = this.boneMap.get(boneIdRef);
\r
603 chainList.add(chaindBone);
\r
610 private void buildMorphList(Element pmdModelElem)
\r
611 throws TogaXmlException{
\r
612 Element morphListElem =
\r
613 getChild(pmdModelElem, "morphList");
\r
615 Map<MorphType, List<MorphPart>> morphMap = this.model.getMorphMap();
\r
617 for(Element morphElem : eachChild(morphListElem, "morph")){
\r
618 MorphPart morphPart = new MorphPart();
\r
620 I18nText name = morphPart.getMorphName();
\r
621 buildI18nName(morphElem, name);
\r
623 String type = getStringAttr(morphElem, "type");
\r
624 MorphType morphType = MorphType.valueOf(type);
\r
625 morphPart.setMorphType(morphType);
\r
627 List<MorphVertex> morphVertexList = morphPart.getMorphVertexList();
\r
629 for(Element morphVertexElem : eachChild(morphElem, "morphVertex")){
\r
630 String vtxIdRef = getStringAttr(morphVertexElem, "vtxIdRef");
\r
631 Vertex baseVertex = this.vertexMap.get(vtxIdRef);
\r
632 float xOff = getFloatAttr(morphVertexElem, "xOff");
\r
633 float yOff = getFloatAttr(morphVertexElem, "yOff");
\r
634 float zOff = getFloatAttr(morphVertexElem, "zOff");
\r
636 MorphVertex morphVertex = new MorphVertex();
\r
637 morphVertex.setBaseVertex(baseVertex);
\r
638 Pos3d position = morphVertex.getOffset();
\r
639 position.setXPos(xOff);
\r
640 position.setYPos(yOff);
\r
641 position.setZPos(zOff);
\r
643 morphVertexList.add(morphVertex);
\r
646 morphMap.get(morphType).add(morphPart);
\r
649 List<MorphPart> serialList = new LinkedList<MorphPart>();
\r
650 MorphPart baseDummy = new MorphPart();
\r
651 serialList.add(baseDummy);
\r
652 for(MorphPart part : morphMap.get(MorphType.EYEBROW)){
\r
653 serialList.add(part);
\r
655 for(MorphPart part : morphMap.get(MorphType.EYE)){
\r
656 serialList.add(part);
\r
658 for(MorphPart part : morphMap.get(MorphType.LIP)){
\r
659 serialList.add(part);
\r
661 for(MorphPart part : morphMap.get(MorphType.EXTRA)){
\r
662 serialList.add(part);
\r
664 ListUtil.assignIndexedSerial(serialList);
\r
669 private void buildBoneGroupList(Element pmdModelElem)
\r
670 throws TogaXmlException{
\r
671 Element boneGroupListElem =
\r
672 getChild(pmdModelElem, "boneGroupList");
\r
674 List<BoneGroup> boneGroupList = this.model.getBoneGroupList();
\r
675 BoneGroup defaultGroup = new BoneGroup();
\r
676 boneGroupList.add(defaultGroup);
\r
678 for(Element boneGroupElem : eachChild(boneGroupListElem, "boneGroup")){
\r
679 BoneGroup group = new BoneGroup();
\r
680 boneGroupList.add(group);
\r
682 I18nText name = group.getGroupName();
\r
683 buildI18nName(boneGroupElem, name);
\r
685 for(Element boneGroupMemberElem : eachChild(boneGroupElem, "boneGroupMember")){
\r
686 String boneIdRef = getStringAttr(boneGroupMemberElem, "boneIdRef");
\r
687 BoneInfo bone = this.boneMap.get(boneIdRef);
\r
688 group.getBoneList().add(bone);
\r
692 ListUtil.assignIndexedSerial(boneGroupList);
\r
697 private void buildRigidList(Element pmdModelElem)
\r
698 throws TogaXmlException{
\r
699 Element rigidListElem =
\r
700 getChild(pmdModelElem, "rigidList");
\r
702 List<RigidInfo> rigidList = this.model.getRigidList();
\r
704 for(Element rigidElem : eachChild(rigidListElem, "rigid")){
\r
705 RigidInfo rigid = new RigidInfo();
\r
706 rigidList.add(rigid);
\r
708 I18nText name = rigid.getRigidName();
\r
709 buildI18nName(rigidElem, name);
\r
711 String behavior = getStringAttr(rigidElem, "behavior");
\r
712 RigidBehaviorType type = RigidBehaviorType.valueOf(behavior);
\r
713 rigid.setBehaviorType(type);
\r
715 String rigidId = getStringAttr(rigidElem, "rigidId");
\r
716 this.rigidMap.put(rigidId, rigid);
\r
718 Element linkedBoneElem = getChild(rigidElem, "linkedBone");
\r
719 String boneIdRef = getStringAttr(linkedBoneElem, "boneIdRef");
\r
720 BoneInfo linkedBone = this.boneMap.get(boneIdRef);
\r
721 rigid.setLinkedBone(linkedBone);
\r
723 RigidShape rigidShape = rigid.getRigidShape();
\r
724 if(hasChild(rigidElem, "rigidShapeSphere")){
\r
725 Element shapeElem =
\r
726 getChild(rigidElem, "rigidShapeSphere");
\r
727 float radius = getFloatAttr(shapeElem, "radius");
\r
728 rigidShape.setShapeType(RigidShapeType.SPHERE);
\r
729 rigidShape.setRadius(radius);
\r
731 if(hasChild(rigidElem, "rigidShapeBox")){
\r
732 Element shapeElem =
\r
733 getChild(rigidElem, "rigidShapeBox");
\r
734 float width = getFloatAttr(shapeElem, "width");
\r
735 float height = getFloatAttr(shapeElem, "height");
\r
736 float depth = getFloatAttr(shapeElem, "depth");
\r
737 rigidShape.setShapeType(RigidShapeType.BOX);
\r
738 rigidShape.setWidth(width);
\r
739 rigidShape.setHeight(height);
\r
740 rigidShape.setDepth(depth);
\r
742 if(hasChild(rigidElem, "rigidShapeCapsule")){
\r
743 Element shapeElem =
\r
744 getChild(rigidElem, "rigidShapeCapsule");
\r
745 float height = getFloatAttr(shapeElem, "height");
\r
746 float radius = getFloatAttr(shapeElem, "radius");
\r
747 rigidShape.setShapeType(RigidShapeType.CAPSULE);
\r
748 rigidShape.setHeight(height);
\r
749 rigidShape.setRadius(radius);
\r
756 Element positionElem = getChild(rigidElem, "position");
\r
757 xVal = getFloatAttr(positionElem, "x");
\r
758 yVal = getFloatAttr(positionElem, "y");
\r
759 zVal = getFloatAttr(positionElem, "z");
\r
760 Pos3d position = rigid.getPosition();
\r
761 position.setXPos(xVal);
\r
762 position.setYPos(yVal);
\r
763 position.setZPos(zVal);
\r
765 Element radRotationElem = getChild(rigidElem, "radRotation");
\r
766 xVal = getFloatAttr(radRotationElem, "xRad");
\r
767 yVal = getFloatAttr(radRotationElem, "yRad");
\r
768 zVal = getFloatAttr(radRotationElem, "zRad");
\r
769 Rad3d rotation = rigid.getRotation();
\r
770 rotation.setXRad(xVal);
\r
771 rotation.setYRad(yVal);
\r
772 rotation.setZRad(zVal);
\r
774 Element dynamicsElem = getChild(rigidElem, "dynamics");
\r
775 float mass = getFloatAttr(dynamicsElem, "mass");
\r
776 float dampingPosition = getFloatAttr(dynamicsElem, "dampingPosition");
\r
777 float dampingRotation = getFloatAttr(dynamicsElem, "dampingRotation");
\r
778 float restitution = getFloatAttr(dynamicsElem, "restitution");
\r
779 float friction = getFloatAttr(dynamicsElem, "friction");
\r
780 DynamicsInfo dynamics = rigid.getDynamicsInfo();
\r
781 dynamics.setMass(mass);
\r
782 dynamics.setDampingPosition(dampingPosition);
\r
783 dynamics.setDampingRotation(dampingRotation);
\r
784 dynamics.setRestitution(restitution);
\r
785 dynamics.setFriction(friction);
\r
788 ListUtil.assignIndexedSerial(rigidList);
\r
793 private void buildRigidGroupList(Element pmdModelElem)
\r
794 throws TogaXmlException{
\r
795 Element rigidGroupListElem =
\r
796 getChild(pmdModelElem, "rigidGroupList");
\r
798 List<RigidGroup> groupList = this.model.getRigidGroupList();
\r
800 for(Element rigidGroupElem : eachChild(rigidGroupListElem, "rigidGroup")){
\r
801 RigidGroup rigidGroup = new RigidGroup();
\r
802 groupList.add(rigidGroup);
\r
804 String rigidGroupId = getStringAttr(rigidGroupElem, "rigidGroupId");
\r
805 this.rigidGroupMap.put(rigidGroupId, rigidGroup);
\r
807 for(Element memberElem : eachChild(rigidGroupElem, "rigidGroupMember")){
\r
808 String rigidIdRef = getStringAttr(memberElem, "rigidIdRef");
\r
809 RigidInfo rigid = this.rigidMap.get(rigidIdRef);
\r
810 rigidGroup.getRigidList().add(rigid);
\r
811 rigid.setRigidGroup(rigidGroup);
\r
815 while(groupList.size() < 16){
\r
816 RigidGroup rigidGroup = new RigidGroup();
\r
817 groupList.add(rigidGroup);
\r
820 ListUtil.assignIndexedSerial(groupList);
\r
825 private void resolveThroughRigidGroup(Element pmdModelElem)
\r
826 throws TogaXmlException{
\r
827 Element rigidListElem =
\r
828 getChild(pmdModelElem, "rigidList");
\r
830 List<RigidInfo> rigidList = this.model.getRigidList();
\r
833 for(Element rigidElem : eachChild(rigidListElem, "rigid")){
\r
834 RigidInfo rigid = rigidList.get(serialNum++);
\r
835 for(Element groupElem : eachChild(rigidElem, "throughRigidGroup")){
\r
836 String groupId = getStringAttr(groupElem, "rigidGroupIdRef");
\r
837 RigidGroup group = this.rigidGroupMap.get(groupId);
\r
838 rigid.getThroughGroupColl().add(group);
\r
845 private void buildJointList(Element pmdModelElem)
\r
846 throws TogaXmlException{
\r
847 Element jointListElem =
\r
848 getChild(pmdModelElem, "jointList");
\r
850 List<JointInfo> jointList = this.model.getJointList();
\r
852 for(Element jointElem : eachChild(jointListElem, "joint")){
\r
853 JointInfo joint = new JointInfo();
\r
854 jointList.add(joint);
\r
856 I18nText name = joint.getJointName();
\r
857 buildI18nName(jointElem, name);
\r
859 Element rigidPairElem = getChild(jointElem, "jointedRigidPair");
\r
860 String rigidIdRef1 = getStringAttr(rigidPairElem, "rigidIdRef1");
\r
861 String rigidIdRef2 = getStringAttr(rigidPairElem, "rigidIdRef2");
\r
862 RigidInfo rigid1 = this.rigidMap.get(rigidIdRef1);
\r
863 RigidInfo rigid2 = this.rigidMap.get(rigidIdRef2);
\r
864 joint.setRigidPair(rigid1, rigid2);
\r
876 Pos3d position = joint.getPosition();
\r
877 Element positionElem = getChild(jointElem, "position");
\r
878 xVal = getFloatAttr(positionElem, "x");
\r
879 yVal = getFloatAttr(positionElem, "y");
\r
880 zVal = getFloatAttr(positionElem, "z");
\r
881 position.setXPos(xVal);
\r
882 position.setYPos(yVal);
\r
883 position.setZPos(zVal);
\r
885 TripletRange limitPosition = joint.getPositionRange();
\r
886 Element limitPositionElem = getChild(jointElem, "limitPosition");
\r
887 xFrom = getFloatAttr(limitPositionElem, "xFrom");
\r
888 xTo = getFloatAttr(limitPositionElem, "xTo");
\r
889 yFrom = getFloatAttr(limitPositionElem, "yFrom");
\r
890 yTo = getFloatAttr(limitPositionElem, "yTo");
\r
891 zFrom = getFloatAttr(limitPositionElem, "zFrom");
\r
892 zTo = getFloatAttr(limitPositionElem, "zTo");
\r
893 limitPosition.setXRange(xFrom, xTo);
\r
894 limitPosition.setYRange(yFrom, yTo);
\r
895 limitPosition.setZRange(zFrom, zTo);
\r
897 Rad3d rotation = joint.getRotation();
\r
898 Element rotationElem = getChild(jointElem, "radRotation");
\r
899 xVal = getFloatAttr(rotationElem, "xRad");
\r
900 yVal = getFloatAttr(rotationElem, "yRad");
\r
901 zVal = getFloatAttr(rotationElem, "zRad");
\r
902 rotation.setXRad(xVal);
\r
903 rotation.setYRad(yVal);
\r
904 rotation.setZRad(zVal);
\r
906 TripletRange limitRotation = joint.getRotationRange();
\r
907 Element limitRotationElem = getChild(jointElem, "limitRotation");
\r
908 xFrom = getFloatAttr(limitRotationElem, "xFrom");
\r
909 xTo = getFloatAttr(limitRotationElem, "xTo");
\r
910 yFrom = getFloatAttr(limitRotationElem, "yFrom");
\r
911 yTo = getFloatAttr(limitRotationElem, "yTo");
\r
912 zFrom = getFloatAttr(limitRotationElem, "zFrom");
\r
913 zTo = getFloatAttr(limitRotationElem, "zTo");
\r
914 limitRotation.setXRange(xFrom, xTo);
\r
915 limitRotation.setYRange(yFrom, yTo);
\r
916 limitRotation.setZRange(zFrom, zTo);
\r
918 Pos3d elasticPosition = joint.getElasticPosition();
\r
919 Element elasticPositionElem = getChild(jointElem, "elasticPosition");
\r
920 xVal = getFloatAttr(elasticPositionElem, "x");
\r
921 yVal = getFloatAttr(elasticPositionElem, "y");
\r
922 zVal = getFloatAttr(elasticPositionElem, "z");
\r
923 elasticPosition.setXPos(xVal);
\r
924 elasticPosition.setYPos(yVal);
\r
925 elasticPosition.setZPos(zVal);
\r
927 Deg3d elasticRotation = joint.getElasticRotation();
\r
928 Element elasticRotationElem = getChild(jointElem, "elasticRotation");
\r
929 xVal = getFloatAttr(elasticRotationElem, "xDeg");
\r
930 yVal = getFloatAttr(elasticRotationElem, "yDeg");
\r
931 zVal = getFloatAttr(elasticRotationElem, "zDeg");
\r
932 elasticRotation.setXDeg(xVal);
\r
933 elasticRotation.setYDeg(yVal);
\r
934 elasticRotation.setZDeg(zVal);
\r