From 44455c1e9cac18c78eb8ab6105459d4dbd41c402 Mon Sep 17 00:00:00 2001 From: Olyutorskii Date: Sat, 8 Jun 2013 13:30:39 +0900 Subject: [PATCH] =?utf8?q?MMD=20Ver7.40=20=E5=AF=BE=E5=BF=9C=20=E6=96=B0?= =?utf8?q?=E3=82=B9=E3=82=AD=E3=83=BC=E3=83=9E=E9=96=8B=E7=99=BA=E9=96=8B?= =?utf8?q?=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CHANGELOG.txt | 1 + pom.xml | 2 +- .../java/jp/sfjp/mikutoga/vmd/model/IkSwitch.java | 81 ++ .../sfjp/mikutoga/vmd/model/NumberedVmdFlag.java | 92 ++ .../java/jp/sfjp/mikutoga/vmd/model/VmdMotion.java | 24 +- .../mikutoga/vmd/model/binio/BoolExporter.java | 96 +++ .../sfjp/mikutoga/vmd/model/binio/BoolLoader.java | 126 +++ .../sfjp/mikutoga/vmd/model/binio/VmdExporter.java | 9 + .../sfjp/mikutoga/vmd/model/binio/VmdLoader.java | 18 +- .../model/xml/{SaxXsdUtil.java => SaxAttr.java} | 29 +- .../mikutoga/vmd/model/xml/SaxCameraListener.java | 24 +- .../vmd/model/xml/SaxLightingListener.java | 20 +- .../mikutoga/vmd/model/xml/SaxMotionListener.java | 30 +- .../mikutoga/vmd/model/xml/SaxVmdListener.java | 8 +- .../jp/sfjp/mikutoga/vmd/model/xml/XmlHandler.java | 2 +- .../java/jp/sfjp/mikutoga/vmd2xml/Vmd2XmlConv.java | 1 - .../vmd/model/xml/resources/vmdxml-130609A.xsd | 944 +++++++++++++++++++++ .../jp/sfjp/mikutoga/vmd/model/VmdMotionTest.java | 9 +- .../testdata/vmd130609/minimum/minmotion.xml | 31 + .../testdata/vmd130609/small/onlyFlag.xml | 36 + 20 files changed, 1508 insertions(+), 75 deletions(-) create mode 100644 src/main/java/jp/sfjp/mikutoga/vmd/model/IkSwitch.java create mode 100644 src/main/java/jp/sfjp/mikutoga/vmd/model/NumberedVmdFlag.java create mode 100644 src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolExporter.java create mode 100644 src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolLoader.java rename src/main/java/jp/sfjp/mikutoga/vmd/model/xml/{SaxXsdUtil.java => SaxAttr.java} (75%) create mode 100644 src/main/resources/jp/sfjp/mikutoga/vmd/model/xml/resources/vmdxml-130609A.xsd create mode 100644 src/test/resources/testdata/vmd130609/minimum/minmotion.xml create mode 100644 src/test/resources/testdata/vmd130609/small/onlyFlag.xml diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2f97907..c13ad5c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -10,6 +10,7 @@ X.XXX.X (20XX-XX_XX) ・ベジェ補間パラメータ冗長部がMMDの版により異なるため、検査をやめた。 ・プロセス終了コードの変更。 ・DOMからSAXへの移行。 + ・MikuMikuDance Ver7.40以降の新VMDファイルフォーマットに対応 1.101.2 (2011-08-25) diff --git a/pom.xml b/pom.xml index 7b31956..5d30fcb 100644 --- a/pom.xml +++ b/pom.xml @@ -112,7 +112,7 @@ jp.sourceforge.mikutoga togagem - 2.102.5-SNAPSHOT + 2.102.7-SNAPSHOT compile diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/IkSwitch.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/IkSwitch.java new file mode 100644 index 0000000..85d6df1 --- /dev/null +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/IkSwitch.java @@ -0,0 +1,81 @@ +/* + * IK ON/OFF switch + * + * License : The MIT License + * Copyright(c) 2013 MikuToga Partners + */ + +package jp.sfjp.mikutoga.vmd.model; + +import java.text.MessageFormat; + +/** + * IK ON/OFF の管理を行う。 + */ +public class IkSwitch { + + private static final String MSG_TXT = + "IKbone {0} : {1}"; + + + private String boneName = ""; + private boolean valid = true; + + + /** + * コンストラクタ。 + */ + public IkSwitch(){ + super(); + return; + } + + + /** + * ボーン名を返す。 + * @return ボーン名 + */ + public String getBoneName(){ + return this.boneName; + } + + /** + * ボーン名を設定する。 + * @param boneNameArg ボーン名 + * @throws NullPointerException 引数がnull + */ + public void setBoneName(String boneNameArg) throws NullPointerException{ + if(boneNameArg == null) throw new NullPointerException(); + this.boneName = boneNameArg; + return; + } + + /** + * IK処理が有効か否か返す。 + * @return 有効ならtrue + */ + public boolean isValid(){ + return this.valid; + } + + /** + * IK処理が有効か否か設定する。 + * @param validArg 有効ならtrue + */ + public void setValid(boolean validArg){ + this.valid = validArg; + return; + } + + /** + * {@inheritDoc} + * @return {@inheritDoc} + */ + @Override + public String toString(){ + String msg; + msg = MessageFormat.format(MSG_TXT, this.boneName, this.valid); + return msg; + } + +} diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/NumberedVmdFlag.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/NumberedVmdFlag.java new file mode 100644 index 0000000..3e1a33b --- /dev/null +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/NumberedVmdFlag.java @@ -0,0 +1,92 @@ +/* + * model presence switch + * + * License : The MIT License + * Copyright(c) 2013 MikuToga Partners + */ + +package jp.sfjp.mikutoga.vmd.model; + +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import jp.sfjp.mikutoga.vmd.AbstractNumbered; + +/** + * フレーム番号が付けられた各種モーションフラグの管理を行う。 + */ +public class NumberedVmdFlag + extends AbstractNumbered + implements Iterable { + + private static final String MSG_TXT = + "#{0} model precense : {1}"; + + + private boolean shown = true; + private List ikSwList = new LinkedList(); + + + /** + * コンストラクタ。 + *

モデル表示ありの状態で初期化される。 + */ + public NumberedVmdFlag(){ + super(); + return; + } + + + /** + * モデルを表示するか否か返す。 + * @return 表示するならtrue + */ + public boolean isModelShown(){ + return this.shown; + } + + /** + * モデルを表示するか否か設定する。 + * @param shownArg 表示するならtrue + */ + public void setModelShown(boolean shownArg){ + this.shown = shownArg; + return; + } + + /** + * 個別IKボーンフラグのリストを返す。 + * @return 個別IKボーンフラグのリスト + */ + public List getIkSwitchList(){ + return this.ikSwList; + } + + /** + * {@inheritDoc} + * @return {@inheritDoc} + */ + @Override + public Iterator iterator(){ + return this.ikSwList.iterator(); + } + + /** + * {@inheritDoc} + * @return {@inheritDoc} + */ + @Override + public String toString(){ + String msg; + msg = MessageFormat.format(MSG_TXT, getFrameNumber(), this.shown); + + StringBuilder submsg = new StringBuilder(msg); + for(IkSwitch sw : this.ikSwList){ + submsg.append('\n').append("\u0020").append(sw.toString()); + } + + return submsg.toString(); + } + +} diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/VmdMotion.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/VmdMotion.java index a006061..c06561c 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/VmdMotion.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/VmdMotion.java @@ -22,8 +22,8 @@ import jp.sfjp.mikutoga.vmd.VmdUniq; public class VmdMotion { private static final String MSG_TXT = - "model name : {0}\n" - + "bone#{1} morph#{2} camera#{3} luminous#{4} shadow#{5}"; + "model name : {0}\n" + + "bone#{1} morph#{2} camera#{3} luminous#{4} shadow#{5} flag#{6}"; private String modelName = VmdUniq.MODELNAME_STAGEACT; @@ -31,9 +31,10 @@ public class VmdMotion { private final Map> bonePartMap; private final Map> morphPartMap; - private final List cameraMotionList; - private final List luminousMotionList; - private final List shadowMotionList; + private final List cameraMotionList; + private final List luminousMotionList; + private final List shadowMotionList; + private final List flagList; /** @@ -48,6 +49,7 @@ public class VmdMotion { this.cameraMotionList = new LinkedList(); this.luminousMotionList = new LinkedList(); this.shadowMotionList = new LinkedList(); + this.flagList = new LinkedList(); return; } @@ -132,6 +134,14 @@ public class VmdMotion { } /** + * 各種フレーム番号付きフラグのリストを返す。 + * @return フレーム番号付きフラグのリスト + */ + public List getNumberedFlagList(){ + return this.flagList; + } + + /** * ボーンモーションを追加する。 * 追加順は保持される。 * @param motion ボーンモーション @@ -186,6 +196,7 @@ public class VmdMotion { Collections.sort(this.cameraMotionList, FrameNumbered.COMPARATOR); Collections.sort(this.luminousMotionList, FrameNumbered.COMPARATOR); Collections.sort(this.shadowMotionList, FrameNumbered.COMPARATOR); + Collections.sort(this.flagList, FrameNumbered.COMPARATOR); return; } @@ -209,11 +220,12 @@ public class VmdMotion { int cameraNo = this.cameraMotionList .size(); int luminousNo = this.luminousMotionList.size(); int shadowNo = this.shadowMotionList .size(); + int flagNo = this.flagList .size(); String msg; msg = MessageFormat.format(MSG_TXT, this.modelName, - boneNo, morphNo, cameraNo, luminousNo, shadowNo ); + boneNo, morphNo, cameraNo, luminousNo, shadowNo, flagNo ); return msg; } diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolExporter.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolExporter.java new file mode 100644 index 0000000..e43bb65 --- /dev/null +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolExporter.java @@ -0,0 +1,96 @@ +/* + * boolean information exporter + * + * License : The MIT License + * Copyright(c) 2013 MikuToga Partners + */ + +package jp.sfjp.mikutoga.vmd.model.binio; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import jp.sfjp.mikutoga.bin.export.BinaryExporter; +import jp.sfjp.mikutoga.bin.export.IllegalTextExportException; +import jp.sfjp.mikutoga.vmd.VmdConst; +import jp.sfjp.mikutoga.vmd.model.IkSwitch; +import jp.sfjp.mikutoga.vmd.model.NumberedVmdFlag; +import jp.sfjp.mikutoga.vmd.model.VmdMotion; + +/** + * フラグ情報のエクスポーター。 + *

MikuMikuDance Ver7.40以降でサポート + */ +class BoolExporter extends BinaryExporter{ + + private static final byte[] FDFILLER = + { (byte)0x00, (byte)0xfd }; + + + /** + * コンストラクタ。 + * @param stream 出力ストリーム + */ + BoolExporter(OutputStream stream){ + super(stream); + return; + } + + + /** + * フラグ情報を出力する。 + * @param motion モーションデータ + * @throws IOException 出力エラー + * @throws IllegalTextExportException 不正な文字列が指定された。 + */ + void dumpNumberedFlagMotion(VmdMotion motion) + throws IOException, IllegalTextExportException { + List list = motion.getNumberedFlagList(); + + if(list.isEmpty()) return; + + int count = list.size(); + dumpLeInt(count); + + for(NumberedVmdFlag flag : list){ + int frameNo = flag.getFrameNumber(); + dumpLeInt(frameNo); + + byte showModel; + if(flag.isModelShown()) showModel = 0x01; + else showModel = 0x00; + dumpByte(showModel); + + dumpIkSwitch(flag); + } + + + return; + } + + /** + * IK有効フラグを出力する。 + * @param flag フラグ情報 + * @throws IOException 出力エラー + * @throws IllegalTextExportException 不正な文字列が指定された。 + */ + private void dumpIkSwitch(NumberedVmdFlag flag) + throws IOException, IllegalTextExportException { + List swList = flag.getIkSwitchList(); + int swNo = swList.size(); + dumpLeInt(swNo); + + for(IkSwitch ikSwitch : swList){ + String boneName = ikSwitch.getBoneName(); + dumpFixedW31j(boneName, VmdConst.IKSWBONENAME_MAX, FDFILLER); + + byte ikValid; + if(ikSwitch.isValid()) ikValid = 0x01; + else ikValid = 0x00; + dumpByte(ikValid); + } + + return; + } + +} diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolLoader.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolLoader.java new file mode 100644 index 0000000..208dd8f --- /dev/null +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/BoolLoader.java @@ -0,0 +1,126 @@ +/* + * boolean information builder + * + * License : The MIT License + * Copyright(c) 2013 MikuToga Partners + */ + +package jp.sfjp.mikutoga.vmd.model.binio; + +import java.util.List; +import jp.sfjp.mikutoga.bin.parser.MmdFormatException; +import jp.sfjp.mikutoga.bin.parser.ParseStage; +import jp.sfjp.mikutoga.vmd.model.IkSwitch; +import jp.sfjp.mikutoga.vmd.model.NumberedVmdFlag; +import jp.sfjp.mikutoga.vmd.model.VmdMotion; +import jp.sfjp.mikutoga.vmd.parser.VmdBoolHandler; + +/** + * フラグ情報のビルダ。 + *

MikuMikuDance Ver7.40以降でサポート + */ +public class BoolLoader implements VmdBoolHandler{ + + private final List flagList; + + private NumberedVmdFlag currentFlag; + private IkSwitch currentSwitch; + + /** + * コンストラクタ。 + * @param vmdMotion モーションデータの格納先。 + */ + BoolLoader(VmdMotion vmdMotion){ + super(); + this.flagList = vmdMotion.getNumberedFlagList(); + return; + } + + + /** + * {@inheritDoc} + * @param stage {@inheritDoc} + * @param loops {@inheritDoc} + * @throws MmdFormatException {@inheritDoc} + */ + @Override + public void loopStart(ParseStage stage, int loops) + throws MmdFormatException{ + if(stage == VmdBoolHandler.MODELSIGHT_LIST){ + this.currentFlag = new NumberedVmdFlag(); + }else if(stage == VmdBoolHandler.IKSW_LIST){ + this.currentSwitch = new IkSwitch(); + } + + return; + } + + /** + * {@inheritDoc} + * @param stage {@inheritDoc} + * @throws MmdFormatException {@inheritDoc} + */ + @Override + public void loopNext(ParseStage stage) + throws MmdFormatException{ + if(stage == VmdBoolHandler.MODELSIGHT_LIST){ + this.flagList.add(this.currentFlag); + this.currentFlag = new NumberedVmdFlag(); + }else if(stage == VmdBoolHandler.IKSW_LIST){ + List swList = this.currentFlag.getIkSwitchList(); + swList.add(this.currentSwitch); + this.currentSwitch = new IkSwitch(); + } + + return; + } + + /** + * {@inheritDoc} + * @param stage {@inheritDoc} + * @throws MmdFormatException {@inheritDoc} + */ + @Override + public void loopEnd(ParseStage stage) + throws MmdFormatException{ + if(stage == VmdBoolHandler.MODELSIGHT_LIST){ + this.currentFlag = null; + }else if(stage == VmdBoolHandler.IKSW_LIST){ + this.currentSwitch = null; + } + + return; + } + + /** + * {@inheritDoc} + * @param show {@inheritDoc} + * @param keyFrameNo {@inheritDoc} + * @throws MmdFormatException {@inheritDoc} + */ + @Override + public void vmdModelSight(boolean show, int keyFrameNo) + throws MmdFormatException { + this.currentFlag.setModelShown(show); + this.currentFlag.setFrameNumber(keyFrameNo); + return; + } + + /** + * {@inheritDoc} + * @param boneName {@inheritDoc} + * @param validIk {@inheritDoc} + * @param keyFrameNo {@inheritDoc} + * @throws MmdFormatException {@inheritDoc} + */ + @Override + public void vmdIkSwitch(String boneName, + boolean validIk, + int keyFrameNo ) + throws MmdFormatException { + this.currentSwitch.setBoneName(boneName); + this.currentSwitch.setValid(validIk); + return; + } + +} diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdExporter.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdExporter.java index e04dfd9..1d372e0 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdExporter.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdExporter.java @@ -21,6 +21,7 @@ public class VmdExporter { private BasicExporter basicExporter = null; private CameraExporter cameraExporter = null; private LightingExporter lightingExporter = null; + private BoolExporter boolExporter = null; /** @@ -44,6 +45,7 @@ public class VmdExporter { this.basicExporter = new BasicExporter(ostream); this.cameraExporter = new CameraExporter(ostream); this.lightingExporter = new LightingExporter(ostream); + this.boolExporter = new BoolExporter(ostream); try{ dumpVmdMotionImpl(motion); @@ -76,6 +78,13 @@ public class VmdExporter { this.lightingExporter.dumpLuminousMotion(motion); this.lightingExporter.dumpShadowMotion(motion); + if(motion.getNumberedFlagList().isEmpty()) return; + try{ + this.boolExporter.dumpNumberedFlagMotion(motion); + }catch(IllegalTextExportException e){ + throw new IllegalVmdDataException(e); + } + return; } diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdLoader.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdLoader.java index be7d841..e832b6b 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdLoader.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/binio/VmdLoader.java @@ -25,7 +25,6 @@ public class VmdLoader { private boolean loaded = false; private boolean hasMoreData = true; - private boolean ignoreName = true; private boolean redundantCheck = false; @@ -49,23 +48,11 @@ public class VmdLoader { } /** - * カメラ・ライティングデータのパースを試みるか否かの判断で、 - * 特殊モデル名判定を無視するか否か設定する。 - * デフォルトではモデル名を無視。 - *

※MMDVer7.30前後のVMD出力不具合を回避したい場合は、 - * オフにするとパースに成功する場合がある。 - * @param mode モデル名を無視してパースを強行するならtrue - */ - public void setIgnoreName(boolean mode){ - this.ignoreName = mode; - return; - } - - /** * ボーンモーション補間情報冗長部のチェックを行うか否か設定する。 * デフォルトではチェックを行わない。 *

※MMDVer7.30前後のVMD出力不具合を回避したい場合は、 * オフにするとパースに成功する場合がある。 + *

※MMD Ver7.39x64以降はチェック回避必須。 * @param mode チェックさせたければtrue */ public void setRedundantCheck(boolean mode){ @@ -92,16 +79,17 @@ public class VmdLoader { VmdParser parser = new VmdParser(source); - parser.setIgnoreName(this.ignoreName); parser.setRedundantCheck(this.redundantCheck); BasicLoader basicBuilder = new BasicLoader(motion); CameraLoader cameraBuilder = new CameraLoader(motion); LightingLoader lightingBuilder = new LightingLoader(motion); + BoolLoader boolBuilder = new BoolLoader(motion); parser.setBasicHandler(basicBuilder); parser.setCameraHandler(cameraBuilder); parser.setLightingHandler(lightingBuilder); + parser.setBoolHandler(boolBuilder); try{ parser.parseVmd(); diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxXsdUtil.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxAttr.java similarity index 75% rename from src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxXsdUtil.java rename to src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxAttr.java index a1e9c0f..283d4f8 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxXsdUtil.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxAttr.java @@ -13,24 +13,35 @@ import org.xml.sax.Attributes; /** * XSD各種型のSAX属性値をJavaプリミティブ型へ変換する。 */ -final class SaxXsdUtil { +public final class SaxAttr { /** * 隠しコンストラクタ。 */ - private SaxXsdUtil(){ + private SaxAttr(){ assert false; throw new AssertionError(); } /** + * 属性名に対応する属性値があるか否か判定する。 + * @param attr 属性群 + * @param name 属性名 + * @return 属性名に対応する属性値がある場合はtrue + */ + public static boolean hasAttr(Attributes attr, String name){ + if(attr.getValue(name) == null) return false; + return true; + } + + /** * xsd:string型属性値の読み込み。 * @param attr 属性群 * @param name 属性名 * @return 属性値。該当する属性が無ければnull。 */ - static String getStringAttr(Attributes attr, String name){ + public static String getStringAttr(Attributes attr, String name){ String attrVal = attr.getValue(name); return attrVal; } @@ -42,7 +53,7 @@ final class SaxXsdUtil { * @return 属性値。 * @throws IllegalArgumentException boolean型表記ではない */ - static boolean getBooleanAttr(Attributes attr, String name) + public static boolean getBooleanAttr(Attributes attr, String name) throws IllegalArgumentException{ String attrVal = attr.getValue(name); boolean bVal; @@ -58,7 +69,9 @@ final class SaxXsdUtil { * @return 属性値。 * @throws IllegalArgumentException boolean型表記ではない */ - static boolean getBooleanAttr(Attributes attr, String name, boolean def) + public static boolean getBooleanAttr(Attributes attr, + String name, + boolean def ) throws IllegalArgumentException{ String attrVal = attr.getValue(name); if(attrVal == null) return def; @@ -76,7 +89,7 @@ final class SaxXsdUtil { * @return 属性値。 * @throws NumberFormatException byte型表記ではない */ - static byte getByteAttr(Attributes attr, String name) + public static byte getByteAttr(Attributes attr, String name) throws NumberFormatException{ String attrVal = attr.getValue(name); byte bVal; @@ -91,7 +104,7 @@ final class SaxXsdUtil { * @return 属性値。 * @throws NumberFormatException float型表記ではない */ - static float getFloatAttr(Attributes attr, String name) + public static float getFloatAttr(Attributes attr, String name) throws NumberFormatException { String attrVal = attr.getValue(name); float fVal; @@ -106,7 +119,7 @@ final class SaxXsdUtil { * @return 属性値。 * @throws NumberFormatException int型表記ではない */ - static int getIntAttr(Attributes attr, String name) + public static int getIntAttr(Attributes attr, String name) throws NumberFormatException { String attrVal = attr.getValue(name); int iVal; diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxCameraListener.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxCameraListener.java index 116777b..e29a620 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxCameraListener.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxCameraListener.java @@ -98,13 +98,13 @@ class SaxCameraListener extends SaxVmdListener{ private void openCameraMotion(Attributes attr){ this.currentCamera = new CameraMotion(); - int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME); + int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME); this.currentCamera.setFrameNumber(frameNo); boolean hasPerspective = - SaxXsdUtil.getBooleanAttr(attr, - XmlAttr.ATTR_HAS_PERSPECTIVE, - true ); + SaxAttr.getBooleanAttr(attr, + XmlAttr.ATTR_HAS_PERSPECTIVE, + true ); this.currentCamera.setPerspectiveMode(hasPerspective); return; @@ -130,9 +130,9 @@ class SaxCameraListener extends SaxVmdListener{ private void openCameraTarget(Attributes attr){ MkPos3D targetPos = this.currentCamera.getCameraTarget(); - float xPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_POS); - float yPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_POS); - float zPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_POS); + float xPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_POS); + float yPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_POS); + float zPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_POS); targetPos.setPosition(xPos, yPos, zPos); @@ -150,9 +150,9 @@ class SaxCameraListener extends SaxVmdListener{ CameraRotation cameraRotation = this.currentCamera.getCameraRotation(); - float latitude = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_RAD); - float longitude = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_RAD); - float roll = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_RAD); + float latitude = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_RAD); + float longitude = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_RAD); + float roll = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_RAD); cameraRotation.setLatitude(latitude); cameraRotation.setLongitude(longitude); @@ -169,7 +169,7 @@ class SaxCameraListener extends SaxVmdListener{ * @param attr 属性群 */ private void openCameraRange(Attributes attr){ - float range = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RANGE); + float range = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_RANGE); this.currentCamera.setRange(range); BezierParam bez = this.currentCamera.getIntpltRange(); @@ -183,7 +183,7 @@ class SaxCameraListener extends SaxVmdListener{ * @param attr 属性群 */ private void openProjection(Attributes attr){ - int vertDeg = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_VERT_DEG); + int vertDeg = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_VERT_DEG); this.currentCamera.setProjectionAngle(vertDeg); BezierParam bez = this.currentCamera.getIntpltProjection(); diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxLightingListener.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxLightingListener.java index 7386d0d..9cfe45a 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxLightingListener.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxLightingListener.java @@ -79,7 +79,7 @@ class SaxLightingListener extends SaxVmdListener{ private void openLumiAct(Attributes attr){ this.currentLuminous = new LuminousMotion(); - int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME); + int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME); this.currentLuminous.setFrameNumber(frameNo); return; @@ -105,9 +105,9 @@ class SaxLightingListener extends SaxVmdListener{ private void openLumiColor(Attributes attr){ LuminousColor color = this.currentLuminous.getColor(); - float rCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_R_COL); - float gCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_G_COL); - float bCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_B_COL); + float rCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_R_COL); + float gCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_G_COL); + float bCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_B_COL); color.setColR(rCol); color.setColG(gCol); @@ -123,9 +123,9 @@ class SaxLightingListener extends SaxVmdListener{ private void openLumiDirection(Attributes attr){ MkVec3D vec = this.currentLuminous.getDirection(); - float xVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_VEC); - float yVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_VEC); - float zVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_VEC); + float xVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_VEC); + float yVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_VEC); + float zVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_VEC); vec.setXVal(xVec); vec.setYVal(yVec); @@ -141,15 +141,15 @@ class SaxLightingListener extends SaxVmdListener{ private void openShadowAct(Attributes attr){ ShadowMotion shadowMotion = new ShadowMotion(); - int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME); + int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME); shadowMotion.setFrameNumber(frameNo); float rawParam = - SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RAW_PARAM); + SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_RAW_PARAM); shadowMotion.setRawScopeParam(rawParam); String modeAttr = - SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_MODE); + SaxAttr.getStringAttr(attr, XmlAttr.ATTR_MODE); ShadowMode mode = ShadowMode.valueOf(modeAttr); shadowMotion.setShadowMode(mode); diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxMotionListener.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxMotionListener.java index b25a150..3cd616b 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxMotionListener.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxMotionListener.java @@ -104,7 +104,7 @@ class SaxMotionListener extends SaxVmdListener{ * @param attr 属性群 */ private void openBonePart(Attributes attr){ - this.boneName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME); + this.boneName = SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME); return; } @@ -116,7 +116,7 @@ class SaxMotionListener extends SaxVmdListener{ this.boneMotion = new BoneMotion(); this.boneMotion.setBoneName(this.boneName); - int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME); + int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME); this.boneMotion.setFrameNumber(frameNo); return; @@ -138,9 +138,9 @@ class SaxMotionListener extends SaxVmdListener{ private void openBonePosition(Attributes attr){ MkPos3D position = this.boneMotion.getPosition(); - float xPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_POS); - float yPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_POS); - float zPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_POS); + float xPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_POS); + float yPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_POS); + float zPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_POS); position.setXpos(xPos); position.setYpos(yPos); @@ -159,10 +159,10 @@ class SaxMotionListener extends SaxVmdListener{ private void openBoneRotQuat(Attributes attr){ MkQuat rotation = this.boneMotion.getRotation(); - float qx = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QX); - float qy = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QY); - float qz = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QZ); - float qw = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QW); + float qx = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QX); + float qy = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QY); + float qz = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QZ); + float qw = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QW); rotation.setQ1(qx); rotation.setQ2(qy); @@ -182,9 +182,9 @@ class SaxMotionListener extends SaxVmdListener{ private void openBoneRotEyxz(Attributes attr){ MkQuat rotation = this.boneMotion.getRotation(); - float xDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_DEG); - float yDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_DEG); - float zDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_DEG); + float xDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_DEG); + float yDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_DEG); + float zDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_DEG); float xRad = (float)StrictMath.toRadians(xDeg); float yRad = (float)StrictMath.toRadians(yDeg); @@ -203,7 +203,7 @@ class SaxMotionListener extends SaxVmdListener{ * @param attr 属性群 */ private void openMorphPart(Attributes attr){ - this.morphName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME); + this.morphName = SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME); return; } @@ -214,8 +214,8 @@ class SaxMotionListener extends SaxVmdListener{ private void openMorphMotion(Attributes attr){ MorphMotion morphMotion = new MorphMotion(); - int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME); - float flex = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_FLEX); + int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME); + float flex = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_FLEX); morphMotion.setMorphName(this.morphName); morphMotion.setFrameNumber(frameNo); diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxVmdListener.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxVmdListener.java index 3e8cc5d..dfc1aa5 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxVmdListener.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/SaxVmdListener.java @@ -175,10 +175,10 @@ class SaxVmdListener { * @param attr 属性群 */ protected void openBezier(Attributes attr){ - byte p1x = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P1X); - byte p1y = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P1Y); - byte p2x = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P2X); - byte p2y = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P2Y); + byte p1x = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P1X); + byte p1y = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P1Y); + byte p2x = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P2X); + byte p2y = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P2Y); putBezier(p1x, p1y, p2x, p2y); diff --git a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/XmlHandler.java b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/XmlHandler.java index 7cf32eb..88a7317 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/XmlHandler.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd/model/xml/XmlHandler.java @@ -129,7 +129,7 @@ class XmlHandler implements ContentHandler{ if(tag == VmdTag.MODEL_NAME){ String modelName = - SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME); + SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME); this.vmdMotion.setModelName(modelName); return; } diff --git a/src/main/java/jp/sfjp/mikutoga/vmd2xml/Vmd2XmlConv.java b/src/main/java/jp/sfjp/mikutoga/vmd2xml/Vmd2XmlConv.java index 3decd1d..1b0135e 100644 --- a/src/main/java/jp/sfjp/mikutoga/vmd2xml/Vmd2XmlConv.java +++ b/src/main/java/jp/sfjp/mikutoga/vmd2xml/Vmd2XmlConv.java @@ -401,7 +401,6 @@ public class Vmd2XmlConv { throws IOException, MmdFormatException{ VmdLoader loader = new VmdLoader(); - loader.setIgnoreName(true); loader.setRedundantCheck(false); VmdMotion motion = loader.load(is); diff --git a/src/main/resources/jp/sfjp/mikutoga/vmd/model/xml/resources/vmdxml-130609A.xsd b/src/main/resources/jp/sfjp/mikutoga/vmd/model/xml/resources/vmdxml-130609A.xsd new file mode 100644 index 0000000..d1109fd --- /dev/null +++ b/src/main/resources/jp/sfjp/mikutoga/vmd/model/xml/resources/vmdxml-130609A.xsd @@ -0,0 +1,944 @@ + + + + + + + +]> + + + + + + + MikuMikuDance motion-data(*.vmd) on XML. + License : The MIT License + Copyright(c) 2013 MikuToga Partners + + + + + + + + + Root element. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + frame No. + + + + + + + + + + + + + + morph flexible value. [0.0-1.0] + + + + + + + + + + + + + + + screen-projection angle(degree). + + + + + + + + + + + + + + color component value. + + + + + + + + + + + + + + direction vector component value. + + + + + + + + + + + + + + type of shadow + + NONE : no self-shadow + + MODE_1 : reduce shadow-quality suddenly at range + + MODE_2 : reduce shadow-quality gradually with range + + + + + + + + + + + + + + + + shadow range raw value. + + UI_VALUE = EFFECTIVE_RANGE * 100 ??? + rawParam = 0.1 - (UI_VALUE / 1.0E+5) + + UI_VALUE:0 => rawParam:0.1 + UI_VALUE:8875 => rawParam:0.01125 + UI_VALUE:9999 => rawParam:1.0E-5 + + + + + + + + + + + + + + Bezier points coordinates value. [XY:0-127] + + + + + + + + + + + + + + + frame numbered type. + + + + + + + + + + + + bezier cubic curve parameters. + p0=(0, 0) p3=(127, 127) [implicit points] + + + + + + + + + + + + + + + bezier cubic curve parameters. + p0=(0, 0) p3=(127, 127) [implicit points] + P1 and P2 points are required. + + + + + + + + + + + + + + + + + + + + + default linear bezier curve. + p0=(0, 0) p1=(20, 20) p2=(107, 107) p3=(127, 127) + + + + + + + + + + + + + + + + + + + + + default ease-in-out bezier curve. + p0=(0, 0) p1=(64, 0) p2=(64, 127) p3=(127, 127) + + + + + + + + + + + + + + + + + + + + + has single interpolation curve. + If omitted, it means default linear curve. + + + + + + + + + + + + + + + + 3D-position with XYZ-interpolation curve. + If omitted, it means default linear curve *3 [XYZ]. + + + + + + + + + + + + + + + + + + + + + + Meta-information of motion. + Use free. + but, some meta-name has recommended usage. + + "generator" (Generator application name) + + "siteURL" (about motion creator) + + + + + + + + + + + + + + + name of motion-model. + + + + + + + + + + + + + + bone motion data sequence. + + + + + + + + + + + + + + + + + + + + + bone motion data group by bone-name. + + + + + + + + + + + + + + + + + + + + + + + bone motion data. + + + + + + + + + + + + + + + + + + + + + + + + bone position. + + + + + + + + + + bone rotation. (Quaternion parameters) + + + + + + + + + + + + + + + + + + + + + bone rotation. (YXZ-Euler rotation parameters) + + + + + + + + + + + + + + + + + + + + morphing data sequence. + + + + + + + + + + + + + + + + + + + + + morphing data group by morph-name. + + + + + + + + + + + + + + + + + + + + + + + morphing data. + + + + + + + + + + + + + + + + + + camera sequence. + + + + + + + + + + + + + + + + + + + + + camera data. + + + + + + + + + + + + + + + + + + + + + + + + camera target. + + + + + + + + + + camera-rotation around camera-target + with polar-coordinates parameters. + + xRad = -radian(UI_X) [latitude] + yRad = radian(UI_Y) [longitude] + zRad = radian(UI_Z) [roll] + + + + + + + + + + + + + + + + + + + + camera range. + sign was negated from UI_RANGE. + + + + + + + + + + + + + + + + + + projection data. + vertDeg : vertical screen-projection angle by degree. + + + + + + + + + + + + + + + + + + luminous sequence. + + + + + + + + + + + + + + + + + + + + + luminous data. + + + + + + + + + + + + + + + + + + + + + luminous color by RGB color space. + + + + + + + + + + + + + + + + luminous direction by vector. + + + + + + + + + + + + + + + + shadow sequence. + + + + + + + + + + + + + + + + + + + + + shadow data. + + + + + + + + + + + + + + + + + + + numbered flag sequence. + + + + + + + + + + + + + + + + + + + + + numbered motion flags. + + + + + + + + + + + + + + + + + + + + + + + + + + IK ON/OFF switch for each IK-Bone. + + + + + + + + + + + + + + + diff --git a/src/test/java/jp/sfjp/mikutoga/vmd/model/VmdMotionTest.java b/src/test/java/jp/sfjp/mikutoga/vmd/model/VmdMotionTest.java index 796bf90..eabbdc5 100644 --- a/src/test/java/jp/sfjp/mikutoga/vmd/model/VmdMotionTest.java +++ b/src/test/java/jp/sfjp/mikutoga/vmd/model/VmdMotionTest.java @@ -395,7 +395,7 @@ public class VmdMotionTest { assertEquals( "model name : カメラ・照明\n" - +"bone#0 morph#0 camera#0 luminous#0 shadow#0", + +"bone#0 morph#0 camera#0 luminous#0 shadow#0 flag#0", motion.toString()); motion.setModelName("model"); @@ -414,10 +414,15 @@ public class VmdMotionTest { motion.getShadowMotionList().add(new ShadowMotion()); motion.getShadowMotionList().add(new ShadowMotion()); motion.getShadowMotionList().add(new ShadowMotion()); + motion.getNumberedFlagList().add(new NumberedVmdFlag()); + motion.getNumberedFlagList().add(new NumberedVmdFlag()); + motion.getNumberedFlagList().add(new NumberedVmdFlag()); + motion.getNumberedFlagList().add(new NumberedVmdFlag()); + motion.getNumberedFlagList().add(new NumberedVmdFlag()); assertEquals( "model name : model\n" - +"bone#1 morph#2 camera#3 luminous#4 shadow#5", + +"bone#1 morph#2 camera#3 luminous#4 shadow#5 flag#5", motion.toString()); return; diff --git a/src/test/resources/testdata/vmd130609/minimum/minmotion.xml b/src/test/resources/testdata/vmd130609/minimum/minmotion.xml new file mode 100644 index 0000000..1deeea6 --- /dev/null +++ b/src/test/resources/testdata/vmd130609/minimum/minmotion.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/testdata/vmd130609/small/onlyFlag.xml b/src/test/resources/testdata/vmd130609/small/onlyFlag.xml new file mode 100644 index 0000000..f880cee --- /dev/null +++ b/src/test/resources/testdata/vmd130609/small/onlyFlag.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.11.0