+/*\r
+ * xml loader\r
+ *\r
+ * License : The MIT License\r
+ * Copyright(c) 2010 MikuToga Partners\r
+ */\r
+\r
+package jp.sourceforge.mikutoga.pmd.xml;\r
+\r
+import java.awt.Color;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+import java.util.Map;\r
+import javax.xml.parsers.DocumentBuilder;\r
+import jp.sourceforge.mikutoga.corelib.I18nText;\r
+import jp.sourceforge.mikutoga.corelib.ListUtil;\r
+import jp.sourceforge.mikutoga.pmd.BoneGroup;\r
+import jp.sourceforge.mikutoga.pmd.BoneInfo;\r
+import jp.sourceforge.mikutoga.pmd.BoneType;\r
+import jp.sourceforge.mikutoga.pmd.Deg3d;\r
+import jp.sourceforge.mikutoga.pmd.DynamicsInfo;\r
+import jp.sourceforge.mikutoga.pmd.IKChain;\r
+import jp.sourceforge.mikutoga.pmd.JointInfo;\r
+import jp.sourceforge.mikutoga.pmd.Material;\r
+import jp.sourceforge.mikutoga.pmd.MorphPart;\r
+import jp.sourceforge.mikutoga.pmd.MorphType;\r
+import jp.sourceforge.mikutoga.pmd.MorphVertex;\r
+import jp.sourceforge.mikutoga.pmd.PmdModel;\r
+import jp.sourceforge.mikutoga.pmd.Pos2d;\r
+import jp.sourceforge.mikutoga.pmd.Pos3d;\r
+import jp.sourceforge.mikutoga.pmd.Rad3d;\r
+import jp.sourceforge.mikutoga.pmd.RigidBehaviorType;\r
+import jp.sourceforge.mikutoga.pmd.RigidGroup;\r
+import jp.sourceforge.mikutoga.pmd.RigidInfo;\r
+import jp.sourceforge.mikutoga.pmd.RigidShape;\r
+import jp.sourceforge.mikutoga.pmd.RigidShapeType;\r
+import jp.sourceforge.mikutoga.pmd.ShadeInfo;\r
+import jp.sourceforge.mikutoga.pmd.Surface;\r
+import jp.sourceforge.mikutoga.pmd.ToonMap;\r
+import jp.sourceforge.mikutoga.pmd.TripletRange;\r
+import jp.sourceforge.mikutoga.pmd.Vec3d;\r
+import jp.sourceforge.mikutoga.pmd.Vertex;\r
+import jp.sourceforge.mikutoga.xml.DomUtils;\r
+import jp.sourceforge.mikutoga.xml.TogaXmlException;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Element;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+\r
+/**\r
+ * XML形式でのモデルファイルを読み込む。\r
+ */\r
+public class Xml2PmdLoader {\r
+\r
+ private final DocumentBuilder builder;\r
+\r
+ private PmdModel model;\r
+\r
+ private final Map<String, Integer> toonIdxMap =\r
+ new HashMap<String, Integer>();\r
+ private final Map<String, BoneInfo> boneMap =\r
+ new HashMap<String, BoneInfo>();\r
+ private final Map<String, Vertex> vertexMap =\r
+ new HashMap<String, Vertex>();\r
+ private final Map<String, List<Surface>> surfaceGroupMap =\r
+ new HashMap<String, List<Surface>>();\r
+ private final Map<String, RigidInfo> rigidMap =\r
+ new HashMap<String, RigidInfo>();\r
+ private final Map<String, RigidGroup> rigidGroupMap =\r
+ new HashMap<String, RigidGroup>();\r
+\r
+\r
+ /**\r
+ * コンストラクタ。\r
+ * @param builder ビルダ\r
+ */\r
+ public Xml2PmdLoader(DocumentBuilder builder){\r
+ super();\r
+ this.builder = builder;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 要素からxsd:string型属性値を読み取る。\r
+ * @param elem 要素\r
+ * @param attrName 属性名\r
+ * @return 文字列\r
+ * @throw TogaXmlException 属性値が見つからなかった。\r
+ */\r
+ private static String getStringAttr(Element elem, String attrName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getStringAttr(elem, attrName);\r
+ }\r
+\r
+ /**\r
+ * 要素からxsd:boolean型属性値を読み取る。\r
+ * @param elem 要素\r
+ * @param attrName 属性名\r
+ * @return 真ならtrue\r
+ * @throw TogaXmlException 属性値が見つからなかった。\r
+ */\r
+ private static boolean getBooleanAttr(Element elem, String attrName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getBooleanAttr(elem, attrName);\r
+ }\r
+\r
+ /**\r
+ * 要素からxsd:integer型属性値を読み取る。\r
+ * @param elem 要素\r
+ * @param attrName 属性名\r
+ * @return int値\r
+ * @throw TogaXmlException 属性値が見つからなかった。\r
+ */\r
+ private static int getIntegerAttr(Element elem, String attrName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getIntegerAttr(elem, attrName);\r
+ }\r
+\r
+ /**\r
+ * 要素からxsd:float型属性値を読み取る。\r
+ * @param elem 要素\r
+ * @param attrName 属性名\r
+ * @return float値\r
+ * @throw TogaXmlException 属性値が見つからなかった。\r
+ */\r
+ private static float getFloatAttr(Element elem, String attrName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getFloatAttr(elem, attrName);\r
+ }\r
+\r
+ /**\r
+ * 要素から日本語Windows用ファイル名を属性値として読み取る。\r
+ * 念のため文字U+00A5は文字U-005Cに変換される。\r
+ * @param elem 要素\r
+ * @param attrName 属性名\r
+ * @return ファイル名\r
+ * @throw TogaXmlException 属性値が見つからなかった。\r
+ */\r
+ private static String getSjisFileNameAttr(Element elem, String attrName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getSjisFileNameAttr(elem, attrName);\r
+ }\r
+\r
+ /**\r
+ * 指定された名前の子要素を1つだけ返す。\r
+ * @param parent 親要素\r
+ * @param tagName 子要素名\r
+ * @return 子要素\r
+ * @throw TogaXmlException 1つも見つからなかった\r
+ */\r
+ private static Element getChild(Element parent, String tagName)\r
+ throws TogaXmlException{\r
+ return DomUtils.getChild(parent, tagName);\r
+ }\r
+\r
+ /**\r
+ * 親要素が指定された名前の子要素を持つか判定する。\r
+ * @param parent 親要素\r
+ * @param tagName 子要素名\r
+ * @return 指定名の子要素が存在すればtrue\r
+ */\r
+ private static boolean hasChild(Element parent, String tagName){\r
+ return DomUtils.hasChild(parent, tagName);\r
+ }\r
+\r
+ /**\r
+ * 指定された名前の子要素のforeachを返す。\r
+ * @param parent 親要素\r
+ * @param childTag 子要素名\r
+ * @return 子要素のforeach\r
+ */\r
+ private static Iterable<Element> eachChild(Element parent,\r
+ String childTag){\r
+ return DomUtils.getEachChild(parent, childTag);\r
+ }\r
+\r
+ private static String getGlobalName(Element parent){\r
+ NodeList nodeList = parent.getElementsByTagName("i18nName");\r
+ int length = nodeList.getLength();\r
+ for(int idx = 0; idx < length; idx++){\r
+ Node i18nNameNode = nodeList.item(idx);\r
+ Element i18nNameElem = (Element)i18nNameNode;\r
+ String lang = i18nNameElem.getAttribute("lang");\r
+ if(lang == null || lang.length() <= 0) continue;\r
+ if(lang.equals("en")){\r
+ String name = i18nNameElem.getAttribute("name");\r
+ return name;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * brタグで区切られた文字列内容(Mixed content)を改行付き文字列に変換する。\r
+ * brタグはその出現回数だけ\nに変換される。\r
+ * 生文字列コンテンツ中の\n,\rは削除される。\r
+ * 改行文字以外のホワイトスペースは保持される。\r
+ * @param parent br要素及び文字列コンテンツを含む要素\r
+ * @return 変換された文字列\r
+ */\r
+ private static String getBRedContent(Element parent){\r
+ StringBuilder result = new StringBuilder();\r
+\r
+ for(Node node = parent.getFirstChild();\r
+ node != null;\r
+ node = node.getNextSibling() ){\r
+\r
+ switch(node.getNodeType()){\r
+ case Node.ELEMENT_NODE:\r
+ Element elem = (Element) node;\r
+ if("br".equals(elem.getTagName())){\r
+ result.append('\n');\r
+ }\r
+ break;\r
+ case Node.TEXT_NODE:\r
+ case Node.CDATA_SECTION_NODE:\r
+ String content = node.getTextContent();\r
+ content = content.replace("\r", "");\r
+ content = content.replace("\n", "");\r
+ result.append(content);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ return result.toString();\r
+ }\r
+\r
+ private static void buildI18nName(Element baseElement, I18nText text)\r
+ throws TogaXmlException{\r
+ String primaryText;\r
+ primaryText = getStringAttr(baseElement, "name");\r
+ text.setPrimaryText(primaryText);\r
+\r
+ for(Element i18nNameElem : eachChild(baseElement, "i18nName")){\r
+ String lang = getStringAttr(i18nNameElem, "lang");\r
+ String name = getStringAttr(i18nNameElem, "name");\r
+ if("en".equals(lang)){\r
+ text.setGlobalText(name);\r
+ }else{\r
+ text.setText(lang, text);\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ public PmdModel parse(InputSource source)\r
+ throws SAXException, IOException, TogaXmlException{\r
+ Document document = this.builder.parse(source);\r
+\r
+ this.model = new PmdModel();\r
+\r
+ Element pmdModelElem = document.getDocumentElement();\r
+\r
+ buildBasicInfo(pmdModelElem);\r
+\r
+ buildBoneList(pmdModelElem);\r
+ buildVertexList(pmdModelElem);\r
+ buildSurfaceList(pmdModelElem);\r
+\r
+ buildToonMap(pmdModelElem);\r
+ buildMaterialList(pmdModelElem);\r
+ buildIkChainList(pmdModelElem);\r
+ buildMorphList(pmdModelElem);\r
+ buildBoneGroupList(pmdModelElem);\r
+\r
+ buildRigidList(pmdModelElem);\r
+ buildRigidGroupList(pmdModelElem);\r
+ resolveThroughRigidGroup(pmdModelElem);\r
+\r
+ buildJointList(pmdModelElem);\r
+\r
+ return this.model;\r
+ }\r
+\r
+ private void buildBasicInfo(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ String primaryName = getStringAttr(pmdModelElem, "name");\r
+ String globalName = getGlobalName(pmdModelElem);\r
+\r
+ I18nText modelName = this.model.getModelName();\r
+ modelName.setPrimaryText(primaryName);\r
+ modelName.setGlobalText(globalName);\r
+\r
+ String primaryDescription = null;\r
+ String globalDescription = null;\r
+ for(Element descriptionElem :\r
+ eachChild(pmdModelElem, "description")){\r
+ String descriptionText = getBRedContent(descriptionElem);\r
+ if( ! descriptionElem.hasAttribute("lang") ){\r
+ primaryDescription = descriptionText;\r
+ }else{\r
+ String lang = getStringAttr(descriptionElem, "lang");\r
+ if(lang.equals("ja")){\r
+ primaryDescription = descriptionText;\r
+ }else if(lang.equals("en")){\r
+ globalDescription = descriptionText;\r
+ }\r
+ }\r
+ }\r
+\r
+ I18nText description = this.model.getDescription();\r
+ description.setPrimaryText(primaryDescription);\r
+ description.setGlobalText(globalDescription);\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildToonMap(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ ToonMap toonMap = this.model.getToonMap();\r
+\r
+ Element toonMapElem = getChild(pmdModelElem, "toonMap");\r
+\r
+ for(Element toonDefElem : eachChild(toonMapElem, "toonDef")){\r
+ String toonFileId = getStringAttr(toonDefElem, "toonFileId");\r
+ int toonIndex = getIntegerAttr(toonDefElem, "index");\r
+ String toonFile = getSjisFileNameAttr(toonDefElem, "winFileName");\r
+\r
+ toonMap.setIndexedToon(toonIndex, toonFile);\r
+ this.toonIdxMap.put(toonFileId, toonIndex);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildBoneList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element boneListElem = getChild(pmdModelElem, "boneList");\r
+\r
+ List<BoneInfo> boneList = this.model.getBoneList();\r
+\r
+ for(Element boneElem : eachChild(boneListElem, "bone")){\r
+ BoneInfo boneInfo = new BoneInfo();\r
+ boneList.add(boneInfo);\r
+\r
+ I18nText boneName = boneInfo.getBoneName();\r
+ buildI18nName(boneElem, boneName);\r
+\r
+ String boneType = getStringAttr(boneElem, "type");\r
+ BoneType type = BoneType.valueOf(boneType);\r
+ boneInfo.setBoneType(type);\r
+\r
+ String boneId = getStringAttr(boneElem, "boneId");\r
+ this.boneMap.put(boneId, boneInfo);\r
+\r
+ Element positionElem = getChild(boneElem, "position");\r
+ float xPos = getFloatAttr(positionElem, "x");\r
+ float yPos = getFloatAttr(positionElem, "y");\r
+ float zPos = getFloatAttr(positionElem, "z");\r
+ Pos3d position = boneInfo.getPosition();\r
+ position.setXPos(xPos);\r
+ position.setYPos(yPos);\r
+ position.setZPos(zPos);\r
+ }\r
+\r
+ ListUtil.assignIndexedSerial(boneList);\r
+\r
+ int serial = 0;\r
+ for(Element boneElem : eachChild(boneListElem, "bone")){\r
+ BoneInfo boneInfo = boneList.get(serial++);\r
+\r
+ if(hasChild(boneElem, "ikBone")){\r
+ Element ikBoneElem = getChild(boneElem, "ikBone");\r
+ String ikBoneId = getStringAttr(ikBoneElem, "boneIdRef");\r
+ BoneInfo ikBone = this.boneMap.get(ikBoneId);\r
+ boneInfo.setIKBone(ikBone);\r
+ }else if(hasChild(boneElem, "rotationRatio")){\r
+ Element ikBoneElem = getChild(boneElem, "rotationRatio");\r
+ int ratio = getIntegerAttr(ikBoneElem, "ratio");\r
+ boneInfo.setRotationRatio(ratio);\r
+ }\r
+\r
+ Element boneChainElem = getChild(boneElem, "boneChain");\r
+ if(boneChainElem.hasAttribute("prevBoneIdRef")){\r
+ String prevId = getStringAttr(boneChainElem, "prevBoneIdRef");\r
+ BoneInfo prevBone = this.boneMap.get(prevId);\r
+ boneInfo.setPrevBone(prevBone);\r
+ }\r
+ if(boneChainElem.hasAttribute("nextBoneIdRef")){\r
+ String nextId = getStringAttr(boneChainElem, "nextBoneIdRef");\r
+ BoneInfo nextBone = this.boneMap.get(nextId);\r
+ boneInfo.setNextBone(nextBone);\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildVertexList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element vertexListElem = getChild(pmdModelElem, "vertexList");\r
+\r
+ List<Vertex> vertexList = this.model.getVertexList();\r
+\r
+ for(Element vertexElem : eachChild(vertexListElem, "vertex")){\r
+ Vertex vertex = new Vertex();\r
+ vertexList.add(vertex);\r
+\r
+ String vertexId = getStringAttr(vertexElem, "vtxId");\r
+ this.vertexMap.put(vertexId, vertex);\r
+\r
+ boolean showEdge = getBooleanAttr(vertexElem, "showEdge");\r
+ vertex.setEdgeAppearance(showEdge);\r
+\r
+ float xVal;\r
+ float yVal;\r
+ float zVal;\r
+\r
+ Element positionElem = getChild(vertexElem, "position");\r
+ xVal = getFloatAttr(positionElem, "x");\r
+ yVal = getFloatAttr(positionElem, "y");\r
+ zVal = getFloatAttr(positionElem, "z");\r
+ Pos3d position = vertex.getPosition();\r
+ position.setXPos(xVal);\r
+ position.setYPos(yVal);\r
+ position.setZPos(zVal);\r
+\r
+ Element normalElem = getChild(vertexElem, "normal");\r
+ xVal = getFloatAttr(normalElem, "x");\r
+ yVal = getFloatAttr(normalElem, "y");\r
+ zVal = getFloatAttr(normalElem, "z");\r
+ Vec3d normal = vertex.getNormal();\r
+ normal.setXVal(xVal);\r
+ normal.setYVal(yVal);\r
+ normal.setZVal(zVal);\r
+\r
+ Element uvElem = getChild(vertexElem, "uvMap");\r
+ float uVal = getFloatAttr(uvElem, "u");\r
+ float vVal = getFloatAttr(uvElem, "v");\r
+ Pos2d uv = vertex.getUVPosition();\r
+ uv.setXPos(uVal);\r
+ uv.setYPos(vVal);\r
+\r
+ Element skinningElem = getChild(vertexElem, "skinning");\r
+ String boneId1 = getStringAttr(skinningElem, "boneIdRef1");\r
+ String boneId2 = getStringAttr(skinningElem, "boneIdRef2");\r
+ int weight = getIntegerAttr(skinningElem, "weightBalance");\r
+ BoneInfo boneA = this.boneMap.get(boneId1);\r
+ BoneInfo boneB = this.boneMap.get(boneId2);\r
+ vertex.setBonePair(boneA, boneB);\r
+ vertex.setWeightA(weight);\r
+ }\r
+\r
+ ListUtil.assignIndexedSerial(vertexList);\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildSurfaceList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element surfaceGroupListElem =\r
+ getChild(pmdModelElem, "surfaceGroupList");\r
+\r
+ for(Element surfaceGroupElem :\r
+ eachChild(surfaceGroupListElem, "surfaceGroup") ){\r
+\r
+ String groupId = getStringAttr(surfaceGroupElem, "surfaceGroupId");\r
+ List<Surface> surfaceList = buildSurface(surfaceGroupElem);\r
+\r
+ this.surfaceGroupMap.put(groupId, surfaceList);\r
+ }\r
+ }\r
+\r
+ private List<Surface> buildSurface(Element surfaceGroupElem)\r
+ throws TogaXmlException{\r
+ List<Surface> result = new ArrayList<Surface>();\r
+\r
+ for(Element surfaceElem : eachChild(surfaceGroupElem, "surface")){\r
+ Surface surface = new Surface();\r
+ result.add(surface);\r
+\r
+ String id1 = getStringAttr(surfaceElem, "vtxIdRef1");\r
+ String id2 = getStringAttr(surfaceElem, "vtxIdRef2");\r
+ String id3 = getStringAttr(surfaceElem, "vtxIdRef3");\r
+\r
+ Vertex vertex1 = this.vertexMap.get(id1);\r
+ Vertex vertex2 = this.vertexMap.get(id2);\r
+ Vertex vertex3 = this.vertexMap.get(id3);\r
+\r
+ surface.setTriangle(vertex1, vertex2, vertex3);\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+ private void buildMaterialList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element materialListElem =\r
+ getChild(pmdModelElem, "materialList");\r
+\r
+ List<Surface> surfaceList = this.model.getSurfaceList();\r
+ List<Material> materialList = this.model.getMaterialList();\r
+\r
+ for(Element materialElem : eachChild(materialListElem, "material")){\r
+ Material material = new Material();\r
+ materialList.add(material);\r
+\r
+ material.getShadeInfo().setToonMap(this.model.getToonMap());\r
+\r
+ String surfaceGroupId =\r
+ getStringAttr(materialElem, "surfaceGroupIdRef");\r
+ List<Surface> surfaceGroup =\r
+ this.surfaceGroupMap.get(surfaceGroupId);\r
+ surfaceList.addAll(surfaceGroup);\r
+ material.getSurfaceList().addAll(surfaceGroup);\r
+\r
+ boolean hasEdge = getBooleanAttr(materialElem, "showEdge");\r
+ material.setEdgeAppearance(hasEdge);\r
+\r
+ ShadeInfo shadeInfo = material.getShadeInfo();\r
+\r
+ int toonIdx;\r
+ if(hasChild(materialElem, "toon")){\r
+ Element toonElem = getChild(materialElem, "toon");\r
+ String toonId = getStringAttr(toonElem, "toonFileIdRef");\r
+ toonIdx = this.toonIdxMap.get(toonId);\r
+ }else{\r
+ toonIdx = 255;\r
+ }\r
+ shadeInfo.setToonIndex(toonIdx);\r
+\r
+ if(hasChild(materialElem, "textureFile")){\r
+ Element textureFileElem =\r
+ getChild(materialElem, "textureFile");\r
+ String textureFile =\r
+ getSjisFileNameAttr(textureFileElem, "winFileName");\r
+ shadeInfo.setTextureFileName(textureFile);\r
+ }\r
+\r
+ if(hasChild(materialElem, "spheremapFile")){\r
+ Element spheremapFileElem =\r
+ getChild(materialElem, "spheremapFile");\r
+ String spheremapFile =\r
+ getSjisFileNameAttr(spheremapFileElem, "winFileName");\r
+ shadeInfo.setSpheremapFileName(spheremapFile);\r
+ }\r
+\r
+ float red;\r
+ float green;\r
+ float blue;\r
+\r
+ Element diffuseElem = getChild(materialElem, "diffuse");\r
+ red = getFloatAttr(diffuseElem, "r");\r
+ green = getFloatAttr(diffuseElem, "g");\r
+ blue = getFloatAttr(diffuseElem, "b");\r
+ float alpha = getFloatAttr(diffuseElem, "alpha");\r
+ Color diffuse = new Color(red, green, blue, alpha);\r
+ material.setDiffuseColor(diffuse);\r
+\r
+ Element specularElem = getChild(materialElem, "specular");\r
+ red = getFloatAttr(specularElem, "r");\r
+ green = getFloatAttr(specularElem, "g");\r
+ blue = getFloatAttr(specularElem, "b");\r
+ float shininess = getFloatAttr(specularElem, "shininess");\r
+ Color specular = new Color(red, green, blue);\r
+ material.setSpecularColor(specular);\r
+ material.setShininess(shininess);\r
+\r
+ Element ambientElem = getChild(materialElem, "ambient");\r
+ red = getFloatAttr(ambientElem, "r");\r
+ green = getFloatAttr(ambientElem, "g");\r
+ blue = getFloatAttr(ambientElem, "b");\r
+ Color ambient = new Color(red, green, blue);\r
+ material.setAmbientColor(ambient);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildIkChainList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element ikChainListElem =\r
+ getChild(pmdModelElem, "ikChainList");\r
+\r
+ List<IKChain> ikChainList = this.model.getIKChainList();\r
+\r
+ for(Element ikChainElem : eachChild(ikChainListElem, "ikChain")){\r
+ IKChain ikChain = new IKChain();\r
+ ikChainList.add(ikChain);\r
+\r
+ String ikBoneIdRef = getStringAttr(ikChainElem, "ikBoneIdRef");\r
+ int rucursiveDepth = getIntegerAttr(ikChainElem, "recursiveDepth");\r
+ float weight = getFloatAttr(ikChainElem, "weight");\r
+\r
+ BoneInfo ikBone = this.boneMap.get(ikBoneIdRef);\r
+ ikChain.setIkBone(ikBone);\r
+ ikChain.setIKDepth(rucursiveDepth);\r
+ ikChain.setIKWeight(weight);\r
+\r
+ List<BoneInfo> chainList = ikChain.getChainedBoneList();\r
+\r
+ for(Element orderElem : eachChild(ikChainElem, "chainOrder")){\r
+ String boneIdRef = getStringAttr(orderElem, "boneIdRef");\r
+ BoneInfo chaindBone = this.boneMap.get(boneIdRef);\r
+ chainList.add(chaindBone);\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildMorphList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element morphListElem =\r
+ getChild(pmdModelElem, "morphList");\r
+\r
+ Map<MorphType, List<MorphPart>> morphMap = this.model.getMorphMap();\r
+\r
+ for(Element morphElem : eachChild(morphListElem, "morph")){\r
+ MorphPart morphPart = new MorphPart();\r
+\r
+ I18nText name = morphPart.getMorphName();\r
+ buildI18nName(morphElem, name);\r
+\r
+ String type = getStringAttr(morphElem, "type");\r
+ MorphType morphType = MorphType.valueOf(type);\r
+ morphPart.setMorphType(morphType);\r
+\r
+ List<MorphVertex> morphVertexList = morphPart.getMorphVertexList();\r
+\r
+ for(Element morphVertexElem : eachChild(morphElem, "morphVertex")){\r
+ String vtxIdRef = getStringAttr(morphVertexElem, "vtxIdRef");\r
+ Vertex baseVertex = this.vertexMap.get(vtxIdRef);\r
+ float xOff = getFloatAttr(morphVertexElem, "xOff");\r
+ float yOff = getFloatAttr(morphVertexElem, "yOff");\r
+ float zOff = getFloatAttr(morphVertexElem, "zOff");\r
+\r
+ MorphVertex morphVertex = new MorphVertex();\r
+ morphVertex.setBaseVertex(baseVertex);\r
+ Pos3d position = morphVertex.getOffset();\r
+ position.setXPos(xOff);\r
+ position.setYPos(yOff);\r
+ position.setZPos(zOff);\r
+\r
+ morphVertexList.add(morphVertex);\r
+ }\r
+\r
+ morphMap.get(morphType).add(morphPart);\r
+ }\r
+\r
+ List<MorphPart> serialList = new LinkedList<MorphPart>();\r
+ MorphPart baseDummy = new MorphPart();\r
+ serialList.add(baseDummy);\r
+ for(MorphPart part : morphMap.get(MorphType.EYEBROW)){\r
+ serialList.add(part);\r
+ }\r
+ for(MorphPart part : morphMap.get(MorphType.EYE)){\r
+ serialList.add(part);\r
+ }\r
+ for(MorphPart part : morphMap.get(MorphType.LIP)){\r
+ serialList.add(part);\r
+ }\r
+ for(MorphPart part : morphMap.get(MorphType.EXTRA)){\r
+ serialList.add(part);\r
+ }\r
+ ListUtil.assignIndexedSerial(serialList);\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildBoneGroupList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element boneGroupListElem =\r
+ getChild(pmdModelElem, "boneGroupList");\r
+\r
+ List<BoneGroup> boneGroupList = this.model.getBoneGroupList();\r
+ BoneGroup defaultGroup = new BoneGroup();\r
+ boneGroupList.add(defaultGroup);\r
+\r
+ for(Element boneGroupElem : eachChild(boneGroupListElem, "boneGroup")){\r
+ BoneGroup group = new BoneGroup();\r
+ boneGroupList.add(group);\r
+\r
+ I18nText name = group.getGroupName();\r
+ buildI18nName(boneGroupElem, name);\r
+\r
+ for(Element boneGroupMemberElem : eachChild(boneGroupElem, "boneGroupMember")){\r
+ String boneIdRef = getStringAttr(boneGroupMemberElem, "boneIdRef");\r
+ BoneInfo bone = this.boneMap.get(boneIdRef);\r
+ group.getBoneList().add(bone);\r
+ }\r
+ }\r
+\r
+ ListUtil.assignIndexedSerial(boneGroupList);\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildRigidList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element rigidListElem =\r
+ getChild(pmdModelElem, "rigidList");\r
+\r
+ List<RigidInfo> rigidList = this.model.getRigidList();\r
+\r
+ for(Element rigidElem : eachChild(rigidListElem, "rigid")){\r
+ RigidInfo rigid = new RigidInfo();\r
+ rigidList.add(rigid);\r
+\r
+ I18nText name = rigid.getRigidName();\r
+ buildI18nName(rigidElem, name);\r
+\r
+ String behavior = getStringAttr(rigidElem, "behavior");\r
+ RigidBehaviorType type = RigidBehaviorType.valueOf(behavior);\r
+ rigid.setBehaviorType(type);\r
+\r
+ String rigidId = getStringAttr(rigidElem, "rigidId");\r
+ this.rigidMap.put(rigidId, rigid);\r
+\r
+ Element linkedBoneElem = getChild(rigidElem, "linkedBone");\r
+ String boneIdRef = getStringAttr(linkedBoneElem, "boneIdRef");\r
+ BoneInfo linkedBone = this.boneMap.get(boneIdRef);\r
+ rigid.setLinkedBone(linkedBone);\r
+\r
+ RigidShape rigidShape = rigid.getRigidShape();\r
+ if(hasChild(rigidElem, "rigidShapeSphere")){\r
+ Element shapeElem =\r
+ getChild(rigidElem, "rigidShapeSphere");\r
+ float radius = getFloatAttr(shapeElem, "radius");\r
+ rigidShape.setShapeType(RigidShapeType.SPHERE);\r
+ rigidShape.setRadius(radius);\r
+ }\r
+ if(hasChild(rigidElem, "rigidShapeBox")){\r
+ Element shapeElem =\r
+ getChild(rigidElem, "rigidShapeBox");\r
+ float width = getFloatAttr(shapeElem, "width");\r
+ float height = getFloatAttr(shapeElem, "height");\r
+ float depth = getFloatAttr(shapeElem, "depth");\r
+ rigidShape.setShapeType(RigidShapeType.BOX);\r
+ rigidShape.setWidth(width);\r
+ rigidShape.setHeight(height);\r
+ rigidShape.setDepth(depth);\r
+ }\r
+ if(hasChild(rigidElem, "rigidShapeCapsule")){\r
+ Element shapeElem =\r
+ getChild(rigidElem, "rigidShapeCapsule");\r
+ float height = getFloatAttr(shapeElem, "height");\r
+ float radius = getFloatAttr(shapeElem, "radius");\r
+ rigidShape.setShapeType(RigidShapeType.CAPSULE);\r
+ rigidShape.setHeight(height);\r
+ rigidShape.setRadius(radius);\r
+ }\r
+\r
+ float xVal;\r
+ float yVal;\r
+ float zVal;\r
+\r
+ Element positionElem = getChild(rigidElem, "position");\r
+ xVal = getFloatAttr(positionElem, "x");\r
+ yVal = getFloatAttr(positionElem, "y");\r
+ zVal = getFloatAttr(positionElem, "z");\r
+ Pos3d position = rigid.getPosition();\r
+ position.setXPos(xVal);\r
+ position.setYPos(yVal);\r
+ position.setZPos(zVal);\r
+\r
+ Element radRotationElem = getChild(rigidElem, "radRotation");\r
+ xVal = getFloatAttr(radRotationElem, "xRad");\r
+ yVal = getFloatAttr(radRotationElem, "yRad");\r
+ zVal = getFloatAttr(radRotationElem, "zRad");\r
+ Rad3d rotation = rigid.getRotation();\r
+ rotation.setXRad(xVal);\r
+ rotation.setYRad(yVal);\r
+ rotation.setZRad(zVal);\r
+\r
+ Element dynamicsElem = getChild(rigidElem, "dynamics");\r
+ float mass = getFloatAttr(dynamicsElem, "mass");\r
+ float dampingPosition = getFloatAttr(dynamicsElem, "dampingPosition");\r
+ float dampingRotation = getFloatAttr(dynamicsElem, "dampingRotation");\r
+ float restitution = getFloatAttr(dynamicsElem, "restitution");\r
+ float friction = getFloatAttr(dynamicsElem, "friction");\r
+ DynamicsInfo dynamics = rigid.getDynamicsInfo();\r
+ dynamics.setMass(mass);\r
+ dynamics.setDampingPosition(dampingPosition);\r
+ dynamics.setDampingRotation(dampingRotation);\r
+ dynamics.setRestitution(restitution);\r
+ dynamics.setFriction(friction);\r
+ }\r
+\r
+ ListUtil.assignIndexedSerial(rigidList);\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildRigidGroupList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element rigidGroupListElem =\r
+ getChild(pmdModelElem, "rigidGroupList");\r
+\r
+ List<RigidGroup> groupList = this.model.getRigidGroupList();\r
+\r
+ for(Element rigidGroupElem : eachChild(rigidGroupListElem, "rigidGroup")){\r
+ RigidGroup rigidGroup = new RigidGroup();\r
+ groupList.add(rigidGroup);\r
+\r
+ String rigidGroupId = getStringAttr(rigidGroupElem, "rigidGroupId");\r
+ this.rigidGroupMap.put(rigidGroupId, rigidGroup);\r
+\r
+ for(Element memberElem : eachChild(rigidGroupElem, "rigidGroupMember")){\r
+ String rigidIdRef = getStringAttr(memberElem, "rigidIdRef");\r
+ RigidInfo rigid = this.rigidMap.get(rigidIdRef);\r
+ rigidGroup.getRigidList().add(rigid);\r
+ rigid.setRigidGroup(rigidGroup);\r
+ }\r
+ }\r
+\r
+ while(groupList.size() < 16){\r
+ RigidGroup rigidGroup = new RigidGroup();\r
+ groupList.add(rigidGroup);\r
+ }\r
+\r
+ ListUtil.assignIndexedSerial(groupList);\r
+\r
+ return;\r
+ }\r
+\r
+ private void resolveThroughRigidGroup(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element rigidListElem =\r
+ getChild(pmdModelElem, "rigidList");\r
+\r
+ List<RigidInfo> rigidList = this.model.getRigidList();\r
+\r
+ int serialNum = 0;\r
+ for(Element rigidElem : eachChild(rigidListElem, "rigid")){\r
+ RigidInfo rigid = rigidList.get(serialNum++);\r
+ for(Element groupElem : eachChild(rigidElem, "throughRigidGroup")){\r
+ String groupId = getStringAttr(groupElem, "rigidGroupIdRef");\r
+ RigidGroup group = this.rigidGroupMap.get(groupId);\r
+ rigid.getThroughGroupColl().add(group);\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+ private void buildJointList(Element pmdModelElem)\r
+ throws TogaXmlException{\r
+ Element jointListElem =\r
+ getChild(pmdModelElem, "jointList");\r
+\r
+ List<JointInfo> jointList = this.model.getJointList();\r
+\r
+ for(Element jointElem : eachChild(jointListElem, "joint")){\r
+ JointInfo joint = new JointInfo();\r
+ jointList.add(joint);\r
+\r
+ I18nText name = joint.getJointName();\r
+ buildI18nName(jointElem, name);\r
+\r
+ Element rigidPairElem = getChild(jointElem, "jointedRigidPair");\r
+ String rigidIdRef1 = getStringAttr(rigidPairElem, "rigidIdRef1");\r
+ String rigidIdRef2 = getStringAttr(rigidPairElem, "rigidIdRef2");\r
+ RigidInfo rigid1 = this.rigidMap.get(rigidIdRef1);\r
+ RigidInfo rigid2 = this.rigidMap.get(rigidIdRef2);\r
+ joint.setRigidPair(rigid1, rigid2);\r
+\r
+ float xVal;\r
+ float yVal;\r
+ float zVal;\r
+ float xFrom;\r
+ float xTo;\r
+ float yFrom;\r
+ float yTo;\r
+ float zFrom;\r
+ float zTo;\r
+\r
+ Pos3d position = joint.getPosition();\r
+ Element positionElem = getChild(jointElem, "position");\r
+ xVal = getFloatAttr(positionElem, "x");\r
+ yVal = getFloatAttr(positionElem, "y");\r
+ zVal = getFloatAttr(positionElem, "z");\r
+ position.setXPos(xVal);\r
+ position.setYPos(yVal);\r
+ position.setZPos(zVal);\r
+\r
+ TripletRange limitPosition = joint.getPositionRange();\r
+ Element limitPositionElem = getChild(jointElem, "limitPosition");\r
+ xFrom = getFloatAttr(limitPositionElem, "xFrom");\r
+ xTo = getFloatAttr(limitPositionElem, "xTo");\r
+ yFrom = getFloatAttr(limitPositionElem, "yFrom");\r
+ yTo = getFloatAttr(limitPositionElem, "yTo");\r
+ zFrom = getFloatAttr(limitPositionElem, "zFrom");\r
+ zTo = getFloatAttr(limitPositionElem, "zTo");\r
+ limitPosition.setXRange(xFrom, xTo);\r
+ limitPosition.setYRange(yFrom, yTo);\r
+ limitPosition.setZRange(zFrom, zTo);\r
+\r
+ Rad3d rotation = joint.getRotation();\r
+ Element rotationElem = getChild(jointElem, "radRotation");\r
+ xVal = getFloatAttr(rotationElem, "xRad");\r
+ yVal = getFloatAttr(rotationElem, "yRad");\r
+ zVal = getFloatAttr(rotationElem, "zRad");\r
+ rotation.setXRad(xVal);\r
+ rotation.setYRad(yVal);\r
+ rotation.setZRad(zVal);\r
+\r
+ TripletRange limitRotation = joint.getRotationRange();\r
+ Element limitRotationElem = getChild(jointElem, "limitRotation");\r
+ xFrom = getFloatAttr(limitRotationElem, "xFrom");\r
+ xTo = getFloatAttr(limitRotationElem, "xTo");\r
+ yFrom = getFloatAttr(limitRotationElem, "yFrom");\r
+ yTo = getFloatAttr(limitRotationElem, "yTo");\r
+ zFrom = getFloatAttr(limitRotationElem, "zFrom");\r
+ zTo = getFloatAttr(limitRotationElem, "zTo");\r
+ limitRotation.setXRange(xFrom, xTo);\r
+ limitRotation.setYRange(yFrom, yTo);\r
+ limitRotation.setZRange(zFrom, zTo);\r
+\r
+ Pos3d elasticPosition = joint.getElasticPosition();\r
+ Element elasticPositionElem = getChild(jointElem, "elasticPosition");\r
+ xVal = getFloatAttr(elasticPositionElem, "x");\r
+ yVal = getFloatAttr(elasticPositionElem, "y");\r
+ zVal = getFloatAttr(elasticPositionElem, "z");\r
+ elasticPosition.setXPos(xVal);\r
+ elasticPosition.setYPos(yVal);\r
+ elasticPosition.setZPos(zVal);\r
+\r
+ Deg3d elasticRotation = joint.getElasticRotation();\r
+ Element elasticRotationElem = getChild(jointElem, "elasticRotation");\r
+ xVal = getFloatAttr(elasticRotationElem, "xDeg");\r
+ yVal = getFloatAttr(elasticRotationElem, "yDeg");\r
+ zVal = getFloatAttr(elasticRotationElem, "zDeg");\r
+ elasticRotation.setXDeg(xVal);\r
+ elasticRotation.setYDeg(yVal);\r
+ elasticRotation.setZDeg(zVal);\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+}\r