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