OSDN Git Service

テストセット整備
authorOlyutorskii <olyutorskii@users.osdn.me>
Sun, 27 Jan 2013 22:28:46 +0000 (07:28 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Sun, 27 Jan 2013 22:28:46 +0000 (07:28 +0900)
モーフ数0のデータを読み込めるように

70 files changed:
CHANGELOG.txt
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Exporter.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/xml/PmdXmlExporter.java with 73% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Loader.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/xml/Xml2PmdLoader.java with 99% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/Xml101009Resources.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/xml/PmdXmlResources.java with 92% similarity]
src/main/java/jp/sfjp/mikutoga/pmd/xml101009/package-info.java [moved from src/main/java/jp/sourceforge/mikutoga/pmd/model/xml/package-info.java with 52% similarity]
src/main/java/jp/sourceforge/mikutoga/pmd/model/binio/TextBuilder.java
src/main/java/jp/sourceforge/mikutoga/pmd2xml/ModelFileTypes.java [deleted file]
src/main/java/jp/sourceforge/mikutoga/pmd2xml/OptInfo.java
src/main/java/jp/sourceforge/mikutoga/pmd2xml/Pmd2XmlConv.java
src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.dtd [moved from src/main/resources/jp/sourceforge/mikutoga/pmd/model/xml/resources/pmdxml-101009.dtd with 100% similarity]
src/main/resources/jp/sfjp/mikutoga/pmd/xml101009/resources/pmdxml-101009.xsd [moved from src/main/resources/jp/sourceforge/mikutoga/pmd/model/xml/resources/pmdxml-101009.xsd with 100% similarity]
src/test/java/testdata/CnvAssert.java
src/test/java/testdata/TestDriver.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/bone/BoneTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/charset/CharsetTest.java [moved from src/test/java/testdata/charset/CharsetTest.java with 83% similarity]
src/test/java/testdata/pmd101009/group/GroupTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/i18n/I18nTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/ik/IkBoneTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/material/MaterialTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/minimum/MinimumTest.java [moved from src/test/java/testdata/minimum/MinimumTest.java with 83% similarity]
src/test/java/testdata/pmd101009/morph/MorphTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/numeric/NumericTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/rigid/RigidTest.java [new file with mode: 0644]
src/test/java/testdata/pmd101009/small/SmallTest.java [new file with mode: 0644]
src/test/resources/testdata/charset/Readme.txt [deleted file]
src/test/resources/testdata/charset/test.pmd [deleted file]
src/test/resources/testdata/minimum/Readme.txt [deleted file]
src/test/resources/testdata/pmd101009/bone/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/bone/allbone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/bone/allbone.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/charset/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/charset/charset.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/charset/result.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/charset/source.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/group/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/group/boneGroup.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/group/boneGroup.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/i18n/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/i18n/i18n.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/i18n/i18n.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/ik/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/ik/ikBone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/ik/ikBone.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/material/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/material/material.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/material/material.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/minimum/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/minimum/minimum.pmd [moved from src/test/resources/testdata/minimum/test.pmd with 100% similarity]
src/test/resources/testdata/pmd101009/minimum/minimum.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/morph/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/morph/allmorph.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/morph/allmorph.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/numeric/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/numeric/numeric.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/numeric/result.xml [moved from src/test/resources/testdata/charset/result.xml with 68% similarity]
src/test/resources/testdata/pmd101009/numeric/source.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/rigid/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/rigid/allrigid.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/rigid/allrigid.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/Readme.txt [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlybone.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlybone.xml [moved from src/test/resources/testdata/minimum/test.xml with 86% similarity]
src/test/resources/testdata/pmd101009/small/onlyjoint.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlyjoint.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlymorph.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlymorph.xml [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlyrigid.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlyrigid.xml [moved from src/test/resources/testdata/charset/source.xml with 75% similarity]
src/test/resources/testdata/pmd101009/small/onlytriangle.pmd [new file with mode: 0644]
src/test/resources/testdata/pmd101009/small/onlytriangle.xml [new file with mode: 0644]

index 539010a..44148b5 100644 (file)
@@ -7,6 +7,7 @@ Pmd2XML 変更履歴
 X.XXX.X (20XX-XX-XX)
     ・Maven3対応。
     ・XML出力改行コードの指定が可能になる。
 X.XXX.X (20XX-XX-XX)
     ・Maven3対応。
     ・XML出力改行コードの指定が可能になる。
+    ・モーフ数0のモデルデータを読み書きできないバグに対処。(チケット#23394)
 
 1.102.4 (2010-10-09)
     ・TogaGem1.105.2のバグ修正(接続ボーンを持たない剛体の件)に対処。
 
 1.102.4 (2010-10-09)
     ・TogaGem1.105.2のバグ修正(接続ボーンを持たない剛体の件)に対処。
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.xml;
+package jp.sfjp.mikutoga.pmd.xml101009;
 
 import java.awt.Color;
 import java.io.IOException;
 
 import java.awt.Color;
 import java.io.IOException;
@@ -43,14 +43,13 @@ import jp.sourceforge.mikutoga.xml.BasicXmlExporter;
 import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
 
 /**
 import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
 
 /**
- * XML形式でPMDモデルデータを出力する。
+ * 101009形式XMLでPMDモデルデータを出力する。
  */
  */
-public class PmdXmlExporter extends BasicXmlExporter{
+public class Xml101009Exporter extends BasicXmlExporter{
 
     private static final String TOP_COMMENT =
 
     private static final String TOP_COMMENT =
-            "  MikuMikuDance\n    model-data(*.pmd) on XML";
-    private static final String SCHEMA_LOCATION =
-            PmdXmlResources.NS_PMDXML + " " + PmdXmlResources.SCHEMA_PMDXML;
+              "  MikuMikuDance\n"
+            + "    model-data(*.pmd) on XML";
 
     /** 改行文字列 CR。 */
     private static final String CR = "\r";       // 0x0d
 
     /** 改行文字列 CR。 */
     private static final String CR = "\r";       // 0x0d
@@ -99,7 +98,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * 文字エンコーディングはUTF-8が用いられる。
      * @param stream 出力ストリーム
      */
      * 文字エンコーディングはUTF-8が用いられる。
      * @param stream 出力ストリーム
      */
-    public PmdXmlExporter(OutputStream stream){
+    public Xml101009Exporter(OutputStream stream){
         super(stream);
         return;
     }
         super(stream);
         return;
     }
@@ -134,7 +133,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @throws IOException {@inheritDoc}
      */
     @Override
      * @throws IOException {@inheritDoc}
      */
     @Override
-    public PmdXmlExporter ind() throws IOException{
+    public Xml101009Exporter ind() throws IOException{
         super.ind();
         return this;
     }
         super.ind();
         return this;
     }
@@ -145,7 +144,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putUnescapedComment(CharSequence seq)
+    protected Xml101009Exporter putUnescapedComment(CharSequence seq)
             throws IOException{
         if( ! isBasicLatinOnlyOut() ) return this;
         if(hasOnlyBasicLatin(seq)) return this;
             throws IOException{
         if( ! isBasicLatinOnlyOut() ) return this;
         if(hasOnlyBasicLatin(seq)) return this;
@@ -160,14 +159,14 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putI18nName(I18nText text) throws IOException{
+    protected Xml101009Exporter putI18nName(I18nText text) throws IOException{
         for(String lang639 : text.lang639CodeList()){
             if(lang639.equals(I18nText.CODE639_PRIMARY)) continue;
             String name = text.getI18nText(lang639);
         for(String lang639 : text.lang639CodeList()){
             if(lang639.equals(I18nText.CODE639_PRIMARY)) continue;
             String name = text.getI18nText(lang639);
-            ind().put("<i18nName ");
+            ind().putRawText("<i18nName ");
             putAttr("lang", lang639).sp();
             putAttr("name", name);
             putAttr("lang", lang639).sp();
             putAttr("name", name);
-            put(" />");
+            putRawText(" />");
             putUnescapedComment(name);
             ln();
         }
             putUnescapedComment(name);
             ln();
         }
@@ -182,13 +181,13 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putNumberedIdAttr(CharSequence attrName,
+    protected Xml101009Exporter putNumberedIdAttr(CharSequence attrName,
                                                  CharSequence prefix,
                                                  int num )
             throws IOException{
                                                  CharSequence prefix,
                                                  int num )
             throws IOException{
-        put(attrName).put("=\"");
-        put(prefix).put(num);
-        put('"');
+        putRawText(attrName).putRawText("=\"");
+        putRawText(prefix).putXsdInt(num);
+        putRawCh('"');
         return this;
     }
 
         return this;
     }
 
@@ -200,7 +199,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putNumberedIdAttr(CharSequence attrName,
+    protected Xml101009Exporter putNumberedIdAttr(CharSequence attrName,
                                                  CharSequence prefix,
                                                  SerialNumbered numbered )
             throws IOException{
                                                  CharSequence prefix,
                                                  SerialNumbered numbered )
             throws IOException{
@@ -214,13 +213,13 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putPosition(MkPos3D position)
+    protected Xml101009Exporter putPosition(MkPos3D position)
             throws IOException{
             throws IOException{
-        put("<position ");
+        putRawText("<position ");
         putFloatAttr("x", (float) position.getXpos()).sp();
         putFloatAttr("y", (float) position.getYpos()).sp();
         putFloatAttr("z", (float) position.getZpos()).sp();
         putFloatAttr("x", (float) position.getXpos()).sp();
         putFloatAttr("y", (float) position.getYpos()).sp();
         putFloatAttr("z", (float) position.getZpos()).sp();
-        put("/>");
+        putRawText("/>");
         return this;
     }
 
         return this;
     }
 
@@ -230,13 +229,13 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putRadRotation(Rad3d rotation)
+    protected Xml101009Exporter putRadRotation(Rad3d rotation)
             throws IOException{
             throws IOException{
-        put("<radRotation ");
+        putRawText("<radRotation ");
         putFloatAttr("xRad", rotation.getXRad()).sp();
         putFloatAttr("yRad", rotation.getYRad()).sp();
         putFloatAttr("zRad", rotation.getZRad()).sp();
         putFloatAttr("xRad", rotation.getXRad()).sp();
         putFloatAttr("yRad", rotation.getYRad()).sp();
         putFloatAttr("zRad", rotation.getZRad()).sp();
-        put("/>");
+        putRawText("/>");
         return this;
     }
 
         return this;
     }
 
@@ -246,9 +245,12 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putLocalNameComment(I18nText name)
+    protected Xml101009Exporter putLocalNameComment(I18nText name)
             throws IOException{
         String localName = name.getText();
             throws IOException{
         String localName = name.getText();
+        if(localName.isEmpty()){
+            localName = "[NAMELESS]";
+        }
         ind().putLineComment(localName);
         return this;
     }
         ind().putLineComment(localName);
         return this;
     }
@@ -260,7 +262,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    protected PmdXmlExporter putPrimaryNameAttr(CharSequence attrName,
+    protected Xml101009Exporter putPrimaryNameAttr(CharSequence attrName,
                                                    I18nText name)
             throws IOException{
         String primaryName = name.getPrimaryText();
                                                    I18nText name)
             throws IOException{
         String primaryName = name.getPrimaryText();
@@ -274,29 +276,32 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @throws IOException 出力エラー
      */
     public void putPmdModel(PmdModel model) throws IOException{
      * @throws IOException 出力エラー
      */
     public void putPmdModel(PmdModel model) throws IOException{
-        ind().put("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>").ln(2);
+        ind().putRawText("<?xml")
+                .sp().putAttr("version","1.0")
+                .sp().putAttr("encoding","UTF-8")
+                .sp().putRawText("?>").ln(2);
 
         ind().putBlockComment(TOP_COMMENT).ln(2);
 
 
         ind().putBlockComment(TOP_COMMENT).ln(2);
 
-        /*
-        ind().put("<!DOCTYPE pmdModel").ln();
-        ind().put(" SYSTEM \"")
-             .put(PmdXmlResources.DTD_PMDXML)
-             .put("\" >")
-             .ln(3);
-         */
-
         I18nText modelName = model.getModelName();
         ind().putLocalNameComment(modelName).ln();
         I18nText modelName = model.getModelName();
         ind().putLocalNameComment(modelName).ln();
-        ind().put("<pmdModel").ln();
+        ind().putRawText("<pmdModel").ln();
         pushNest();
         pushNest();
-        ind().putAttr("xmlns", PmdXmlResources.NS_PMDXML).ln();
+
+        ind().putAttr("xmlns", Xml101009Resources.NS_PMDXML).ln();
         ind().putAttr("xmlns:xsi", XmlResourceResolver.NS_XSD).ln();
         ind().putAttr("xmlns:xsi", XmlResourceResolver.NS_XSD).ln();
-        ind().putAttr("xsi:schemaLocation", SCHEMA_LOCATION).ln();
-        ind().putAttr("schemaVersion", PmdXmlResources.VER_PMDXML).ln(2);
+
+        ind().putRawText("xsi:schemaLocation").putRawText("=\"");
+        putRawText(Xml101009Resources.NS_PMDXML).ln();
+        pushNest();
+        ind().putRawText(Xml101009Resources.SCHEMA_PMDXML).putRawCh('"').ln();
+        popNest();
+
+        ind().putAttr("schemaVersion", Xml101009Resources.VER_PMDXML).ln(2);
         ind().putPrimaryNameAttr("name", modelName).ln();
         ind().putPrimaryNameAttr("name", modelName).ln();
+
         popNest();
         popNest();
-        put(">").ln(2);
+        putRawText(">").ln(2);
 
         putModelInfo(model).flush();
         putMetaInfo(model).flush();
 
         putModelInfo(model).flush();
         putMetaInfo(model).flush();
@@ -312,8 +317,8 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putSurfaceGroupList(model).flush();
         putVertexList(model).flush();
 
         putSurfaceGroupList(model).flush();
         putVertexList(model).flush();
 
-        ind().put("</pmdModel>").ln(2);
-        ind().put("<!-- EOF -->").ln();
+        ind().putRawText("</pmdModel>").ln(2);
+        ind().putRawText("<!-- EOF -->").ln();
 
         return;
     }
 
         return;
     }
@@ -324,7 +329,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putModelInfo(PmdModel model)
+    private Xml101009Exporter putModelInfo(PmdModel model)
             throws IOException{
         I18nText modelName = model.getModelName();
         putI18nName(modelName);
             throws IOException{
         I18nText modelName = model.getModelName();
         putI18nName(modelName);
@@ -347,23 +352,22 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putDescription(CharSequence lang639,
+    private Xml101009Exporter putDescription(CharSequence lang639,
                                               CharSequence content)
             throws IOException{
         String text = content.toString();
         text = text.replace(CRLF, LF);
         text = text.replace(CR,   LF);
 
                                               CharSequence content)
             throws IOException{
         String text = content.toString();
         text = text.replace(CRLF, LF);
         text = text.replace(CR,   LF);
 
-        ind().put("<description");
+        ind().putRawText("<description");
         if( ! I18nText.CODE639_PRIMARY.equals(lang639) ){
         if( ! I18nText.CODE639_PRIMARY.equals(lang639) ){
-            sp();
-            putAttr("lang", lang639);
+            sp().putAttr("lang", lang639).sp();
         }
         }
-        put(">").ln();
+        putRawText(">").ln();
 
         putBRedContent(text);
 
 
         putBRedContent(text);
 
-        ind().put("</description>").ln();
+        ind().putRawText("</description>").ln();
 
         if( ! hasOnlyBasicLatin(text) && isBasicLatinOnlyOut() ){
             putBlockComment(text);
 
         if( ! hasOnlyBasicLatin(text) && isBasicLatinOnlyOut() ){
             putBlockComment(text);
@@ -391,7 +395,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
             char ch = content.charAt(idx);
             if(ch == '\n'){
                 CharSequence seq = content.subSequence(startPos, idx);
             char ch = content.charAt(idx);
             if(ch == '\n'){
                 CharSequence seq = content.subSequence(startPos, idx);
-                putContent(seq).put("<br/>").ln();
+                putContent(seq).putRawText("<br/>").ln();
                 startPos = idx + 1;
             }
         }
                 startPos = idx + 1;
             }
         }
@@ -410,26 +414,26 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putMetaInfo(PmdModel model) throws IOException{
-        ind().put("<license>").ln();
-        ind().put("</license>").ln(2);
+    private Xml101009Exporter putMetaInfo(PmdModel model) throws IOException{
+        ind().putRawText("<license>").ln();
+        ind().putRawText("</license>").ln(2);
 
 
-        ind().put("<credits>").ln();
-        ind().put("</credits>").ln(2);
+        ind().putRawText("<credits>").ln();
+        ind().putRawText("</credits>").ln(2);
 
         if(this.generator != null){
 
         if(this.generator != null){
-            ind().put("<meta ");
+            ind().putRawText("<meta ");
             putAttr("name", "generator").sp()
                                         .putAttr("content", this.generator);
             putAttr("name", "generator").sp()
                                         .putAttr("content", this.generator);
-            put(" />").ln();
+            putRawText(" />").ln();
         }
 
         }
 
-        ind().put("<meta ");
+        ind().putRawText("<meta ");
         putAttr("name", "siteURL").sp().putAttr("content", "");
         putAttr("name", "siteURL").sp().putAttr("content", "");
-        put(" />").ln();
-        ind().put("<meta ");
+        putRawText(" />").ln();
+        ind().putRawText("<meta ");
         putAttr("name", "imageURL").sp().putAttr("content", "");
         putAttr("name", "imageURL").sp().putAttr("content", "");
-        put(" />").ln(2);
+        putRawText(" />").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -440,18 +444,22 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putMaterialList(PmdModel model)
+    private Xml101009Exporter putMaterialList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<materialList>").ln(2);
-        pushNest();
+        ind().putRawText("<materialList>").ln();
 
 
+        pushNest();
         int ct = 0;
         int ct = 0;
-        for(Material material : model.getMaterialList()){
+        boolean dumped = false;
+        List<Material> materialList = model.getMaterialList();
+        for(Material material : materialList){
+            if( ! dumped ) ln();
             putMaterial(material, ct++);
             putMaterial(material, ct++);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</materialList>").ln(2);
+
+        ind().putRawText("</materialList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -463,7 +471,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putMaterial(Material material, int no)
+    private Xml101009Exporter putMaterial(Material material, int no)
             throws IOException{
         String bool;
         if(material.getEdgeAppearance()) bool = "true";
             throws IOException{
         String bool;
         if(material.getEdgeAppearance()) bool = "true";
@@ -475,7 +483,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         if(local != null && local.length() > 0){
             ind().putLineComment(local).ln();
         }
         if(local != null && local.length() > 0){
             ind().putLineComment(local).ln();
         }
-        ind().put("<material ");
+        ind().putRawText("<material ");
         if(primary != null && primary.length() > 0){
             putAttr("name", primary).sp();
         }
         if(primary != null && primary.length() > 0){
             putAttr("name", primary).sp();
         }
@@ -483,7 +491,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putAttr("showEdge", bool);
         sp();
         putNumberedIdAttr("surfaceGroupIdRef", PFX_SURFACEGROUP, no);
         putAttr("showEdge", bool);
         sp();
         putNumberedIdAttr("surfaceGroupIdRef", PFX_SURFACEGROUP, no);
-        put('>').ln();
+        sp().putRawCh('>').ln();
         pushNest();
 
         putI18nName(name);
         pushNest();
 
         putI18nName(name);
@@ -492,40 +500,40 @@ public class PmdXmlExporter extends BasicXmlExporter{
 
         Color diffuse = material.getDiffuseColor();
         diffuse.getRGBComponents(rgba);
 
         Color diffuse = material.getDiffuseColor();
         diffuse.getRGBComponents(rgba);
-        ind().put("<diffuse ");
+        ind().putRawText("<diffuse ");
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
         putFloatAttr("alpha", rgba[3]).sp();
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
         putFloatAttr("alpha", rgba[3]).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         Color specular = material.getSpecularColor();
         specular.getRGBComponents(rgba);
         float shininess = material.getShininess();
 
         Color specular = material.getSpecularColor();
         specular.getRGBComponents(rgba);
         float shininess = material.getShininess();
-        ind().put("<specular ");
+        ind().putRawText("<specular ");
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
         putFloatAttr("shininess", shininess).sp();
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
         putFloatAttr("shininess", shininess).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         Color ambient = material.getAmbientColor();
         ambient.getRGBComponents(rgba);
 
         Color ambient = material.getAmbientColor();
         ambient.getRGBComponents(rgba);
-        ind().put("<ambient ");
+        ind().putRawText("<ambient ");
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
         putFloatAttr("r", rgba[0]).sp();
         putFloatAttr("g", rgba[1]).sp();
         putFloatAttr("b", rgba[2]).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         ShadeInfo shade = material.getShadeInfo();
         String textureFileName = shade.getTextureFileName();
         String spheremapFileName = shade.getSpheremapFileName();
 
         if(shade.isValidToonIndex()){
 
         ShadeInfo shade = material.getShadeInfo();
         String textureFileName = shade.getTextureFileName();
         String spheremapFileName = shade.getSpheremapFileName();
 
         if(shade.isValidToonIndex()){
-            ind().put("<toon ");
+            ind().putRawText("<toon ");
             int toonIdx = shade.getToonIndex();
             putNumberedIdAttr("toonFileIdRef", PFX_TOONFILE, toonIdx);
             int toonIdx = shade.getToonIndex();
             putNumberedIdAttr("toonFileIdRef", PFX_TOONFILE, toonIdx);
-            put(" />");
+            putRawText(" />");
             String toonFileName = shade.getToonFileName();
             if(toonFileName != null && toonFileName.length() > 0){
                 sp().putLineComment(toonFileName);
             String toonFileName = shade.getToonFileName();
             if(toonFileName != null && toonFileName.length() > 0){
                 sp().putLineComment(toonFileName);
@@ -534,19 +542,19 @@ public class PmdXmlExporter extends BasicXmlExporter{
         }
 
         if(textureFileName != null && textureFileName.length() > 0){
         }
 
         if(textureFileName != null && textureFileName.length() > 0){
-            ind().put("<textureFile ");
+            ind().putRawText("<textureFile ");
             putAttr("winFileName", textureFileName);
             putAttr("winFileName", textureFileName);
-            put(" />").ln();
+            putRawText(" />").ln();
         }
 
         if(spheremapFileName != null && spheremapFileName.length() > 0){
         }
 
         if(spheremapFileName != null && spheremapFileName.length() > 0){
-            ind().put("<spheremapFile ");
+            ind().putRawText("<spheremapFile ");
             putAttr("winFileName", spheremapFileName);
             putAttr("winFileName", spheremapFileName);
-            put(" />").ln();
+            putRawText(" />").ln();
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</material>").ln(2);
+        ind().putRawText("</material>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -557,9 +565,9 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putToonMap(PmdModel model)
+    private Xml101009Exporter putToonMap(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<toonMap>").ln();
+        ind().putRawText("<toonMap>").ln();
         pushNest();
 
         ToonMap map = model.getToonMap();
         pushNest();
 
         ToonMap map = model.getToonMap();
@@ -568,7 +576,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</toonMap>").ln(2);
+        ind().putRawText("</toonMap>").ln(2);
         return this;
     }
 
         return this;
     }
 
@@ -579,14 +587,14 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putToon(ToonMap map, int index)
+    private Xml101009Exporter putToon(ToonMap map, int index)
             throws IOException{
             throws IOException{
-        put("<toonDef ");
+        putRawText("<toonDef ");
         putNumberedIdAttr("toonFileId", PFX_TOONFILE, index).sp();
         putIntAttr("index", index).sp();
         String toonFile = map.getIndexedToon(index);
         putAttr("winFileName", toonFile);
         putNumberedIdAttr("toonFileId", PFX_TOONFILE, index).sp();
         putIntAttr("index", index).sp();
         String toonFile = map.getIndexedToon(index);
         putAttr("winFileName", toonFile);
-        put(" />");
+        putRawText(" />");
         putUnescapedComment(toonFile);
         return this;
     }
         putUnescapedComment(toonFile);
         return this;
     }
@@ -597,19 +605,23 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putSurfaceGroupList(PmdModel model)
+    private Xml101009Exporter putSurfaceGroupList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<surfaceGroupList>").ln(2);
-        pushNest();
+        ind().putRawText("<surfaceGroupList>").ln();
 
 
+        pushNest();
         int ct = 0;
         int ct = 0;
-        for(Material material : model.getMaterialList()){
+        boolean dumped = false;
+        List<Material> materialList = model.getMaterialList();
+        for(Material material : materialList){
             List<Surface> surfaceList = material.getSurfaceList();
             List<Surface> surfaceList = material.getSurfaceList();
+            if( ! dumped ) ln();
             putSurfaceList(surfaceList, ct++);
             putSurfaceList(surfaceList, ct++);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</surfaceGroupList>").ln(2);
+
+        ind().putRawText("</surfaceGroupList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -621,12 +633,12 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putSurfaceList(List<Surface> surfaceList,
+    private Xml101009Exporter putSurfaceList(List<Surface> surfaceList,
                                               int index)
             throws IOException{
                                               int index)
             throws IOException{
-        ind().put("<surfaceGroup ");
+        ind().putRawText("<surfaceGroup ");
         putNumberedIdAttr("surfaceGroupId", PFX_SURFACEGROUP, index);
         putNumberedIdAttr("surfaceGroupId", PFX_SURFACEGROUP, index);
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         for(Surface surface : surfaceList){
         pushNest();
 
         for(Surface surface : surfaceList){
@@ -634,7 +646,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</surfaceGroup>").ln(2);
+        ind().putRawText("</surfaceGroup>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -645,9 +657,9 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putSurface(Surface surface)
+    private Xml101009Exporter putSurface(Surface surface)
             throws IOException{
             throws IOException{
-        ind().put("<surface ");
+        ind().putRawText("<surface ");
 
         Vertex vertex1 = surface.getVertex1();
         Vertex vertex2 = surface.getVertex2();
 
         Vertex vertex1 = surface.getVertex1();
         Vertex vertex2 = surface.getVertex2();
@@ -657,7 +669,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putNumberedIdAttr("vtxIdRef2", PFX_VERTEX, vertex2).sp();
         putNumberedIdAttr("vtxIdRef3", PFX_VERTEX, vertex3).sp();
 
         putNumberedIdAttr("vtxIdRef2", PFX_VERTEX, vertex2).sp();
         putNumberedIdAttr("vtxIdRef3", PFX_VERTEX, vertex3).sp();
 
-        put("/>").ln();
+        putRawText("/>").ln();
         return this;
     }
 
         return this;
     }
 
@@ -667,17 +679,21 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putVertexList(PmdModel model)
+    private Xml101009Exporter putVertexList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<vertexList>").ln(2);
-        pushNest();
+        ind().putRawText("<vertexList>").ln();
 
 
-        for(Vertex vertex : model.getVertexList()){
+        pushNest();
+        boolean dumped = false;
+        List<Vertex> vertexList = model.getVertexList();
+        for(Vertex vertex : vertexList){
+            if( ! dumped ) ln();
             putVertex(vertex);
             putVertex(vertex);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</vertexList>").ln(2);
+
+        ind().putRawText("</vertexList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -688,45 +704,45 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putVertex(Vertex vertex)
+    private Xml101009Exporter putVertex(Vertex vertex)
             throws IOException{
         String bool;
         if(vertex.getEdgeAppearance()) bool = "true";
         else                           bool = "false";
 
             throws IOException{
         String bool;
         if(vertex.getEdgeAppearance()) bool = "true";
         else                           bool = "false";
 
-        ind().put("<vertex ");
+        ind().putRawText("<vertex ");
         putNumberedIdAttr("vtxId", PFX_VERTEX, vertex).sp();
         putAttr("showEdge", bool);
         putNumberedIdAttr("vtxId", PFX_VERTEX, vertex).sp();
         putAttr("showEdge", bool);
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         MkPos3D position = vertex.getPosition();
         ind().putPosition(position).ln();
 
         MkVec3D normal = vertex.getNormal();
         pushNest();
 
         MkPos3D position = vertex.getPosition();
         ind().putPosition(position).ln();
 
         MkVec3D normal = vertex.getNormal();
-        ind().put("<normal ");
+        ind().putRawText("<normal ");
         putFloatAttr("x", (float) normal.getXVal()).sp();
         putFloatAttr("y", (float) normal.getYVal()).sp();
         putFloatAttr("z", (float) normal.getZVal()).sp();
         putFloatAttr("x", (float) normal.getXVal()).sp();
         putFloatAttr("y", (float) normal.getYVal()).sp();
         putFloatAttr("z", (float) normal.getZVal()).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         MkPos2D uvPos = vertex.getUVPosition();
 
         MkPos2D uvPos = vertex.getUVPosition();
-        ind().put("<uvMap ");
+        ind().putRawText("<uvMap ");
         putFloatAttr("u", (float) uvPos.getXpos()).sp();
         putFloatAttr("v", (float) uvPos.getYpos()).sp();
         putFloatAttr("u", (float) uvPos.getXpos()).sp();
         putFloatAttr("v", (float) uvPos.getYpos()).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         BoneInfo boneA = vertex.getBoneA();
         BoneInfo boneB = vertex.getBoneB();
         int weight = vertex.getWeightA();
 
         BoneInfo boneA = vertex.getBoneA();
         BoneInfo boneB = vertex.getBoneB();
         int weight = vertex.getWeightA();
-        ind().put("<skinning ");
+        ind().putRawText("<skinning ");
         putNumberedIdAttr("boneIdRef1", PFX_BONE, boneA).sp();
         putNumberedIdAttr("boneIdRef2", PFX_BONE, boneB).sp();
         putIntAttr("weightBalance", weight).sp();
         putNumberedIdAttr("boneIdRef1", PFX_BONE, boneA).sp();
         putNumberedIdAttr("boneIdRef2", PFX_BONE, boneB).sp();
         putIntAttr("weightBalance", weight).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         popNest();
 
         popNest();
-        ind().put("</vertex>").ln(2);
+        ind().putRawText("</vertex>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -737,19 +753,22 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putBoneList(PmdModel model)
+    private Xml101009Exporter putBoneList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<boneList>").ln(2);
+        ind().putRawText("<boneList>").ln();
         pushNest();
 
         pushNest();
 
-        putBlockComment(BONETYPE_COMMENT).ln();
-
+        boolean dumped = false;
         for(BoneInfo bone : model.getBoneList()){
         for(BoneInfo bone : model.getBoneList()){
+            if( ! dumped ){
+                ln().putBlockComment(BONETYPE_COMMENT).ln();
+            }
             putBone(bone);
             putBone(bone);
+            dumped = true;
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</boneList>").ln(2);
+        ind().putRawText("</boneList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -760,17 +779,26 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putBone(BoneInfo bone)
+    private Xml101009Exporter putBone(BoneInfo bone)
             throws IOException{
         I18nText i18nName = bone.getBoneName();
         BoneType type = bone.getBoneType();
 
             throws IOException{
         I18nText i18nName = bone.getBoneName();
         BoneType type = bone.getBoneType();
 
-        putLocalNameComment(i18nName).putLineComment(type.getGuiName()).ln();
-        ind().put("<bone ");
+        StringBuilder boneComment = new StringBuilder();
+        String boneName = i18nName.getText();
+        if(boneName.isEmpty()){
+            boneName = "[NAMELESS]";
+        }
+        boneComment.append(boneName);
+        String typeName = type.getGuiName();
+        boneComment.append(" [").append(typeName).append(']');
+        ind().putLineComment(boneComment.toString()).ln();
+
+        ind().putRawText("<bone ");
         putPrimaryNameAttr("name", i18nName).sp();
         putNumberedIdAttr("boneId", PFX_BONE, bone).sp();
         putAttr("type", type.name());
         putPrimaryNameAttr("name", i18nName).sp();
         putNumberedIdAttr("boneId", PFX_BONE, bone).sp();
         putAttr("type", type.name());
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         putI18nName(i18nName);
         pushNest();
 
         putI18nName(i18nName);
@@ -780,44 +808,53 @@ public class PmdXmlExporter extends BasicXmlExporter{
 
         BoneInfo ikBone = bone.getIKBone();
         if(bone.getBoneType() == BoneType.LINKEDROT){
 
         BoneInfo ikBone = bone.getIKBone();
         if(bone.getBoneType() == BoneType.LINKEDROT){
-            ind().put("<rotationRatio ");
+            ind().putRawText("<rotationRatio ");
             putIntAttr("ratio", bone.getRotationRatio());
             putIntAttr("ratio", bone.getRotationRatio());
-            put(" />").ln();
+            putRawText(" />").ln();
         }else if(ikBone != null){
         }else if(ikBone != null){
-            ind().put("<ikBone ");
+            ind().putRawText("<ikBone ");
             putNumberedIdAttr("boneIdRef", PFX_BONE, ikBone);
             putNumberedIdAttr("boneIdRef", PFX_BONE, ikBone);
-            put(" /> ");
+            putRawText(" /> ");
             String ikBoneName = "Ref:" + ikBone.getBoneName().getText();
             putLineComment(ikBoneName);
             ln();
         }
 
             String ikBoneName = "Ref:" + ikBone.getBoneName().getText();
             putLineComment(ikBoneName);
             ln();
         }
 
-        StringBuilder chainComment = new StringBuilder();
-        ind().put("<boneChain");
         BoneInfo prev = bone.getPrevBone();
         BoneInfo next = bone.getNextBone();
         BoneInfo prev = bone.getPrevBone();
         BoneInfo next = bone.getNextBone();
+
+        StringBuilder chainComment = new StringBuilder();
         if(prev != null){
         if(prev != null){
-            sp();
-            putNumberedIdAttr("prevBoneIdRef", PFX_BONE, prev);
             chainComment.append('[')
                         .append(prev.getBoneName().getPrimaryText())
                         .append(']')
             chainComment.append('[')
                         .append(prev.getBoneName().getPrimaryText())
                         .append(']')
-                        .append("=> #");
+                        .append(" >>#");
         }
         if(next != null){
         }
         if(next != null){
-            sp();
-            putNumberedIdAttr("nextBoneIdRef", PFX_BONE, next);
             if(chainComment.length() <= 0) chainComment.append("#");
             if(chainComment.length() <= 0) chainComment.append("#");
-            chainComment.append(" =>")
+            chainComment.append(">> ")
                         .append('[')
                         .append(next.getBoneName().getPrimaryText())
                         .append(']');
         }
                         .append('[')
                         .append(next.getBoneName().getPrimaryText())
                         .append(']');
         }
-        put(" />").ln();
-        ind().putLineComment(chainComment).ln();
+        if(chainComment.length() > 0){
+            ln();
+            ind().putLineComment(chainComment).ln();
+        }
+
+        ind().putRawText("<boneChain");
+        if(prev != null){
+            sp();
+            putNumberedIdAttr("prevBoneIdRef", PFX_BONE, prev);
+        }
+        if(next != null){
+            sp();
+            putNumberedIdAttr("nextBoneIdRef", PFX_BONE, next);
+        }
+        putRawText(" />").ln();
 
         popNest();
 
         popNest();
-        ind().put("</bone>").ln(2);
+        ind().putRawText("</bone>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -828,18 +865,22 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putBoneGroupList(PmdModel model)
+    private Xml101009Exporter putBoneGroupList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<boneGroupList>").ln(2);
-        pushNest();
+        ind().putRawText("<boneGroupList>").ln();
 
 
-        for(BoneGroup group : model.getBoneGroupList()){
+        pushNest();
+        boolean dumped = false;
+        List<BoneGroup> groupList = model.getBoneGroupList();
+        for(BoneGroup group : groupList){
             if(group.isDefaultBoneGroup()) continue;
             if(group.isDefaultBoneGroup()) continue;
+            if( ! dumped ) ln();
             putBoneGroup(group);
             putBoneGroup(group);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</boneGroupList>").ln(2);
+
+        ind().putRawText("</boneGroupList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -850,28 +891,28 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putBoneGroup(BoneGroup group)
+    private Xml101009Exporter putBoneGroup(BoneGroup group)
             throws IOException{
         I18nText i18nName = group.getGroupName();
 
         putLocalNameComment(i18nName).ln();
             throws IOException{
         I18nText i18nName = group.getGroupName();
 
         putLocalNameComment(i18nName).ln();
-        ind().put("<boneGroup ");
+        ind().putRawText("<boneGroup ");
         putPrimaryNameAttr("name", i18nName);
         putPrimaryNameAttr("name", i18nName);
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         putI18nName(i18nName);
 
         for(BoneInfo bone : group){
         pushNest();
 
         putI18nName(i18nName);
 
         for(BoneInfo bone : group){
-            ind().put("<boneGroupMember ");
+            ind().putRawText("<boneGroupMember ");
             putNumberedIdAttr("boneIdRef", PFX_BONE, bone);
             putNumberedIdAttr("boneIdRef", PFX_BONE, bone);
-            put(" /> ");
+            putRawText(" /> ");
             String boneName = "Ref:" + bone.getBoneName().getText();
             putLineComment(boneName).ln();
         }
 
         popNest();
             String boneName = "Ref:" + bone.getBoneName().getText();
             putLineComment(boneName).ln();
         }
 
         popNest();
-        ind().put("</boneGroup>").ln(2);
+        ind().putRawText("</boneGroup>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -882,17 +923,21 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putIKChainList(PmdModel model)
+    private Xml101009Exporter putIKChainList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<ikChainList>").ln(2);
-        pushNest();
+        ind().putRawText("<ikChainList>").ln();
 
 
-        for(IKChain chain : model.getIKChainList()){
+        pushNest();
+        boolean dumped = false;
+        List<IKChain> chainList = model.getIKChainList();
+        for(IKChain chain : chainList){
+            if( ! dumped ) ln();
             putIKChain(chain);
             putIKChain(chain);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</ikChainList>").ln(2);
+
+        ind().putRawText("</ikChainList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -903,30 +948,30 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putIKChain(IKChain chain)
+    private Xml101009Exporter putIKChain(IKChain chain)
             throws IOException{
         int depth = chain.getIKDepth();
         float weight = chain.getIKWeight();
         BoneInfo ikBone = chain.getIkBone();
 
         ind().putLineComment("Ref:" + ikBone.getBoneName().getText()).ln();
             throws IOException{
         int depth = chain.getIKDepth();
         float weight = chain.getIKWeight();
         BoneInfo ikBone = chain.getIkBone();
 
         ind().putLineComment("Ref:" + ikBone.getBoneName().getText()).ln();
-        ind().put("<ikChain ");
+        ind().putRawText("<ikChain ");
         putNumberedIdAttr("ikBoneIdRef", PFX_BONE, ikBone).sp();
         putIntAttr("recursiveDepth", depth).sp();
         putFloatAttr("weight", weight);
         putNumberedIdAttr("ikBoneIdRef", PFX_BONE, ikBone).sp();
         putIntAttr("recursiveDepth", depth).sp();
         putFloatAttr("weight", weight);
-        put("> ").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         for(BoneInfo bone : chain){
         pushNest();
 
         for(BoneInfo bone : chain){
-            ind().put("<chainOrder ");
+            ind().putRawText("<chainOrder ");
             putNumberedIdAttr("boneIdRef", PFX_BONE, bone);
             putNumberedIdAttr("boneIdRef", PFX_BONE, bone);
-            put(" /> ");
+            putRawText(" /> ");
             putLineComment("Ref:" + bone.getBoneName().getText());
             ln();
         }
 
         popNest();
             putLineComment("Ref:" + bone.getBoneName().getText());
             ln();
         }
 
         popNest();
-        ind().put("</ikChain>").ln(2);
+        ind().putRawText("</ikChain>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -937,25 +982,28 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putMorphList(PmdModel model)
+    private Xml101009Exporter putMorphList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<morphList>").ln(2);
+        ind().putRawText("<morphList>").ln();
         pushNest();
 
         pushNest();
 
-        putBlockComment(MORPHTYPE_COMMENT).ln();
-
+        boolean dumped = false;
         Map<MorphType, List<MorphPart>> morphMap = model.getMorphMap();
         for(MorphType type : MorphType.values()){
             if(type == MorphType.BASE) continue;
             List<MorphPart> partList = morphMap.get(type);
             if(partList == null) continue;
             for(MorphPart part : partList){
         Map<MorphType, List<MorphPart>> morphMap = model.getMorphMap();
         for(MorphType type : MorphType.values()){
             if(type == MorphType.BASE) continue;
             List<MorphPart> partList = morphMap.get(type);
             if(partList == null) continue;
             for(MorphPart part : partList){
+                if( ! dumped ){
+                    ln().putBlockComment(MORPHTYPE_COMMENT).ln();
+                }
                 putMorphPart(part);
                 putMorphPart(part);
+                dumped = true;
             }
         }
 
         popNest();
             }
         }
 
         popNest();
-        ind().put("</morphList>").ln(2);
+        ind().putRawText("</morphList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -966,16 +1014,16 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putMorphPart(MorphPart part)
+    private Xml101009Exporter putMorphPart(MorphPart part)
             throws IOException{
         I18nText i18nName = part.getMorphName();
         String primary = i18nName.getPrimaryText();
 
             throws IOException{
         I18nText i18nName = part.getMorphName();
         String primary = i18nName.getPrimaryText();
 
-        ind().put("<morph ");
+        putLocalNameComment(i18nName).ln();
+        ind().putRawText("<morph ");
         putAttr("name", primary).sp();
         putAttr("type", part.getMorphType().name());
         putAttr("name", primary).sp();
         putAttr("type", part.getMorphType().name());
-        put(">");
-        putUnescapedComment(primary);
+        sp().putRawText(">");
         ln();
         pushNest();
 
         ln();
         pushNest();
 
@@ -985,17 +1033,17 @@ public class PmdXmlExporter extends BasicXmlExporter{
             MkPos3D offset = mvertex.getOffset();
             Vertex base = mvertex.getBaseVertex();
 
             MkPos3D offset = mvertex.getOffset();
             Vertex base = mvertex.getBaseVertex();
 
-            ind().put("<morphVertex ");
+            ind().putRawText("<morphVertex ");
             putNumberedIdAttr("vtxIdRef", PFX_VERTEX, base).sp();
             putFloatAttr("xOff", (float) offset.getXpos()).sp();
             putFloatAttr("yOff", (float) offset.getYpos()).sp();
             putFloatAttr("zOff", (float) offset.getZpos()).sp();
             putNumberedIdAttr("vtxIdRef", PFX_VERTEX, base).sp();
             putFloatAttr("xOff", (float) offset.getXpos()).sp();
             putFloatAttr("yOff", (float) offset.getYpos()).sp();
             putFloatAttr("zOff", (float) offset.getZpos()).sp();
-            put("/>");
+            putRawText("/>");
             ln();
         }
 
         popNest();
             ln();
         }
 
         popNest();
-        ind().put("</morph>").ln(2);
+        ind().putRawText("</morph>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -1006,19 +1054,22 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putRigidList(PmdModel model)
+    private Xml101009Exporter putRigidList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<rigidList>").ln(2);
+        ind().putRawText("<rigidList>").ln();
         pushNest();
 
         pushNest();
 
-        putBlockComment(RIGIDBEHAVIOR_COMMENT).ln();
-
+        boolean dumped = false;
         for(RigidInfo rigid : model.getRigidList()){
         for(RigidInfo rigid : model.getRigidList()){
+            if( ! dumped ){
+                ln().putBlockComment(RIGIDBEHAVIOR_COMMENT).ln();
+            }
             putRigid(rigid);
             putRigid(rigid);
+            dumped = true;
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</rigidList>").ln(2);
+        ind().putRawText("</rigidList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -1029,26 +1080,26 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putRigid(RigidInfo rigid)
+    private Xml101009Exporter putRigid(RigidInfo rigid)
             throws IOException{
         BoneInfo linkedBone = rigid.getLinkedBone();
         I18nText i18nName = rigid.getRigidName();
         String primary = i18nName.getPrimaryText();
 
         putLocalNameComment(i18nName).ln();
             throws IOException{
         BoneInfo linkedBone = rigid.getLinkedBone();
         I18nText i18nName = rigid.getRigidName();
         String primary = i18nName.getPrimaryText();
 
         putLocalNameComment(i18nName).ln();
-        ind().put("<rigid ");
+        ind().putRawText("<rigid ");
         putAttr("name", primary).sp();
         putNumberedIdAttr("rigidId", PFX_RIGID, rigid).sp();
         putAttr("behavior", rigid.getBehaviorType().name());
         putAttr("name", primary).sp();
         putNumberedIdAttr("rigidId", PFX_RIGID, rigid).sp();
         putAttr("behavior", rigid.getBehaviorType().name());
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         putI18nName(i18nName);
 
         if(linkedBone != null){
         pushNest();
 
         putI18nName(i18nName);
 
         if(linkedBone != null){
-            ind().put("<linkedBone ");
+            ind().putRawText("<linkedBone ");
             putNumberedIdAttr("boneIdRef", PFX_BONE, linkedBone);
             putNumberedIdAttr("boneIdRef", PFX_BONE, linkedBone);
-            put(" /> ");
+            putRawText(" /> ");
             putLineComment("Ref:" + linkedBone.getBoneName().getText());
             ln(2);
         }
             putLineComment("Ref:" + linkedBone.getBoneName().getText());
             ln(2);
         }
@@ -1066,15 +1117,15 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putDynamics(dynamics).ln();
 
         for(RigidGroup group : rigid.getThroughGroupColl()){
         putDynamics(dynamics).ln();
 
         for(RigidGroup group : rigid.getThroughGroupColl()){
-            ind().put("<throughRigidGroup ");
+            ind().putRawText("<throughRigidGroup ");
             putNumberedIdAttr("rigidGroupIdRef",
                               PFX_RIGIDGROUP,
                               group.getSerialNumber() + 1).sp();
             putNumberedIdAttr("rigidGroupIdRef",
                               PFX_RIGIDGROUP,
                               group.getSerialNumber() + 1).sp();
-            put(" />").ln();
+            putRawText(" />").ln();
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</rigid>").ln(2);
+        ind().putRawText("</rigid>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -1085,23 +1136,23 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putRigidShape(RigidShape shape)
+    private Xml101009Exporter putRigidShape(RigidShape shape)
             throws IOException{
         RigidShapeType type = shape.getShapeType();
 
         switch(type){
         case BOX:
             throws IOException{
         RigidShapeType type = shape.getShapeType();
 
         switch(type){
         case BOX:
-            ind().put("<rigidShapeBox ");
+            ind().putRawText("<rigidShapeBox ");
             putFloatAttr("width", shape.getWidth()).sp();
             putFloatAttr("height", shape.getHeight()).sp();
             putFloatAttr("depth", shape.getDepth()).sp();
             break;
         case SPHERE:
             putFloatAttr("width", shape.getWidth()).sp();
             putFloatAttr("height", shape.getHeight()).sp();
             putFloatAttr("depth", shape.getDepth()).sp();
             break;
         case SPHERE:
-            ind().put("<rigidShapeSphere ");
+            ind().putRawText("<rigidShapeSphere ");
             putFloatAttr("radius", shape.getRadius()).sp();
             break;
         case CAPSULE:
             putFloatAttr("radius", shape.getRadius()).sp();
             break;
         case CAPSULE:
-            ind().put("<rigidShapeCapsule ");
+            ind().putRawText("<rigidShapeCapsule ");
             putFloatAttr("height", shape.getHeight()).sp();
             putFloatAttr("radius", shape.getRadius()).sp();
             break;
             putFloatAttr("height", shape.getHeight()).sp();
             putFloatAttr("radius", shape.getRadius()).sp();
             break;
@@ -1110,7 +1161,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
             throw new AssertionError();
         }
 
             throw new AssertionError();
         }
 
-        put("/>").ln();
+        putRawText("/>").ln();
 
         return this;
     }
 
         return this;
     }
@@ -1121,9 +1172,9 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putDynamics(DynamicsInfo dynamics)
+    private Xml101009Exporter putDynamics(DynamicsInfo dynamics)
             throws IOException{
             throws IOException{
-        ind().put("<dynamics").ln();
+        ind().putRawText("<dynamics").ln();
         pushNest();
         ind().putFloatAttr("mass", dynamics.getMass()).ln();
         ind().putFloatAttr("dampingPosition",
         pushNest();
         ind().putFloatAttr("mass", dynamics.getMass()).ln();
         ind().putFloatAttr("dampingPosition",
@@ -1133,7 +1184,7 @@ public class PmdXmlExporter extends BasicXmlExporter{
         ind().putFloatAttr("restitution", dynamics.getRestitution()).ln();
         ind().putFloatAttr("friction", dynamics.getFriction()).ln();
         popNest();
         ind().putFloatAttr("restitution", dynamics.getRestitution()).ln();
         ind().putFloatAttr("friction", dynamics.getFriction()).ln();
         popNest();
-        ind().put("/>").ln();
+        ind().putRawText("/>").ln();
 
         return this;
     }
 
         return this;
     }
@@ -1144,39 +1195,49 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putRigidGroupList(PmdModel model)
+    private Xml101009Exporter putRigidGroupList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<rigidGroupList>").ln(2);
+        ind().putRawText("<rigidGroupList>").ln(2);
         pushNest();
 
         pushNest();
 
+        boolean singleLast = false;
         for(RigidGroup group : model.getRigidGroupList()){
         for(RigidGroup group : model.getRigidGroupList()){
-            ind().put("<rigidGroup ");
+            List<RigidInfo> rigidList = group.getRigidList();
+            if(singleLast &&  ! rigidList.isEmpty()){
+                ln();
+            }
+            ind().putRawText("<rigidGroup ");
             putNumberedIdAttr("rigidGroupId",
                               PFX_RIGIDGROUP,
                               group.getSerialNumber() + 1);
             putNumberedIdAttr("rigidGroupId",
                               PFX_RIGIDGROUP,
                               group.getSerialNumber() + 1);
-            List<RigidInfo> rigidList = group.getRigidList();
-            if(rigidList.size() <= 0){
-                put(" />").ln(2);
+            if(rigidList.isEmpty()){
+                putRawText(" />").ln();
+                singleLast = true;
                 continue;
             }
                 continue;
             }
-            put(">").ln();
+            putRawText(" >").ln();
             pushNest();
 
             for(RigidInfo rigid : rigidList){
             pushNest();
 
             for(RigidInfo rigid : rigidList){
-                ind().put("<rigidGroupMember ");
+                ind().putRawText("<rigidGroupMember ");
                 putNumberedIdAttr("rigidIdRef", PFX_RIGID, rigid).sp();
                 putNumberedIdAttr("rigidIdRef", PFX_RIGID, rigid).sp();
-                put("/>");
+                putRawText("/>");
                 sp();
                 putLineComment("Ref:" + rigid.getRigidName().getText());
                 ln();
             }
 
             popNest();
                 sp();
                 putLineComment("Ref:" + rigid.getRigidName().getText());
                 ln();
             }
 
             popNest();
-            ind().put("</rigidGroup>").ln(2);
+            ind().putRawText("</rigidGroup>").ln(2);
+            singleLast = false;
+        }
+
+        if(singleLast){
+            ln();
         }
 
         popNest();
         }
 
         popNest();
-        ind().put("</rigidGroupList>").ln(2);
+        ind().putRawText("</rigidGroupList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -1187,17 +1248,21 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putJointList(PmdModel model)
+    private Xml101009Exporter putJointList(PmdModel model)
             throws IOException{
             throws IOException{
-        ind().put("<jointList>").ln(2);
-        pushNest();
+        ind().putRawText("<jointList>").ln();
 
 
-        for(JointInfo joint : model.getJointList()){
+        pushNest();
+        boolean dumped = false;
+        List<JointInfo> jointList = model.getJointList();
+        for(JointInfo joint : jointList){
+            if( ! dumped ) ln();
             putJoint(joint);
             putJoint(joint);
+            dumped = true;
         }
         }
-
         popNest();
         popNest();
-        ind().put("</jointList>").ln(2);
+
+        ind().putRawText("</jointList>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -1208,34 +1273,36 @@ public class PmdXmlExporter extends BasicXmlExporter{
      * @return this本体
      * @throws IOException 出力エラー
      */
      * @return this本体
      * @throws IOException 出力エラー
      */
-    private PmdXmlExporter putJoint(JointInfo joint)
+    private Xml101009Exporter putJoint(JointInfo joint)
             throws IOException{
         I18nText i18nName = joint.getJointName();
 
         putLocalNameComment(i18nName).ln();
             throws IOException{
         I18nText i18nName = joint.getJointName();
 
         putLocalNameComment(i18nName).ln();
-        ind().put("<joint ");
+        ind().putRawText("<joint ");
         putPrimaryNameAttr("name", i18nName);
         putPrimaryNameAttr("name", i18nName);
-        put(">").ln();
+        sp().putRawText(">").ln();
         pushNest();
 
         putI18nName(i18nName);
 
         RigidInfo rigidA = joint.getRigidA();
         RigidInfo rigidB = joint.getRigidB();
         pushNest();
 
         putI18nName(i18nName);
 
         RigidInfo rigidA = joint.getRigidA();
         RigidInfo rigidB = joint.getRigidB();
-        ind().put("<jointedRigidPair ");
-        putNumberedIdAttr("rigidIdRef1", PFX_RIGID, rigidA).sp();
-        putNumberedIdAttr("rigidIdRef2", PFX_RIGID, rigidB).sp();
-        put("/>").ln();
+
         ind();
         putLineComment("[" + rigidA.getRigidName().getText() + "]"
                 + " <=> [" + rigidB.getRigidName().getText() + "]");
         ind();
         putLineComment("[" + rigidA.getRigidName().getText() + "]"
                 + " <=> [" + rigidB.getRigidName().getText() + "]");
-        ln(2);
+        ln();
+
+        ind().putRawText("<jointedRigidPair ");
+        putNumberedIdAttr("rigidIdRef1", PFX_RIGID, rigidA).sp();
+        putNumberedIdAttr("rigidIdRef2", PFX_RIGID, rigidB).sp();
+        putRawText("/>").ln(2);
 
         MkPos3D position = joint.getPosition();
         ind().putPosition(position).ln();
 
         TripletRange posRange = joint.getPositionRange();
 
         MkPos3D position = joint.getPosition();
         ind().putPosition(position).ln();
 
         TripletRange posRange = joint.getPositionRange();
-        ind().put("<limitPosition").ln();
+        ind().putRawText("<limitPosition").ln();
         pushNest();
         ind();
         putFloatAttr("xFrom", posRange.getXFrom()).sp();
         pushNest();
         ind();
         putFloatAttr("xFrom", posRange.getXFrom()).sp();
@@ -1247,12 +1314,12 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putFloatAttr("zFrom", posRange.getZFrom()).sp();
         putFloatAttr("zTo",   posRange.getZTo()).ln();
         popNest();
         putFloatAttr("zFrom", posRange.getZFrom()).sp();
         putFloatAttr("zTo",   posRange.getZTo()).ln();
         popNest();
-        ind().put("/>").ln(2);
+        ind().putRawText("/>").ln(2);
 
         Rad3d rotation = joint.getRotation();
         ind().putRadRotation(rotation).ln();
         TripletRange rotRange = joint.getRotationRange();
 
         Rad3d rotation = joint.getRotation();
         ind().putRadRotation(rotation).ln();
         TripletRange rotRange = joint.getRotationRange();
-        ind().put("<limitRotation").ln();
+        ind().putRawText("<limitRotation").ln();
         pushNest();
         ind();
         putFloatAttr("xFrom", rotRange.getXFrom()).sp();
         pushNest();
         ind();
         putFloatAttr("xFrom", rotRange.getXFrom()).sp();
@@ -1264,24 +1331,24 @@ public class PmdXmlExporter extends BasicXmlExporter{
         putFloatAttr("zFrom", rotRange.getZFrom()).sp();
         putFloatAttr("zTo",   rotRange.getZTo()).ln();
         popNest();
         putFloatAttr("zFrom", rotRange.getZFrom()).sp();
         putFloatAttr("zTo",   rotRange.getZTo()).ln();
         popNest();
-        ind().put("/>").ln(2);
+        ind().putRawText("/>").ln(2);
 
         MkPos3D elaPosition = joint.getElasticPosition();
 
         MkPos3D elaPosition = joint.getElasticPosition();
-        ind().put("<elasticPosition ");
+        ind().putRawText("<elasticPosition ");
         putFloatAttr("x", (float) elaPosition.getXpos()).sp();
         putFloatAttr("y", (float) elaPosition.getYpos()).sp();
         putFloatAttr("z", (float) elaPosition.getZpos()).sp();
         putFloatAttr("x", (float) elaPosition.getXpos()).sp();
         putFloatAttr("y", (float) elaPosition.getYpos()).sp();
         putFloatAttr("z", (float) elaPosition.getZpos()).sp();
-        put("/>").ln();
+        putRawText("/>").ln();
 
         Deg3d elaRotation = joint.getElasticRotation();
 
         Deg3d elaRotation = joint.getElasticRotation();
-        ind().put("<elasticRotation ");
+        ind().putRawText("<elasticRotation ");
         putFloatAttr("xDeg", elaRotation.getXDeg()).sp();
         putFloatAttr("yDeg", elaRotation.getYDeg()).sp();
         putFloatAttr("zDeg", elaRotation.getZDeg()).sp();
         putFloatAttr("xDeg", elaRotation.getXDeg()).sp();
         putFloatAttr("yDeg", elaRotation.getYDeg()).sp();
         putFloatAttr("zDeg", elaRotation.getZDeg()).sp();
-        put("/>").ln(2);
+        putRawText("/>").ln(2);
 
         popNest();
 
         popNest();
-        ind().put("</joint>").ln(2);
+        ind().putRawText("</joint>").ln(2);
 
         return this;
     }
 
         return this;
     }
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.xml;
+package jp.sfjp.mikutoga.pmd.xml101009;
 
 import java.awt.Color;
 import java.io.IOException;
 
 import java.awt.Color;
 import java.io.IOException;
@@ -53,9 +53,9 @@ import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
 import org.xml.sax.SAXException;
 
 /**
- * XML形式でのモデルファイルを読み込む。
+ * 101009形式XML形式でのモデルファイルを読み込む。
  */
  */
-public class Xml2PmdLoader {
+public class Xml101009Loader {
 
     private final DocumentBuilder builder;
 
 
     private final DocumentBuilder builder;
 
@@ -79,7 +79,7 @@ public class Xml2PmdLoader {
      * コンストラクタ。
      * @param builder ビルダ
      */
      * コンストラクタ。
      * @param builder ビルダ
      */
-    public Xml2PmdLoader(DocumentBuilder builder){
+    public Xml101009Loader(DocumentBuilder builder){
         super();
         this.builder = builder;
         return;
         super();
         this.builder = builder;
         return;
@@ -5,7 +5,7 @@
  * Copyright(c) 2010 MikuToga Partners
  */
 
  * Copyright(c) 2010 MikuToga Partners
  */
 
-package jp.sourceforge.mikutoga.pmd.model.xml;
+package jp.sfjp.mikutoga.pmd.xml101009;
 
 import java.net.URI;
 import java.net.URISyntaxException;
 
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -20,9 +20,9 @@ import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
 
 /**
 import org.xml.sax.SAXException;
 
 /**
- * XML各種リソースの定義。
+ * 101009形式XML各種リソースの定義。
  */
  */
-public final class PmdXmlResources {
+public final class Xml101009Resources {
 
     public static final String NS_PMDXML =
             "http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009";
 
     public static final String NS_PMDXML =
             "http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009";
@@ -42,10 +42,10 @@ public final class PmdXmlResources {
     public static final URI RES_SCHEMA_PMDXML;
     public static final URI RES_DTD_PMDXML;
 
     public static final URI RES_SCHEMA_PMDXML;
     public static final URI RES_DTD_PMDXML;
 
-    private static final Class THISCLASS = PmdXmlResources.class;
+    private static final Class THISCLASS = Xml101009Resources.class;
 
     static{
 
     static{
-        Object dummy = new PmdXmlResources();
+        Object dummy = new Xml101009Resources();
 
         try{
             RES_SCHEMA_PMDXML =
 
         try{
             RES_SCHEMA_PMDXML =
@@ -60,7 +60,7 @@ public final class PmdXmlResources {
     /**
      * 隠しコンストラクタ。
      */
     /**
      * 隠しコンストラクタ。
      */
-    private PmdXmlResources(){
+    private Xml101009Resources(){
         super();
         assert this.getClass().equals(THISCLASS);
         return;
         super();
         assert this.getClass().equals(THISCLASS);
         return;
@@ -6,9 +6,9 @@
  */
 
 /**
  */
 
 /**
- * PMDモデル内容をXMLで出力するためのライブラリ。
+ * PMDモデル内容を101009版XMLで出力するためのライブラリ。
  */
 
  */
 
-package jp.sourceforge.mikutoga.pmd.model.xml;
+package jp.sfjp.mikutoga.pmd.xml101009;
 
 /* EOF */
 
 /* EOF */
index 51c0ac8..9a720a8 100644 (file)
@@ -101,10 +101,13 @@ class TextBuilder implements PmdBasicHandler, PmdEngHandler {
                 this.currentBone = this.boneIt.next();
             }
         }else if(stage == PmdEngHandler.ENGMORPH_LIST){
                 this.currentBone = this.boneIt.next();
             }
         }else if(stage == PmdEngHandler.ENGMORPH_LIST){
+            if(this.morphPartList.isEmpty()){
+                return;
+            }
+
             this.morphPartIt = this.morphPartList.iterator();
 
             // 「base」モーフを読み飛ばす
             this.morphPartIt = this.morphPartList.iterator();
 
             // 「base」モーフを読み飛ばす
-            assert this.morphPartIt.hasNext();
             MorphPart part = this.morphPartIt.next();
             assert part != null;
 
             MorphPart part = this.morphPartIt.next();
             assert part != null;
 
diff --git a/src/main/java/jp/sourceforge/mikutoga/pmd2xml/ModelFileTypes.java b/src/main/java/jp/sourceforge/mikutoga/pmd2xml/ModelFileTypes.java
deleted file mode 100644 (file)
index 14d51f7..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * MMD model file types.
- *
- * License : The MIT License
- * Copyright(c) 2012 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.pmd2xml;
-
-/**
- * モデルファイル種別。
- */
-public enum ModelFileTypes {
-    /** 不明。 */
-    NONE,
-
-    /** MikuMikuDance ver7 前後で読み書きが可能なPMDファイル。 */
-    PMD,
-
-    /**
-     * スキーマ
-     * http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd
-     * で定義されたXMLファイル。
-     */
-    XML_101009,
-
-}
index f50f2de..7b8cf71 100644 (file)
@@ -10,6 +10,7 @@ package jp.sourceforge.mikutoga.pmd2xml;
 import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.Map;
 import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.Map;
+import jp.sourceforge.mikutoga.pmd.ModelFileType;
 
 /**
  * コマンドラインオプション情報。
 
 /**
  * コマンドラインオプション情報。
@@ -50,8 +51,8 @@ final class OptInfo {
     private String errMsg = null;
 
     private boolean needHelp = false;
     private String errMsg = null;
 
     private boolean needHelp = false;
-    private ModelFileTypes inTypes  = ModelFileTypes.NONE;
-    private ModelFileTypes outTypes = ModelFileTypes.NONE;
+    private ModelFileType inTypes  = ModelFileType.NONE;
+    private ModelFileType outTypes = ModelFileType.NONE;
     private String inFilename = null;
     private String outFilename = null;
     private boolean overwrite = false;
     private String inFilename = null;
     private String outFilename = null;
     private boolean overwrite = false;
@@ -97,12 +98,12 @@ final class OptInfo {
                 result.overwrite = true;
                 break;
             case OPT_PMD2XML:
                 result.overwrite = true;
                 break;
             case OPT_PMD2XML:
-                result.inTypes  = ModelFileTypes.PMD;
-                result.outTypes = ModelFileTypes.XML_101009;
+                result.inTypes  = ModelFileType.PMD;
+                result.outTypes = ModelFileType.XML_101009;
                 break;
             case OPT_XML2PMD:
                 break;
             case OPT_XML2PMD:
-                result.inTypes  = ModelFileTypes.XML_101009;
-                result.outTypes = ModelFileTypes.PMD;
+                result.inTypes  = ModelFileType.XML_101009;
+                result.outTypes = ModelFileType.PMD;
                 break;
             case OPT_INFILE:
                 argIdx++;
                 break;
             case OPT_INFILE:
                 argIdx++;
@@ -157,8 +158,8 @@ final class OptInfo {
      * @param result オプション情報
      */
     private static void checkResult(OptInfo result){
      * @param result オプション情報
      */
     private static void checkResult(OptInfo result){
-        if(   result.getInFileType()  == ModelFileTypes.NONE
-           || result.getOutFileType() == ModelFileTypes.NONE ){
+        if(   result.getInFileType()  == ModelFileType.NONE
+           || result.getOutFileType() == ModelFileType.NONE ){
             result.putErrMsg(ERRMSG_NODIR);
             return;
         }
             result.putErrMsg(ERRMSG_NODIR);
             return;
         }
@@ -213,7 +214,7 @@ final class OptInfo {
      * 入力ファイル種別を返す。
      * @return 入力ファイル種別
      */
      * 入力ファイル種別を返す。
      * @return 入力ファイル種別
      */
-    ModelFileTypes getInFileType(){
+    ModelFileType getInFileType(){
         return this.inTypes;
     }
 
         return this.inTypes;
     }
 
@@ -221,7 +222,7 @@ final class OptInfo {
      * 出力ファイル種別を返す。
      * @return 出力ファイル種別
      */
      * 出力ファイル種別を返す。
      * @return 出力ファイル種別
      */
-    ModelFileTypes getOutFileType(){
+    ModelFileType getOutFileType(){
         return this.outTypes;
     }
 
         return this.outTypes;
     }
 
index bd99da5..0d3d468 100644 (file)
@@ -12,14 +12,15 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
 import java.io.OutputStream;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
+import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Exporter;
+import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Loader;
+import jp.sfjp.mikutoga.pmd.xml101009.Xml101009Resources;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
 import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
 import jp.sourceforge.mikutoga.pmd.IllegalPmdDataException;
+import jp.sourceforge.mikutoga.pmd.ModelFileType;
 import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.model.binio.PmdExporter;
 import jp.sourceforge.mikutoga.pmd.model.binio.PmdLoader;
 import jp.sourceforge.mikutoga.pmd.model.PmdModel;
 import jp.sourceforge.mikutoga.pmd.model.binio.PmdExporter;
 import jp.sourceforge.mikutoga.pmd.model.binio.PmdLoader;
-import jp.sourceforge.mikutoga.pmd.model.xml.PmdXmlExporter;
-import jp.sourceforge.mikutoga.pmd.model.xml.PmdXmlResources;
-import jp.sourceforge.mikutoga.pmd.model.xml.Xml2PmdLoader;
 import jp.sourceforge.mikutoga.xml.TogaXmlException;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import jp.sourceforge.mikutoga.xml.TogaXmlException;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -29,8 +30,8 @@ import org.xml.sax.SAXException;
  */
 public class Pmd2XmlConv {
 
  */
 public class Pmd2XmlConv {
 
-    private ModelFileTypes inTypes  = ModelFileTypes.NONE;
-    private ModelFileTypes outTypes = ModelFileTypes.NONE;
+    private ModelFileType inTypes  = ModelFileType.NONE;
+    private ModelFileType outTypes = ModelFileType.NONE;
     private String newLine = "\r\n";
     private String generator = null;
 
     private String newLine = "\r\n";
     private String generator = null;
 
@@ -44,7 +45,7 @@ public class Pmd2XmlConv {
         super();
 
         try{
         super();
 
         try{
-            this.builder = PmdXmlResources.newBuilder(XmlHandler.HANDLER);
+            this.builder = Xml101009Resources.newBuilder(XmlHandler.HANDLER);
         }catch(SAXException e){
             throw new AssertionError(e);
         }catch(ParserConfigurationException e){
         }catch(SAXException e){
             throw new AssertionError(e);
         }catch(ParserConfigurationException e){
@@ -59,7 +60,7 @@ public class Pmd2XmlConv {
      * 入力ファイル種別を設定する。
      * @param type ファイル種別
      */
      * 入力ファイル種別を設定する。
      * @param type ファイル種別
      */
-    public void setInType(ModelFileTypes type){
+    public void setInType(ModelFileType type){
         if(type == null) throw new NullPointerException();
         this.inTypes = type;
         return;
         if(type == null) throw new NullPointerException();
         this.inTypes = type;
         return;
@@ -69,7 +70,7 @@ public class Pmd2XmlConv {
      * 入力ファイル種別を返す。
      * @return ファイル種別
      */
      * 入力ファイル種別を返す。
      * @return ファイル種別
      */
-    public ModelFileTypes getInTypes(){
+    public ModelFileType getInTypes(){
         return this.inTypes;
     }
 
         return this.inTypes;
     }
 
@@ -77,7 +78,7 @@ public class Pmd2XmlConv {
      * 出力ファイル種別を設定する。
      * @param type ファイル種別
      */
      * 出力ファイル種別を設定する。
      * @param type ファイル種別
      */
-    public void setOutType(ModelFileTypes type){
+    public void setOutType(ModelFileType type){
         if(type == null) throw new NullPointerException();
         this.outTypes = type;
         return;
         if(type == null) throw new NullPointerException();
         this.outTypes = type;
         return;
@@ -87,7 +88,7 @@ public class Pmd2XmlConv {
      * 出力ファイル種別を返す。
      * @return ファイル種別
      */
      * 出力ファイル種別を返す。
      * @return ファイル種別
      */
-    public ModelFileTypes getOutTypes(){
+    public ModelFileType getOutTypes(){
         return this.outTypes;
     }
 
         return this.outTypes;
     }
 
@@ -241,7 +242,7 @@ public class Pmd2XmlConv {
             throws IOException,
                    SAXException,
                    TogaXmlException {
             throws IOException,
                    SAXException,
                    TogaXmlException {
-        Xml2PmdLoader loader = new Xml2PmdLoader(this.builder);
+        Xml101009Loader loader = new Xml101009Loader(this.builder);
         PmdModel model = loader.parse(source);
         return model;
     }
         PmdModel model = loader.parse(source);
         return model;
     }
@@ -270,7 +271,7 @@ public class Pmd2XmlConv {
      */
     private void xmlOut(PmdModel model, OutputStream ostream)
             throws IOException, IllegalPmdDataException{
      */
     private void xmlOut(PmdModel model, OutputStream ostream)
             throws IOException, IllegalPmdDataException{
-        PmdXmlExporter exporter = new PmdXmlExporter(ostream);
+        Xml101009Exporter exporter = new Xml101009Exporter(ostream);
         exporter.setNewLine(this.newLine);
         exporter.setGenerator(this.generator);
         exporter.putPmdModel(model);
         exporter.setNewLine(this.newLine);
         exporter.setGenerator(this.generator);
         exporter.putPmdModel(model);
index 83ca380..8416560 100644 (file)
@@ -11,7 +11,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import jp.sourceforge.mikutoga.pmd2xml.ModelFileTypes;
+import jp.sourceforge.mikutoga.pmd.ModelFileType;
 import jp.sourceforge.mikutoga.pmd2xml.Pmd2XmlConv;
 
 import static org.junit.Assert.*;
 import jp.sourceforge.mikutoga.pmd2xml.Pmd2XmlConv;
 
 import static org.junit.Assert.*;
@@ -56,8 +56,8 @@ public class CnvAssert {
         destOut = new BufferedOutputStream(destOut);
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
         destOut = new BufferedOutputStream(destOut);
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
-        converter.setInType(ModelFileTypes.XML_101009);
-        converter.setOutType(ModelFileTypes.PMD);
+        converter.setInType(ModelFileType.XML_101009);
+        converter.setOutType(ModelFileType.PMD);
         converter.setNewline("\n");
 
         converter.convert(xmlis, destOut);
         converter.setNewline("\n");
 
         converter.convert(xmlis, destOut);
@@ -93,8 +93,8 @@ public class CnvAssert {
         destOut = new BufferedOutputStream(destOut);
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
         destOut = new BufferedOutputStream(destOut);
 
         Pmd2XmlConv converter = new Pmd2XmlConv();
-        converter.setInType(ModelFileTypes.PMD);
-        converter.setOutType(ModelFileTypes.XML_101009);
+        converter.setInType(ModelFileType.PMD);
+        converter.setOutType(ModelFileType.XML_101009);
         converter.setNewline("\n");
         converter.setGenerator(null);
 
         converter.setNewline("\n");
         converter.setGenerator(null);
 
diff --git a/src/test/java/testdata/TestDriver.java b/src/test/java/testdata/TestDriver.java
new file mode 100644 (file)
index 0000000..8b4a952
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ */
+
+package testdata;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * 使い捨てテスト用ドライバ。
+ */
+public class TestDriver {
+
+    static{
+        assert Test.class != null;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * 使い捨てテスト本体。
+     * <p>テストが終わったら必ず元に戻して
+     * アノテーション"Test"をコメントアウトするように。
+     * @throws Exception テスト失敗
+     */
+    //@Test
+    public void main() throws Exception{
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/bone/BoneTest.java b/src/test/java/testdata/pmd101009/bone/BoneTest.java
new file mode 100644 (file)
index 0000000..632c21a
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.bone;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class BoneTest {
+
+    static Class<?> THISCLASS = BoneTest.class;
+
+    public BoneTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "allbone.pmd", "allbone.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allbone.xml", "allbone.pmd");
+        return;
+    }
+
+}
@@ -1,7 +1,7 @@
 /*
  */
 
 /*
  */
 
-package testdata.charset;
+package testdata.pmd101009.charset;
 
 import org.junit.After;
 import org.junit.AfterClass;
 
 import org.junit.After;
 import org.junit.AfterClass;
@@ -42,14 +42,14 @@ public class CharsetTest {
     @Test
     public void pmd2xml() throws Exception{
         System.out.println("pmd2xml");
     @Test
     public void pmd2xml() throws Exception{
         System.out.println("pmd2xml");
-        assertPmd2Xml(THISCLASS, "test.pmd", "result.xml");
+        assertPmd2Xml(THISCLASS, "charset.pmd", "result.xml");
         return;
     }
 
     @Test
     public void xml2pmd() throws Exception{
         System.out.println("xml2pmd");
         return;
     }
 
     @Test
     public void xml2pmd() throws Exception{
         System.out.println("xml2pmd");
-        assertXml2Pmd(THISCLASS, "source.xml", "test.pmd");
+        assertXml2Pmd(THISCLASS, "source.xml", "charset.pmd");
         return;
     }
 
         return;
     }
 
diff --git a/src/test/java/testdata/pmd101009/group/GroupTest.java b/src/test/java/testdata/pmd101009/group/GroupTest.java
new file mode 100644 (file)
index 0000000..adaf40e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.group;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class GroupTest {
+
+    static Class<?> THISCLASS = GroupTest.class;
+
+    public GroupTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "boneGroup.pmd", "boneGroup.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "boneGroup.xml", "boneGroup.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/i18n/I18nTest.java b/src/test/java/testdata/pmd101009/i18n/I18nTest.java
new file mode 100644 (file)
index 0000000..ce74931
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.i18n;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class I18nTest {
+
+    static Class<?> THISCLASS = I18nTest.class;
+
+    public I18nTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "i18n.pmd", "i18n.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "i18n.xml", "i18n.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/ik/IkBoneTest.java b/src/test/java/testdata/pmd101009/ik/IkBoneTest.java
new file mode 100644 (file)
index 0000000..8fbce94
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.ik;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class IkBoneTest {
+
+    static Class<?> THISCLASS = IkBoneTest.class;
+
+    public IkBoneTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "ikBone.pmd", "ikBone.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "ikBone.xml", "ikBone.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/material/MaterialTest.java b/src/test/java/testdata/pmd101009/material/MaterialTest.java
new file mode 100644 (file)
index 0000000..05e442c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.material;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class MaterialTest {
+
+    static Class<?> THISCLASS = MaterialTest.class;
+
+    public MaterialTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "material.pmd", "material.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "material.xml", "material.pmd");
+        return;
+    }
+
+}
@@ -1,7 +1,7 @@
 /*
  */
 
 /*
  */
 
-package testdata.minimum;
+package testdata.pmd101009.minimum;
 
 import org.junit.After;
 import org.junit.AfterClass;
 
 import org.junit.After;
 import org.junit.AfterClass;
@@ -42,14 +42,14 @@ public class MinimumTest {
     @Test
     public void pmd2xml() throws Exception{
         System.out.println("pmd2xml");
     @Test
     public void pmd2xml() throws Exception{
         System.out.println("pmd2xml");
-        assertPmd2Xml(THISCLASS, "test.pmd", "test.xml");
+        assertPmd2Xml(THISCLASS, "minimum.pmd", "minimum.xml");
         return;
     }
 
     @Test
     public void xml2pmd() throws Exception{
         System.out.println("xml2pmd");
         return;
     }
 
     @Test
     public void xml2pmd() throws Exception{
         System.out.println("xml2pmd");
-        assertXml2Pmd(THISCLASS, "test.xml", "test.pmd");
+        assertXml2Pmd(THISCLASS, "minimum.xml", "minimum.pmd");
         return;
     }
 
         return;
     }
 
diff --git a/src/test/java/testdata/pmd101009/morph/MorphTest.java b/src/test/java/testdata/pmd101009/morph/MorphTest.java
new file mode 100644 (file)
index 0000000..e3625bb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.morph;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class MorphTest {
+
+    static Class<?> THISCLASS = MorphTest.class;
+
+    public MorphTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "allmorph.pmd", "allmorph.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allmorph.xml", "allmorph.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/numeric/NumericTest.java b/src/test/java/testdata/pmd101009/numeric/NumericTest.java
new file mode 100644 (file)
index 0000000..991a2dd
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.numeric;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class NumericTest {
+
+    static Class<?> THISCLASS = NumericTest.class;
+
+    public NumericTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "numeric.pmd", "result.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "source.xml", "numeric.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/rigid/RigidTest.java b/src/test/java/testdata/pmd101009/rigid/RigidTest.java
new file mode 100644 (file)
index 0000000..e4ebf06
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ */
+
+package testdata.pmd101009.rigid;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class RigidTest {
+
+    static Class<?> THISCLASS = RigidTest.class;
+
+    public RigidTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xml() throws Exception{
+        System.out.println("pmd2xml");
+        assertPmd2Xml(THISCLASS, "allrigid.pmd", "allrigid.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmd() throws Exception{
+        System.out.println("xml2pmd");
+        assertXml2Pmd(THISCLASS, "allrigid.xml", "allrigid.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/java/testdata/pmd101009/small/SmallTest.java b/src/test/java/testdata/pmd101009/small/SmallTest.java
new file mode 100644 (file)
index 0000000..2e3f031
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ */
+
+package testdata.pmd101009.small;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class SmallTest {
+
+    static Class<?> THISCLASS = SmallTest.class;
+
+    public SmallTest() {
+        assert this.getClass() == THISCLASS;
+        return;
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void pmd2xmlBone() throws Exception{
+        System.out.println("pmd2xmlBone");
+        assertPmd2Xml(THISCLASS, "onlybone.pmd", "onlybone.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlTriangle() throws Exception{
+        System.out.println("pmd2xmlTriangle");
+        assertPmd2Xml(THISCLASS, "onlytriangle.pmd", "onlytriangle.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlMorph() throws Exception{
+        System.out.println("pmd2xmlMorph");
+        assertPmd2Xml(THISCLASS, "onlymorph.pmd", "onlymorph.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlRigid() throws Exception{
+        System.out.println("pmd2xmlRigid");
+        assertPmd2Xml(THISCLASS, "onlyrigid.pmd", "onlyrigid.xml");
+        return;
+    }
+
+    @Test
+    public void pmd2xmlJoint() throws Exception{
+        System.out.println("pmd2xmlJoint");
+        assertPmd2Xml(THISCLASS, "onlyjoint.pmd", "onlyjoint.xml");
+        return;
+    }
+
+    @Test
+    public void xml2pmdBone() throws Exception{
+        System.out.println("xml2pmdBone");
+        assertXml2Pmd(THISCLASS, "onlybone.xml", "onlybone.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdTriangle() throws Exception{
+        System.out.println("xml2pmdTriangle");
+        assertXml2Pmd(THISCLASS, "onlytriangle.xml", "onlytriangle.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdMorph() throws Exception{
+        System.out.println("xml2pmdMorph");
+        assertXml2Pmd(THISCLASS, "onlymorph.xml", "onlymorph.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdRigid() throws Exception{
+        System.out.println("xml2pmdRigid");
+        assertXml2Pmd(THISCLASS, "onlyrigid.xml", "onlyrigid.pmd");
+        return;
+    }
+
+    @Test
+    public void xml2pmdJoint() throws Exception{
+        System.out.println("xml2pmdJoint");
+        assertXml2Pmd(THISCLASS, "onlyjoint.xml", "onlyjoint.pmd");
+        return;
+    }
+
+}
diff --git a/src/test/resources/testdata/charset/Readme.txt b/src/test/resources/testdata/charset/Readme.txt
deleted file mode 100644 (file)
index 4a4691b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-文字集合、エンコーディング、XML文字エスケープ、空白文字に関するテストデータ。
diff --git a/src/test/resources/testdata/charset/test.pmd b/src/test/resources/testdata/charset/test.pmd
deleted file mode 100644 (file)
index 6cb6d5d..0000000
Binary files a/src/test/resources/testdata/charset/test.pmd and /dev/null differ
diff --git a/src/test/resources/testdata/minimum/Readme.txt b/src/test/resources/testdata/minimum/Readme.txt
deleted file mode 100644 (file)
index 7fd068b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-最小構成のPMDファイル。
-※ XMLの改行コードはLF。ジェネレータ名は非表示。
-
-名前は空
-説明文は空
-頂点0
-ボーン0
diff --git a/src/test/resources/testdata/pmd101009/bone/Readme.txt b/src/test/resources/testdata/pmd101009/bone/Readme.txt
new file mode 100644 (file)
index 0000000..5b53910
--- /dev/null
@@ -0,0 +1,13 @@
+[UTF8 Japanese]
+
+
+10種類全てのボーンを含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- allbone.pmd 10種類全てのボーンを含むテストデータ。
+- allbone.xml モデルデータのソースとなったXMLファイル。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/bone/allbone.pmd b/src/test/resources/testdata/pmd101009/bone/allbone.pmd
new file mode 100644 (file)
index 0000000..1e76145
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/bone/allbone.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/bone/allbone.xml b/src/test/resources/testdata/pmd101009/bone/allbone.xml
new file mode 100644 (file)
index 0000000..b584e31
--- /dev/null
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- base [回転/移動] -->
+  <bone name="base" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- #>> [anchor] -->
+    <boneChain nextBoneIdRef="bn1" />
+  </bone>
+
+  <!-- anchor [非表示] -->
+  <bone name="anchor" boneId="bn1" type="HIDDEN" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [base] >># -->
+    <boneChain prevBoneIdRef="bn0" />
+  </bone>
+
+  <!-- hub [回転] -->
+  <bone name="hub" boneId="bn2" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [base] >>#>> [hinge1] -->
+    <boneChain prevBoneIdRef="bn0" nextBoneIdRef="bn3" />
+  </bone>
+
+  <!-- hinge1 [IK影響下(回転)] -->
+  <bone name="hinge1" boneId="bn3" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <ikBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hub] >>#>> [hinge2] -->
+    <boneChain prevBoneIdRef="bn2" nextBoneIdRef="bn4" />
+  </bone>
+
+  <!-- hinge2 [IK影響下(回転)] -->
+  <bone name="hinge2" boneId="bn4" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <ikBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hinge1] >>#>> [iktarget] -->
+    <boneChain prevBoneIdRef="bn3" nextBoneIdRef="bn5" />
+  </bone>
+
+  <!-- iktarget [IK影響下(回転)] -->
+  <bone name="iktarget" boneId="bn5" type="UNDERIK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <ikBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [hinge2] >>#>> [toe] -->
+    <boneChain prevBoneIdRef="bn4" nextBoneIdRef="bn6" />
+  </bone>
+
+  <!-- toe [IK接続先] -->
+  <bone name="toe" boneId="bn6" type="IKCONNECTED" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <ikBone boneIdRef="bn7" /> <!-- Ref:ik -->
+
+    <!-- [iktarget] >># -->
+    <boneChain prevBoneIdRef="bn5" />
+  </bone>
+
+  <!-- ik [IK] -->
+  <bone name="ik" boneId="bn7" type="IK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- toeik [IK] -->
+  <bone name="toeik" boneId="bn8" type="IK" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- botheye [回転] -->
+  <bone name="botheye" boneId="bn9" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [hub] >># -->
+    <boneChain prevBoneIdRef="bn2" />
+  </bone>
+
+  <!-- monoeye [回転影響下] -->
+  <bone name="monoeye" boneId="bn10" type="UNDERROT" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <ikBone boneIdRef="bn9" /> <!-- Ref:botheye -->
+
+    <!-- [hub] >># -->
+    <boneChain prevBoneIdRef="bn2" />
+  </bone>
+
+  <!-- arm [回転] -->
+  <bone name="arm" boneId="bn11" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [hub] >>#>> [elbow] -->
+    <boneChain prevBoneIdRef="bn2" nextBoneIdRef="bn13" />
+  </bone>
+
+  <!-- twist [捩り] -->
+  <bone name="twist" boneId="bn12" type="TWIST" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [arm] >># -->
+    <boneChain prevBoneIdRef="bn11" />
+  </bone>
+
+  <!-- elbow [回転] -->
+  <bone name="elbow" boneId="bn13" type="ROTATE" >
+    <position x="0.0" y="0.0" z="0.0" />
+
+    <!-- [twist] >># -->
+    <boneChain prevBoneIdRef="bn12" />
+  </bone>
+
+  <!-- lr [回転連動] -->
+  <bone name="lr" boneId="bn14" type="LINKEDROT" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <rotationRatio ratio="25" />
+
+    <!-- [arm] >>#>> [twist] -->
+    <boneChain prevBoneIdRef="bn11" nextBoneIdRef="bn12" />
+  </bone>
+
+  <!-- unknown [不明] -->
+  <bone name="unknown" boneId="bn15" type="UNKNOWN" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+
+  <!-- Ref:ik -->
+  <ikChain ikBoneIdRef="bn7" recursiveDepth="10" weight="0.1" >
+    <chainOrder boneIdRef="bn5" /> <!-- Ref:iktarget -->
+    <chainOrder boneIdRef="bn4" /> <!-- Ref:hinge2 -->
+    <chainOrder boneIdRef="bn3" /> <!-- Ref:hinge1 -->
+  </ikChain>
+
+  <!-- Ref:toeik -->
+  <ikChain ikBoneIdRef="bn8" recursiveDepth="10" weight="0.1" >
+    <chainOrder boneIdRef="bn6" /> <!-- Ref:toe -->
+    <chainOrder boneIdRef="bn5" /> <!-- Ref:iktarget -->
+  </ikChain>
+
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/charset/Readme.txt b/src/test/resources/testdata/pmd101009/charset/Readme.txt
new file mode 100644 (file)
index 0000000..f003f87
--- /dev/null
@@ -0,0 +1,27 @@
+[UTF8 Japanese]
+
+
+文字集合、エンコーディング、空白文字に関するPMDテストデータ。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- charset.pmd モデル名とモデル説明文に色々な字が書き込まれたテストデータ。
+- source.xml モデルデータのソースとなったXMLファイル。
+- result.xml モデルデータをXML化したときのあるべきXMLファイル。
+
+
+PMDモデルファイル内の文字データは
+文字集合「JIS X 0208-1990」に
+マイクロソフトによる追加文字を加えた物を
+シフトJISで符号化したものと仮定する。
+
+この文字コード形式の一般的な規格名は
+・Windows-31J
+・CP932
+など
+
+MMDでは、濁点を伴う半角カタカナなどをそのまま識別子に使う機会も多い。
+Unicodeデータとの交換時には、不用意な正規化を行わないよう注意が必要。
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/charset/charset.pmd b/src/test/resources/testdata/pmd101009/charset/charset.pmd
new file mode 100644 (file)
index 0000000..cd33fe5
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/charset/charset.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/charset/result.xml b/src/test/resources/testdata/pmd101009/charset/result.xml
new file mode 100644 (file)
index 0000000..44b20cb
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- a A  9 亜'" -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name="a A &#x20;9&#x3000;&#x4E9C;&apos;&quot;"
+>
+
+
+<description>
+azAZ09&#xFF71;<br/>
+&#xFF21;&#xFF3A;&#xFF10;&#xFF19;&#x3042;&#x30A2;&#x3091;&#x30F5;&#x30F6;<br/>
+&#x30F4;&#x30A6;&#x309B;&#xFF73;&#xFF9E;&#x30D1;&#x30CF;&#x309C;&#xFF8A;&#xFF9F;<br/>
+&#x03A9;&#x03C9;&#x0416;&#x0436;&#x2534;<br/>
+&#x5CE0;&#x58FA;&#x58F7;&#x5C2D;&#x582F;&#x51DC;&#x7199;<br/>
+\&#xFF3C;\&#xFFE5;<br/>
+&#x9AD9;&#x2468;&#x2252;&#x2235;&#xFFE2;&#x3231;&#x03A3;<br/>
+#$[\]^{|}~<br/>
+&apos;&quot;&amp;&lt;&gt;<br/>
+&lt;!--fake comment--&gt;<br/>
+A B &#x20;C<br/>
+A&#x09;B&#x09;&#x09;C<br/>
+A&#x3000;B&#x3000;&#x3000;C<br/>
+AB<br/>
+</description>
+<!--
+azAZ09ア
+AZ09あアゑヵヶ
+ヴウ゛ヴパハ゜パ
+ΩωЖж┴
+峠壺壷尭堯凜熙
+\\\¥
+髙⑨≒∵¬㈱Σ
+#$[\]^{|}~
+'"&<>
+<!- -fake comment- ->
+A B  C
+A␉B␉␉C
+A B  C
+AB
+-->
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/charset/source.xml b/src/test/resources/testdata/pmd101009/charset/source.xml
new file mode 100644 (file)
index 0000000..4eb03bb
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name="a A  9 亜&apos;&quot;"
+>
+
+
+<description>
+azAZ09ア<br/><!--                           半角 -->
+AZ09あアゑヵヶ<br/><!--                全角 -->
+ヴウ゛ヴパハ゜パ<br/><!--                  濁点 & 半濁点 -->
+ΩωЖж┴<br/><!--                        ギリシャ & ロシア & 罫線 -->
+峠壺壷尭堯凜熙<br/><!--                    国字 JIS78 → JIS83 → JIS90 -->
+\\¥¥<br/><!--                            円通貨 & バックスラッシュ -->
+髙⑨≒∵¬㈱Σ<br/><!--                    IBM漢字 & NEC漢字 & MS漢字 -->
+#$[\]^{|}~<br/><!--                        ISO-646 バリアント -->
+<![CDATA['"&<>]]><br/><!--                 XML 特殊文字 -->
+<![CDATA[<!--fake comment-->]]><br/><!--   コメントのCDATA化 -->
+A B  C<br/><!--                            半角スペース -->
+A&#x09;B&#x09;&#x09;C<br/><!--           タブ -->
+A B  C<br/><!--                         全角スペース -->
+A&#x0A;B<br/><!--                          無視される改行 -->
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+</boneList>
+
+<boneGroupList>
+
+</boneGroupList>
+
+<ikChainList>
+
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+
+</jointList>
+
+<surfaceGroupList>
+
+</surfaceGroupList>
+
+<vertexList>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/group/Readme.txt b/src/test/resources/testdata/pmd101009/group/Readme.txt
new file mode 100644 (file)
index 0000000..1f9a2d1
--- /dev/null
@@ -0,0 +1,18 @@
+[UTF8 Japanese]
+
+
+ボーンをグループ分けしたPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- boneGroup.pmd グループ分けされたボーンを有するテストデータ。
+- boneGroup.xml モデルデータのソースとなったXMLファイル。
+
+
+test0からtest3までの名が付けられた4ボーンが
+ボーン枠「偶数ボーン」とボーン枠「奇数ボーン」に2つずつ振り分けられる。
+
+ボーン名「test」は0番ボーン扱い。
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/group/boneGroup.pmd b/src/test/resources/testdata/pmd101009/group/boneGroup.pmd
new file mode 100644 (file)
index 0000000..5e7ba42
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/group/boneGroup.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/group/boneGroup.xml b/src/test/resources/testdata/pmd101009/group/boneGroup.xml
new file mode 100644 (file)
index 0000000..c33e801
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- test [回転/移動] -->
+  <bone name="test" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test0 [回転/移動] -->
+  <bone name="test0" boneId="bn1" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test1 [回転/移動] -->
+  <bone name="test1" boneId="bn2" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test2 [回転/移動] -->
+  <bone name="test2" boneId="bn3" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test3 [回転/移動] -->
+  <bone name="test3" boneId="bn4" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+
+  <!-- 偶数グループ -->
+  <boneGroup name="&#x5076;&#x6570;&#x30B0;&#x30EB;&#x30FC;&#x30D7;" >
+    <boneGroupMember boneIdRef="bn1" /> <!-- Ref:test0 -->
+    <boneGroupMember boneIdRef="bn3" /> <!-- Ref:test2 -->
+  </boneGroup>
+
+  <!-- 奇数グループ -->
+  <boneGroup name="&#x5947;&#x6570;&#x30B0;&#x30EB;&#x30FC;&#x30D7;" >
+    <boneGroupMember boneIdRef="bn2" /> <!-- Ref:test1 -->
+    <boneGroupMember boneIdRef="bn4" /> <!-- Ref:test3 -->
+  </boneGroup>
+
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/i18n/Readme.txt b/src/test/resources/testdata/pmd101009/i18n/Readme.txt
new file mode 100644 (file)
index 0000000..31897a9
--- /dev/null
@@ -0,0 +1,21 @@
+[UTF8 Japanese]
+
+
+各種英語名を記述したPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- i18n.pmd 英語名が記述されたテストデータ。
+- i18n.xml モデルデータのソースとなったXMLファイル。
+
+
+モデル名「テストモデル」に対応する英語名「TestModel」
+説明文「説明」に対応する英語文「Description」
+ボーン名「センター」に対応する英語名「Center」
+ボーン名「テストボーン」に対応する英語名「TestBone」
+グループ枠「テストグループ」に対応する英語名「TestGroup」
+モーフ名「テストモーフ」に対応する英語名「TestMorph」
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/i18n/i18n.pmd b/src/test/resources/testdata/pmd101009/i18n/i18n.pmd
new file mode 100644 (file)
index 0000000..0c689d1
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/i18n/i18n.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/i18n/i18n.xml b/src/test/resources/testdata/pmd101009/i18n/i18n.xml
new file mode 100644 (file)
index 0000000..4e923df
--- /dev/null
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- テストモデル -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name="&#x30C6;&#x30B9;&#x30C8;&#x30E2;&#x30C7;&#x30EB;"
+>
+
+<i18nName lang="en" name="TestModel" />
+
+<description>
+&#x8AAC;&#x660E;
+</description>
+<!--
+説明
+-->
+
+<description lang="en" >
+Description
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+  <material showEdge="true" surfaceGroupIdRef="sg0" >
+    <diffuse r="0.75" g="0.25" b="0.25" alpha="1.0" />
+    <specular r="0.0" g="0.0" b="0.0" shininess="5.0" />
+    <ambient r="0.25" g="0.75" b="0.25" />
+  </material>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- センター [回転/移動] -->
+  <bone name="&#x30BB;&#x30F3;&#x30BF;&#x30FC;" boneId="bn0" type="ROTMOV" >
+    <i18nName lang="en" name="Center" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn1" type="ROTMOV" >
+    <i18nName lang="en" name="TestBone" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+
+  <!-- テストグループ -->
+  <boneGroup name="&#x30C6;&#x30B9;&#x30C8;&#x30B0;&#x30EB;&#x30FC;&#x30D7;" >
+    <i18nName lang="en" name="TestGroup" />
+    <boneGroupMember boneIdRef="bn1" /> <!-- Ref:テストボーン -->
+  </boneGroup>
+
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+
+<!--
+Morph types:
+[1 : EYEBROW : まゆ   ]
+[2 : EYE     : 目     ]
+[3 : LIP     : リップ ]
+[4 : EXTRA   : その他 ]
+-->
+
+  <!-- テストモーフ -->
+  <morph name="&#x30C6;&#x30B9;&#x30C8;&#x30E2;&#x30FC;&#x30D5;" type="EXTRA" >
+    <i18nName lang="en" name="TestMorph" />
+    <morphVertex vtxIdRef="vtx0" xOff="0.0" yOff="3.0" zOff="0.0" />
+  </morph>
+
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+
+  <surfaceGroup surfaceGroupId="sg0" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+</surfaceGroupList>
+
+<vertexList>
+
+  <vertex vtxId="vtx0" showEdge="true" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx1" showEdge="true" >
+    <position x="-5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx2" showEdge="true" >
+    <position x="5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/ik/Readme.txt b/src/test/resources/testdata/pmd101009/ik/Readme.txt
new file mode 100644 (file)
index 0000000..5a1de37
--- /dev/null
@@ -0,0 +1,21 @@
+[UTF8 Japanese]
+
+
+IKボーンを記述したPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- ikBone.pmd IKボーンが記述されたテストデータ。
+- ikBone.xml モデルデータのソースとなったXMLファイル。
+
+
+左足首 → 左ひざ → 左足 → センター の順で親ボーンを参照する。
+左足首、左ひざ、左足、いずれのボーン分類も「IK影響下」
+
+IKボーン「左足IK」のターゲットは「左足首」。
+IKボーン「左足IK」の影響下にあるボーンは「左ひざ」と「左足」の順。
+IKボーン「左足IK」によるIK処理のループ回数は50、単位は0.5
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/ik/ikBone.pmd b/src/test/resources/testdata/pmd101009/ik/ikBone.pmd
new file mode 100644 (file)
index 0000000..1927925
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/ik/ikBone.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/ik/ikBone.xml b/src/test/resources/testdata/pmd101009/ik/ikBone.xml
new file mode 100644 (file)
index 0000000..fe4251a
--- /dev/null
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- センター [回転/移動] -->
+  <bone name="&#x30BB;&#x30F3;&#x30BF;&#x30FC;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- 左足 [IK影響下(回転)] -->
+  <bone name="&#x5DE6;&#x8DB3;" boneId="bn1" type="UNDERIK" >
+    <position x="0.0" y="10.0" z="0.0" />
+    <ikBone boneIdRef="bn4" /> <!-- Ref:左足IK -->
+
+    <!-- [センター] >>#>> [左ひざ] -->
+    <boneChain prevBoneIdRef="bn0" nextBoneIdRef="bn2" />
+  </bone>
+
+  <!-- 左ひざ [IK影響下(回転)] -->
+  <bone name="&#x5DE6;&#x3072;&#x3056;" boneId="bn2" type="UNDERIK" >
+    <position x="0.0" y="7.0" z="-0.01" />
+    <ikBone boneIdRef="bn4" /> <!-- Ref:左足IK -->
+
+    <!-- [左足] >>#>> [左足首] -->
+    <boneChain prevBoneIdRef="bn1" nextBoneIdRef="bn3" />
+  </bone>
+
+  <!-- 左足首 [IK影響下(回転)] -->
+  <bone name="&#x5DE6;&#x8DB3;&#x9996;" boneId="bn3" type="UNDERIK" >
+    <position x="0.0" y="4.0" z="0.0" />
+    <ikBone boneIdRef="bn4" /> <!-- Ref:左足IK -->
+
+    <!-- [左ひざ] >># -->
+    <boneChain prevBoneIdRef="bn2" />
+  </bone>
+
+  <!-- 左足IK [IK] -->
+  <bone name="&#x5DE6;&#x8DB3;&#xFF29;&#xFF2B;" boneId="bn4" type="IK" >
+    <position x="0.0" y="4.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+
+  <!-- Ref:左足IK -->
+  <ikChain ikBoneIdRef="bn4" recursiveDepth="50" weight="0.5" >
+    <chainOrder boneIdRef="bn3" /> <!-- Ref:左足首 -->
+    <chainOrder boneIdRef="bn2" /> <!-- Ref:左ひざ -->
+    <chainOrder boneIdRef="bn1" /> <!-- Ref:左足 -->
+  </ikChain>
+
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/material/Readme.txt b/src/test/resources/testdata/pmd101009/material/Readme.txt
new file mode 100644 (file)
index 0000000..52715d8
--- /dev/null
@@ -0,0 +1,36 @@
+[UTF8 Japanese]
+
+
+様々なマテリアル設定を含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- material.pmd 様々なマテリアル設定を含むテストデータ。
+- material.xml モデルデータのソースとなったXMLファイル。
+
+
+・マテリアル0番
+ エッジ表示フラグがオフな事を確認。
+
+・マテリアル1番
+ ビルトインのトゥーンマップ名"toon01.bmp"が指定されていることを確認。
+
+・マテリアル2番
+ カスタムトゥーンマップ名"test.bmp"が指定されていることを確認。
+
+・マテリアル3番
+ テクスチャマップファイル名に"Test.bmp"が指定されていることを確認。
+
+・マテリアル4番
+ スフィアマップファイル名に"Test.sph"が指定されていることを確認。
+
+・マテリアル5番
+ トゥーンマップとテクスチャマップとスフィアマップが
+ 同時に指定されていることを確認。
+
+・マテリアル6番
+ 加算スフィアマップファイル名に"Test.spa"が指定されていることを確認。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/material/material.pmd b/src/test/resources/testdata/pmd101009/material/material.pmd
new file mode 100644 (file)
index 0000000..e405956
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/material/material.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/material/material.xml b/src/test/resources/testdata/pmd101009/material/material.xml
new file mode 100644 (file)
index 0000000..7ed96b1
--- /dev/null
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+  <material showEdge="false" surfaceGroupIdRef="sg0" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.875" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="3.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg1" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <toon toonFileIdRef="tf0" /> <!-- toon01.bmp -->
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg2" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <toon toonFileIdRef="tf9" /> <!-- test.bmp -->
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg3" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <textureFile winFileName="Tex.bmp" />
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg4" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <spheremapFile winFileName="Tex.sph" />
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg5" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <toon toonFileIdRef="tf0" /> <!-- toon01.bmp -->
+    <textureFile winFileName="Tex.bmp" />
+    <spheremapFile winFileName="Tex.sph" />
+  </material>
+
+  <material showEdge="true" surfaceGroupIdRef="sg6" >
+    <diffuse r="0.25" g="0.5" b="0.75" alpha="0.125" />
+    <specular r="0.0" g="1.0" b="0.5" shininess="0.0" />
+    <ambient r="0.75" g="0.5" b="0.25" />
+    <spheremapFile winFileName="Tex.spa" />
+  </material>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="test.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- test [回転/移動] -->
+  <bone name="test" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+
+  <surfaceGroup surfaceGroupId="sg0" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg1" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg2" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg3" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg4" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg5" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+  <surfaceGroup surfaceGroupId="sg6" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+</surfaceGroupList>
+
+<vertexList>
+
+  <vertex vtxId="vtx0" showEdge="true" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx1" showEdge="true" >
+    <position x="-5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx2" showEdge="true" >
+    <position x="5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/minimum/Readme.txt b/src/test/resources/testdata/pmd101009/minimum/Readme.txt
new file mode 100644 (file)
index 0000000..9f74f62
--- /dev/null
@@ -0,0 +1,18 @@
+[UTF8 Japanese]
+
+
+最小構成のPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- minimum.pmd 最小構成のテストデータ。
+- minimum.xml モデルデータのソースとなったXMLファイル。
+
+
+・名前は空。
+・説明文は空。
+・0頂点。
+・0ボーン。
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/minimum/minimum.xml b/src/test/resources/testdata/pmd101009/minimum/minimum.xml
new file mode 100644 (file)
index 0000000..1ccd4c3
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/morph/Readme.txt b/src/test/resources/testdata/pmd101009/morph/Readme.txt
new file mode 100644 (file)
index 0000000..ba9ba2d
--- /dev/null
@@ -0,0 +1,13 @@
+[UTF8 Japanese]
+
+
+4種類全てのモーフを含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- allmorph.pmd 4種類全てのモーフを含むテストデータ。
+- allmorph.xml モデルデータのソースとなったXMLファイル。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/morph/allmorph.pmd b/src/test/resources/testdata/pmd101009/morph/allmorph.pmd
new file mode 100644 (file)
index 0000000..91f933f
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/morph/allmorph.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/morph/allmorph.xml b/src/test/resources/testdata/pmd101009/morph/allmorph.xml
new file mode 100644 (file)
index 0000000..30d90dc
--- /dev/null
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+  <material showEdge="true" surfaceGroupIdRef="sg0" >
+    <diffuse r="0.75" g="0.25" b="0.25" alpha="1.0" />
+    <specular r="0.0" g="0.0" b="0.0" shininess="5.0" />
+    <ambient r="0.25" g="0.75" b="0.25" />
+  </material>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- testbone [回転/移動] -->
+  <bone name="testbone" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+
+<!--
+Morph types:
+[1 : EYEBROW : まゆ   ]
+[2 : EYE     : 目     ]
+[3 : LIP     : リップ ]
+[4 : EXTRA   : その他 ]
+-->
+
+  <!-- testEyebrow -->
+  <morph name="testEyebrow" type="EYEBROW" >
+    <morphVertex vtxIdRef="vtx0" xOff="3.0" yOff="0.0" zOff="0.001" />
+  </morph>
+
+  <!-- testEye -->
+  <morph name="testEye" type="EYE" >
+    <morphVertex vtxIdRef="vtx0" xOff="0.0" yOff="3.0" zOff="0.0" />
+  </morph>
+
+  <!-- testLip -->
+  <morph name="testLip" type="LIP" >
+    <morphVertex vtxIdRef="vtx0" xOff="0.0" yOff="0.0" zOff="3.0" />
+  </morph>
+
+  <!-- testExtra -->
+  <morph name="testExtra" type="EXTRA" >
+    <morphVertex vtxIdRef="vtx0" xOff="3.0" yOff="3.0" zOff="3.0" />
+    <morphVertex vtxIdRef="vtx1" xOff="2.0" yOff="2.0" zOff="2.0" />
+  </morph>
+
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+
+  <surfaceGroup surfaceGroupId="sg0" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+</surfaceGroupList>
+
+<vertexList>
+
+  <vertex vtxId="vtx0" showEdge="true" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx1" showEdge="true" >
+    <position x="-5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx2" showEdge="true" >
+    <position x="5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/numeric/Readme.txt b/src/test/resources/testdata/pmd101009/numeric/Readme.txt
new file mode 100644 (file)
index 0000000..c0408f1
--- /dev/null
@@ -0,0 +1,49 @@
+[UTF8 Japanese]
+
+
+きわどい数値データを含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- numeric.pmd 様々な数値が書き込まれたテストデータ。
+- source.xml モデルデータのソースとなったXMLファイル。
+- result.xml モデルデータをXML化したときのあるべきXMLファイル。
+
+
+MMDのモデルファイルでは、実数表現としてIEEE754単精度型を用いる。
+IEEE754単精度型は、Javaのfloat型値や、XML Schemaのfloat型値に該当する。
+参照URL: http://www.w3.org/TR/xmlschema-2/#float
+
+ソフトウェアによっては、単精度正規数の最小値
+  1.175494350822287507968736537222245677818665556772087521508751706278
+    4172594547271728515625E-38
+を下回る絶対値の値を扱おうとすると、
+演算トラップが発生して異常終了することがあるので注意。
+MMDやPMDEditorでは、このようなデータが出現しても異常終了しない。
+
+このモデルデータでは、各ボーンの座標にテスト用の数値を格納する。
+
+
+test01
+  様々なゼロ表記。z値のゼロ値には負の符号が付かなければならない。
+  ※ PMDEditorは負のゼロを解釈できない?
+
+test02
+  様々な指数形式での表記その1。
+
+test03
+  様々な指数形式での表記その2。
+
+test04
+  0、およびその次に小さい数、さらにその次に小さい数。
+
+test05
+  最小の正符号の正規数、およびその前後値。
+  ※ PMDEditorはこれらのデータを区別できない?
+
+test06
+  1.0、およびその前後値。
+  ※ PMDEditorは1.0とその次に大きい値を区別できない?
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/numeric/numeric.pmd b/src/test/resources/testdata/pmd101009/numeric/numeric.pmd
new file mode 100644 (file)
index 0000000..ee26a4f
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/numeric/numeric.pmd differ
@@ -6,41 +6,20 @@
 -->
 
 
 -->
 
 
-<!-- a A  9 亜'" -->
+<!-- [NAMELESS] -->
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009 http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
   schemaVersion="101009"
 
   schemaVersion="101009"
 
-  name="a A &#x20;9&#x3000;&#x4E9C;&apos;&quot;"
+  name=""
 >
 
 
 <description>
 >
 
 
 <description>
-azAZ&#xFF21;&#xFF3A;09&#xFF10;&#xFF19;&#x3042;&#x30A2;&#xFF71;&#x3091;&#x30F5;&#x30F6;&#x03A9;&#x03C9;&#x0416;&#x0436;<br/>
-&#x2510;&#x2514;&#x6F22;&#x5CE0;&#x51DC;&#x7199;<br/>
-&#x30F4;&#x30A6;&#x309B;&#xFF73;&#xFF9E;&#x30D1;&#x30CF;&#x309C;&#xFF8A;&#xFF9F;<br/>
-&#x58FA;&#x58F7;&#x5C2D;&#x582F;<br/>
-\&#xFF3C;\&#xFFE5;<br/>
-&#x9AD9;&#x2468;&#x2252;&#x2235;&#xFFE2;&#x3231;&#x03A3;<br/>
-#$[\]^{|}~<br/>
-cdata&apos;&quot;&amp;&lt;&gt;test<br/>
-&lt;!--fake comment--&gt;<br/>
-A B &#x20;C&#x09;D&#x09;&#x09;E&#x3000;F&#x3000;&#x3000;GHI
 </description>
 </description>
-<!--
-azAZAZ0909あアアゑヵヶΩωЖж
-┐└漢峠凜熙
-ヴウ゛ヴパハ゜パ
-壺壷尭堯
-\\\¥
-髙⑨≒∵¬㈱Σ
-#$[\]^{|}~
-cdata'"&<>test
-<!- -fake comment- ->
-A B  C␉D␉␉E F  GHI
--->
 
 <license>
 </license>
 
 <license>
 </license>
@@ -52,7 +31,6 @@ A B  C␉D␉␉E F  GHI
 <meta name="imageURL" content="" />
 
 <materialList>
 <meta name="imageURL" content="" />
 
 <materialList>
-
 </materialList>
 
 <toonMap>
 </materialList>
 
 <toonMap>
@@ -84,85 +62,84 @@ Bone types:
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
+  <!-- test01 [回転/移動] -->
+  <bone name="test01" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="-0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test02 [回転/移動] -->
+  <bone name="test02" boneId="bn1" type="ROTMOV" >
+    <position x="1200.0" y="1200.0" z="0.0012" />
+    <boneChain />
+  </bone>
+
+  <!-- test03 [回転/移動] -->
+  <bone name="test03" boneId="bn2" type="ROTMOV" >
+    <position x="1200.0" y="1.2" z="0.0" />
+    <boneChain />
+  </bone>
+
+  <!-- test04 [回転/移動] -->
+  <bone name="test04" boneId="bn3" type="ROTMOV" >
+    <position x="0.0" y="1.4E-45" z="2.8E-45" />
+    <boneChain />
+  </bone>
+
+  <!-- test05 [回転/移動] -->
+  <bone name="test05" boneId="bn4" type="ROTMOV" >
+    <position x="1.1754942E-38" y="1.17549435E-38" z="1.1754945E-38" />
+    <boneChain />
+  </bone>
+
+  <!-- test06 [回転/移動] -->
+  <bone name="test06" boneId="bn5" type="ROTMOV" >
+    <position x="0.99999994" y="1.0" z="1.0000001" />
+    <boneChain />
+  </bone>
+
 </boneList>
 
 <boneGroupList>
 </boneList>
 
 <boneGroupList>
-
 </boneGroupList>
 
 <ikChainList>
 </boneGroupList>
 
 <ikChainList>
-
 </ikChainList>
 
 <morphList>
 </ikChainList>
 
 <morphList>
-
-<!--
-Morph types:
-[1 : EYEBROW : まゆ   ]
-[2 : EYE     : 目     ]
-[3 : LIP     : リップ ]
-[4 : EXTRA   : その他 ]
--->
-
 </morphList>
 
 <rigidList>
 </morphList>
 
 <rigidList>
-
-<!--
-Rigid behavior types:
-[0 : FOLLOWBONE    : ボーン追従       ]
-[1 : ONLYDYNAMICS  : 物理演算         ]
-[2 : BONEDDYNAMICS : ボーン位置合わせ ]
--->
-
 </rigidList>
 
 <rigidGroupList>
 
   <rigidGroup rigidGroupId="rg1" />
 </rigidList>
 
 <rigidGroupList>
 
   <rigidGroup rigidGroupId="rg1" />
-
   <rigidGroup rigidGroupId="rg2" />
   <rigidGroup rigidGroupId="rg2" />
-
   <rigidGroup rigidGroupId="rg3" />
   <rigidGroup rigidGroupId="rg3" />
-
   <rigidGroup rigidGroupId="rg4" />
   <rigidGroup rigidGroupId="rg4" />
-
   <rigidGroup rigidGroupId="rg5" />
   <rigidGroup rigidGroupId="rg5" />
-
   <rigidGroup rigidGroupId="rg6" />
   <rigidGroup rigidGroupId="rg6" />
-
   <rigidGroup rigidGroupId="rg7" />
   <rigidGroup rigidGroupId="rg7" />
-
   <rigidGroup rigidGroupId="rg8" />
   <rigidGroup rigidGroupId="rg8" />
-
   <rigidGroup rigidGroupId="rg9" />
   <rigidGroup rigidGroupId="rg9" />
-
   <rigidGroup rigidGroupId="rg10" />
   <rigidGroup rigidGroupId="rg10" />
-
   <rigidGroup rigidGroupId="rg11" />
   <rigidGroup rigidGroupId="rg11" />
-
   <rigidGroup rigidGroupId="rg12" />
   <rigidGroup rigidGroupId="rg12" />
-
   <rigidGroup rigidGroupId="rg13" />
   <rigidGroup rigidGroupId="rg13" />
-
   <rigidGroup rigidGroupId="rg14" />
   <rigidGroup rigidGroupId="rg14" />
-
   <rigidGroup rigidGroupId="rg15" />
   <rigidGroup rigidGroupId="rg15" />
-
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
-
 </jointList>
 
 <surfaceGroupList>
 </jointList>
 
 <surfaceGroupList>
-
 </surfaceGroupList>
 
 <vertexList>
 </surfaceGroupList>
 
 <vertexList>
-
 </vertexList>
 
 </pmdModel>
 </vertexList>
 
 </pmdModel>
diff --git a/src/test/resources/testdata/pmd101009/numeric/source.xml b/src/test/resources/testdata/pmd101009/numeric/source.xml
new file mode 100644 (file)
index 0000000..2b59358
--- /dev/null
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <bone name="test01" boneId="bn0" type="ROTMOV" >
+    <position x="0" y="0.0" z="-0.0" />
+    <boneChain />
+  </bone>
+
+  <bone name="test02" boneId="bn1" type="ROTMOV" >
+    <position x="1.2E3" y="1.2E+3" z="1.2E-3" />
+    <boneChain />
+  </bone>
+
+  <bone name="test03" boneId="bn2" type="ROTMOV" >
+    <position x="1.2e3" y="1.2E0" z="0E0" />
+    <boneChain />
+  </bone>
+
+  <bone name="test04" boneId="bn3" type="ROTMOV" >
+    <position
+      x="0.0"
+      y="1.40129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125E-45"
+      z="2.8025969286496341418474591665798322625605238837530315435141365677795821653717212029732763767242431640625E-45"
+    />
+    <boneChain />
+  </bone>
+
+  <bone name="test05" boneId="bn4" type="ROTMOV" >
+    <position
+      x="1.175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875E-38"
+      y="1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625E-38"
+      z="1.175494490952133940450443629595204006810278684798281709160328881985245648433835441437622648663818836212158203125E-38"
+    />
+    <boneChain />
+  </bone>
+
+  <bone name="test06" boneId="bn5" type="ROTMOV" >
+    <position
+      x="0.999999940395355224609375"
+      y="1.0"
+      z="1.00000011920928955078125"
+    />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/rigid/Readme.txt b/src/test/resources/testdata/pmd101009/rigid/Readme.txt
new file mode 100644 (file)
index 0000000..c68b8fb
--- /dev/null
@@ -0,0 +1,13 @@
+[UTF8 Japanese]
+
+
+全種類全形状の剛体を含むPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- allrigid.pmd 全種類全形状の剛体を含むテストデータ。
+- allrigid.xml モデルデータのソースとなったXMLファイル。
+
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/rigid/allrigid.pmd b/src/test/resources/testdata/pmd101009/rigid/allrigid.pmd
new file mode 100644 (file)
index 0000000..05b2a23
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/rigid/allrigid.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/rigid/allrigid.xml b/src/test/resources/testdata/pmd101009/rigid/allrigid.xml
new file mode 100644 (file)
index 0000000..9fa3b6e
--- /dev/null
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- testbone [回転/移動] -->
+  <bone name="testbone" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+
+<!--
+Rigid behavior types:
+[0 : FOLLOWBONE    : ボーン追従       ]
+[1 : ONLYDYNAMICS  : 物理演算         ]
+[2 : BONEDDYNAMICS : ボーン位置合わせ ]
+-->
+
+  <!-- testrigid1 -->
+  <rigid name="testrigid1" rigidId="rd0" behavior="FOLLOWBONE" >
+    <linkedBone boneIdRef="bn0" /> <!-- Ref:testbone -->
+
+    <rigidShapeSphere radius="1.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+  </rigid>
+
+  <!-- testrigid2 -->
+  <rigid name="testrigid2" rigidId="rd1" behavior="ONLYDYNAMICS" >
+    <rigidShapeBox width="1.0" height="1.0" depth="1.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+  </rigid>
+
+  <!-- testrigid3 -->
+  <rigid name="testrigid3" rigidId="rd2" behavior="BONEDDYNAMICS" >
+    <linkedBone boneIdRef="bn0" /> <!-- Ref:testbone -->
+
+    <rigidShapeCapsule height="1.0" radius="1.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+    <throughRigidGroup rigidGroupIdRef="rg1"  />
+  </rigid>
+
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" >
+    <rigidGroupMember rigidIdRef="rd0" /> <!-- Ref:testrigid1 -->
+  </rigidGroup>
+
+  <rigidGroup rigidGroupId="rg2" >
+    <rigidGroupMember rigidIdRef="rd1" /> <!-- Ref:testrigid2 -->
+  </rigidGroup>
+
+  <rigidGroup rigidGroupId="rg3" >
+    <rigidGroupMember rigidIdRef="rd2" /> <!-- Ref:testrigid3 -->
+  </rigidGroup>
+
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/small/Readme.txt b/src/test/resources/testdata/pmd101009/small/Readme.txt
new file mode 100644 (file)
index 0000000..6866278
--- /dev/null
@@ -0,0 +1,103 @@
+[UTF8 Japanese]
+
+
+データの小さいPMDファイル。
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+========================================================================
+onlybone.pmd
+onlybone.xml
+
+ボーンが一つだけ定義されたPMDモデルデータ。
+ボーン名「テストボーン」
+種別「回転/移動」
+座標(0.0, 0.0, 0.0)
+親子関係なし
+
+========================================================================
+onlytriangle.pmd
+onlytriangle.xml
+
+onlybone.pmdに加え、
+三角ポリゴンとマテリアルが一つだけ定義されたPMDモデルデータ。
+
+ポリゴンは三頂点(0.0, 0.0, 0.0), (-5.0, 8.0, 0.0), (5.0, 8.0, 0.0)
+を結ぶ三角形。
+いずれの頂点も法線ベクトルは(0.0, 0.0, -1.0)。
+いずれの頂点もエッジ表示設定はオン。
+いずれの頂点もuv座標は(0.0, 1.0)
+いずれの頂点も唯一のテストボーンへのウェイト100%。
+
+マテリアル設定:
+Diffuse色 0.75, 0.25, 0.25
+Specular色 0.0, 0.0, 0.0
+Ambient色 0.25, 0.75, 0.26
+Alpha値 1.0
+Shininess値 5
+輪郭表示あり
+Toon設定はなし。
+
+========================================================================
+onlymorph.pmd
+onlymorph.xml
+
+onlytriangle.pmdに加え、
+頂点モーフが一つだけ定義されたPMDモデルデータ。
+
+モーフ名:テストモーフ
+モーフ種別:その他
+三角形の一番Y値の低い頂点(0.0, 0.0, 0.0)を
+(0.0, 3.0, 0.0)までモーフする。
+
+========================================================================
+onlyrigid.pmd
+onlyrigid.xml
+
+onlybone.pmdに加え、
+剛体が一つだけ定義されたPMDモデルデータ。
+
+剛体名:テスト剛体
+唯一のテストボーンに追従
+
+箱形状(W:1.0 H:2.0 D:3.0)
+剛体位置:(0.0, 0.0, 0.0)
+剛体姿勢:(0.0, 0.0, 0.0)
+
+剛体グループ1に所属。
+いかなる剛体グループとも衝突する。
+
+質量:0.1
+移動減衰:0.2
+回転減衰:0.3
+反発力:0.4
+摩擦力:0.5
+
+========================================================================
+onlyjoint.pmd
+onlyjoint.xml
+
+onlyrigid.pmdに加え、
+接続ボーンを持たない剛体「フリー剛体」を追加し、
+二つになった剛体を結ぶジョイントが一つだけ定義されたPMDモデルデータ。
+
+「フリー剛体」は、接続ボーンを持たないことと物理演算属性であること意外は
+「テスト剛体」と同じ設定。
+
+ジョイント名:テストジョイント
+テスト剛体とフリー剛体を結ぶ。
+
+ジョイント位置:(0.0,0.0,0.0)
+位置制限(0.0-0.0, 0.0-0.0, 0.0-0.0)
+
+ジョイント姿勢:(0.0,0.0,0.0)
+姿勢制限(0.0-0.0, 0.0-0.0, 0.0-0.0)
+
+バネ移動:(0.0, 0.0, 0.0)
+バネ姿勢:(0.0, 0.0, 0.0)
+
+
+========================================================================
+
+
+-- EOF --
diff --git a/src/test/resources/testdata/pmd101009/small/onlybone.pmd b/src/test/resources/testdata/pmd101009/small/onlybone.pmd
new file mode 100644 (file)
index 0000000..9f3a3bb
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/small/onlybone.pmd differ
@@ -6,11 +6,12 @@
 -->
 
 
 -->
 
 
-<!--  -->
+<!-- [NAMELESS] -->
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009 http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
   schemaVersion="101009"
 
   name=""
   schemaVersion="101009"
 
   name=""
@@ -30,7 +31,6 @@
 <meta name="imageURL" content="" />
 
 <materialList>
 <meta name="imageURL" content="" />
 
 <materialList>
-
 </materialList>
 
 <toonMap>
 </materialList>
 
 <toonMap>
@@ -62,85 +62,54 @@ Bone types:
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
 </boneList>
 
 <boneGroupList>
 </boneList>
 
 <boneGroupList>
-
 </boneGroupList>
 
 <ikChainList>
 </boneGroupList>
 
 <ikChainList>
-
 </ikChainList>
 
 <morphList>
 </ikChainList>
 
 <morphList>
-
-<!--
-Morph types:
-[1 : EYEBROW : まゆ   ]
-[2 : EYE     : 目     ]
-[3 : LIP     : リップ ]
-[4 : EXTRA   : その他 ]
--->
-
 </morphList>
 
 <rigidList>
 </morphList>
 
 <rigidList>
-
-<!--
-Rigid behavior types:
-[0 : FOLLOWBONE    : ボーン追従       ]
-[1 : ONLYDYNAMICS  : 物理演算         ]
-[2 : BONEDDYNAMICS : ボーン位置合わせ ]
--->
-
 </rigidList>
 
 <rigidGroupList>
 
   <rigidGroup rigidGroupId="rg1" />
 </rigidList>
 
 <rigidGroupList>
 
   <rigidGroup rigidGroupId="rg1" />
-
   <rigidGroup rigidGroupId="rg2" />
   <rigidGroup rigidGroupId="rg2" />
-
   <rigidGroup rigidGroupId="rg3" />
   <rigidGroup rigidGroupId="rg3" />
-
   <rigidGroup rigidGroupId="rg4" />
   <rigidGroup rigidGroupId="rg4" />
-
   <rigidGroup rigidGroupId="rg5" />
   <rigidGroup rigidGroupId="rg5" />
-
   <rigidGroup rigidGroupId="rg6" />
   <rigidGroup rigidGroupId="rg6" />
-
   <rigidGroup rigidGroupId="rg7" />
   <rigidGroup rigidGroupId="rg7" />
-
   <rigidGroup rigidGroupId="rg8" />
   <rigidGroup rigidGroupId="rg8" />
-
   <rigidGroup rigidGroupId="rg9" />
   <rigidGroup rigidGroupId="rg9" />
-
   <rigidGroup rigidGroupId="rg10" />
   <rigidGroup rigidGroupId="rg10" />
-
   <rigidGroup rigidGroupId="rg11" />
   <rigidGroup rigidGroupId="rg11" />
-
   <rigidGroup rigidGroupId="rg12" />
   <rigidGroup rigidGroupId="rg12" />
-
   <rigidGroup rigidGroupId="rg13" />
   <rigidGroup rigidGroupId="rg13" />
-
   <rigidGroup rigidGroupId="rg14" />
   <rigidGroup rigidGroupId="rg14" />
-
   <rigidGroup rigidGroupId="rg15" />
   <rigidGroup rigidGroupId="rg15" />
-
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
-
 </jointList>
 
 <surfaceGroupList>
 </jointList>
 
 <surfaceGroupList>
-
 </surfaceGroupList>
 
 <vertexList>
 </surfaceGroupList>
 
 <vertexList>
-
 </vertexList>
 
 </pmdModel>
 </vertexList>
 
 </pmdModel>
diff --git a/src/test/resources/testdata/pmd101009/small/onlyjoint.pmd b/src/test/resources/testdata/pmd101009/small/onlyjoint.pmd
new file mode 100644 (file)
index 0000000..3d9ca8a
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/small/onlyjoint.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/small/onlyjoint.xml b/src/test/resources/testdata/pmd101009/small/onlyjoint.xml
new file mode 100644 (file)
index 0000000..3e61dbe
--- /dev/null
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+
+<!--
+Rigid behavior types:
+[0 : FOLLOWBONE    : ボーン追従       ]
+[1 : ONLYDYNAMICS  : 物理演算         ]
+[2 : BONEDDYNAMICS : ボーン位置合わせ ]
+-->
+
+  <!-- テスト剛体 -->
+  <rigid name="&#x30C6;&#x30B9;&#x30C8;&#x525B;&#x4F53;" rigidId="rd0" behavior="FOLLOWBONE" >
+    <linkedBone boneIdRef="bn0" /> <!-- Ref:テストボーン -->
+
+    <rigidShapeBox width="1.0" height="2.0" depth="3.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+  </rigid>
+
+  <!-- フリー剛体 -->
+  <rigid name="&#x30D5;&#x30EA;&#x30FC;&#x525B;&#x4F53;" rigidId="rd1" behavior="ONLYDYNAMICS" >
+    <rigidShapeBox width="1.0" height="2.0" depth="3.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+  </rigid>
+
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" >
+    <rigidGroupMember rigidIdRef="rd0" /> <!-- Ref:テスト剛体 -->
+    <rigidGroupMember rigidIdRef="rd1" /> <!-- Ref:フリー剛体 -->
+  </rigidGroup>
+
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+
+  <!-- テストジョイント -->
+  <joint name="&#x30C6;&#x30B9;&#x30C8;&#x30B8;&#x30E7;&#x30A4;&#x30F3;&#x30C8;" >
+    <!-- [テスト剛体] <=> [フリー剛体] -->
+    <jointedRigidPair rigidIdRef1="rd0" rigidIdRef2="rd1" />
+
+    <position x="0.0" y="0.0" z="0.0" />
+    <limitPosition
+      xFrom="0.0" xTo="0.0"
+      yFrom="0.0" yTo="0.0"
+      zFrom="0.0" zTo="0.0"
+    />
+
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <limitRotation
+      xFrom="0.0" xTo="0.0"
+      yFrom="0.0" yTo="0.0"
+      zFrom="0.0" zTo="0.0"
+    />
+
+    <elasticPosition x="0.0" y="0.0" z="0.0" />
+    <elasticRotation xDeg="0.0" yDeg="0.0" zDeg="0.0" />
+
+  </joint>
+
+</jointList>
+
+<surfaceGroupList>
+</surfaceGroupList>
+
+<vertexList>
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/small/onlymorph.pmd b/src/test/resources/testdata/pmd101009/small/onlymorph.pmd
new file mode 100644 (file)
index 0000000..e43927e
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/small/onlymorph.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/small/onlymorph.xml b/src/test/resources/testdata/pmd101009/small/onlymorph.xml
new file mode 100644 (file)
index 0000000..73d19b2
--- /dev/null
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+  <material showEdge="true" surfaceGroupIdRef="sg0" >
+    <diffuse r="0.75" g="0.25" b="0.25" alpha="1.0" />
+    <specular r="0.0" g="0.0" b="0.0" shininess="5.0" />
+    <ambient r="0.25" g="0.75" b="0.25" />
+  </material>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+
+<!--
+Morph types:
+[1 : EYEBROW : まゆ   ]
+[2 : EYE     : 目     ]
+[3 : LIP     : リップ ]
+[4 : EXTRA   : その他 ]
+-->
+
+  <!-- テストモーフ -->
+  <morph name="&#x30C6;&#x30B9;&#x30C8;&#x30E2;&#x30FC;&#x30D5;" type="EXTRA" >
+    <morphVertex vtxIdRef="vtx0" xOff="0.0" yOff="3.0" zOff="0.0" />
+  </morph>
+
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+
+  <surfaceGroup surfaceGroupId="sg0" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+</surfaceGroupList>
+
+<vertexList>
+
+  <vertex vtxId="vtx0" showEdge="true" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx1" showEdge="true" >
+    <position x="-5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx2" showEdge="true" >
+    <position x="5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->
diff --git a/src/test/resources/testdata/pmd101009/small/onlyrigid.pmd b/src/test/resources/testdata/pmd101009/small/onlyrigid.pmd
new file mode 100644 (file)
index 0000000..b636f57
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/small/onlyrigid.pmd differ
@@ -6,28 +6,19 @@
 -->
 
 
 -->
 
 
+<!-- [NAMELESS] -->
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 <pmdModel
   xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009 http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
   schemaVersion="101009"
 
   schemaVersion="101009"
 
-  name="a A  9 亜&apos;&quot;"
+  name=""
 >
 
 
 <description>
 >
 
 
 <description>
-azAZAZ0909あアアゑヵヶΩωЖж<br/>
-┐└漢峠凜熙<br/>
-ヴウ゛ヴパハ゜パ<br/>
-壺壷尭堯<br/>
-\\¥¥<br/>
-髙⑨≒∵¬㈱Σ<br/>
-#$[\]^{|}~<br/>
-<![CDATA[cdata'"&<>test]]><br/>
-<![CDATA[<!--fake comment-->]]><br/>
-A B  C&#x09;D&#x09;&#x09;E F  G
-H&#x0A;I
 </description>
 
 <license>
 </description>
 
 <license>
@@ -40,7 +31,6 @@ H&#x0A;I
 <meta name="imageURL" content="" />
 
 <materialList>
 <meta name="imageURL" content="" />
 
 <materialList>
-
 </materialList>
 
 <toonMap>
 </materialList>
 
 <toonMap>
@@ -72,26 +62,21 @@ Bone types:
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
 [9 : LINKEDROT   : Linked Rotate: 回転連動       :]
 -->
 
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
 </boneList>
 
 <boneGroupList>
 </boneList>
 
 <boneGroupList>
-
 </boneGroupList>
 
 <ikChainList>
 </boneGroupList>
 
 <ikChainList>
-
 </ikChainList>
 
 <morphList>
 </ikChainList>
 
 <morphList>
-
-<!--
-Morph types:
-[1 : EYEBROW : まゆ   ]
-[2 : EYE     : 目     ]
-[3 : LIP     : リップ ]
-[4 : EXTRA   : その他 ]
--->
-
 </morphList>
 
 <rigidList>
 </morphList>
 
 <rigidList>
@@ -103,54 +88,56 @@ Rigid behavior types:
 [2 : BONEDDYNAMICS : ボーン位置合わせ ]
 -->
 
 [2 : BONEDDYNAMICS : ボーン位置合わせ ]
 -->
 
+  <!-- テスト剛体 -->
+  <rigid name="&#x30C6;&#x30B9;&#x30C8;&#x525B;&#x4F53;" rigidId="rd0" behavior="FOLLOWBONE" >
+    <linkedBone boneIdRef="bn0" /> <!-- Ref:テストボーン -->
+
+    <rigidShapeBox width="1.0" height="2.0" depth="3.0" />
+    <position x="0.0" y="0.0" z="0.0" />
+    <radRotation xRad="0.0" yRad="0.0" zRad="0.0" />
+    <dynamics
+      mass="0.1"
+      dampingPosition="0.2"
+      dampingRotation="0.3"
+      restitution="0.4"
+      friction="0.5"
+    />
+
+  </rigid>
+
 </rigidList>
 
 <rigidGroupList>
 
 </rigidList>
 
 <rigidGroupList>
 
-  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg1" >
+    <rigidGroupMember rigidIdRef="rd0" /> <!-- Ref:テスト剛体 -->
+  </rigidGroup>
 
   <rigidGroup rigidGroupId="rg2" />
 
   <rigidGroup rigidGroupId="rg2" />
-
   <rigidGroup rigidGroupId="rg3" />
   <rigidGroup rigidGroupId="rg3" />
-
   <rigidGroup rigidGroupId="rg4" />
   <rigidGroup rigidGroupId="rg4" />
-
   <rigidGroup rigidGroupId="rg5" />
   <rigidGroup rigidGroupId="rg5" />
-
   <rigidGroup rigidGroupId="rg6" />
   <rigidGroup rigidGroupId="rg6" />
-
   <rigidGroup rigidGroupId="rg7" />
   <rigidGroup rigidGroupId="rg7" />
-
   <rigidGroup rigidGroupId="rg8" />
   <rigidGroup rigidGroupId="rg8" />
-
   <rigidGroup rigidGroupId="rg9" />
   <rigidGroup rigidGroupId="rg9" />
-
   <rigidGroup rigidGroupId="rg10" />
   <rigidGroup rigidGroupId="rg10" />
-
   <rigidGroup rigidGroupId="rg11" />
   <rigidGroup rigidGroupId="rg11" />
-
   <rigidGroup rigidGroupId="rg12" />
   <rigidGroup rigidGroupId="rg12" />
-
   <rigidGroup rigidGroupId="rg13" />
   <rigidGroup rigidGroupId="rg13" />
-
   <rigidGroup rigidGroupId="rg14" />
   <rigidGroup rigidGroupId="rg14" />
-
   <rigidGroup rigidGroupId="rg15" />
   <rigidGroup rigidGroupId="rg15" />
-
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
   <rigidGroup rigidGroupId="rg16" />
 
 </rigidGroupList>
 
 <jointList>
-
 </jointList>
 
 <surfaceGroupList>
 </jointList>
 
 <surfaceGroupList>
-
 </surfaceGroupList>
 
 <vertexList>
 </surfaceGroupList>
 
 <vertexList>
-
 </vertexList>
 
 </pmdModel>
 </vertexList>
 
 </pmdModel>
diff --git a/src/test/resources/testdata/pmd101009/small/onlytriangle.pmd b/src/test/resources/testdata/pmd101009/small/onlytriangle.pmd
new file mode 100644 (file)
index 0000000..daf75c5
Binary files /dev/null and b/src/test/resources/testdata/pmd101009/small/onlytriangle.pmd differ
diff --git a/src/test/resources/testdata/pmd101009/small/onlytriangle.xml b/src/test/resources/testdata/pmd101009/small/onlytriangle.xml
new file mode 100644 (file)
index 0000000..ad34bb1
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  MikuMikuDance
+    model-data(*.pmd) on XML
+-->
+
+
+<!-- [NAMELESS] -->
+<pmdModel
+  xmlns="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/pmdxml/101009
+    http://mikutoga.sourceforge.jp/xml/xsd/pmdxml-101009.xsd"
+  schemaVersion="101009"
+
+  name=""
+>
+
+
+<description>
+</description>
+
+<license>
+</license>
+
+<credits>
+</credits>
+
+<meta name="siteURL" content="" />
+<meta name="imageURL" content="" />
+
+<materialList>
+
+  <material showEdge="true" surfaceGroupIdRef="sg0" >
+    <diffuse r="0.75" g="0.25" b="0.25" alpha="1.0" />
+    <specular r="0.0" g="0.0" b="0.0" shininess="5.0" />
+    <ambient r="0.25" g="0.75" b="0.25" />
+  </material>
+
+</materialList>
+
+<toonMap>
+  <toonDef toonFileId="tf0" index="0" winFileName="toon01.bmp" />
+  <toonDef toonFileId="tf1" index="1" winFileName="toon02.bmp" />
+  <toonDef toonFileId="tf2" index="2" winFileName="toon03.bmp" />
+  <toonDef toonFileId="tf3" index="3" winFileName="toon04.bmp" />
+  <toonDef toonFileId="tf4" index="4" winFileName="toon05.bmp" />
+  <toonDef toonFileId="tf5" index="5" winFileName="toon06.bmp" />
+  <toonDef toonFileId="tf6" index="6" winFileName="toon07.bmp" />
+  <toonDef toonFileId="tf7" index="7" winFileName="toon08.bmp" />
+  <toonDef toonFileId="tf8" index="8" winFileName="toon09.bmp" />
+  <toonDef toonFileId="tf9" index="9" winFileName="toon10.bmp" />
+</toonMap>
+
+<boneList>
+
+<!--
+Bone types:
+[0 : ROTATE      : Rotate       : 回転           :]
+[1 : ROTMOV      : Rotate/Move  : 回転/移動      :]
+[2 : IK          : IK           : IK             :]
+[3 : UNKNOWN     : Unknown      : 不明           :]
+[4 : UNDERIK     : Under IK     : IK影響下(回転) :]
+[5 : UNDERROT    : Under rotate : 回転影響下     :]
+[6 : IKCONNECTED : IK connected : IK接続先       :]
+[7 : HIDDEN      : Hidden       : 非表示         :]
+[8 : TWIST       : Twist        : 捩り           :]
+[9 : LINKEDROT   : Linked Rotate: 回転連動       :]
+-->
+
+  <!-- テストボーン [回転/移動] -->
+  <bone name="&#x30C6;&#x30B9;&#x30C8;&#x30DC;&#x30FC;&#x30F3;" boneId="bn0" type="ROTMOV" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <boneChain />
+  </bone>
+
+</boneList>
+
+<boneGroupList>
+</boneGroupList>
+
+<ikChainList>
+</ikChainList>
+
+<morphList>
+</morphList>
+
+<rigidList>
+</rigidList>
+
+<rigidGroupList>
+
+  <rigidGroup rigidGroupId="rg1" />
+  <rigidGroup rigidGroupId="rg2" />
+  <rigidGroup rigidGroupId="rg3" />
+  <rigidGroup rigidGroupId="rg4" />
+  <rigidGroup rigidGroupId="rg5" />
+  <rigidGroup rigidGroupId="rg6" />
+  <rigidGroup rigidGroupId="rg7" />
+  <rigidGroup rigidGroupId="rg8" />
+  <rigidGroup rigidGroupId="rg9" />
+  <rigidGroup rigidGroupId="rg10" />
+  <rigidGroup rigidGroupId="rg11" />
+  <rigidGroup rigidGroupId="rg12" />
+  <rigidGroup rigidGroupId="rg13" />
+  <rigidGroup rigidGroupId="rg14" />
+  <rigidGroup rigidGroupId="rg15" />
+  <rigidGroup rigidGroupId="rg16" />
+
+</rigidGroupList>
+
+<jointList>
+</jointList>
+
+<surfaceGroupList>
+
+  <surfaceGroup surfaceGroupId="sg0" >
+    <surface vtxIdRef1="vtx0" vtxIdRef2="vtx1" vtxIdRef3="vtx2" />
+  </surfaceGroup>
+
+</surfaceGroupList>
+
+<vertexList>
+
+  <vertex vtxId="vtx0" showEdge="true" >
+    <position x="0.0" y="0.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx1" showEdge="true" >
+    <position x="-5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+  <vertex vtxId="vtx2" showEdge="true" >
+    <position x="5.0" y="8.0" z="0.0" />
+    <normal x="0.0" y="0.0" z="-1.0" />
+    <uvMap u="0.0" v="1.0" />
+    <skinning boneIdRef1="bn0" boneIdRef2="bn0" weightBalance="100" />
+  </vertex>
+
+</vertexList>
+
+</pmdModel>
+
+<!-- EOF -->