4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sourceforge.mikutoga.pmd.model.xml;
10 import java.awt.Color;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.LinkedList;
15 import java.util.List;
17 import javax.xml.parsers.DocumentBuilder;
18 import jp.sourceforge.mikutoga.corelib.I18nText;
19 import jp.sourceforge.mikutoga.corelib.ListUtil;
20 import jp.sourceforge.mikutoga.math.MkPos2D;
21 import jp.sourceforge.mikutoga.math.MkPos3D;
22 import jp.sourceforge.mikutoga.math.MkVec3D;
23 import jp.sourceforge.mikutoga.pmd.BoneType;
24 import jp.sourceforge.mikutoga.pmd.Deg3d;
25 import jp.sourceforge.mikutoga.pmd.MorphType;
26 import jp.sourceforge.mikutoga.pmd.Rad3d;
27 import jp.sourceforge.mikutoga.pmd.RigidBehaviorType;
28 import jp.sourceforge.mikutoga.pmd.RigidShapeType;
29 import jp.sourceforge.mikutoga.pmd.TripletRange;
30 import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
31 import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
32 import jp.sourceforge.mikutoga.pmd.model.DynamicsInfo;
33 import jp.sourceforge.mikutoga.pmd.model.IKChain;
34 import jp.sourceforge.mikutoga.pmd.model.JointInfo;
35 import jp.sourceforge.mikutoga.pmd.model.Material;
36 import jp.sourceforge.mikutoga.pmd.model.MorphPart;
37 import jp.sourceforge.mikutoga.pmd.model.MorphVertex;
38 import jp.sourceforge.mikutoga.pmd.model.PmdModel;
39 import jp.sourceforge.mikutoga.pmd.model.RigidGroup;
40 import jp.sourceforge.mikutoga.pmd.model.RigidInfo;
41 import jp.sourceforge.mikutoga.pmd.model.RigidShape;
42 import jp.sourceforge.mikutoga.pmd.model.ShadeInfo;
43 import jp.sourceforge.mikutoga.pmd.model.Surface;
44 import jp.sourceforge.mikutoga.pmd.model.ToonMap;
45 import jp.sourceforge.mikutoga.pmd.model.Vertex;
46 import jp.sourceforge.mikutoga.xml.DomUtils;
47 import jp.sourceforge.mikutoga.xml.TogaXmlException;
48 import org.w3c.dom.Document;
49 import org.w3c.dom.Element;
50 import org.w3c.dom.Node;
51 import org.w3c.dom.NodeList;
52 import org.xml.sax.InputSource;
53 import org.xml.sax.SAXException;
56 * XML形式でのモデルファイルを読み込む。
58 public class Xml2PmdLoader {
60 private final DocumentBuilder builder;
62 private PmdModel model;
64 private final Map<String, Integer> toonIdxMap =
65 new HashMap<String, Integer>();
66 private final Map<String, BoneInfo> boneMap =
67 new HashMap<String, BoneInfo>();
68 private final Map<String, Vertex> vertexMap =
69 new HashMap<String, Vertex>();
70 private final Map<String, List<Surface>> surfaceGroupMap =
71 new HashMap<String, List<Surface>>();
72 private final Map<String, RigidInfo> rigidMap =
73 new HashMap<String, RigidInfo>();
74 private final Map<String, RigidGroup> rigidGroupMap =
75 new HashMap<String, RigidGroup>();
82 public Xml2PmdLoader(DocumentBuilder builder){
84 this.builder = builder;
89 * 要素からxsd:string型属性値を読み取る。
93 * @throws TogaXmlException 属性値が見つからなかった。
95 private static String getStringAttr(Element elem, String attrName)
96 throws TogaXmlException{
97 return DomUtils.getStringAttr(elem, attrName);
101 * 要素からxsd:boolean型属性値を読み取る。
103 * @param attrName 属性名
105 * @throws TogaXmlException 属性値が見つからなかった。
107 private static boolean getBooleanAttr(Element elem, String attrName)
108 throws TogaXmlException{
109 return DomUtils.getBooleanAttr(elem, attrName);
113 * 要素からxsd:integer型属性値を読み取る。
115 * @param attrName 属性名
117 * @throws TogaXmlException 属性値が見つからなかった。
119 private static int getIntegerAttr(Element elem, String attrName)
120 throws TogaXmlException{
121 return DomUtils.getIntegerAttr(elem, attrName);
125 * 要素からxsd:float型属性値を読み取る。
127 * @param attrName 属性名
129 * @throws TogaXmlException 属性値が見つからなかった。
131 private static float getFloatAttr(Element elem, String attrName)
132 throws TogaXmlException{
133 return DomUtils.getFloatAttr(elem, attrName);
137 * 要素から日本語Windows用ファイル名を属性値として読み取る。
138 * 念のため文字U+00A5は文字U-005Cに変換される。
140 * @param attrName 属性名
142 * @throws TogaXmlException 属性値が見つからなかった。
144 private static String getSjisFileNameAttr(Element elem, String attrName)
145 throws TogaXmlException{
146 return DomUtils.getSjisFileNameAttr(elem, attrName);
150 * 指定された名前の子要素を1つだけ返す。
152 * @param tagName 子要素名
154 * @throws TogaXmlException 1つも見つからなかった
156 private static Element getChild(Element parent, String tagName)
157 throws TogaXmlException{
158 return DomUtils.getChild(parent, tagName);
162 * 親要素が指定された名前の子要素を持つか判定する。
164 * @param tagName 子要素名
165 * @return 指定名の子要素が存在すればtrue
167 private static boolean hasChild(Element parent, String tagName){
168 return DomUtils.hasChild(parent, tagName);
172 * 指定された名前の子要素のforeachを返す。
174 * @param childTag 子要素名
175 * @return 子要素のforeach
177 private static Iterable<Element> eachChild(Element parent,
179 return DomUtils.getEachChild(parent, childTag);
184 * 元要素のname属性及びi18nNameタグを持つ子要素が検索対象
186 * @return グローバル名。なければnull
188 private static String getGlobalName(Element parent){
189 NodeList nodeList = parent.getElementsByTagName("i18nName");
190 int length = nodeList.getLength();
191 for(int idx = 0; idx < length; idx++){
192 Node i18nNameNode = nodeList.item(idx);
193 Element i18nNameElem = (Element)i18nNameNode;
194 String lang = i18nNameElem.getAttribute("lang");
195 if(lang == null || lang.length() <= 0) continue;
196 if(lang.equals("en")){
197 String name = i18nNameElem.getAttribute("name");
205 * brタグで区切られた文字列内容(Mixed content)を改行付き文字列に変換する。
206 * brタグはその出現回数だけ\nに変換される。
207 * 生文字列コンテンツ中の\n,\rは削除される。
208 * 改行文字以外のホワイトスペースは保持される。
209 * @param parent br要素及び文字列コンテンツを含む要素
212 private static String getBRedContent(Element parent){
213 StringBuilder result = new StringBuilder();
215 for(Node node = parent.getFirstChild();
217 node = node.getNextSibling() ){
219 switch(node.getNodeType()){
220 case Node.ELEMENT_NODE:
221 Element elem = (Element) node;
222 if("br".equals(elem.getTagName())){
227 case Node.CDATA_SECTION_NODE:
228 String content = node.getTextContent();
229 content = content.replace("\r", "");
230 content = content.replace("\n", "");
231 result.append(content);
238 return result.toString();
243 * @param baseElement 元要素
245 * @throws TogaXmlException あるべき属性が存在しない。
247 private static void buildI18nName(Element baseElement, I18nText text)
248 throws TogaXmlException{
250 primaryText = getStringAttr(baseElement, "name");
251 text.setPrimaryText(primaryText);
253 for(Element i18nNameElem : eachChild(baseElement, "i18nName")){
254 String lang = getStringAttr(i18nNameElem, "lang");
255 String name = getStringAttr(i18nNameElem, "name");
256 if("en".equals(lang)){
257 text.setGlobalText(name);
259 text.setI18nText(lang, text);
268 * @param source XML入力
270 * @throws SAXException 構文エラー
271 * @throws IOException 入力エラー
272 * @throws TogaXmlException 構文エラー
274 public PmdModel parse(InputSource source)
275 throws SAXException, IOException, TogaXmlException{
276 Document document = this.builder.parse(source);
278 this.model = new PmdModel();
280 Element pmdModelElem = document.getDocumentElement();
282 buildBasicInfo(pmdModelElem);
284 buildBoneList(pmdModelElem);
285 buildVertexList(pmdModelElem);
286 buildSurfaceList(pmdModelElem);
288 buildToonMap(pmdModelElem);
289 buildMaterialList(pmdModelElem);
290 buildIkChainList(pmdModelElem);
291 buildMorphList(pmdModelElem);
292 buildBoneGroupList(pmdModelElem);
294 buildRigidList(pmdModelElem);
295 buildRigidGroupList(pmdModelElem);
296 resolveThroughRigidGroup(pmdModelElem);
298 buildJointList(pmdModelElem);
303 private void buildBasicInfo(Element pmdModelElem)
304 throws TogaXmlException{
305 String primaryName = getStringAttr(pmdModelElem, "name");
306 String globalName = getGlobalName(pmdModelElem);
308 I18nText modelName = this.model.getModelName();
309 modelName.setPrimaryText(primaryName);
310 modelName.setGlobalText(globalName);
312 String primaryDescription = null;
313 String globalDescription = null;
314 for(Element descriptionElem :
315 eachChild(pmdModelElem, "description")){
316 String descriptionText = getBRedContent(descriptionElem);
317 if( ! descriptionElem.hasAttribute("lang") ){
318 primaryDescription = descriptionText;
320 String lang = getStringAttr(descriptionElem, "lang");
321 if(lang.equals("ja")){
322 primaryDescription = descriptionText;
323 }else if(lang.equals("en")){
324 globalDescription = descriptionText;
329 I18nText description = this.model.getDescription();
330 description.setPrimaryText(primaryDescription);
331 description.setGlobalText(globalDescription);
336 private void buildToonMap(Element pmdModelElem)
337 throws TogaXmlException{
338 ToonMap toonMap = this.model.getToonMap();
340 Element toonMapElem = getChild(pmdModelElem, "toonMap");
342 for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){
343 String toonFileId = getStringAttr(toonDefElem, "toonFileId");
344 int toonIndex = getIntegerAttr(toonDefElem, "index");
345 String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");
347 toonMap.setIndexedToon(toonIndex, toonFile);
348 this.toonIdxMap.put(toonFileId, toonIndex);
354 private void buildBoneList(Element pmdModelElem)
355 throws TogaXmlException{
356 Element boneListElem = getChild(pmdModelElem, "boneList");
358 List<BoneInfo> boneList = this.model.getBoneList();
360 for(Element boneElem : eachChild(boneListElem, "bone")){
361 BoneInfo boneInfo = new BoneInfo();
362 boneList.add(boneInfo);
364 I18nText boneName = boneInfo.getBoneName();
365 buildI18nName(boneElem, boneName);
367 String boneType = getStringAttr(boneElem, "type");
368 BoneType type = BoneType.valueOf(boneType);
369 boneInfo.setBoneType(type);
371 String boneId = getStringAttr(boneElem, "boneId");
372 this.boneMap.put(boneId, boneInfo);
374 Element positionElem = getChild(boneElem, "position");
375 float xPos = getFloatAttr(positionElem, "x");
376 float yPos = getFloatAttr(positionElem, "y");
377 float zPos = getFloatAttr(positionElem, "z");
378 MkPos3D position = boneInfo.getPosition();
379 position.setXpos(xPos);
380 position.setYpos(yPos);
381 position.setZpos(zPos);
384 ListUtil.assignIndexedSerial(boneList);
387 for(Element boneElem : eachChild(boneListElem, "bone")){
388 BoneInfo boneInfo = boneList.get(serial++);
390 if(hasChild(boneElem, "ikBone")){
391 Element ikBoneElem = getChild(boneElem, "ikBone");
392 String ikBoneId = getStringAttr(ikBoneElem, "boneIdRef");
393 BoneInfo ikBone = this.boneMap.get(ikBoneId);
394 boneInfo.setIKBone(ikBone);
395 }else if(hasChild(boneElem, "rotationRatio")){
396 Element ikBoneElem = getChild(boneElem, "rotationRatio");
397 int ratio = getIntegerAttr(ikBoneElem, "ratio");
398 boneInfo.setRotationRatio(ratio);
401 Element boneChainElem = getChild(boneElem, "boneChain");
402 if(boneChainElem.hasAttribute("prevBoneIdRef")){
403 String prevId = getStringAttr(boneChainElem, "prevBoneIdRef");
404 BoneInfo prevBone = this.boneMap.get(prevId);
405 boneInfo.setPrevBone(prevBone);
407 if(boneChainElem.hasAttribute("nextBoneIdRef")){
408 String nextId = getStringAttr(boneChainElem, "nextBoneIdRef");
409 BoneInfo nextBone = this.boneMap.get(nextId);
410 boneInfo.setNextBone(nextBone);
417 private void buildVertexList(Element pmdModelElem)
418 throws TogaXmlException{
419 Element vertexListElem = getChild(pmdModelElem, "vertexList");
421 List<Vertex> vertexList = this.model.getVertexList();
423 for(Element vertexElem : eachChild(vertexListElem, "vertex")){
424 Vertex vertex = new Vertex();
425 vertexList.add(vertex);
427 String vertexId = getStringAttr(vertexElem, "vtxId");
428 this.vertexMap.put(vertexId, vertex);
430 boolean showEdge = getBooleanAttr(vertexElem, "showEdge");
431 vertex.setEdgeAppearance(showEdge);
437 Element positionElem = getChild(vertexElem, "position");
438 xVal = getFloatAttr(positionElem, "x");
439 yVal = getFloatAttr(positionElem, "y");
440 zVal = getFloatAttr(positionElem, "z");
441 MkPos3D position = vertex.getPosition();
442 position.setXpos(xVal);
443 position.setYpos(yVal);
444 position.setZpos(zVal);
446 Element normalElem = getChild(vertexElem, "normal");
447 xVal = getFloatAttr(normalElem, "x");
448 yVal = getFloatAttr(normalElem, "y");
449 zVal = getFloatAttr(normalElem, "z");
450 MkVec3D normal = vertex.getNormal();
451 normal.setXVal(xVal);
452 normal.setYVal(yVal);
453 normal.setZVal(zVal);
455 Element uvElem = getChild(vertexElem, "uvMap");
456 float uVal = getFloatAttr(uvElem, "u");
457 float vVal = getFloatAttr(uvElem, "v");
458 MkPos2D uv = vertex.getUVPosition();
462 Element skinningElem = getChild(vertexElem, "skinning");
463 String boneId1 = getStringAttr(skinningElem, "boneIdRef1");
464 String boneId2 = getStringAttr(skinningElem, "boneIdRef2");
465 int weight = getIntegerAttr(skinningElem, "weightBalance");
466 BoneInfo boneA = this.boneMap.get(boneId1);
467 BoneInfo boneB = this.boneMap.get(boneId2);
468 vertex.setBonePair(boneA, boneB);
469 vertex.setWeightA(weight);
472 ListUtil.assignIndexedSerial(vertexList);
477 private void buildSurfaceList(Element pmdModelElem)
478 throws TogaXmlException{
479 Element surfaceGroupListElem =
480 getChild(pmdModelElem, "surfaceGroupList");
482 for(Element surfaceGroupElem :
483 eachChild(surfaceGroupListElem, "surfaceGroup") ){
486 getStringAttr(surfaceGroupElem, "surfaceGroupId");
487 List<Surface> surfaceList = buildSurface(surfaceGroupElem);
489 this.surfaceGroupMap.put(groupId, surfaceList);
493 private List<Surface> buildSurface(Element surfaceGroupElem)
494 throws TogaXmlException{
495 List<Surface> result = new ArrayList<Surface>();
497 for(Element surfaceElem : eachChild(surfaceGroupElem, "surface")){
498 Surface surface = new Surface();
501 String id1 = getStringAttr(surfaceElem, "vtxIdRef1");
502 String id2 = getStringAttr(surfaceElem, "vtxIdRef2");
503 String id3 = getStringAttr(surfaceElem, "vtxIdRef3");
505 Vertex vertex1 = this.vertexMap.get(id1);
506 Vertex vertex2 = this.vertexMap.get(id2);
507 Vertex vertex3 = this.vertexMap.get(id3);
509 surface.setTriangle(vertex1, vertex2, vertex3);
515 private void buildMaterialList(Element pmdModelElem)
516 throws TogaXmlException{
517 Element materialListElem =
518 getChild(pmdModelElem, "materialList");
520 List<Surface> surfaceList = this.model.getSurfaceList();
521 List<Material> materialList = this.model.getMaterialList();
523 for(Element materialElem : eachChild(materialListElem, "material")){
524 Material material = new Material();
525 materialList.add(material);
527 material.getShadeInfo().setToonMap(this.model.getToonMap());
529 String surfaceGroupId =
530 getStringAttr(materialElem, "surfaceGroupIdRef");
531 List<Surface> surfaceGroup =
532 this.surfaceGroupMap.get(surfaceGroupId);
533 surfaceList.addAll(surfaceGroup);
534 material.getSurfaceList().addAll(surfaceGroup);
536 boolean hasEdge = getBooleanAttr(materialElem, "showEdge");
537 material.setEdgeAppearance(hasEdge);
539 ShadeInfo shadeInfo = material.getShadeInfo();
542 if(hasChild(materialElem, "toon")){
543 Element toonElem = getChild(materialElem, "toon");
544 String toonId = getStringAttr(toonElem, "toonFileIdRef");
545 toonIdx = this.toonIdxMap.get(toonId);
549 shadeInfo.setToonIndex(toonIdx);
551 if(hasChild(materialElem, "textureFile")){
552 Element textureFileElem =
553 getChild(materialElem, "textureFile");
555 getSjisFileNameAttr(textureFileElem, "winFileName");
556 shadeInfo.setTextureFileName(textureFile);
559 if(hasChild(materialElem, "spheremapFile")){
560 Element spheremapFileElem =
561 getChild(materialElem, "spheremapFile");
562 String spheremapFile =
563 getSjisFileNameAttr(spheremapFileElem, "winFileName");
564 shadeInfo.setSpheremapFileName(spheremapFile);
571 Element diffuseElem = getChild(materialElem, "diffuse");
572 red = getFloatAttr(diffuseElem, "r");
573 green = getFloatAttr(diffuseElem, "g");
574 blue = getFloatAttr(diffuseElem, "b");
575 float alpha = getFloatAttr(diffuseElem, "alpha");
576 Color diffuse = new Color(red, green, blue, alpha);
577 material.setDiffuseColor(diffuse);
579 Element specularElem = getChild(materialElem, "specular");
580 red = getFloatAttr(specularElem, "r");
581 green = getFloatAttr(specularElem, "g");
582 blue = getFloatAttr(specularElem, "b");
583 float shininess = getFloatAttr(specularElem, "shininess");
584 Color specular = new Color(red, green, blue);
585 material.setSpecularColor(specular);
586 material.setShininess(shininess);
588 Element ambientElem = getChild(materialElem, "ambient");
589 red = getFloatAttr(ambientElem, "r");
590 green = getFloatAttr(ambientElem, "g");
591 blue = getFloatAttr(ambientElem, "b");
592 Color ambient = new Color(red, green, blue);
593 material.setAmbientColor(ambient);
599 private void buildIkChainList(Element pmdModelElem)
600 throws TogaXmlException{
601 Element ikChainListElem =
602 getChild(pmdModelElem, "ikChainList");
604 List<IKChain> ikChainList = this.model.getIKChainList();
606 for(Element ikChainElem : eachChild(ikChainListElem, "ikChain")){
607 IKChain ikChain = new IKChain();
608 ikChainList.add(ikChain);
610 String ikBoneIdRef = getStringAttr(ikChainElem, "ikBoneIdRef");
612 getIntegerAttr(ikChainElem, "recursiveDepth");
613 float weight = getFloatAttr(ikChainElem, "weight");
615 BoneInfo ikBone = this.boneMap.get(ikBoneIdRef);
616 ikChain.setIkBone(ikBone);
617 ikChain.setIKDepth(rucursiveDepth);
618 ikChain.setIKWeight(weight);
620 List<BoneInfo> chainList = ikChain.getChainedBoneList();
622 for(Element orderElem : eachChild(ikChainElem, "chainOrder")){
623 String boneIdRef = getStringAttr(orderElem, "boneIdRef");
624 BoneInfo chaindBone = this.boneMap.get(boneIdRef);
625 chainList.add(chaindBone);
632 private void buildMorphList(Element pmdModelElem)
633 throws TogaXmlException{
634 Element morphListElem =
635 getChild(pmdModelElem, "morphList");
637 Map<MorphType, List<MorphPart>> morphMap = this.model.getMorphMap();
639 for(Element morphElem : eachChild(morphListElem, "morph")){
640 MorphPart morphPart = new MorphPart();
642 I18nText name = morphPart.getMorphName();
643 buildI18nName(morphElem, name);
645 String type = getStringAttr(morphElem, "type");
646 MorphType morphType = MorphType.valueOf(type);
647 morphPart.setMorphType(morphType);
649 List<MorphVertex> morphVertexList =
650 morphPart.getMorphVertexList();
652 for(Element morphVertexElem
653 : eachChild(morphElem, "morphVertex")){
654 String vtxIdRef = getStringAttr(morphVertexElem, "vtxIdRef");
655 Vertex baseVertex = this.vertexMap.get(vtxIdRef);
656 float xOff = getFloatAttr(morphVertexElem, "xOff");
657 float yOff = getFloatAttr(morphVertexElem, "yOff");
658 float zOff = getFloatAttr(morphVertexElem, "zOff");
660 MorphVertex morphVertex = new MorphVertex();
661 morphVertex.setBaseVertex(baseVertex);
662 MkPos3D position = morphVertex.getOffset();
663 position.setXpos(xOff);
664 position.setYpos(yOff);
665 position.setZpos(zOff);
667 morphVertexList.add(morphVertex);
670 morphMap.get(morphType).add(morphPart);
673 List<MorphPart> serialList = new LinkedList<MorphPart>();
674 MorphPart baseDummy = new MorphPart();
675 serialList.add(baseDummy);
676 for(MorphPart part : morphMap.get(MorphType.EYEBROW)){
677 serialList.add(part);
679 for(MorphPart part : morphMap.get(MorphType.EYE)){
680 serialList.add(part);
682 for(MorphPart part : morphMap.get(MorphType.LIP)){
683 serialList.add(part);
685 for(MorphPart part : morphMap.get(MorphType.EXTRA)){
686 serialList.add(part);
688 ListUtil.assignIndexedSerial(serialList);
693 private void buildBoneGroupList(Element pmdModelElem)
694 throws TogaXmlException{
695 Element boneGroupListElem =
696 getChild(pmdModelElem, "boneGroupList");
698 List<BoneGroup> boneGroupList = this.model.getBoneGroupList();
699 BoneGroup defaultGroup = new BoneGroup();
700 boneGroupList.add(defaultGroup);
702 for(Element boneGroupElem
703 : eachChild(boneGroupListElem, "boneGroup")){
704 BoneGroup group = new BoneGroup();
705 boneGroupList.add(group);
707 I18nText name = group.getGroupName();
708 buildI18nName(boneGroupElem, name);
710 for(Element boneGroupMemberElem
711 : eachChild(boneGroupElem, "boneGroupMember")){
713 getStringAttr(boneGroupMemberElem, "boneIdRef");
714 BoneInfo bone = this.boneMap.get(boneIdRef);
715 group.getBoneList().add(bone);
719 ListUtil.assignIndexedSerial(boneGroupList);
724 private void buildRigidList(Element pmdModelElem)
725 throws TogaXmlException{
726 Element rigidListElem =
727 getChild(pmdModelElem, "rigidList");
729 List<RigidInfo> rigidList = this.model.getRigidList();
731 for(Element rigidElem : eachChild(rigidListElem, "rigid")){
732 RigidInfo rigid = new RigidInfo();
733 rigidList.add(rigid);
735 I18nText name = rigid.getRigidName();
736 buildI18nName(rigidElem, name);
738 String behavior = getStringAttr(rigidElem, "behavior");
739 RigidBehaviorType type = RigidBehaviorType.valueOf(behavior);
740 rigid.setBehaviorType(type);
742 String rigidId = getStringAttr(rigidElem, "rigidId");
743 this.rigidMap.put(rigidId, rigid);
745 if(hasChild(rigidElem, "linkedBone")){
746 Element linkedBoneElem = getChild(rigidElem, "linkedBone");
747 String boneIdRef = getStringAttr(linkedBoneElem, "boneIdRef");
748 BoneInfo linkedBone = this.boneMap.get(boneIdRef);
749 rigid.setLinkedBone(linkedBone);
752 RigidShape rigidShape = rigid.getRigidShape();
753 if(hasChild(rigidElem, "rigidShapeSphere")){
755 getChild(rigidElem, "rigidShapeSphere");
756 float radius = getFloatAttr(shapeElem, "radius");
757 rigidShape.setShapeType(RigidShapeType.SPHERE);
758 rigidShape.setRadius(radius);
760 if(hasChild(rigidElem, "rigidShapeBox")){
762 getChild(rigidElem, "rigidShapeBox");
763 float width = getFloatAttr(shapeElem, "width");
764 float height = getFloatAttr(shapeElem, "height");
765 float depth = getFloatAttr(shapeElem, "depth");
766 rigidShape.setShapeType(RigidShapeType.BOX);
767 rigidShape.setWidth(width);
768 rigidShape.setHeight(height);
769 rigidShape.setDepth(depth);
771 if(hasChild(rigidElem, "rigidShapeCapsule")){
773 getChild(rigidElem, "rigidShapeCapsule");
774 float height = getFloatAttr(shapeElem, "height");
775 float radius = getFloatAttr(shapeElem, "radius");
776 rigidShape.setShapeType(RigidShapeType.CAPSULE);
777 rigidShape.setHeight(height);
778 rigidShape.setRadius(radius);
785 Element positionElem = getChild(rigidElem, "position");
786 xVal = getFloatAttr(positionElem, "x");
787 yVal = getFloatAttr(positionElem, "y");
788 zVal = getFloatAttr(positionElem, "z");
789 MkPos3D position = rigid.getPosition();
790 position.setXpos(xVal);
791 position.setYpos(yVal);
792 position.setZpos(zVal);
794 Element radRotationElem = getChild(rigidElem, "radRotation");
795 xVal = getFloatAttr(radRotationElem, "xRad");
796 yVal = getFloatAttr(radRotationElem, "yRad");
797 zVal = getFloatAttr(radRotationElem, "zRad");
798 Rad3d rotation = rigid.getRotation();
799 rotation.setXRad(xVal);
800 rotation.setYRad(yVal);
801 rotation.setZRad(zVal);
803 Element dynamicsElem = getChild(rigidElem, "dynamics");
804 float mass = getFloatAttr(dynamicsElem, "mass");
805 float dampingPosition =
806 getFloatAttr(dynamicsElem, "dampingPosition");
807 float dampingRotation =
808 getFloatAttr(dynamicsElem, "dampingRotation");
809 float restitution = getFloatAttr(dynamicsElem, "restitution");
810 float friction = getFloatAttr(dynamicsElem, "friction");
811 DynamicsInfo dynamics = rigid.getDynamicsInfo();
812 dynamics.setMass(mass);
813 dynamics.setDampingPosition(dampingPosition);
814 dynamics.setDampingRotation(dampingRotation);
815 dynamics.setRestitution(restitution);
816 dynamics.setFriction(friction);
819 ListUtil.assignIndexedSerial(rigidList);
824 private void buildRigidGroupList(Element pmdModelElem)
825 throws TogaXmlException{
826 Element rigidGroupListElem =
827 getChild(pmdModelElem, "rigidGroupList");
829 List<RigidGroup> groupList = this.model.getRigidGroupList();
831 for(Element rigidGroupElem
832 : eachChild(rigidGroupListElem, "rigidGroup")){
833 RigidGroup rigidGroup = new RigidGroup();
834 groupList.add(rigidGroup);
836 String rigidGroupId =
837 getStringAttr(rigidGroupElem, "rigidGroupId");
838 this.rigidGroupMap.put(rigidGroupId, rigidGroup);
840 for(Element memberElem
841 : eachChild(rigidGroupElem, "rigidGroupMember")){
842 String rigidIdRef = getStringAttr(memberElem, "rigidIdRef");
843 RigidInfo rigid = this.rigidMap.get(rigidIdRef);
844 rigidGroup.getRigidList().add(rigid);
845 rigid.setRigidGroup(rigidGroup);
849 while(groupList.size() < 16){
850 RigidGroup rigidGroup = new RigidGroup();
851 groupList.add(rigidGroup);
854 ListUtil.assignIndexedSerial(groupList);
859 private void resolveThroughRigidGroup(Element pmdModelElem)
860 throws TogaXmlException{
861 Element rigidListElem =
862 getChild(pmdModelElem, "rigidList");
864 List<RigidInfo> rigidList = this.model.getRigidList();
867 for(Element rigidElem : eachChild(rigidListElem, "rigid")){
868 RigidInfo rigid = rigidList.get(serialNum++);
869 for(Element groupElem
870 : eachChild(rigidElem, "throughRigidGroup")){
871 String groupId = getStringAttr(groupElem, "rigidGroupIdRef");
872 RigidGroup group = this.rigidGroupMap.get(groupId);
873 rigid.getThroughGroupColl().add(group);
880 private void buildJointList(Element pmdModelElem)
881 throws TogaXmlException{
882 Element jointListElem =
883 getChild(pmdModelElem, "jointList");
885 List<JointInfo> jointList = this.model.getJointList();
887 for(Element jointElem : eachChild(jointListElem, "joint")){
888 JointInfo joint = new JointInfo();
889 jointList.add(joint);
891 I18nText name = joint.getJointName();
892 buildI18nName(jointElem, name);
894 Element rigidPairElem = getChild(jointElem, "jointedRigidPair");
895 String rigidIdRef1 = getStringAttr(rigidPairElem, "rigidIdRef1");
896 String rigidIdRef2 = getStringAttr(rigidPairElem, "rigidIdRef2");
897 RigidInfo rigid1 = this.rigidMap.get(rigidIdRef1);
898 RigidInfo rigid2 = this.rigidMap.get(rigidIdRef2);
899 joint.setRigidPair(rigid1, rigid2);
911 MkPos3D position = joint.getPosition();
912 Element positionElem = getChild(jointElem, "position");
913 xVal = getFloatAttr(positionElem, "x");
914 yVal = getFloatAttr(positionElem, "y");
915 zVal = getFloatAttr(positionElem, "z");
916 position.setXpos(xVal);
917 position.setYpos(yVal);
918 position.setZpos(zVal);
920 TripletRange limitPosition = joint.getPositionRange();
921 Element limitPositionElem = getChild(jointElem, "limitPosition");
922 xFrom = getFloatAttr(limitPositionElem, "xFrom");
923 xTo = getFloatAttr(limitPositionElem, "xTo");
924 yFrom = getFloatAttr(limitPositionElem, "yFrom");
925 yTo = getFloatAttr(limitPositionElem, "yTo");
926 zFrom = getFloatAttr(limitPositionElem, "zFrom");
927 zTo = getFloatAttr(limitPositionElem, "zTo");
928 limitPosition.setXRange(xFrom, xTo);
929 limitPosition.setYRange(yFrom, yTo);
930 limitPosition.setZRange(zFrom, zTo);
932 Rad3d rotation = joint.getRotation();
933 Element rotationElem = getChild(jointElem, "radRotation");
934 xVal = getFloatAttr(rotationElem, "xRad");
935 yVal = getFloatAttr(rotationElem, "yRad");
936 zVal = getFloatAttr(rotationElem, "zRad");
937 rotation.setXRad(xVal);
938 rotation.setYRad(yVal);
939 rotation.setZRad(zVal);
941 TripletRange limitRotation = joint.getRotationRange();
942 Element limitRotationElem = getChild(jointElem, "limitRotation");
943 xFrom = getFloatAttr(limitRotationElem, "xFrom");
944 xTo = getFloatAttr(limitRotationElem, "xTo");
945 yFrom = getFloatAttr(limitRotationElem, "yFrom");
946 yTo = getFloatAttr(limitRotationElem, "yTo");
947 zFrom = getFloatAttr(limitRotationElem, "zFrom");
948 zTo = getFloatAttr(limitRotationElem, "zTo");
949 limitRotation.setXRange(xFrom, xTo);
950 limitRotation.setYRange(yFrom, yTo);
951 limitRotation.setZRange(zFrom, zTo);
953 MkPos3D elasticPosition = joint.getElasticPosition();
954 Element elasticPositionElem =
955 getChild(jointElem, "elasticPosition");
956 xVal = getFloatAttr(elasticPositionElem, "x");
957 yVal = getFloatAttr(elasticPositionElem, "y");
958 zVal = getFloatAttr(elasticPositionElem, "z");
959 elasticPosition.setXpos(xVal);
960 elasticPosition.setYpos(yVal);
961 elasticPosition.setZpos(zVal);
963 Deg3d elasticRotation = joint.getElasticRotation();
964 Element elasticRotationElem =
965 getChild(jointElem, "elasticRotation");
966 xVal = getFloatAttr(elasticRotationElem, "xDeg");
967 yVal = getFloatAttr(elasticRotationElem, "yDeg");
968 zVal = getFloatAttr(elasticRotationElem, "zDeg");
969 elasticRotation.setXDeg(xVal);
970 elasticRotation.setYDeg(yVal);
971 elasticRotation.setZDeg(zVal);