・オイラー角出力時の精度を向上させた。
・ベジェ補間パラメータ冗長部がMMDの版により異なるため、検査をやめた。
・プロセス終了コードの変更。
+ ・DOMからSAXへの移行。
+
1.101.2 (2011-08-25)
・初回リリース。
<checkstyle.config.location>${project.mainconf}/checks.xml</checkstyle.config.location>
<checkstyle.enable.rss>false</checkstyle.enable.rss>
- <project.mainentry>jp.sourceforge.mikutoga.vmd2xml.Vmd2Xml</project.mainentry>
+ <project.mainentry>jp.sfjp.mikutoga.vmd2xml.Vmd2Xml</project.mainentry>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
- <version>2.0</version>
+ <version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
- <version>3.2</version>
+ <version>3.3</version>
<configuration>
<generateReports>true</generateReports>
<locales>ja</locales>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
- <version>2.6</version>
+ <version>2.7</version>
<configuration>
<linkOnly>true</linkOnly>
<offline>true</offline>
<!--
Checkstyle用チェック項目定義。
- Checkstyle 5.3 以降向けに記述。
+ Checkstyle 5.5 以降向けに記述。
[ http://checkstyle.sourceforge.net/ ]
<module name="RegexpHeader">
<property name="header" value="^/\*$\n^ \*( .*)?$\n^ \*/$\n" />
<property name="multiLines" value="2" />
+ <property name="fileExtensions" value="java" />
</module>
<!-- Miscellaneous -->
- <module name="NewlineAtEndOfFile" />
+ <module name="NewlineAtEndOfFile">
+ <property name="fileExtensions" value="java" />
+ </module>
<module name="Translation" />
<module name="FallThrough" />
<module name="MultipleStringLiterals" />
<module name="MultipleVariableDeclarations" />
+ <module name="RequireThis">
+ <property name="checkMethods" value="false" />
+ </module>
<module name="UnnecessaryParentheses" />
<module name="OneStatementPerLine" />
<module name="RegexpSinglelineJava" />
-->
-<!-- バグ?
- <module name="RequireThis" />
--->
-
<!-- Obsolated
<module name="TabCharacter" />
-->
private static final String MSG_TXT = "r={0} g={1} b={2}";
- static{
- assert 0.602f != 0.602;
- }
-
private float colR = DEF_BRIGHT;
private float colG = DEF_BRIGHT;
private static final int BZTOTAL_SIZE = BZXYZR_SIZE * BZ_REDUNDANT;
private static final Charset CS_ASCII = Charset.forName("US-ASCII");
+
+ // '\0' * 5byte の版もあり
private static final String HEADFILLER = "\u0000" + "JKLM";
+
private static final byte[] FDFILLER =
{ (byte)0x00, (byte)0xfd };
private static final byte[] INTPLT_FILLER = {
*/
public class VmdExporter {
- private BasicExporter basicExporter;
- private CameraExporter cameraExporter;
- private LightingExporter lightingExporter;
+ private BasicExporter basicExporter = null;
+ private CameraExporter cameraExporter = null;
+ private LightingExporter lightingExporter = null;
/**
* Copyright(c) 2013 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.vmd.model.xml;
+package jp.sfjp.mikutoga.vmd.model.xml;
import java.io.IOException;
import java.util.List;
/**
*カメラ情報のXMLエクスポーター。
*/
-class CameraXmlExporter extends ProxyXmlExporter{
+class CameraXmlExporter extends ProxyXmlExporter {
+
+ private final ExtraXmlExporter extraExporter;
/**
* コンストラクタ。
- * @param proxy 委譲先
+ * @param delegate 委譲先
*/
- CameraXmlExporter(VmdXmlExporter proxy) {
- super(proxy);
+ CameraXmlExporter(VmdXmlExporter delegate) {
+ super(delegate);
+ this.extraExporter = new ExtraXmlExporter(delegate);
return;
}
throws IOException{
List<CameraMotion> list = vmdMotion.getCameraMotionList();
if( ! list.isEmpty() ){
- ind().putBlockComment(XmlSyms.CAMERA_COMMENT);
- ind().putBlockComment(XmlSyms.BEZIER_COMMENT);
+ ind().putBlockComment(XmlComment.CAMERA_COMMENT);
+ ind().putBlockComment(XmlComment.BEZIER_COMMENT);
}
- ind().putSimpleSTag(XmlSyms.TAG_CAMERA_SEQUENCE).ln();
+ ind().putSimpleSTag(VmdTag.CAMERA_SEQUENCE.tag()).ln();
pushNest();
if( ! list.isEmpty() ) ln();
}
popNest();
- ind().putETag(XmlSyms.TAG_CAMERA_SEQUENCE).ln(2);
+ ind().putETag(VmdTag.CAMERA_SEQUENCE.tag()).ln(2);
return;
}
*/
private void putCameraMotion(CameraMotion cameraMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_CAMERA_MOTION).sp();
+ ind().putOpenSTag(VmdTag.CAMERA_MOTION.tag()).sp();
int frameNo = cameraMotion.getFrameNumber();
- putIntAttr(XmlSyms.ATTR_FRAME, frameNo).sp();
+ putIntAttr(XmlAttr.ATTR_FRAME, frameNo).sp();
if( ! cameraMotion.hasPerspective() ){
- putAttr(XmlSyms.ATTR_HAS_PERSPECTIVE, "false").sp();
+ putAttr(XmlAttr.ATTR_HAS_PERSPECTIVE, "false").sp();
}
putCloseSTag().ln();
putProjection(cameraMotion);
popNest();
- ind().putETag(XmlSyms.TAG_CAMERA_MOTION).ln(2);
+ ind().putETag(VmdTag.CAMERA_MOTION.tag()).ln(2);
return;
}
*/
private void putCameraTarget(CameraMotion cameraMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_CAMERA_TARGET).sp();
+ ind().putOpenSTag(VmdTag.CAMERA_TARGET.tag()).sp();
+
MkPos3D position = cameraMotion.getCameraTarget();
- putFloatAttr(XmlSyms.ATTR_X_POS, (float) position.getXpos()).sp();
- putFloatAttr(XmlSyms.ATTR_Y_POS, (float) position.getYpos()).sp();
- putFloatAttr(XmlSyms.ATTR_Z_POS, (float) position.getZpos()).sp();
+
+ float xPos = (float) position.getXpos();
+ float yPos = (float) position.getYpos();
+ float zPos = (float) position.getZpos();
+
+ putFloatAttr(XmlAttr.ATTR_X_POS, xPos).sp();
+ putFloatAttr(XmlAttr.ATTR_Y_POS, yPos).sp();
+ putFloatAttr(XmlAttr.ATTR_Z_POS, zPos).sp();
PosCurve posCurve = cameraMotion.getTargetPosCurve();
if(posCurve.isDefaultLinear()){
putCloseSTag().ln();
pushNest();
- putPositionCurve(posCurve);
+ this.extraExporter.putPositionCurve(posCurve);
popNest();
- ind().putETag(XmlSyms.TAG_CAMERA_TARGET).ln();
+ ind().putETag(VmdTag.CAMERA_TARGET.tag()).ln();
}
return;
}
/**
- * 位置移動補間カーブを出力する。
- * @param posCurve 移動補間情報
- * @throws IOException 出力エラー
- */
- private void putPositionCurve(PosCurve posCurve)
- throws IOException{
- BezierParam xCurve = posCurve.getIntpltXpos();
- BezierParam yCurve = posCurve.getIntpltYpos();
- BezierParam zCurve = posCurve.getIntpltZpos();
-
- ind().putLineComment("X-Y-Z interpolation *3").ln();
-
- ind();
- putBezierCurve(xCurve);
- ln();
-
- ind();
- putBezierCurve(yCurve);
- ln();
-
- ind();
- putBezierCurve(zCurve);
- ln();
-
- return;
- }
-
- /**
* カメラ回転情報を出力する。
* @param cameraMotion カメラモーション
* @throws IOException 出力エラー
*/
private void putCameraRotation(CameraMotion cameraMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_CAMERA_ROTATION).sp();
+ ind().putOpenSTag(VmdTag.CAMERA_ROTATION.tag()).sp();
+
CameraRotation rotation = cameraMotion.getCameraRotation();
- float latitude = (float) rotation.getLatitude();
+
+ float latitude = (float) rotation.getLatitude();
float longitude = (float) rotation.getLongitude();
- float roll = (float) rotation.getRoll();
- putFloatAttr(XmlSyms.ATTR_X_RAD, latitude).sp();
- putFloatAttr(XmlSyms.ATTR_Y_RAD, longitude).sp();
- putFloatAttr(XmlSyms.ATTR_Z_RAD, roll).sp();
+ float roll = (float) rotation.getRoll();
+
+ putFloatAttr(XmlAttr.ATTR_X_RAD, latitude) .sp();
+ putFloatAttr(XmlAttr.ATTR_Y_RAD, longitude).sp();
+ putFloatAttr(XmlAttr.ATTR_Z_RAD, roll) .sp();
BezierParam rotCurve = cameraMotion.getIntpltRotation();
if(rotCurve.isDefaultLinear()){
putCloseSTag().ln();
pushNest();
ind();
- putBezierCurve(rotCurve);
+ this.extraExporter.putBezierCurve(rotCurve);
ln();
popNest();
- ind().putETag(XmlSyms.TAG_CAMERA_ROTATION).ln();
+ ind().putETag(VmdTag.CAMERA_ROTATION.tag()).ln();
}
return;
*/
private void putCameraRange(CameraMotion cameraMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_CAMERA_RANGE).sp();
+ ind().putOpenSTag(VmdTag.CAMERA_RANGE.tag()).sp();
+
float range = (float) cameraMotion.getRange();
- putFloatAttr(XmlSyms.ATTR_RANGE, range).sp();
+ putFloatAttr(XmlAttr.ATTR_RANGE, range).sp();
BezierParam rangeCurve = cameraMotion.getIntpltRange();
if(rangeCurve.isDefaultLinear()){
putCloseSTag().ln();
pushNest();
ind();
- putBezierCurve(rangeCurve);
+ this.extraExporter.putBezierCurve(rangeCurve);
ln();
popNest();
- ind().putETag(XmlSyms.TAG_CAMERA_RANGE).ln();
+ ind().putETag(VmdTag.CAMERA_RANGE.tag()).ln();
}
return;
*/
private void putProjection(CameraMotion cameraMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_PROJECTION).sp();
+ ind().putOpenSTag(VmdTag.PROJECTION.tag()).sp();
+
int angle = cameraMotion.getProjectionAngle();
- putIntAttr(XmlSyms.ATTR_VERT_DEG, angle).sp();
+ putIntAttr(XmlAttr.ATTR_VERT_DEG, angle).sp();
BezierParam projCurve = cameraMotion.getIntpltProjection();
if(projCurve.isDefaultLinear()){
putCloseSTag().ln();
pushNest();
ind();
- putBezierCurve(projCurve);
+ this.extraExporter.putBezierCurve(projCurve);
ln();
popNest();
- ind().putETag(XmlSyms.TAG_PROJECTION).ln();
+ ind().putETag(VmdTag.PROJECTION.tag()).ln();
}
return;
}
- /**
- * ベジェ曲線による補間曲線情報を出力する。
- * @param bezier ベジェ曲線
- * @throws IOException 出力エラー
- */
- private void putBezierCurve(BezierParam bezier)
- throws IOException{
- if(bezier.isDefaultLinear()){
- putSimpleEmpty(XmlSyms.TAG_DEF_LINEAR);
- }else if(bezier.isDefaultEaseInOut()){
- putSimpleEmpty(XmlSyms.TAG_DEF_EASE_IN_OUT);
- }else{
- putOpenSTag(XmlSyms.TAG_BEZIER).sp();
- putIntAttr(XmlSyms.ATTR_P1X, bezier.getP1x()).sp();
- putIntAttr(XmlSyms.ATTR_P1Y, bezier.getP1y()).sp();
- putIntAttr(XmlSyms.ATTR_P2X, bezier.getP2x()).sp();
- putIntAttr(XmlSyms.ATTR_P2Y, bezier.getP2y()).sp();
- putCloseEmpty();
- }
- return;
- }
-
}
--- /dev/null
+/*
+ * extra common xml exporter
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import java.io.IOException;
+import jp.sfjp.mikutoga.vmd.model.BezierParam;
+import jp.sfjp.mikutoga.vmd.model.PosCurve;
+import jp.sourceforge.mikutoga.xml.ProxyXmlExporter;
+import jp.sourceforge.mikutoga.xml.XmlExporter;
+
+/**
+ * XML出力機構の共通部。
+ * <p>主にベジェ補間パラメータ出力部。
+ */
+class ExtraXmlExporter extends ProxyXmlExporter {
+
+ /**
+ * コンストラクタ。
+ * @param delegate 委譲先
+ */
+ ExtraXmlExporter(XmlExporter delegate){
+ super(delegate);
+ return;
+ }
+
+
+ /**
+ * 位置移動補間カーブを出力する。
+ * @param posCurve 移動補間情報
+ * @throws IOException 出力エラー
+ */
+ void putPositionCurve(PosCurve posCurve)
+ throws IOException{
+ BezierParam xCurve = posCurve.getIntpltXpos();
+ BezierParam yCurve = posCurve.getIntpltYpos();
+ BezierParam zCurve = posCurve.getIntpltZpos();
+
+ ind().putLineComment("X-Y-Z interpolation *3").ln();
+
+ ind();
+ putBezierCurve(xCurve);
+ ln();
+
+ ind();
+ putBezierCurve(yCurve);
+ ln();
+
+ ind();
+ putBezierCurve(zCurve);
+ ln();
+
+ return;
+ }
+
+ /**
+ * ベジェ曲線による補間曲線情報を出力する。
+ * @param bezier ベジェ曲線
+ * @throws IOException 出力エラー
+ */
+ void putBezierCurve(BezierParam bezier)
+ throws IOException{
+ if(bezier.isDefaultLinear()){
+ putSimpleEmpty(VmdTag.DEF_LINEAR.tag());
+ }else if(bezier.isDefaultEaseInOut()){
+ putSimpleEmpty(VmdTag.DEF_EASE_IN_OUT.tag());
+ }else{
+ putOpenSTag(VmdTag.BEZIER.tag()).sp();
+
+ byte p1x = bezier.getP1x();
+ byte p1y = bezier.getP1y();
+ byte p2x = bezier.getP2x();
+ byte p2y = bezier.getP2y();
+
+ putIntAttr(XmlAttr.ATTR_P1X, p1x).sp();
+ putIntAttr(XmlAttr.ATTR_P1Y, p1y).sp();
+ putIntAttr(XmlAttr.ATTR_P2X, p2x).sp();
+ putIntAttr(XmlAttr.ATTR_P2Y, p2y).sp();
+
+ putCloseEmpty();
+ }
+ return;
+ }
+
+}
* Copyright(c) 2013 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.vmd.model.xml;
+package jp.sfjp.mikutoga.vmd.model.xml;
import java.io.IOException;
import java.util.List;
/**
* コンストラクタ。
- * @param proxy 委譲先
+ * @param delegate 委譲先
*/
- LightingXmlExpoter(XmlExporter proxy) {
- super(proxy);
+ LightingXmlExpoter(XmlExporter delegate) {
+ super(delegate);
return;
}
+
/**
* 照明演出データを出力する。
* @param vmdMotion 演出データ
*/
void putLuminousSequence(VmdMotion vmdMotion)
throws IOException{
- ind().putSimpleSTag(XmlSyms.TAG_LUMI_SEQUENCE).ln();
+ ind().putSimpleSTag(VmdTag.LUMI_SEQUENCE.tag()).ln();
pushNest();
List<LuminousMotion> list = vmdMotion.getLuminousMotionList();
}
popNest();
- ind().putETag(XmlSyms.TAG_LUMI_SEQUENCE).ln(2);
+ ind().putETag(VmdTag.LUMI_SEQUENCE.tag()).ln(2);
return;
}
*/
private void putLuminousMotion(LuminousMotion luminousMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_LUMINOUS_ACT).sp();
+ ind().putOpenSTag(VmdTag.LUMINOUS_ACT.tag()).sp();
+
int frameNo = luminousMotion.getFrameNumber();
- putIntAttr(XmlSyms.ATTR_FRAME, frameNo).sp();
+ putIntAttr(XmlAttr.ATTR_FRAME, frameNo).sp();
+
putCloseSTag().ln();
LuminousColor color = luminousMotion.getColor();
putLuminousDirection(vector);
popNest();
- ind().putETag(XmlSyms.TAG_LUMINOUS_ACT).ln(2);
+ ind().putETag(VmdTag.LUMINOUS_ACT.tag()).ln(2);
return;
}
*/
private void putLuminousColor(LuminousColor color)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_LUMI_COLOR).sp();
- putFloatAttr(XmlSyms.ATTR_R_COL, color.getColR()).sp();
- putFloatAttr(XmlSyms.ATTR_G_COL, color.getColG()).sp();
- putFloatAttr(XmlSyms.ATTR_B_COL, color.getColB()).sp();
+ ind().putOpenSTag(VmdTag.LUMI_COLOR.tag()).sp();
+
+ float colR = color.getColR();
+ float colG = color.getColG();
+ float colB = color.getColB();
+
+ putFloatAttr(XmlAttr.ATTR_R_COL, colR).sp();
+ putFloatAttr(XmlAttr.ATTR_G_COL, colG).sp();
+ putFloatAttr(XmlAttr.ATTR_B_COL, colB).sp();
+
putCloseEmpty().ln();
return;
*/
private void putLuminousDirection(MkVec3D vector)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_LUMI_DIRECTION).sp();
- putFloatAttr(XmlSyms.ATTR_X_VEC, (float) vector.getXVal()).sp();
- putFloatAttr(XmlSyms.ATTR_Y_VEC, (float) vector.getYVal()).sp();
- putFloatAttr(XmlSyms.ATTR_Z_VEC, (float) vector.getZVal()).sp();
+ ind().putOpenSTag(VmdTag.LUMI_DIRECTION.tag()).sp();
+
+ float xVec = (float) vector.getXVal();
+ float yVec = (float) vector.getYVal();
+ float zVec = (float) vector.getZVal();
+
+ putFloatAttr(XmlAttr.ATTR_X_VEC, xVec).sp();
+ putFloatAttr(XmlAttr.ATTR_Y_VEC, yVec).sp();
+ putFloatAttr(XmlAttr.ATTR_Z_VEC, zVec).sp();
+
putCloseEmpty().ln();
return;
throws IOException{
List<ShadowMotion> list = vmdMotion.getShadowMotionList();
if( ! list.isEmpty() ){
- ind().putBlockComment(XmlSyms.SHADOW_COMMENT);
+ ind().putBlockComment(XmlComment.SHADOW_COMMENT);
}
- ind().putSimpleSTag(XmlSyms.TAG_SHADOW_SEQUENCE).ln();
+ ind().putSimpleSTag(VmdTag.SHADOW_SEQUENCE.tag()).ln();
pushNest();
for(ShadowMotion shadow : list){
}
popNest();
- ind().putETag(XmlSyms.TAG_SHADOW_SEQUENCE).ln(2);
+ ind().putETag(VmdTag.SHADOW_SEQUENCE.tag()).ln(2);
return;
}
*/
private void putShadowMotion(ShadowMotion shadowMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_SHADOW_ACT).sp();
+ ind().putOpenSTag(VmdTag.SHADOW_ACT.tag()).sp();
int frameNo = shadowMotion.getFrameNumber();
ShadowMode mode = shadowMotion.getShadowMode();
float rawParam = (float) shadowMotion.getRawScopeParam();
- putIntAttr(XmlSyms.ATTR_FRAME, frameNo).sp();
- putAttr(XmlSyms.ATTR_MODE, mode.name()).sp();
- putFloatAttr(XmlSyms.ATTR_RAW_PARAM, rawParam).sp();
+ putIntAttr(XmlAttr.ATTR_FRAME, frameNo).sp();
+ putAttr(XmlAttr.ATTR_MODE, mode.name()).sp();
+ putFloatAttr(XmlAttr.ATTR_RAW_PARAM, rawParam).sp();
putCloseEmpty();
--- /dev/null
+/*
+ * camera listener from XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import java.util.List;
+import jp.sfjp.mikutoga.math.MkPos3D;
+import jp.sfjp.mikutoga.vmd.model.BezierParam;
+import jp.sfjp.mikutoga.vmd.model.CameraMotion;
+import jp.sfjp.mikutoga.vmd.model.CameraRotation;
+import jp.sfjp.mikutoga.vmd.model.PosCurve;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import org.xml.sax.Attributes;
+
+/**
+ * カメラ関連のXML要素出現イベントを受信する。
+ */
+class SaxCameraListener extends SaxVmdListener{
+
+ private CameraMotion currentCamera = null;
+
+
+ /**
+ * コンストラクタ。
+ */
+ SaxCameraListener(){
+ super();
+ return;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ * @param attr {@inheritDoc}
+ */
+ @Override
+ void openTag(VmdTag tag, Attributes attr){
+ switch(tag){
+ case CAMERA_MOTION:
+ openCameraMotion(attr);
+ break;
+ case CAMERA_TARGET:
+ openCameraTarget(attr);
+ break;
+ case CAMERA_ROTATION:
+ openCameraRotation(attr);
+ break;
+ case CAMERA_RANGE:
+ openCameraRange(attr);
+ break;
+ case PROJECTION:
+ openProjection(attr);
+ break;
+
+ default:
+ super.openTag(tag, attr);
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ */
+ @Override
+ void closeTag(VmdTag tag){
+ switch(tag){
+ case CAMERA_MOTION:
+ closeCameraMotion();
+ break;
+ case CAMERA_TARGET:
+ setCurrentPosCurve(null);
+ break;
+ case CAMERA_ROTATION:
+ case CAMERA_RANGE:
+ case PROJECTION:
+ setCurrentBezierParam(null);
+ break;
+ default:
+ super.closeTag(tag);
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * cameraMotion要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openCameraMotion(Attributes attr){
+ this.currentCamera = new CameraMotion();
+
+ int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ this.currentCamera.setFrameNumber(frameNo);
+
+ boolean hasPerspective =
+ SaxXsdUtil.getBooleanAttr(attr,
+ XmlAttr.ATTR_HAS_PERSPECTIVE,
+ true );
+ this.currentCamera.setPerspectiveMode(hasPerspective);
+
+ return;
+ }
+
+ /**
+ * cameraMotion要素終了の通知。
+ */
+ private void closeCameraMotion(){
+ VmdMotion motion = getVmdMotion();
+ List<CameraMotion> cameraList = motion.getCameraMotionList();
+ cameraList.add(this.currentCamera);
+
+ this.currentCamera = null;
+
+ return;
+ }
+
+ /**
+ * cameraTarget要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ targetPos.setPosition(xPos, yPos, zPos);
+
+ PosCurve curve = this.currentCamera.getTargetPosCurve();
+ setCurrentPosCurve(curve);
+
+ return;
+ }
+
+ /**
+ * cameraRotation要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openCameraRotation(Attributes attr){
+ 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);
+
+ cameraRotation.setLatitude(latitude);
+ cameraRotation.setLongitude(longitude);
+ cameraRotation.setRoll(roll);
+
+ BezierParam bez = this.currentCamera.getIntpltRotation();
+ setCurrentBezierParam(bez);
+
+ return;
+ }
+
+ /**
+ * cameraRange要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openCameraRange(Attributes attr){
+ float range = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RANGE);
+ this.currentCamera.setRange(range);
+
+ BezierParam bez = this.currentCamera.getIntpltRange();
+ setCurrentBezierParam(bez);
+
+ return;
+ }
+
+ /**
+ * projection要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openProjection(Attributes attr){
+ int vertDeg = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_VERT_DEG);
+ this.currentCamera.setProjectionAngle(vertDeg);
+
+ BezierParam bez = this.currentCamera.getIntpltProjection();
+ setCurrentBezierParam(bez);
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * lighting listener from XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import java.util.List;
+import jp.sfjp.mikutoga.math.MkVec3D;
+import jp.sfjp.mikutoga.vmd.model.LuminousColor;
+import jp.sfjp.mikutoga.vmd.model.LuminousMotion;
+import jp.sfjp.mikutoga.vmd.model.ShadowMode;
+import jp.sfjp.mikutoga.vmd.model.ShadowMotion;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import org.xml.sax.Attributes;
+
+/**
+ * 照明・シャドウ関連のXML要素出現イベントを受信する。
+ */
+class SaxLightingListener extends SaxVmdListener{
+
+ private LuminousMotion currentLuminous = null;
+
+
+ /**
+ * コンストラクタ。
+ */
+ SaxLightingListener(){
+ super();
+ return;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ * @param attr {@inheritDoc}
+ */
+ @Override
+ void openTag(VmdTag tag, Attributes attr){
+ switch(tag){
+ case LUMINOUS_ACT:
+ openLumiAct(attr);
+ break;
+ case LUMI_COLOR:
+ openLumiColor(attr);
+ break;
+ case LUMI_DIRECTION:
+ openLumiDirection(attr);
+ break;
+ case SHADOW_ACT:
+ openShadowAct(attr);
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ */
+ @Override
+ void closeTag(VmdTag tag){
+ if(tag == VmdTag.LUMINOUS_ACT){
+ closeLumiAct();
+ }
+ return;
+ }
+
+ /**
+ * lumiAct要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openLumiAct(Attributes attr){
+ this.currentLuminous = new LuminousMotion();
+
+ int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ this.currentLuminous.setFrameNumber(frameNo);
+
+ return;
+ }
+
+ /**
+ * lumiAct要素終了の通知。
+ */
+ private void closeLumiAct(){
+ VmdMotion motion = getVmdMotion();
+ List<LuminousMotion> lumiList = motion.getLuminousMotionList();
+ lumiList.add(this.currentLuminous);
+
+ this.currentLuminous = null;
+
+ return;
+ }
+
+ /**
+ * lumiColor要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ color.setColR(rCol);
+ color.setColG(gCol);
+ color.setColB(bCol);
+
+ return;
+ }
+
+ /**
+ * lumiDirection要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ vec.setXVal(xVec);
+ vec.setYVal(yVec);
+ vec.setZVal(zVec);
+
+ return;
+ }
+
+ /**
+ * shadowAct要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openShadowAct(Attributes attr){
+ ShadowMotion shadowMotion = new ShadowMotion();
+
+ int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ shadowMotion.setFrameNumber(frameNo);
+
+ float rawParam =
+ SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RAW_PARAM);
+ shadowMotion.setRawScopeParam(rawParam);
+
+ String modeAttr =
+ SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_MODE);
+ ShadowMode mode = ShadowMode.valueOf(modeAttr);
+ shadowMotion.setShadowMode(mode);
+
+ VmdMotion motion = getVmdMotion();
+ List<ShadowMotion> shadowList = motion.getShadowMotionList();
+ shadowList.add(shadowMotion);
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * motion listener from XML
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import jp.sfjp.mikutoga.math.MkPos3D;
+import jp.sfjp.mikutoga.math.MkQuat;
+import jp.sfjp.mikutoga.vmd.model.BezierParam;
+import jp.sfjp.mikutoga.vmd.model.BoneMotion;
+import jp.sfjp.mikutoga.vmd.model.MorphMotion;
+import jp.sfjp.mikutoga.vmd.model.PosCurve;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import org.xml.sax.Attributes;
+
+/**
+ * モーション関連のXML要素出現イベントを受信する。
+ */
+class SaxMotionListener extends SaxVmdListener{
+
+ private BoneMotion boneMotion;
+ private String boneName;
+ private String morphName;
+
+
+ /**
+ * コンストラクタ。
+ */
+ SaxMotionListener() {
+ super();
+ return;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ * @param attr {@inheritDoc}
+ */
+ @Override
+ void openTag(VmdTag tag, Attributes attr){
+ switch(tag){
+ case BONE_PART:
+ openBonePart(attr);
+ break;
+ case BONE_MOTION:
+ openBoneMotion(attr);
+ break;
+ case BONE_POSITION:
+ openBonePosition(attr);
+ break;
+ case BONE_ROT_QUAT:
+ openBoneRotQuat(attr);
+ break;
+ case BONE_ROT_EYXZ:
+ openBoneRotEyxz(attr);
+ break;
+
+ case MORPH_PART:
+ openMorphPart(attr);
+ break;
+ case MORPH_MOTION:
+ openMorphMotion(attr);
+ break;
+
+ default:
+ super.openTag(tag, attr);
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param tag {@inheritDoc}
+ */
+ @Override
+ void closeTag(VmdTag tag){
+ switch(tag){
+ case BONE_MOTION:
+ closeBoneMotion();
+ break;
+ case BONE_POSITION:
+ setCurrentPosCurve(null);
+ break;
+ case BONE_ROT_QUAT:
+ case BONE_ROT_EYXZ:
+ setCurrentBezierParam(null);
+ break;
+ default:
+ super.closeTag(tag);
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * bonePart要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openBonePart(Attributes attr){
+ this.boneName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ return;
+ }
+
+ /**
+ * boneMotion要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openBoneMotion(Attributes attr){
+ this.boneMotion = new BoneMotion();
+ this.boneMotion.setBoneName(this.boneName);
+
+ int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ this.boneMotion.setFrameNumber(frameNo);
+
+ return;
+ }
+
+ /**
+ * boneMotion要素終了の通知。
+ */
+ private void closeBoneMotion(){
+ VmdMotion motion = getVmdMotion();
+ motion.addBoneMotion(this.boneMotion);
+ return;
+ }
+
+ /**
+ * bonePosition要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ position.setXpos(xPos);
+ position.setYpos(yPos);
+ position.setZpos(zPos);
+
+ PosCurve curve = this.boneMotion.getPosCurve();
+ setCurrentPosCurve(curve);
+
+ return;
+ }
+
+ /**
+ * boneRotQuat要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ rotation.setQ1(qx);
+ rotation.setQ2(qy);
+ rotation.setQ3(qz);
+ rotation.setQW(qw);
+
+ BezierParam bez = this.boneMotion.getIntpltRotation();
+ setCurrentBezierParam(bez);
+
+ return;
+ }
+
+ /**
+ * boneRotEyxz要素開始の通知。
+ * @param attr 属性群
+ */
+ 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 xRad = (float)StrictMath.toRadians(xDeg);
+ float yRad = (float)StrictMath.toRadians(yDeg);
+ float zRad = (float)StrictMath.toRadians(zDeg);
+
+ rotation.setEulerYXZ(xRad, yRad, zRad);
+
+ BezierParam bez = this.boneMotion.getIntpltRotation();
+ setCurrentBezierParam(bez);
+
+ return;
+ }
+
+ /**
+ * morphPart要素開始の通知。
+ * @param attr 属性群
+ */
+ private void openMorphPart(Attributes attr){
+ this.morphName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ return;
+ }
+
+ /**
+ * morphMotion要素開始の通知。
+ * @param attr 属性群
+ */
+ 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);
+
+ morphMotion.setMorphName(this.morphName);
+ morphMotion.setFrameNumber(frameNo);
+ morphMotion.setFlex(flex);
+
+ VmdMotion motion = getVmdMotion();
+ motion.addMorphMotion(morphMotion);
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * VMD-SAX element listsner
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import jp.sfjp.mikutoga.vmd.model.BezierParam;
+import jp.sfjp.mikutoga.vmd.model.PosCurve;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import org.xml.sax.Attributes;
+
+/**
+ * XML要素出現の通知受信部の共通実装。
+ */
+class SaxVmdListener {
+
+ private VmdMotion vmdMotion;
+
+ private PosCurve currentPosCurve;
+ private int axisIdx;
+
+ private BezierParam currentBezParam;
+
+
+ /**
+ * コンストラクタ。
+ */
+ protected SaxVmdListener(){
+ super();
+
+ this.vmdMotion = null;
+
+ this.currentPosCurve = null;
+ this.axisIdx = -1;
+
+ this.currentBezParam = null;
+
+ return;
+ }
+
+
+ /**
+ * XML要素開始の通知。
+ * @param tag 要素種別
+ * @param attr 属性群
+ */
+ void openTag(VmdTag tag, Attributes attr){
+ switch(tag){
+ case BEZIER:
+ openBezier(attr);
+ break;
+ case DEF_LINEAR:
+ openDefLinear();
+ break;
+ case DEF_EASE_IN_OUT:
+ openDefEaseInOut();
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * XML要素終了の通知。
+ * @param tag 要素種別
+ */
+ void closeTag(VmdTag tag){
+ return;
+ }
+
+ /**
+ * ビルド対象オブジェクトの登録。
+ * @param motion ビルド対象オブジェクト
+ * @throws NullPointerException 引数がnull
+ */
+ void setVmdMotion(VmdMotion motion) throws NullPointerException{
+ if(motion == null) throw new NullPointerException();
+ this.vmdMotion = motion;
+ return;
+ }
+
+ /**
+ * ビルド対象オブジェクトの取得。
+ * @return ビルド対象オブジェクト。未登録の場合はnull。
+ */
+ protected VmdMotion getVmdMotion(){
+ return this.vmdMotion;
+ }
+
+ /**
+ * ビルド対象の位置補間曲線情報を受け取る。
+ * @param curve 位置補間曲線情報
+ */
+ protected void setCurrentPosCurve(PosCurve curve){
+ this.currentPosCurve = curve;
+ this.axisIdx = 0;
+
+ this.currentBezParam = null;
+
+ return;
+ }
+
+ /**
+ * ビルド対象の単一補間曲線情報を受け取る。
+ * @param bez 補間曲線情報
+ */
+ protected void setCurrentBezierParam(BezierParam bez){
+ this.currentBezParam = bez;
+
+ this.currentPosCurve = null;
+ this.axisIdx = -1;
+
+ return;
+ }
+
+ /**
+ * ビルド対象の補間曲線情報を返す。
+ * @return 補間曲線情報
+ */
+ private BezierParam getTargetBezierParam(){
+ if(this.currentBezParam != null){
+ return this.currentBezParam;
+ }
+
+ if(this.currentPosCurve == null){
+ assert false;
+ throw new AssertionError();
+ }
+
+ BezierParam result;
+
+ switch(this.axisIdx){
+ case 0:
+ result = this.currentPosCurve.getIntpltXpos();
+ break;
+ case 1:
+ result = this.currentPosCurve.getIntpltYpos();
+ break;
+ case 2:
+ result = this.currentPosCurve.getIntpltZpos();
+ break;
+ default:
+ assert false;
+ throw new AssertionError();
+ }
+
+ this.axisIdx++;
+
+ return result;
+ }
+
+ /**
+ * ベジェ補間曲線情報を構築。
+ * @param p1x P1-x
+ * @param p1y P1-y
+ * @param p2x P2-x
+ * @param p2y P2-y
+ */
+ protected void putBezier(byte p1x, byte p1y, byte p2x, byte p2y){
+ BezierParam bez = getTargetBezierParam();
+
+ bez.setP1(p1x, p1y);
+ bez.setP2(p2x, p2y);
+
+ return;
+ }
+
+ /**
+ * bezier要素開始の通知。
+ * @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);
+
+ putBezier(p1x, p1y, p2x, p2y);
+
+ return;
+ }
+
+ /**
+ * defLinear要素開始の通知。
+ */
+ protected void openDefLinear(){
+ byte p1x = BezierParam.DEF_P1X;
+ byte p1y = BezierParam.DEF_P1Y;
+ byte p2x = BezierParam.DEF_P2X;
+ byte p2y = BezierParam.DEF_P2Y;
+
+ putBezier(p1x, p1y, p2x, p2y);
+
+ return;
+ }
+
+ /**
+ * defEaseInOut要素開始の通知。
+ */
+ protected void openDefEaseInOut(){
+ byte p1x = BezierParam.EIO_P1X;
+ byte p1y = BezierParam.EIO_P1Y;
+ byte p2x = BezierParam.EIO_P2X;
+ byte p2y = BezierParam.EIO_P2Y;
+
+ putBezier(p1x, p1y, p2x, p2y);
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * Sax 2 Xsd-types converter
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import javax.xml.bind.DatatypeConverter;
+import org.xml.sax.Attributes;
+
+/**
+ * XSD各種型のSAX属性値をJavaプリミティブ型へ変換する。
+ */
+final class SaxXsdUtil {
+
+ /**
+ * 隠しコンストラクタ。
+ */
+ private SaxXsdUtil(){
+ assert false;
+ throw new AssertionError();
+ }
+
+
+ /**
+ * xsd:string型属性値の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性値。該当する属性が無ければnull。
+ */
+ static String getStringAttr(Attributes attr, String name){
+ String attrVal = attr.getValue(name);
+ return attrVal;
+ }
+
+ /**
+ * xsd:boolean型属性値の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性値。
+ * @throws IllegalArgumentException boolean型表記ではない
+ */
+ static boolean getBooleanAttr(Attributes attr, String name)
+ throws IllegalArgumentException{
+ String attrVal = attr.getValue(name);
+ boolean bVal;
+ bVal = DatatypeConverter.parseBoolean(attrVal);
+ return bVal;
+ }
+
+ /**
+ * xsd:boolean型属性値の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @param def 属性が無い場合のデフォルト値
+ * @return 属性値。
+ * @throws IllegalArgumentException boolean型表記ではない
+ */
+ static boolean getBooleanAttr(Attributes attr, String name, boolean def)
+ throws IllegalArgumentException{
+ String attrVal = attr.getValue(name);
+ if(attrVal == null) return def;
+
+ boolean bVal;
+ bVal = DatatypeConverter.parseBoolean(attrVal);
+
+ return bVal;
+ }
+
+ /**
+ * xsd:byte型属性の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性値。
+ * @throws NumberFormatException byte型表記ではない
+ */
+ static byte getByteAttr(Attributes attr, String name)
+ throws NumberFormatException{
+ String attrVal = attr.getValue(name);
+ byte bVal;
+ bVal = DatatypeConverter.parseByte(attrVal);
+ return bVal;
+ }
+
+ /**
+ * xsd:float型属性値の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性値。
+ * @throws NumberFormatException float型表記ではない
+ */
+ static float getFloatAttr(Attributes attr, String name)
+ throws NumberFormatException {
+ String attrVal = attr.getValue(name);
+ float fVal;
+ fVal = DatatypeConverter.parseFloat(attrVal);
+ return fVal;
+ }
+
+ /**
+ * xsd:int型属性値の読み込み。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性値。
+ * @throws NumberFormatException int型表記ではない
+ */
+ static int getIntAttr(Attributes attr, String name)
+ throws NumberFormatException {
+ String attrVal = attr.getValue(name);
+ int iVal;
+ iVal = DatatypeConverter.parseInt(attrVal);
+ return iVal;
+ }
+
+}
* Copyright(c) 2013 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.vmd.model.xml;
+package jp.sfjp.mikutoga.vmd.model.xml;
import java.net.URI;
import java.net.URISyntaxException;
--- /dev/null
+/*
+ * tags of vmd xml file
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * XML要素名一覧。
+ */
+enum VmdTag {
+
+ VMD_MOTION ("vmdMotion"),
+ META ("meta"),
+ MODEL_NAME ("modelName"),
+
+ BONE_M_SEQUENCE("boneMotionSequence"),
+ BONE_PART ("bonePart"),
+ BONE_MOTION ("boneMotion"),
+ BONE_POSITION ("bonePosition"),
+ BONE_ROT_QUAT ("boneRotQuat"),
+ BONE_ROT_EYXZ ("boneRotEyxz"),
+
+ MORPH_SEQUENCE ("morphSequence"),
+ MORPH_PART ("morphPart"),
+ MORPH_MOTION ("morphMotion"),
+
+ CAMERA_SEQUENCE("cameraSequence"),
+ CAMERA_MOTION ("cameraMotion"),
+ CAMERA_TARGET ("cameraTarget"),
+ CAMERA_ROTATION("cameraRotation"),
+ CAMERA_RANGE ("cameraRange"),
+ PROJECTION ("projection"),
+
+ LUMI_SEQUENCE ("luminousSequence"),
+ LUMINOUS_ACT ("luminousAct"),
+ LUMI_COLOR ("lumiColor"),
+ LUMI_DIRECTION ("lumiDirection"),
+
+ SHADOW_SEQUENCE("shadowSequence"),
+ SHADOW_ACT ("shadowAct"),
+
+ BEZIER ("bezier"),
+ DEF_LINEAR ("defLinear"),
+ DEF_EASE_IN_OUT("defEaseInOut"),
+
+ ;
+
+
+ private static final Map<String, VmdTag> NAME_MAP =
+ new HashMap<String, VmdTag>();
+
+ static{
+ for(VmdTag tag : values()){
+ NAME_MAP.put(tag.tag(), tag);
+ }
+ }
+
+
+ private final String tagName;
+
+
+ /**
+ * コンストラクタ。
+ * @param tagName 要素名
+ */
+ private VmdTag(String tagName){
+ this.tagName = tagName.intern();
+ return;
+ }
+
+
+ /**
+ * XML要素名から列挙子を得る。
+ * @param name 要素名
+ * @return 列挙子。合致する物がなければnull。
+ */
+ static VmdTag parse(String name){
+ VmdTag result;
+ result = NAME_MAP.get(name);
+ return result;
+ }
+
+
+ /**
+ * XML要素名を返す。
+ * @return 要素名
+ */
+ String tag(){
+ return this.tagName;
+ }
+
+}
* Copyright(c) 2011 MikuToga Partners
*/
-package jp.sourceforge.mikutoga.vmd.model.xml;
+package jp.sfjp.mikutoga.vmd.model.xml;
import java.io.IOException;
-import java.io.OutputStream;
+import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import jp.sfjp.mikutoga.math.EulerYXZ;
*/
public class VmdXmlExporter extends BasicXmlExporter {
+ private static final String XML_VER = "1.0";
+ private static final String XML_ENC = "UTF-8";
private static final String XML_DECL =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
+ "<?xml version=\"" + XML_VER
+ + "\" encoding=\"" + XML_ENC
+ + "\" ?>";
private static final String XSINS = "xsi";
+ private static final String MSG_MAYBE = "Perhaps : [{0}]";
+
private boolean isQuaternionMode = true;
private String generator = "";
private final CameraXmlExporter cameraXmlExporter;
private final LightingXmlExpoter lightingExporter;
+ private final ExtraXmlExporter extraExporter;
/**
* コンストラクタ。
- * 文字エンコーディングはUTF-8が用いられる。
- * @param ostream 出力ストリーム
*/
- public VmdXmlExporter(OutputStream ostream){
- super(ostream);
+ public VmdXmlExporter(){
+ super();
+
this.cameraXmlExporter = new CameraXmlExporter(this);
- this.lightingExporter = new LightingXmlExpoter(this);
+ this.lightingExporter = new LightingXmlExpoter(this);
+ this.extraExporter = new ExtraXmlExporter(this);
+
return;
}
/**
* VMDモーションデータをXML形式で出力する。
* @param vmdMotion VMDモーションデータ
+ * @param xmlOut 出力先
* @throws IOException 出力エラー
* @throws IllegalVmdDataException 不正なモーションデータを検出
*/
- public void putVmdXml(VmdMotion vmdMotion)
+ public void putVmdXml(VmdMotion vmdMotion, Appendable xmlOut)
throws IOException, IllegalVmdDataException{
+ setAppendable(xmlOut);
+
try{
putVmdXmlImpl(vmdMotion);
}finally{
throws IOException, IllegalVmdDataException{
ind().putRawText(XML_DECL).ln(2);
- ind().putBlockComment(XmlSyms.TOP_COMMENT).ln(2);
+ ind().putBlockComment(XmlComment.TOP_COMMENT).ln(2);
- ind().putOpenSTag(XmlSyms.TAG_VMD_MOTION).ln();
+ ind().putOpenSTag(VmdTag.VMD_MOTION.tag()).ln();
pushNest();
ind().putAttr("xmlns", Schema110820.NS_VMDXML).ln();
ind().putAttr("xmlns:" + XSINS, XmlResourceResolver.NS_XSD).ln();
.putRawCh('"')
.ln();
- ind().putAttr(XmlSyms.ATTR_VERSION, Schema110820.VER_VMDXML).ln();
+ ind().putAttr(XmlAttr.ATTR_VERSION, Schema110820.VER_VMDXML).ln();
popNest();
putCloseSTag().ln(2);
- if(this.generator != null && this.generator.length() > 0){
- ind().putOpenSTag(XmlSyms.TAG_META).sp();
- putAttr(XmlSyms.ATTR_NAME, "generator").sp();
- putAttr(XmlSyms.ATTR_CONTENT, this.generator).sp();
- putCloseEmpty().ln(2);
- }
+ putGenerator();
if(vmdMotion.isModelMotion()){
putModelName(vmdMotion);
this.lightingExporter.putShadowSequence(vmdMotion);
}
- ind().putETag(XmlSyms.TAG_VMD_MOTION).ln(2);
+ ind().putETag(VmdTag.VMD_MOTION.tag()).ln(2);
ind().putLineComment("EOF").ln();
return;
}
/**
- * 位置移動補間カーブを出力する。
- * @param posCurve 移動補間情報
+ * ジェネレータ名を出力する。
* @throws IOException 出力エラー
*/
- private void putPositionCurve(PosCurve posCurve)
- throws IOException{
- BezierParam xCurve = posCurve.getIntpltXpos();
- BezierParam yCurve = posCurve.getIntpltYpos();
- BezierParam zCurve = posCurve.getIntpltZpos();
-
- ind().putLineComment("X-Y-Z interpolation *3").ln();
-
- ind();
- putBezierCurve(xCurve);
- ln();
-
- ind();
- putBezierCurve(yCurve);
- ln();
-
- ind();
- putBezierCurve(zCurve);
- ln();
-
- return;
- }
+ private void putGenerator() throws IOException{
+ String genTxt = getGenerator();
+ if(genTxt == null) return;
+ if(genTxt.isEmpty()) return;
+
+ ind().putOpenSTag(VmdTag.META.tag()).sp();
+ putAttr(XmlAttr.ATTR_NAME, "generator").sp();
+ putAttr(XmlAttr.ATTR_CONTENT, genTxt).sp();
+ putCloseEmpty().ln(2);
- /**
- * ベジェ曲線による補間曲線情報を出力する。
- * @param bezier ベジェ曲線
- * @throws IOException 出力エラー
- */
- private void putBezierCurve(BezierParam bezier)
- throws IOException{
- if(bezier.isDefaultLinear()){
- putSimpleEmpty(XmlSyms.TAG_DEF_LINEAR);
- }else if(bezier.isDefaultEaseInOut()){
- putSimpleEmpty(XmlSyms.TAG_DEF_EASE_IN_OUT);
- }else{
- putOpenSTag(XmlSyms.TAG_BEZIER).sp();
- putIntAttr(XmlSyms.ATTR_P1X, bezier.getP1x()).sp();
- putIntAttr(XmlSyms.ATTR_P1Y, bezier.getP1y()).sp();
- putIntAttr(XmlSyms.ATTR_P2X, bezier.getP2x()).sp();
- putIntAttr(XmlSyms.ATTR_P2Y, bezier.getP2y()).sp();
- putCloseEmpty();
- }
return;
}
}
ind().putLineComment(modelComm).ln();
- ind().putOpenSTag(XmlSyms.TAG_MODEL_NAME).sp();
- putAttr(XmlSyms.ATTR_NAME, modelName).sp();
+ ind().putOpenSTag(VmdTag.MODEL_NAME.tag()).sp();
+ putAttr(XmlAttr.ATTR_NAME, modelName).sp();
putCloseEmpty().ln(2);
return;
Map<String, List<BoneMotion>> boneMap = vmdMotion.getBonePartMap();
if( ! boneMap.isEmpty() ){
- ind().putBlockComment(XmlSyms.QUATERNION_COMMENT);
- ind().putBlockComment(XmlSyms.BEZIER_COMMENT);
+ ind().putBlockComment(XmlComment.QUATERNION_COMMENT);
+ ind().putBlockComment(XmlComment.BEZIER_COMMENT);
}
- ind().putSimpleSTag(XmlSyms.TAG_BONE_M_SEQUENCE).ln();
+ ind().putSimpleSTag(VmdTag.BONE_M_SEQUENCE.tag()).ln();
pushNest();
if( ! boneMap.isEmpty() ) ln();
}
popNest();
- ind().putETag(XmlSyms.TAG_BONE_M_SEQUENCE).ln(2);
+ ind().putETag(VmdTag.BONE_M_SEQUENCE.tag()).ln(2);
return;
}
ind().putLineComment(boneName);
String globalName = TypicalBone.primary2global(boneName);
if(globalName != null){
- sp(2).putLineComment("Perhaps : [" + globalName + "]");
+ String gname =
+ MessageFormat.format(MSG_MAYBE, globalName);
+ sp(2).putLineComment(gname);
}
ln();
- ind().putOpenSTag(XmlSyms.TAG_BONE_PART).sp();
- putAttr(XmlSyms.ATTR_NAME, boneName).sp();
+ ind().putOpenSTag(VmdTag.BONE_PART.tag()).sp();
+ putAttr(XmlAttr.ATTR_NAME, boneName).sp();
putCloseSTag().ln(2);
pushNest();
}
popNest();
- ind().putETag(XmlSyms.TAG_BONE_PART).ln(2);
+ ind().putETag(VmdTag.BONE_PART.tag()).ln(2);
return;
}
*/
private void putBoneMotion(BoneMotion boneMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_BONE_MOTION).sp();
+ ind().putOpenSTag(VmdTag.BONE_MOTION.tag()).sp();
int frameNo = boneMotion.getFrameNumber();
- putIntAttr(XmlSyms.ATTR_FRAME, frameNo).sp();
+ putIntAttr(XmlAttr.ATTR_FRAME, frameNo).sp();
putCloseSTag().ln();
pushNest();
putBonePosition(boneMotion);
- if(this.isQuaternionMode){
+ if(isQuaternionMode()){
putBoneRotQuat(boneMotion);
}else{
putBoneRotEyxz(boneMotion);
}
popNest();
- ind().putETag(XmlSyms.TAG_BONE_MOTION).ln(2);
+ ind().putETag(VmdTag.BONE_MOTION.tag()).ln(2);
return;
}
return;
}
- ind().putOpenSTag(XmlSyms.TAG_BONE_POSITION).sp();
+ ind().putOpenSTag(VmdTag.BONE_POSITION.tag()).sp();
+
MkPos3D position = boneMotion.getPosition();
+
float xPos = (float) position.getXpos();
float yPos = (float) position.getYpos();
float zPos = (float) position.getZpos();
- putFloatAttr(XmlSyms.ATTR_X_POS, xPos).sp();
- putFloatAttr(XmlSyms.ATTR_Y_POS, yPos).sp();
- putFloatAttr(XmlSyms.ATTR_Z_POS, zPos).sp();
+
+ putFloatAttr(XmlAttr.ATTR_X_POS, xPos).sp();
+ putFloatAttr(XmlAttr.ATTR_Y_POS, yPos).sp();
+ putFloatAttr(XmlAttr.ATTR_Z_POS, zPos).sp();
PosCurve posCurve = boneMotion.getPosCurve();
if(posCurve.isDefaultLinear()){
putCloseSTag().ln();
pushNest();
- putPositionCurve(posCurve);
+ this.extraExporter.putPositionCurve(posCurve);
popNest();
- ind().putETag(XmlSyms.TAG_BONE_POSITION).ln();
+ ind().putETag(VmdTag.BONE_POSITION.tag()).ln();
}
return;
MkQuat rotation = boneMotion.getRotation();
BezierParam rotCurve = boneMotion.getIntpltRotation();
- ind().putOpenSTag(XmlSyms.TAG_BONE_ROT_QUAT).ln();
+ ind().putOpenSTag(VmdTag.BONE_ROT_QUAT.tag()).ln();
pushNest();
- ind().putFloatAttr(XmlSyms.ATTR_QX, (float) rotation.getQ1()).ln();
- ind().putFloatAttr(XmlSyms.ATTR_QY, (float) rotation.getQ2()).ln();
- ind().putFloatAttr(XmlSyms.ATTR_QZ, (float) rotation.getQ3()).ln();
- ind().putFloatAttr(XmlSyms.ATTR_QW, (float) rotation.getQW()).ln();
+
+ float qx = (float) rotation.getQ1();
+ float qy = (float) rotation.getQ2();
+ float qz = (float) rotation.getQ3();
+ float qw = (float) rotation.getQW();
+
+ ind().putFloatAttr(XmlAttr.ATTR_QX, qx).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_QY, qy).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_QZ, qz).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_QW, qw).ln();
+
popNest();
ind();
putCloseSTag().ln();
pushNest();
ind();
- putBezierCurve(rotCurve);
+ this.extraExporter.putBezierCurve(rotCurve);
ln();
popNest();
- ind().putETag(XmlSyms.TAG_BONE_ROT_QUAT).ln();
+ ind().putETag(VmdTag.BONE_ROT_QUAT.tag()).ln();
}
return;
float yDeg = (float)StrictMath.toDegrees(euler.getYRot());
float zDeg = (float)StrictMath.toDegrees(euler.getZRot());
- ind().putOpenSTag(XmlSyms.TAG_BONE_ROT_EYXZ).ln();
+ ind().putOpenSTag(VmdTag.BONE_ROT_EYXZ.tag()).ln();
pushNest();
- ind().putFloatAttr(XmlSyms.ATTR_X_DEG, xDeg).ln();
- ind().putFloatAttr(XmlSyms.ATTR_Y_DEG, yDeg).ln();
- ind().putFloatAttr(XmlSyms.ATTR_Z_DEG, zDeg).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_X_DEG, xDeg).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_Y_DEG, yDeg).ln();
+ ind().putFloatAttr(XmlAttr.ATTR_Z_DEG, zDeg).ln();
popNest();
ind();
putCloseSTag().ln();
pushNest();
ind();
- putBezierCurve(rotCurve);
+ this.extraExporter.putBezierCurve(rotCurve);
ln();
popNest();
- ind().putETag(XmlSyms.TAG_BONE_ROT_EYXZ).ln();
+ ind().putETag(VmdTag.BONE_ROT_EYXZ.tag()).ln();
}
return;
*/
private void putMorphSequence(VmdMotion vmdMotion)
throws IOException{
- ind().putSimpleSTag(XmlSyms.TAG_MORPH_SEQUENCE).ln();
+ ind().putSimpleSTag(VmdTag.MORPH_SEQUENCE.tag()).ln();
pushNest();
Map<String, List<MorphMotion>> listMap = vmdMotion.getMorphPartMap();
putMorphPartList(listMap);
popNest();
- ind().putETag(XmlSyms.TAG_MORPH_SEQUENCE).ln(2);
+ ind().putETag(VmdTag.MORPH_SEQUENCE.tag()).ln(2);
return;
}
ind().putLineComment(morphName);
String globalName = TypicalMorph.primary2global(morphName);
if(globalName != null){
- sp(2).putLineComment("Perhaps : [" + globalName + "]");
+ String gname =
+ MessageFormat.format(MSG_MAYBE, globalName);
+ sp(2).putLineComment(gname);
}
ln();
- ind().putOpenSTag(XmlSyms.TAG_MORPH_PART).sp();
- putAttr(XmlSyms.ATTR_NAME, morphName).sp();
+ ind().putOpenSTag(VmdTag.MORPH_PART.tag()).sp();
+ putAttr(XmlAttr.ATTR_NAME, morphName).sp();
putCloseSTag().ln();
pushNest();
}
popNest();
- ind().putETag(XmlSyms.TAG_MORPH_PART).ln(2);
+ ind().putETag(VmdTag.MORPH_PART.tag()).ln(2);
}
return;
*/
private void putMorphMotion(MorphMotion morphMotion)
throws IOException{
- ind().putOpenSTag(XmlSyms.TAG_MORPH_MOTION).sp();
+ ind().putOpenSTag(VmdTag.MORPH_MOTION.tag()).sp();
int frameNo = morphMotion.getFrameNumber();
float flex = morphMotion.getFlex();
- putIntAttr(XmlSyms.ATTR_FRAME, frameNo).sp();
- putFloatAttr(XmlSyms.ATTR_FLEX, flex).sp();
+ putIntAttr(XmlAttr.ATTR_FRAME, frameNo).sp();
+ putFloatAttr(XmlAttr.ATTR_FLEX, flex).sp();
putCloseEmpty().ln();
--- /dev/null
+/*
+ * xml attribution names
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+/**
+ * VMD-XML 各種属性名。
+ */
+final class XmlAttr {
+
+ static final String ATTR_VERSION = "version";
+
+ static final String ATTR_NAME = "name";
+ static final String ATTR_CONTENT = "content";
+
+ static final String ATTR_FRAME = "frame";
+
+ static final String ATTR_QX = "qx";
+ static final String ATTR_QY = "qy";
+ static final String ATTR_QZ = "qz";
+ static final String ATTR_QW = "qw";
+
+ static final String ATTR_X_POS = "xPos";
+ static final String ATTR_Y_POS = "yPos";
+ static final String ATTR_Z_POS = "zPos";
+
+ static final String ATTR_X_DEG = "xDeg";
+ static final String ATTR_Y_DEG = "yDeg";
+ static final String ATTR_Z_DEG = "zDeg";
+
+ static final String ATTR_X_RAD = "xRad";
+ static final String ATTR_Y_RAD = "yRad";
+ static final String ATTR_Z_RAD = "zRad";
+
+ static final String ATTR_X_VEC = "xVec";
+ static final String ATTR_Y_VEC = "yVec";
+ static final String ATTR_Z_VEC = "zVec";
+
+ static final String ATTR_R_COL = "rCol";
+ static final String ATTR_G_COL = "gCol";
+ static final String ATTR_B_COL = "bCol";
+
+ static final String ATTR_P1X = "p1x";
+ static final String ATTR_P1Y = "p1y";
+ static final String ATTR_P2X = "p2x";
+ static final String ATTR_P2Y = "p2y";
+
+ static final String ATTR_VERT_DEG = "vertDeg";
+ static final String ATTR_HAS_PERSPECTIVE = "hasPerspective";
+ static final String ATTR_RANGE = "range";
+
+ static final String ATTR_FLEX = "flex";
+
+ static final String ATTR_MODE = "mode";
+ static final String ATTR_RAW_PARAM = "rawParam";
+
+
+ /**
+ * 隠しコンストラクタ。
+ */
+ private XmlAttr(){
+ assert false;
+ throw new AssertionError();
+ }
+
+}
--- /dev/null
+/*
+ * xml comment strings
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+/**
+ * 各種XMLコメント内容。
+ */
+final class XmlComment {
+
+ static final String TOP_COMMENT =
+ " MikuMikuDance\n motion-data(*.vmd) on XML";
+
+ static final String QUATERNION_COMMENT =
+ " bone-rotation has Quaternion parameters [boneRotQuat]\n"
+ + " or YXZ-Euler angles [boneRotEyxz].\n"
+ + " Quaternion form is strongly recommended"
+ + " if you are data-exchanging.";
+
+ static final String BEZIER_COMMENT =
+ " motion-interpolation is described with Bezier-cubic-curve.\n"
+ + " implicit bezier curve point : P0=(0,0) P3=(127,127)\n"
+ + " defLinear : MMD default linear curve."
+ + " P1=(20,20) P2=(107,107) [DEFAULT]\n"
+ + " defEaseInOut : MMD default ease-in-out curve."
+ + " P1=(64,0) P2=(64,127)";
+
+ static final String CAMERA_COMMENT =
+ " camera-rotation has polar-coordinates parameters.\n"
+ + " xRad = -radian(UI_X) [latitude]\n"
+ + " yRad = radian(UI_Y) [longitude]\n"
+ + " zRad = radian(UI_Z) [roll]\n"
+ + " range = -(UI_RANGE)";
+
+ static final String SHADOW_COMMENT =
+ " UI_VALUE = EFFECTIVE_RANGE * 100 ???\n"
+ +" rawParam = 0.1 - (UI_VALUE / 1.0E+5)\n\n"
+ +" NONE : no self-shadow\n"
+ +" MODE_1 : reduce shadow-quality suddenly at range\n"
+ +" MODE_2 : reduce shadow-quality gradually with range";
+
+
+ /**
+ * 隠しコンストラクタ。
+ */
+ private XmlComment(){
+ assert false;
+ throw new AssertionError();
+ }
+
+}
--- /dev/null
+/*
+ * xml 2 vmd SAX Handler
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * XMLモーションファイルパース用SAXハンドラ。
+ * <p>下位リスナに各種通知が振り分けられる。
+ */
+class XmlHandler implements ContentHandler{
+
+ private VmdMotion vmdMotion;
+
+ private String nspfx = "";
+ private String nsuri = null;
+
+ private final SaxVmdListener motionListener;
+ private final SaxVmdListener cameraListener;
+ private final SaxVmdListener lightListener;
+
+ private SaxVmdListener currentListener = null;
+
+
+ /**
+ * コンストラクタ。
+ */
+ XmlHandler(){
+ super();
+
+ this.motionListener = new SaxMotionListener();
+ this.cameraListener = new SaxCameraListener();
+ this.lightListener = new SaxLightingListener();
+
+ return;
+ }
+
+
+ /**
+ * ビルド対象のモーションを返す。
+ * @return ビルド対象のモーション
+ */
+ VmdMotion getVmdMotion(){
+ return this.vmdMotion;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void startDocument() throws SAXException{
+ this.vmdMotion = new VmdMotion();
+
+ this.motionListener.setVmdMotion(this.vmdMotion);
+ this.cameraListener.setVmdMotion(this.vmdMotion);
+ this.lightListener .setVmdMotion(this.vmdMotion);
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void endDocument() throws SAXException{
+ assert this.vmdMotion != null;
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param prefix {@inheritDoc}
+ * @param uri {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+ if(Schema110820.NS_VMDXML.equals(uri)){
+ this.nspfx = prefix;
+ this.nsuri = uri;
+ }
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param prefix {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ if(prefix.equals(this.nspfx)){
+ this.nspfx = "";
+ this.nsuri = null;
+ }
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param uri {@inheritDoc}
+ * @param localName {@inheritDoc}
+ * @param qName {@inheritDoc}
+ * @param attr {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void startElement(String uri,
+ String localName,
+ String qName,
+ Attributes attr)
+ throws SAXException {
+ if( ! this.nsuri.equals(uri) ) return;
+
+ VmdTag tag = VmdTag.parse(localName);
+ if(tag == null) return;
+
+ if(tag == VmdTag.MODEL_NAME){
+ String modelName =
+ SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ this.vmdMotion.setModelName(modelName);
+ return;
+ }
+
+ switchListener(tag);
+ if(this.currentListener != null){
+ this.currentListener.openTag(tag, attr);
+ }
+
+ return;
+ }
+
+ /**
+ * タグ出現に従い通知リスナを切り替える。
+ * @param tag タグ種別
+ */
+ private void switchListener(VmdTag tag){
+ switch(tag){
+ case BONE_M_SEQUENCE:
+ case MORPH_SEQUENCE:
+ this.currentListener = this.motionListener;
+ break;
+ case CAMERA_SEQUENCE:
+ this.currentListener = this.cameraListener;
+ break;
+ case LUMI_SEQUENCE:
+ case SHADOW_SEQUENCE:
+ this.currentListener = this.lightListener;
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param uri {@inheritDoc}
+ * @param localName {@inheritDoc}
+ * @param qName {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if( ! this.nsuri.equals(uri) ) return;
+
+ VmdTag tag = VmdTag.parse(localName);
+ if(tag == null) return;
+
+ if(this.currentListener != null){
+ this.currentListener.closeTag(tag);
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param locator {@inheritDoc}
+ */
+ @Override
+ public void setDocumentLocator(Locator locator){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param target {@inheritDoc}
+ * @param data {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void processingInstruction(String target, String data)
+ throws SAXException {
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param ch {@inheritDoc}
+ * @param start {@inheritDoc}
+ * @param length {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param ch {@inheritDoc}
+ * @param start {@inheritDoc}
+ * @param length {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void ignorableWhitespace(char[] ch, int start, int length)
+ throws SAXException {
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param name {@inheritDoc}
+ * @throws SAXException {@inheritDoc}
+ */
+ @Override
+ public void skippedEntity(String name) throws SAXException{
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * xml 2 vmd loader
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.xml;
+
+import java.io.IOException;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import jp.sourceforge.mikutoga.xml.TogaXmlException;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * XMLモーションファイルを読み込むためのローダ。
+ */
+public class XmlVmdLoader {
+
+ private final XMLReader reader;
+ private final XmlHandler handler = new XmlHandler();
+
+
+ /**
+ * コンストラクタ。
+ * <p>XMLリーダは名前空間をサポートしていなければならない。
+ * @param reader XMLリーダ
+ * @throws NullPointerException 引数がnull
+ */
+ public XmlVmdLoader(XMLReader reader) throws NullPointerException{
+ super();
+ if(reader == null) throw new NullPointerException();
+ this.reader = reader;
+ return;
+ }
+
+
+ /**
+ * XMLのパースを開始する。
+ * @param source XML入力
+ * @return モーションデータ
+ * @throws SAXException 構文エラー
+ * @throws IOException 入力エラー
+ * @throws TogaXmlException 構文エラー
+ */
+ public VmdMotion parse(InputSource source)
+ throws SAXException, IOException, TogaXmlException{
+ this.reader.setContentHandler(this.handler);
+
+ try{
+ this.reader.parse(source);
+ }catch(SAXException e){
+ Throwable cause = e.getCause();
+ if(cause instanceof TogaXmlException){
+ throw (TogaXmlException) cause;
+ }
+ throw e;
+ }
+
+ return this.handler.getVmdMotion();
+ }
+
+}
* VMDモーション独自データモデルとXML間でデータ交換を行うためのライブラリ。
*/
-package jp.sourceforge.mikutoga.vmd.model.xml;
+package jp.sfjp.mikutoga.vmd.model.xml;
/* EOF */
* コンストラクタ。
* @param message {@inheritDoc}
*/
- public CmdLineException(String message) {
+ CmdLineException(String message) {
super(message);
return;
}
* @return XMLならtrue
*/
public boolean isXml(){
- boolean result;
-
- switch(this){
- case XML_110820:
- result = true;
- break;
- default:
- result = false;
- break;
- }
-
- return result;
+ if(this == XML_110820) return true;
+ return false;
}
/**
* @return VMDならtrue
*/
public boolean isVmd(){
- boolean result;
-
- switch(this){
- case VMD:
- result = true;
- break;
- default:
- result = false;
- break;
- }
-
- return result;
+ if(this == VMD) return true;
+ return false;
}
}
private static final String NL_LF = "lf";
private static final String NL_CRLF = "crlf";
- private static final String GENERATOR =
- Vmd2Xml.APPNAME + ' ' + Vmd2Xml.APPVER;
-
private static final String ERRMSG_UNKNOWN =
"Unknown option : {0}";
private static final String ERRMSG_MOREARG =
private String outFilename = null;
private boolean overwrite = false;
private String newline = EOL_DEFAULT;
- private String generator = GENERATOR;
+ private String generator = Vmd2Xml.GENERATOR;
private boolean isQuaternionMode = true;
}
/**
+ * ヘルプ要求があるかコマンドライン列を調べる。
+ * @param cmds コマンドライン列
+ * @return ヘルプ要求があればtrue
+ */
+ private static boolean hasHelp(List<CmdLine> cmds){
+ for(CmdLine cmd : cmds){
+ OptSwitch opt = cmd.getOptSwitch();
+ if(opt == OptSwitch.OPT_HELP){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 個別のオプション情報を格納する。
+ * @param opt オプション識別子
+ * @param exArg 引数。なければnull
+ * @param result オプション情報格納先
+ * @throws CmdLineException 不正なコマンドライン
+ */
+ private static void storeOptInfo(OptSwitch opt,
+ String exArg,
+ OptInfo result )
+ throws CmdLineException{
+ switch(opt){
+ case OPT_FORCE:
+ result.overwrite = true;
+ break;
+ case OPT_QUAT:
+ result.isQuaternionMode = true;
+ break;
+ case OPT_EYXZ:
+ result.isQuaternionMode = false;
+ break;
+ case OPT_INFILE:
+ result.inFilename = exArg;
+ break;
+ case OPT_OUTFILE:
+ result.outFilename = exArg;
+ break;
+ case OPT_NEWLINE:
+ result.newline = decodeNewline(exArg);
+ break;
+ case OPT_IFORM:
+ MotionFileType itype = decodeFormatType(exArg);
+ result.inTypes = itype;
+ break;
+ case OPT_OFORM:
+ MotionFileType otype = decodeFormatType(exArg);
+ result.outTypes = otype;
+ break;
+ case OPT_GENOUT:
+ boolean genout = decodeBoolean(exArg);
+ if(genout) result.generator = Vmd2Xml.GENERATOR;
+ else result.generator = null;
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+
+ /**
* コマンドラインを解析する。
* @param args コマンドライン
* @return オプション情報
* @throws CmdLineException 不正なコマンドライン
*/
static OptInfo parseOption(String... args) throws CmdLineException{
+ List<CmdLine> cmdLines = CmdLine.parse(args);
+
OptInfo result = new OptInfo();
- List<CmdLine> cmdLines = CmdLine.parse(args);
- for(CmdLine cmd : cmdLines){
- OptSwitch opt = cmd.getOptSwitch();
- if(opt == OptSwitch.OPT_HELP){
- result.needHelp = true;
- return result;
- }
+ if(hasHelp(cmdLines)){
+ result.needHelp = true;
+ return result;
}
checkCmdLineList(cmdLines);
for(CmdLine cmd : cmdLines){
+ OptSwitch opt = cmd.getOptSwitch();
+
List<String> optArgs = cmd.getOptArgs();
String exArg1 = null;
if(optArgs.size() >= 2){
exArg1 = optArgs.get(1);
}
- OptSwitch opt = cmd.getOptSwitch();
- switch(opt){
- case OPT_HELP:
- break;
- case OPT_FORCE:
- result.overwrite = true;
- break;
- case OPT_INFILE:
- result.inFilename = exArg1;
- break;
- case OPT_OUTFILE:
- result.outFilename = exArg1;
- break;
- case OPT_NEWLINE:
- result.newline = decodeNewline(exArg1);
- break;
- case OPT_GENOUT:
- boolean genout = decodeBoolean(exArg1);
- if(genout) result.generator = GENERATOR;
- else result.generator = null;
- break;
- case OPT_QUAT:
- result.isQuaternionMode = true;
- break;
- case OPT_EYXZ:
- result.isQuaternionMode = false;
- break;
- case OPT_IFORM:
- MotionFileType itype = decodeFormatType(exArg1);
- result.inTypes = itype;
- break;
- case OPT_OFORM:
- MotionFileType otype = decodeFormatType(exArg1);
- result.outTypes = otype;
- break;
- default:
- assert false;
- throw new AssertionError();
- }
+ storeOptInfo(opt, exArg1, result);
}
fixFormat(result);
package jp.sfjp.mikutoga.vmd2xml;
-import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
import java.nio.channels.FileChannel;
import java.text.MessageFormat;
import java.util.Properties;
import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
import jp.sfjp.mikutoga.vmd.IllegalVmdDataException;
import jp.sourceforge.mikutoga.xml.TogaXmlException;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public static final String APPLICENSE;
/** 開発元URL。 */
public static final String APPURL;
+ /** ジェネレータ名。 */
+ public static final String GENERATOR;
private static final Class<?> THISCLASS;
private static final String RES_VER = "resources/version.properties";
APPLICENSE = verProps.getProperty("app.license");
APPURL = verProps.getProperty("app.url");
+ GENERATOR = APPNAME + ' ' + APPVER;
+
new Vmd2Xml().hashCode();
}
}
/**
- * å\85¥å\8a\9bã\82¹ã\83\88ã\83ªã\83¼ã\83 を準備する。
+ * å\85¥å\8a\9bã\82½ã\83¼ã\82¹を準備する。
* <p>入力ファイルが通常ファイルとして存在しなければエラー終了。
- * @param fileName 入力ファイル名
- * @return å\85¥å\8a\9bã\82¹ã\83\88ã\83ªã\83¼ã\83
+ * @param optInfo オプション情報
+ * @return å\85¥å\8a\9bã\82½ã\83¼ã\82¹
*/
- private static InputStream openInfile(String fileName){
+ private static InputSource openInfile(OptInfo optInfo){
+ String fileName = optInfo.getInFilename();
File inFile = new File(fileName);
if( (! inFile.exists()) || (! inFile.isFile()) ){
exit(EXIT_IOERR);
}
- InputStream is;
+ URI uri = inFile.toURI();
+ URL url;
try{
- is = new FileInputStream(inFile);
- }catch(FileNotFoundException e){
- ioError(e);
+ url = uri.toURL();
+ }catch(MalformedURLException e){
+ // File由来のURLでは起こりえない
assert false;
throw new AssertionError(e);
}
+ String systemId = url.toString();
- is = new BufferedInputStream(is);
+ InputSource source = new InputSource(systemId);
- return is;
+ return source;
}
/**
* 出力ストリームを準備する。
* <p>出力ファイルが通常ファイルでない場合はエラー終了。
* <p>既存の出力ファイルに上書き指示が伴っていなければエラー終了。
- * @param fileName 出力ファイル名
- * @param overWrite 頭から上書きして良ければtrue
+ * @param optInfo オプション情報
* @return 出力ストリーム
*/
- private static OutputStream openOutfile(String fileName,
- boolean overWrite) {
- File outFile = new File(fileName);
+ private static OutputStream openOutfile(OptInfo optInfo) {
+ String outputFile = optInfo.getOutFilename();
+ boolean overwrite = optInfo.overwriteMode();
+
+ File outFile = new File(outputFile);
if(outFile.exists()){
String absPath = outFile.getAbsolutePath();
String msg = MessageFormat.format(MSG_ABNFILE, absPath);
errMsg(msg);
exit(EXIT_IOERR);
- }else if( ! overWrite ){
+ }else if( ! overwrite ){
String msg = MessageFormat.format(MSG_OWOUTFILE, absPath);
errMsg(msg);
exit(EXIT_IOERR);
}
/**
- * Mainエントリ。
- * @param args コマンドパラメータ
+ * オプション情報に従いコンバータを生成する。
+ * @param optInfo オプション情報
+ * @return コンバータ
*/
- public static void main(String[] args){
- checkJRE();
-
- OptInfo optInfo;
- try{
- optInfo = OptInfo.parseOption(args);
- }catch(CmdLineException e){
- String optErrMsg = e.getLocalizedMessage();
- errMsg(optErrMsg);
- exit(EXIT_OPTERR);
- return;
- }
-
- if(optInfo.needHelp()){
- putHelp();
- exit(EXIT_OK);
- }
-
- String inputFile = optInfo.getInFilename();
- String outputFile = optInfo.getOutFilename();
- boolean overwrite = optInfo.overwriteMode();
-
- InputStream is = openInfile(inputFile);
- OutputStream os = openOutfile(outputFile, overwrite);
-
+ private static Vmd2XmlConv buildConverter(OptInfo optInfo){
Vmd2XmlConv converter = new Vmd2XmlConv();
converter.setInType (optInfo.getInFileType());
converter.setGenerator(optInfo.getGenerator());
converter.setQuaterniomMode(optInfo.isQuaterniomMode());
+ return converter;
+ }
+
+ /**
+ * 実際のコンバート作業と異常系処理を行う。
+ * <p>異常系が起きた場合、このメソッドは制御を戻さない。
+ * @param converter コンバータ
+ * @param source 入力ソース
+ * @param ostream 出力ストリーム
+ */
+ private static void doConvert(Vmd2XmlConv converter,
+ InputSource source,
+ OutputStream ostream ){
try{
- converter.convert(is, os);
+ converter.convert(source, ostream);
}catch(IOException e){
ioError(e);
}catch(IllegalVmdDataException e){
xmlError(e);
}
+ return;
+ }
+
+ /**
+ * コマンドライン文字列をオプション情報としてパースする。
+ * <p>異常系が起きた場合、このメソッドは制御を戻さない。
+ * @param args コマンドライン文字列群
+ * @return オプション情報
+ */
+ private static OptInfo parseOption(String[] args){
+ OptInfo optInfo;
+
try{
- is.close();
- try{
- os.close();
- }catch(IOException e){
- ioError(e);
- }
+ optInfo = OptInfo.parseOption(args);
+ }catch(CmdLineException e){
+ String optErrMsg = e.getLocalizedMessage();
+ errMsg(optErrMsg);
+ exit(EXIT_OPTERR);
+
+ assert false;
+ throw new AssertionError(e);
+ }
+
+ return optInfo;
+ }
+
+ /**
+ * Mainエントリ。
+ * @param args コマンドパラメータ
+ */
+ public static void main(String[] args){
+ checkJRE();
+
+ OptInfo optInfo = parseOption(args);
+ if(optInfo.needHelp()){
+ putHelp();
+ exit(EXIT_OK);
+ }
+
+ Vmd2XmlConv converter = buildConverter(optInfo);
+ InputSource source = openInfile(optInfo);
+ OutputStream ostream = openOutfile(optInfo);
+
+ doConvert(converter, source, ostream);
+
+ try{
+ ostream.close();
}catch(IOException e){
ioError(e);
}
package jp.sfjp.mikutoga.vmd2xml;
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.Charset;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
import jp.sfjp.mikutoga.vmd.IllegalVmdDataException;
import jp.sfjp.mikutoga.vmd.model.VmdMotion;
import jp.sfjp.mikutoga.vmd.model.binio.VmdExporter;
import jp.sfjp.mikutoga.vmd.model.binio.VmdLoader;
-import jp.sourceforge.mikutoga.vmd.model.xml.Schema110820;
-import jp.sourceforge.mikutoga.vmd.model.xml.VmdXmlExporter;
-import jp.sourceforge.mikutoga.vmd.model.xml.Xml2VmdLoader;
+import jp.sfjp.mikutoga.vmd.model.xml.Schema110820;
+import jp.sfjp.mikutoga.vmd.model.xml.VmdXmlExporter;
+import jp.sfjp.mikutoga.vmd.model.xml.XmlVmdLoader;
import jp.sourceforge.mikutoga.xml.BotherHandler;
import jp.sourceforge.mikutoga.xml.SchemaUtil;
import jp.sourceforge.mikutoga.xml.TogaXmlException;
import jp.sourceforge.mikutoga.xml.XmlResourceResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
/**
* VMD-XML間コンバータ本体。
*/
public class Vmd2XmlConv {
+ /** デフォルトエンコーディング。 */
+ private static final Charset CS_UTF8 = Charset.forName("UTF-8");
+
+
private MotionFileType inTypes = MotionFileType.NONE;
private MotionFileType outTypes = MotionFileType.NONE;
private String newLine = "\r\n";
/**
- * ドキュメントビルダファクトリを初期化する。
- * @param builderFactory ドキュメントビルダファクトリ
+ * InputSourceからInputStreamを得る。
+ * <p>入力ソースには、少なくともバイトストリームか
+ * URL文字列(SystemId)のいずれかが設定されていなければならない。
+ * @param source 入力ソース
+ * @return 入力バイトストリーム
+ * @throws IllegalArgumentException 入力ソースの設定が足りない。
+ * @throws IOException 入力ソースにアクセス不能。
*/
- private static void initBuilderFactory(
- DocumentBuilderFactory builderFactory ){
- builderFactory.setCoalescing(true);
- builderFactory.setExpandEntityReferences(true);
- builderFactory.setIgnoringComments(true);
- builderFactory.setIgnoringElementContentWhitespace(false);
- builderFactory.setNamespaceAware(true);
- builderFactory.setValidating(false);
- builderFactory.setXIncludeAware(false);
-
-// builderFactory.setFeature(name, value);
-// builderFactory.setAttribute(name, value);
+ private static InputStream openInputSource(InputSource source)
+ throws IllegalArgumentException, IOException{
+ InputStream is;
- return;
+ is = source.getByteStream();
+
+ if(is == null){
+ String systemId = source.getSystemId();
+ if(systemId == null) throw new IllegalArgumentException();
+
+ URL url = new URL(systemId);
+ is = url.openStream();
+ }
+
+ is = new BufferedInputStream(is);
+
+ return is;
}
/**
- * DOMビルダ生成。
- * @return DOMビルダ
+ * SAXパーサファクトリを生成する。
+ * <ul>
+ * <li>XML名前空間機能は有効になる。
+ * <li>DTDによる形式検証は無効となる。
+ * <li>XIncludeによる差し込み機能は無効となる。
+ * </ul>
+ * @param schema スキーマ
+ * @return ファクトリ
*/
- private DocumentBuilder buildBuilder(){
- XmlResourceResolver resolver = new XmlResourceResolver();
+ private static SAXParserFactory buildFactory(Schema schema){
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+
+ factory.setNamespaceAware(true);
+ factory.setValidating(false);
+ factory.setXIncludeAware(false);
+// factory.setFeature(name, value);
+
+ factory.setSchema(schema);
+
+ return factory;
+ }
+
+ /**
+ * SAXパーサを生成する。
+ * @param schema スキーマ
+ * @return SAXパーサ
+ */
+ private static SAXParser buildParser(Schema schema){
+ SAXParserFactory factory = buildFactory(schema);
+
+ SAXParser parser;
+ try{
+ parser = factory.newSAXParser();
+ }catch(ParserConfigurationException e){
+ assert false;
+ throw new AssertionError(e);
+ }catch(SAXException e){
+ assert false;
+ throw new AssertionError(e);
+ }
+
+// parser.setProperty(name, value);
+ return parser;
+ }
+
+ /**
+ * XMLリーダを生成する。
+ * <p>エラーハンドラには{@link BotherHandler}が指定される。
+ * @param resolver リゾルバ
+ * @return XMLリーダ
+ */
+ private static XMLReader buildReader(XmlResourceResolver resolver){
Schema schema;
schema = SchemaUtil.newSchema(resolver, Schema110820.SINGLETON);
- DocumentBuilderFactory builderFactory =
- DocumentBuilderFactory.newInstance();
- initBuilderFactory(builderFactory);
- builderFactory.setSchema(schema);
+ SAXParser parser = buildParser(schema);
- DocumentBuilder result;
+ XMLReader reader;
try{
- result = builderFactory.newDocumentBuilder();
- }catch(ParserConfigurationException e){
+ reader = parser.getXMLReader();
+ }catch(SAXException e){
assert false;
throw new AssertionError(e);
}
- result.setEntityResolver(resolver);
- result.setErrorHandler(BotherHandler.HANDLER);
- return result;
+ reader.setEntityResolver(resolver);
+ reader.setErrorHandler(BotherHandler.HANDLER);
+
+ return reader;
}
/**
/**
* ファイル変換を行う。
+ * <p>XML入力の場合は{@link #convert(InputSource, OutputStream)}を
+ * 推奨する。
* @param is 入力ストリーム
* @param os 出力ストリーム
* @throws IOException 入力エラー
}
/**
+ * ファイル変換を行う。
+ * <p>VMD入力の場合は{@link InputStream}に
+ * バイトストリームが直接設定されていなければならない。
+ * <p>XML入力の場合は{@link InputStream}に
+ * URL(systemId)のみの設定を推奨する。
+ * @param source 入力ソース
+ * @param os 出力ストリーム
+ * @throws IOException 入力エラー
+ * @throws MmdFormatException フォーマットエラー
+ * @throws SAXException XMLエラー
+ * @throws TogaXmlException XMLエラー
+ * @throws IllegalVmdDataException 内部エラー
+ */
+ public void convert(InputSource source, OutputStream os)
+ throws IOException,
+ MmdFormatException,
+ SAXException,
+ TogaXmlException,
+ IllegalVmdDataException {
+ VmdMotion motion = readMotion(source);
+ motion.frameSort();
+ writeMotion(motion, os);
+ return;
+ }
+
+ /**
* モーションファイルを読み込む。
+ * <p>XML読み込みの場合は、
+ * こちらより{@link #readMotion(InputSource)}版を推奨する。
* @param is 入力ストリーム
* @return モーションデータ
* @throws IOException 入力エラー
MmdFormatException,
SAXException,
TogaXmlException {
+ InputSource source = new InputSource(is);
+
+ VmdMotion motion;
+ try{
+ motion = readMotion(source);
+ }finally{
+ is.close();
+ }
+
+ return motion;
+ }
+
+ /**
+ * モーションファイルを読み込む。
+ * <p>VMD入力の場合は、{@link InputStream}に
+ * 納められたバイトストリームかSystemId-URLから読み込む。
+ * @param source 入力ソース
+ * @return モーションデータ
+ * @throws IOException 入力エラー
+ * @throws MmdFormatException フォーマットエラー
+ * @throws SAXException XMLエラー
+ * @throws TogaXmlException XMLエラー
+ */
+ public VmdMotion readMotion(InputSource source)
+ throws IOException,
+ MmdFormatException,
+ SAXException,
+ TogaXmlException {
VmdMotion motion = null;
if(this.inTypes.isVmd()){
- motion = vmdRead(is);
+ InputStream is = openInputSource(source);
+ try{
+ motion = vmdRead(is);
+ }finally{
+ is.close();
+ }
}else if(this.inTypes.isXml()){
- motion = xmlRead(is);
+ motion = xmlRead(source);
}else{
throw new IllegalStateException();
}
/**
* VMDファイルからモーションデータを読み込む。
+ * <p>入力ストリームは最後に閉じられる。
* @param is 入力ストリーム
* @return モーションデータ
* @throws IOException 入力エラー
/**
* XMLファイルからモーションデータを読み込む。
- * @param is 入力ストリーム
- * @return モーションデータ
- * @throws IOException 入力エラー
- * @throws SAXException XML構文エラー
- * @throws TogaXmlException 不正なXMLデータ
- */
- private VmdMotion xmlRead(InputStream is)
- throws IOException,
- SAXException,
- TogaXmlException {
- InputSource source = new InputSource(is);
- VmdMotion result = xmlRead(source);
- return result;
- }
-
- /**
- * XMLファイルからモーションデータを読み込む。
* @param source 入力ソース
* @return モーションデータ
* @throws IOException 入力エラー
throws IOException,
SAXException,
TogaXmlException {
- DocumentBuilder builder = buildBuilder();
- Xml2VmdLoader loader = new Xml2VmdLoader(builder);
+ XmlResourceResolver resolver = new XmlResourceResolver();
+ XMLReader reader = buildReader(resolver);
+ XmlVmdLoader loader = new XmlVmdLoader(reader);
+
VmdMotion motion = loader.parse(source);
+
return motion;
}
*/
private void xmlOut(VmdMotion motion, OutputStream ostream)
throws IOException, IllegalVmdDataException{
- VmdXmlExporter exporter = new VmdXmlExporter(ostream);
+ VmdXmlExporter exporter = new VmdXmlExporter();
exporter.setNewLine(this.newLine);
exporter.setGenerator(this.generator);
exporter.setQuaternionMode(this.isQuaternionMode);
- exporter.putVmdXml(motion);
+ Writer writer;
+ writer = new OutputStreamWriter(ostream, CS_UTF8);
+ writer = new BufferedWriter(writer);
+
+ exporter.putVmdXml(motion, writer);
exporter.close();
+++ /dev/null
-/*
- * xml common
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.vmd.model.xml;
-
-import java.util.Iterator;
-import jp.sfjp.mikutoga.vmd.model.BezierParam;
-import jp.sfjp.mikutoga.vmd.model.PosCurve;
-import jp.sourceforge.mikutoga.xml.DomNsUtils;
-import jp.sourceforge.mikutoga.xml.SiblingElemIterator;
-import jp.sourceforge.mikutoga.xml.TogaXmlException;
-import org.w3c.dom.Element;
-
-/**
- * XMLユーティリティ集。
- * <p>VMDに特化したDomNsUtilsのWrapper群や共通要素の共通処理を含む。
- * <p>要素に関する名前空間は{@link VmdXmlResources.NS_VMDXML}が暗黙で用いられる。
- * <p>非グローバル属性に関する名前空間は{@NS_NULL}が暗黙で用いられる。
- * @see jp.sourceforge.mikutoga.xml.DomNsUtils
- */
-final class Xml {
-
- /** 非グローバル属性用名前空間。 */
- static final String NS_NULL = null;
-
-
- /**
- * 隠しコンストラクタ。
- */
- private Xml(){
- assert false;
- throw new AssertionError();
- }
-
-
- /**
- * ローカル名が一致する要素か判定する。
- * @param elem 要素
- * @param localName ローカル名。
- * @return ローカル名が一致する要素であればtrue
- */
- static boolean hasNsLocalNameElem(Element elem,
- String localName ){
- return DomNsUtils.hasNsLocalNameElem(elem,
- Schema110820.NS_VMDXML,
- localName );
- }
-
- /**
- * ローカル名に合致する最初の直下子要素を返す。
- * @param parent 親要素
- * @param localName 子要素名
- * @return 最初の直下子要素。見つからなければnull。
- */
- static Element pickChild(Element parent, String localName){
- return DomNsUtils.pickFirstChild(parent,
- Schema110820.NS_VMDXML,
- localName );
- }
-
- /**
- * ローカル名に合致する最初の直下子要素を返す。
- * <p>見つからなければ例外を投げる。
- * @param parent 親要素
- * @param localName 子要素名
- * @return 最初の直下子要素
- * @throws TogaXmlException 1つも見つからなかった
- */
- static Element getChild(Element parent, String localName)
- throws TogaXmlException{
- return DomNsUtils.getFirstChild(parent,
- Schema110820.NS_VMDXML,
- localName );
- }
-
- /**
- * 指定された名前の子要素のforeachを返す。
- * @param parent 親要素
- * @param localName 子要素名
- * @return 子要素のforeach
- */
- static Iterable<Element> eachChild(Element parent, String localName){
- return DomNsUtils.getEachChild(parent,
- Schema110820.NS_VMDXML,
- localName );
- }
-
- /**
- * 要素からxsd:string型属性値を読み取る。
- * @param elem 要素
- * @param attrName 属性名
- * @return 文字列
- * @throws TogaXmlException 属性値が見つからなかった。
- */
- static String getStringAttr(Element elem, String attrName)
- throws TogaXmlException{
- return DomNsUtils.getStringAttrNS(elem, NS_NULL, attrName);
- }
-
- /**
- * 要素からxsd:boolean型属性値を読み取る。
- * @param elem 要素
- * @param attrName 属性名
- * @return 真ならtrue
- * @throws TogaXmlException 属性値が見つからなかった。
- */
- static boolean getBooleanAttr(Element elem, String attrName)
- throws TogaXmlException{
- return DomNsUtils.getBooleanAttrNS(elem, NS_NULL, attrName);
- }
-
- /**
- * 要素からxsd:integer型属性値を読み取る。
- * @param elem 要素
- * @param attrName 属性名
- * @return int値
- * @throws TogaXmlException 属性値が見つからなかった。
- */
- static int getIntegerAttr(Element elem, String attrName)
- throws TogaXmlException{
- return DomNsUtils.getIntegerAttrNS(elem, NS_NULL, attrName);
- }
-
- /**
- * 要素から符号付きbyte型整数属性値を読み取る。
- * @param elem 要素
- * @param attrName 属性名
- * @return byte値
- * @throws TogaXmlException 属性値が見つからなかった。
- */
- static byte getByteAttr(Element elem, String attrName)
- throws TogaXmlException{
- int iVal = getIntegerAttr(elem, attrName);
- byte result = (byte) iVal;
- return result;
- }
-
- /**
- * 要素からxsd:float型属性値を読み取る。
- * @param elem 要素
- * @param attrName 属性名
- * @return float値
- * @throws TogaXmlException 属性値が見つからなかった。
- */
- static float getFloatAttr(Element elem, String attrName)
- throws TogaXmlException{
- return DomNsUtils.getFloatAttrNS(elem, NS_NULL, attrName);
- }
-
- /**
- * ベジェ曲線による補間カーブ記述を読み込む。
- * @param elem defLinear,defEaseInOut,bezier要素のいずれか
- * @param bezier ベジェ曲線
- * @throws TogaXmlException 構文エラー
- */
- static void setBezier(Element elem, BezierParam bezier)
- throws TogaXmlException{
- byte p1x;
- byte p1y;
- byte p2x;
- byte p2y;
-
- if(hasNsLocalNameElem(elem, "defLinear")){
- p1x = BezierParam.DEF_P1X;
- p1y = BezierParam.DEF_P1Y;
- p2x = BezierParam.DEF_P2X;
- p2y = BezierParam.DEF_P2Y;
- }else if(hasNsLocalNameElem(elem, "defEaseInOut")){
- p1x = BezierParam.EIO_P1X;
- p1y = BezierParam.EIO_P1Y;
- p2x = BezierParam.EIO_P2X;
- p2y = BezierParam.EIO_P2Y;
- }else if(hasNsLocalNameElem(elem, "bezier")){
- p1x = getByteAttr(elem, "p1x");
- p1y = getByteAttr(elem, "p1y");
- p2x = getByteAttr(elem, "p2x");
- p2y = getByteAttr(elem, "p2y");
- }else{
- assert false;
- throw new AssertionError();
- }
-
- bezier.setP1(p1x, p1y);
- bezier.setP2(p2x, p2y);
-
- return;
- }
-
- /**
- * 補間カーブ情報を読み込む。
- * @param parentElem 親要素
- * @param bezier 補間カーブ
- * @throws TogaXmlException 構文エラー
- */
- static void buildCurve(Element parentElem, BezierParam bezier)
- throws TogaXmlException{
- Element bezierElem = pickChild(parentElem, null);
- if(bezierElem == null) return;
-
- setBezier(bezierElem, bezier);
-
- return;
- }
-
- /**
- * 位置補間情報を読み込む。
- * @param positionElem 親要素
- * @param curve 位置補間カーブ
- * @throws TogaXmlException 構文エラー
- */
- static void buildPosCurve(Element positionElem, PosCurve curve)
- throws TogaXmlException{
- Iterator<Element> itElem =
- new SiblingElemIterator(positionElem,
- Schema110820.NS_VMDXML, null);
- Iterator<BezierParam> itBez = curve.iterator();
-
- int ct = 0;
- while(itElem.hasNext()){
- Element curveElem = itElem.next();
- BezierParam bz = itBez.next();
- setBezier(curveElem, bz);
- ct++;
- }
-
- assert ct == 0 || ct == 3;
-
- return;
- }
-
-}
+++ /dev/null
-/*
- * xml loader
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.vmd.model.xml;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import javax.xml.parsers.DocumentBuilder;
-import jp.sfjp.mikutoga.math.MkPos3D;
-import jp.sfjp.mikutoga.math.MkQuat;
-import jp.sfjp.mikutoga.vmd.model.BezierParam;
-import jp.sfjp.mikutoga.vmd.model.BoneMotion;
-import jp.sfjp.mikutoga.vmd.model.MorphMotion;
-import jp.sfjp.mikutoga.vmd.model.PosCurve;
-import jp.sfjp.mikutoga.vmd.model.VmdMotion;
-import jp.sourceforge.mikutoga.xml.TogaXmlException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * XML形式でのモーションファイルを読み込む。
- */
-public class Xml2VmdLoader {
-
- private static final String ERRMSG_INVROOT =
- "RootElem:[{0}] must be [vmdMotion]";
-
-
- private final DocumentBuilder builder;
-
-
- /**
- * コンストラクタ。
- * @param builder ビルダ
- */
- public Xml2VmdLoader(DocumentBuilder builder){
- super();
- assert builder.isNamespaceAware();
- this.builder = builder;
- return;
- }
-
-
- /**
- * ルート要素の取得とチェックを行う。
- * @param document XMLドキュメント
- * @return ルート要素
- * @throws TogaXmlException 不正なルート要素の検出
- */
- private static Element getRootElem(Document document)
- throws TogaXmlException {
- Element vmdMotionElem = document.getDocumentElement();
- if( ! Xml.hasNsLocalNameElem(vmdMotionElem, "vmdMotion") ){
- String message =
- MessageFormat.format(ERRMSG_INVROOT,
- vmdMotionElem.getLocalName() );
- throw new TogaXmlException(message);
- }
- return vmdMotionElem;
- }
-
- /**
- * モーションのモデル名を読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildModelName(Element vmdMotionElem,
- VmdMotion vmdMotion)
- throws TogaXmlException{
- Element modelNameElem = Xml.getChild(vmdMotionElem, "modelName");
- String modelName = Xml.getStringAttr(modelNameElem, "name");
- vmdMotion.setModelName(modelName);
- return;
- }
-
- /**
- * ボーンシーケンスを読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildBoneSeq(Element vmdMotionElem,
- VmdMotion vmdMotion )
- throws TogaXmlException{
- Element boneSeqElem =
- Xml.getChild(vmdMotionElem, "boneMotionSequence");
-
- for(Element bonePartElem : Xml.eachChild(boneSeqElem, "bonePart")){
- buildBonePart(bonePartElem, vmdMotion);
- }
-
- return;
- }
-
- /**
- * ボーンパートを読み込む。
- * @param bonePartElem bonePart要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildBonePart(Element bonePartElem,
- VmdMotion vmdMotion )
- throws TogaXmlException{
- String boneName = Xml.getStringAttr(bonePartElem, "name");
-
- for(Element boneMotionElem :
- Xml.eachChild(bonePartElem, "boneMotion")){
- BoneMotion boneMotion = buildBoneMotion(boneMotionElem);
- boneMotion.setBoneName(boneName);
- vmdMotion.addBoneMotion(boneMotion);
- }
-
- return;
- }
-
- /**
- * ボーンモーションを読み込む。
- * @param boneMotionElem boneMotion要素
- * @return ボーンモーション
- * @throws TogaXmlException 構文エラー
- */
- private static BoneMotion buildBoneMotion(Element boneMotionElem)
- throws TogaXmlException {
- BoneMotion boneMotion = new BoneMotion();
- int frameNo = Xml.getIntegerAttr(boneMotionElem, "frame");
- boneMotion.setFrameNumber(frameNo);
-
- buildBonePosition(boneMotionElem, boneMotion);
- if(Xml.pickChild(boneMotionElem, "boneRotQuat") != null){
- buildBoneRotQuat(boneMotionElem, boneMotion);
- }else{
- buildBoneRotEyxz(boneMotionElem, boneMotion);
- }
-
- return boneMotion;
- }
-
- /**
- * ボーン位置を読み込む。
- * @param boneMotionElem boneMotion要素
- * @param boneMotion ボーンモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildBonePosition(Element boneMotionElem,
- BoneMotion boneMotion )
- throws TogaXmlException {
- Element bonePositionElem =
- Xml.pickChild(boneMotionElem, "bonePosition");
- if(bonePositionElem == null) return;
-
- MkPos3D position = boneMotion.getPosition();
- float xPos = Xml.getFloatAttr(bonePositionElem, "xPos");
- float yPos = Xml.getFloatAttr(bonePositionElem, "yPos");
- float zPos = Xml.getFloatAttr(bonePositionElem, "zPos");
- position.setXpos(xPos);
- position.setYpos(yPos);
- position.setZpos(zPos);
-
- PosCurve curve = boneMotion.getPosCurve();
- Xml.buildPosCurve(bonePositionElem, curve);
-
- return;
- }
-
- /**
- * ボーン回転をクォータニオン形式で読み込む。
- * @param boneMotionElem boneMotion要素
- * @param boneMotion ボーンモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildBoneRotQuat(Element boneMotionElem,
- BoneMotion boneMotion )
- throws TogaXmlException{
- Element boneRotationElem =
- Xml.getChild(boneMotionElem, "boneRotQuat");
-
- MkQuat rotation = boneMotion.getRotation();
- float qx = Xml.getFloatAttr(boneRotationElem, "qx");
- float qy = Xml.getFloatAttr(boneRotationElem, "qy");
- float qz = Xml.getFloatAttr(boneRotationElem, "qz");
- float qw = Xml.getFloatAttr(boneRotationElem, "qw");
-
- rotation.setQ1(qx);
- rotation.setQ2(qy);
- rotation.setQ3(qz);
- rotation.setQW(qw);
-
- BezierParam rotationCurve = boneMotion.getIntpltRotation();
- Xml.buildCurve(boneRotationElem, rotationCurve);
-
- return;
- }
-
- /**
- * ボーン回転をオイラー角で読み込む。
- * @param boneMotionElem boneMotion要素
- * @param boneMotion ボーンモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildBoneRotEyxz(Element boneMotionElem,
- BoneMotion boneMotion )
- throws TogaXmlException{
- Element boneRotationElem =
- Xml.getChild(boneMotionElem, "boneRotEyxz");
-
- MkQuat rotation = boneMotion.getRotation();
-
- float xDeg = Xml.getFloatAttr(boneRotationElem, "xDeg");
- float yDeg = Xml.getFloatAttr(boneRotationElem, "yDeg");
- float zDeg = Xml.getFloatAttr(boneRotationElem, "zDeg");
- float xRad = (float)StrictMath.toRadians(xDeg);
- float yRad = (float)StrictMath.toRadians(yDeg);
- float zRad = (float)StrictMath.toRadians(zDeg);
- rotation.setEulerYXZ(xRad, yRad, zRad);
-
- BezierParam rotationCurve = boneMotion.getIntpltRotation();
- Xml.buildCurve(boneRotationElem, rotationCurve);
-
- return;
- }
-
- /**
- * モーフシーケンスを読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildMorphSeq(Element vmdMotionElem,
- VmdMotion vmdMotion )
- throws TogaXmlException{
- Element morphSeqElem = Xml.getChild(vmdMotionElem, "morphSequence");
-
- for(Element morphPartElem :
- Xml.eachChild(morphSeqElem, "morphPart")){
- buildMorphPart(morphPartElem, vmdMotion);
- }
-
- return;
- }
-
- /**
- * モーフパートを読み込む。
- * @param morphPartElem morphPart要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildMorphPart(Element morphPartElem,
- VmdMotion vmdMotion )
- throws TogaXmlException{
- String morphName = Xml.getStringAttr(morphPartElem, "name");
-
- Iterable<Element> childs =
- Xml.eachChild(morphPartElem, "morphMotion");
- for(Element morphMotionElem : childs){
- MorphMotion morphMotion = buildMorphMotion(morphMotionElem);
- morphMotion.setMorphName(morphName);
- vmdMotion.addMorphMotion(morphMotion);
- }
-
- return;
- }
-
- /**
- * モーフモーションを読み込む。
- * @param morphMotionElem morphMotion要素
- * @return モーフモーション
- * @throws TogaXmlException 構文エラー
- */
- private static MorphMotion buildMorphMotion(Element morphMotionElem)
- throws TogaXmlException {
- MorphMotion morphMotion = new MorphMotion();
-
- int frameNo = Xml.getIntegerAttr(morphMotionElem, "frame");
- float flex = Xml.getFloatAttr(morphMotionElem, "flex");
-
- morphMotion.setFrameNumber(frameNo);
- morphMotion.setFlex(flex);
-
- return morphMotion;
- }
-
- /**
- * XMLのパースを開始する。
- * @param source XML入力
- * @return モーションデータ
- * @throws SAXException 構文エラー
- * @throws IOException 入力エラー
- * @throws TogaXmlException 構文エラー
- */
- public VmdMotion parse(InputSource source)
- throws SAXException, IOException, TogaXmlException{
- Document document = this.builder.parse(source);
- Element vmdMotionElem = getRootElem(document);
- VmdMotion vmdMotion = new VmdMotion();
-
- // ignore <meta>
-
- if(Xml.pickChild(vmdMotionElem, "modelName") != null){
- buildModelName(vmdMotionElem, vmdMotion);
- buildBoneSeq(vmdMotionElem, vmdMotion);
- buildMorphSeq(vmdMotionElem, vmdMotion);
- }else{
- XmlCameraLoader.buildCameraSeq(vmdMotionElem, vmdMotion);
- XmlLightingLoader.buildLuminousSeq(vmdMotionElem, vmdMotion);
- XmlLightingLoader.buildShadowSeq(vmdMotionElem, vmdMotion);
- }
-
- return vmdMotion;
- }
-
-}
+++ /dev/null
-/*
- * xml camera loader
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.vmd.model.xml;
-
-import java.util.List;
-import jp.sfjp.mikutoga.math.MkPos3D;
-import jp.sfjp.mikutoga.vmd.model.BezierParam;
-import jp.sfjp.mikutoga.vmd.model.CameraMotion;
-import jp.sfjp.mikutoga.vmd.model.CameraRotation;
-import jp.sfjp.mikutoga.vmd.model.PosCurve;
-import jp.sfjp.mikutoga.vmd.model.VmdMotion;
-import jp.sourceforge.mikutoga.xml.TogaXmlException;
-import org.w3c.dom.Element;
-
-/**
- * XMLによるカメラ制御データを読み取る。
- */
-final class XmlCameraLoader {
-
- /**
- * 隠しコンストラクタ。
- */
- private XmlCameraLoader(){
- assert false;
- throw new AssertionError();
- }
-
-
- /**
- * カメラシーケンスを読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- static void buildCameraSeq(Element vmdMotionElem, VmdMotion vmdMotion)
- throws TogaXmlException{
- List<CameraMotion> cameraList = vmdMotion.getCameraMotionList();
-
- Element cameraSeqElem =
- Xml.getChild(vmdMotionElem, "cameraSequence");
-
- Iterable<Element> childs =
- Xml.eachChild(cameraSeqElem, "cameraMotion");
- for(Element cameraMotionElem : childs){
- buildCameraMotion(cameraMotionElem, cameraList);
- }
-
- return;
- }
-
- /**
- * カメラモーションを読み込む。
- * @param cameraMotionElem cameraMotion要素
- * @param cameraList カメラモーションリスト
- * @throws TogaXmlException 構文エラー
- */
- private static void buildCameraMotion(Element cameraMotionElem,
- List<CameraMotion> cameraList)
- throws TogaXmlException{
- CameraMotion cameraMotion = new CameraMotion();
-
- int frameNo = Xml.getIntegerAttr(cameraMotionElem, "frame");
- cameraMotion.setFrameNumber(frameNo);
-
- if(cameraMotionElem.hasAttributeNS(Xml.NS_NULL, "hasPerspective")){
- boolean hasPerspective =
- Xml.getBooleanAttr(cameraMotionElem, "hasPerspective");
- cameraMotion.setPerspectiveMode(hasPerspective);
- }
-
- buildCameraTarget(cameraMotionElem, cameraMotion);
- buildCameraRotation(cameraMotionElem, cameraMotion);
- buildCameraRange(cameraMotionElem, cameraMotion);
- buildProjection(cameraMotionElem, cameraMotion);
-
- cameraList.add(cameraMotion);
-
- return;
- }
-
- /**
- * カメラターゲット情報を読み込む。
- * @param cameraMotionElem cameraMotion要素
- * @param cameraMotion カメラモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildCameraTarget(Element cameraMotionElem,
- CameraMotion cameraMotion)
- throws TogaXmlException{
- Element cameraTargetElem =
- Xml.getChild(cameraMotionElem, "cameraTarget");
- MkPos3D targetPos = cameraMotion.getCameraTarget();
-
- float xPos = Xml.getFloatAttr(cameraTargetElem, "xPos");
- float yPos = Xml.getFloatAttr(cameraTargetElem, "yPos");
- float zPos = Xml.getFloatAttr(cameraTargetElem, "zPos");
- targetPos.setPosition(xPos, yPos, zPos);
-
- PosCurve curve = cameraMotion.getTargetPosCurve();
- Xml.buildPosCurve(cameraTargetElem, curve);
-
- return;
- }
-
- /**
- * カメラ回転情報を読み込む。
- * @param cameraMotionElem cameraMotion要素
- * @param cameraMotion カメラモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildCameraRotation(Element cameraMotionElem,
- CameraMotion cameraMotion)
- throws TogaXmlException{
- Element cameraRotationElem =
- Xml.getChild(cameraMotionElem, "cameraRotation");
- CameraRotation cameraRotation = cameraMotion.getCameraRotation();
-
- float latitude = Xml.getFloatAttr(cameraRotationElem, "xRad");
- float longitude = Xml.getFloatAttr(cameraRotationElem, "yRad");
- float roll = Xml.getFloatAttr(cameraRotationElem, "zRad");
- cameraRotation.setLatitude(latitude);
- cameraRotation.setLongitude(longitude);
- cameraRotation.setRoll(roll);
-
- BezierParam rotationCurve = cameraMotion.getIntpltRotation();
- Xml.buildCurve(cameraRotationElem, rotationCurve);
-
- return;
- }
-
- /**
- * カメラ距離情報を読み込む。
- * @param cameraMotionElem cameraMotion要素
- * @param cameraMotion カメラモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildCameraRange(Element cameraMotionElem,
- CameraMotion cameraMotion)
- throws TogaXmlException{
- Element cameraRangeElem =
- Xml.getChild(cameraMotionElem, "cameraRange");
-
- float range = Xml.getFloatAttr(cameraRangeElem, "range");
- cameraMotion.setRange(range);
-
- BezierParam rangeCurve = cameraMotion.getIntpltRange();
- Xml.buildCurve(cameraRangeElem, rangeCurve);
-
- return;
- }
-
- /**
- * カメラ投影情報を読み込む。
- * @param cameraMotionElem cameraMotion要素
- * @param cameraMotion カメラモーション
- * @throws TogaXmlException 構文エラー
- */
- private static void buildProjection(Element cameraMotionElem,
- CameraMotion cameraMotion)
- throws TogaXmlException{
- Element projectionElem =
- Xml.getChild(cameraMotionElem, "projection");
-
- int vertDeg = Xml.getIntegerAttr(projectionElem, "vertDeg");
- cameraMotion.setProjectionAngle(vertDeg);
-
- BezierParam projCurve = cameraMotion.getIntpltProjection();
- Xml.buildCurve(projectionElem, projCurve);
-
- return;
- }
-
-}
+++ /dev/null
-/*
- * xml lighting loader
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.vmd.model.xml;
-
-import java.util.List;
-import jp.sfjp.mikutoga.math.MkVec3D;
-import jp.sfjp.mikutoga.vmd.model.LuminousColor;
-import jp.sfjp.mikutoga.vmd.model.LuminousMotion;
-import jp.sfjp.mikutoga.vmd.model.ShadowMode;
-import jp.sfjp.mikutoga.vmd.model.ShadowMotion;
-import jp.sfjp.mikutoga.vmd.model.VmdMotion;
-import jp.sourceforge.mikutoga.xml.TogaXmlException;
-import org.w3c.dom.Element;
-
-/**
- * XMLによるカメラ制御データを読み取る。
- */
-final class XmlLightingLoader {
-
- /**
- * 隠しコンストラクタ。
- */
- private XmlLightingLoader(){
- assert false;
- throw new AssertionError();
- }
-
-
- /**
- * 照明シーケンスを読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- static void buildLuminousSeq(Element vmdMotionElem, VmdMotion vmdMotion)
- throws TogaXmlException{
- List<LuminousMotion> luminousList =
- vmdMotion.getLuminousMotionList();
-
- Element luminousSeqElem =
- Xml.getChild(vmdMotionElem, "luminousSequence");
-
- Iterable<Element> childs =
- Xml.eachChild(luminousSeqElem, "luminousAct");
- for(Element luminousActElem : childs){
- buildLuminousAct(luminousActElem, luminousList);
- }
-
- return;
- }
-
- /**
- * 照明モーションを読み込む。
- * @param luminousActElem luminousAct要素
- * @param luminousList 照明モーションリスト
- * @throws TogaXmlException 構文エラー
- */
- private static void buildLuminousAct(Element luminousActElem,
- List<LuminousMotion> luminousList)
- throws TogaXmlException{
- LuminousMotion luminousMotion = new LuminousMotion();
-
- int frameNo = Xml.getIntegerAttr(luminousActElem, "frame");
- luminousMotion.setFrameNumber(frameNo);
-
- Element lumiColorElem = Xml.getChild(luminousActElem, "lumiColor");
- LuminousColor color = luminousMotion.getColor();
- float rCol = Xml.getFloatAttr(lumiColorElem, "rCol");
- float gCol = Xml.getFloatAttr(lumiColorElem, "gCol");
- float bCol = Xml.getFloatAttr(lumiColorElem, "bCol");
- color.setColR(rCol);
- color.setColG(gCol);
- color.setColB(bCol);
-
- Element lumiDirectionElem =
- Xml.getChild(luminousActElem, "lumiDirection");
- MkVec3D vec = luminousMotion.getDirection();
- float xVec = Xml.getFloatAttr(lumiDirectionElem, "xVec");
- float yVec = Xml.getFloatAttr(lumiDirectionElem, "yVec");
- float zVec = Xml.getFloatAttr(lumiDirectionElem, "zVec");
- vec.setXVal(xVec);
- vec.setYVal(yVec);
- vec.setZVal(zVec);
-
- luminousList.add(luminousMotion);
-
- return;
- }
-
- /**
- * シャドウシーケンスを読み込む。
- * @param vmdMotionElem vmdMotion要素
- * @param vmdMotion モーション
- * @throws TogaXmlException 構文エラー
- */
- static void buildShadowSeq(Element vmdMotionElem,
- VmdMotion vmdMotion)
- throws TogaXmlException{
- List<ShadowMotion> shadowMotionList =
- vmdMotion.getShadowMotionList();
-
- Element shadowSeqElem =
- Xml.getChild(vmdMotionElem, "shadowSequence");
-
- for(Element shadowActElem :
- Xml.eachChild(shadowSeqElem, "shadowAct")){
- buildShadowAct(shadowActElem, shadowMotionList);
- }
-
- return;
- }
-
- /**
- * シャドウモーションを読み込む。
- * @param shadowActElem shadowAct要素
- * @param shadowMotionList シャドウモーションリスト
- * @throws TogaXmlException 構文エラー
- */
- private static void buildShadowAct(Element shadowActElem,
- List<ShadowMotion> shadowMotionList)
- throws TogaXmlException{
- ShadowMotion shadowMotion = new ShadowMotion();
-
- int frameNo = Xml.getIntegerAttr(shadowActElem, "frame");
- shadowMotion.setFrameNumber(frameNo);
-
- float rawParam = Xml.getFloatAttr(shadowActElem, "rawParam");
- shadowMotion.setRawScopeParam(rawParam);
-
- String modeAttr = Xml.getStringAttr(shadowActElem, "mode");
- ShadowMode mode = ShadowMode.valueOf(modeAttr);
- shadowMotion.setShadowMode(mode);
-
- shadowMotionList.add(shadowMotion);
-
- return;
- }
-
-}
+++ /dev/null
-/*
- * xml symbols
- *
- * License : The MIT License
- * Copyright(c) 2013 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.vmd.model.xml;
-
-/**
- * XML 各種シンボル名。
- */
-final class XmlSyms {
-
- static final String TOP_COMMENT =
- " MikuMikuDance\n motion-data(*.vmd) on XML";
-
- static final String QUATERNION_COMMENT =
- " bone-rotation has Quaternion parameters [boneRotQuat]\n"
- + " or YXZ-Euler angles [boneRotEyxz].\n"
- + " Quaternion form is strongly recommended"
- + " if you are data-exchanging.";
-
- static final String BEZIER_COMMENT =
- " motion-interpolation is described with Bezier-cubic-curve.\n"
- + " implicit bezier curve point : P0=(0,0) P3=(127,127)\n"
- + " defLinear : MMD default linear curve."
- + " P1=(20,20) P2=(107,107) [DEFAULT]\n"
- + " defEaseInOut : MMD default ease-in-out curve."
- + " P1=(64,0) P2=(64,127)";
-
- static final String CAMERA_COMMENT =
- " camera-rotation has polar-coordinates parameters.\n"
- + " xRad = -radian(UI_X) [latitude]\n"
- + " yRad = radian(UI_Y) [longitude]\n"
- + " zRad = radian(UI_Z) [roll]\n"
- + " range = -(UI_RANGE)";
-
- static final String SHADOW_COMMENT =
- " UI_VALUE = EFFECTIVE_RANGE * 100 ???\n"
- +" rawParam = 0.1 - (UI_VALUE / 1.0E+5)\n\n"
- +" NONE : no self-shadow\n"
- +" MODE_1 : reduce shadow-quality suddenly at range\n"
- +" MODE_2 : reduce shadow-quality gradually with range";
-
- static final String TAG_VMD_MOTION = "vmdMotion";
- static final String TAG_META = "meta";
- static final String TAG_MODEL_NAME = "modelName";
- static final String TAG_BONE_M_SEQUENCE = "boneMotionSequence";
- static final String TAG_BONE_PART = "bonePart";
- static final String TAG_BONE_MOTION = "boneMotion";
- static final String TAG_BONE_POSITION = "bonePosition";
- static final String TAG_BONE_ROT_QUAT = "boneRotQuat";
- static final String TAG_BONE_ROT_EYXZ = "boneRotEyxz";
- static final String TAG_BEZIER = "bezier";
- static final String TAG_DEF_LINEAR = "defLinear";
- static final String TAG_DEF_EASE_IN_OUT = "defEaseInOut";
- static final String TAG_MORPH_SEQUENCE = "morphSequence";
- static final String TAG_MORPH_PART = "morphPart";
- static final String TAG_MORPH_MOTION = "morphMotion";
- static final String TAG_CAMERA_SEQUENCE = "cameraSequence";
- static final String TAG_CAMERA_MOTION = "cameraMotion";
- static final String TAG_CAMERA_TARGET = "cameraTarget";
- static final String TAG_CAMERA_ROTATION = "cameraRotation";
- static final String TAG_CAMERA_RANGE = "cameraRange";
- static final String TAG_PROJECTION = "projection";
- static final String TAG_LUMI_SEQUENCE = "luminousSequence";
- static final String TAG_LUMINOUS_ACT = "luminousAct";
- static final String TAG_LUMI_COLOR = "lumiColor";
- static final String TAG_LUMI_DIRECTION = "lumiDirection";
- static final String TAG_SHADOW_SEQUENCE = "shadowSequence";
- static final String TAG_SHADOW_ACT = "shadowAct";
-
- static final String ATTR_VERSION = "version";
- static final String ATTR_CONTENT = "content";
- static final String ATTR_FRAME = "frame";
- static final String ATTR_NAME = "name";
- static final String ATTR_P1X = "p1x";
- static final String ATTR_P1Y = "p1y";
- static final String ATTR_P2X = "p2x";
- static final String ATTR_P2Y = "p2y";
- static final String ATTR_QX = "qx";
- static final String ATTR_QY = "qy";
- static final String ATTR_QZ = "qz";
- static final String ATTR_QW = "qw";
- static final String ATTR_X_DEG = "xDeg";
- static final String ATTR_Y_DEG = "yDeg";
- static final String ATTR_Z_DEG = "zDeg";
- static final String ATTR_X_POS = "xPos";
- static final String ATTR_Y_POS = "yPos";
- static final String ATTR_Z_POS = "zPos";
- static final String ATTR_FLEX = "flex";
- static final String ATTR_RANGE = "range";
- static final String ATTR_X_RAD = "xRad";
- static final String ATTR_Y_RAD = "yRad";
- static final String ATTR_Z_RAD = "zRad";
- static final String ATTR_VERT_DEG = "vertDeg";
- static final String ATTR_HAS_PERSPECTIVE = "hasPerspective";
- static final String ATTR_X_VEC = "xVec";
- static final String ATTR_Y_VEC = "yVec";
- static final String ATTR_Z_VEC = "zVec";
- static final String ATTR_R_COL = "rCol";
- static final String ATTR_G_COL = "gCol";
- static final String ATTR_B_COL = "bCol";
- static final String ATTR_MODE = "mode";
- static final String ATTR_RAW_PARAM = "rawParam";
-
-
- /**
- * 隠しコンストラクタ。
- */
- private XmlSyms(){
- assert false;
- throw new AssertionError();
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<!--
- MikuMikuDance
- motion-data(*.vmd) on XML
- DTD definition
-
- License : The MIT License
- Copyright(c) 2011 MikuToga Partners
-
- SYSTEM ID: http://mikutoga.sourceforge.jp/xml/dtd/vmdxml-110820.dtd
--->
-
-
-<!--
- ROOT
--->
-<!ELEMENT vmdMotion (
- meta*,
- (
- ( modelName, boneMotionSequence, morphSequence )
- | ( cameraSequence, luminousSequence, shadowSequence )
- )
-) >
-<!ATTLIST vmdMotion
- xmlns CDATA #IMPLIED
- xmlns:xsi CDATA #IMPLIED
- xsi:schemaLocation CDATA #IMPLIED
- version CDATA #FIXED "110820"
->
-
-
-<!--
- Meta-information of model.
- Use free.
- but, some meta-name has recommended usage.
- + "generator" (Generator application name)
- + "siteURL" (Website URL)
--->
-<!ELEMENT meta EMPTY >
-<!ATTLIST meta
- name CDATA #REQUIRED
- content CDATA #REQUIRED
->
-
-
-<!--
- bezier cubic curve parameters for interpolation.
- p0=(0, 0) p3=(127, 127) [implicit points]
- P1 and P2 points are required.
--->
-<!ELEMENT bezier EMPTY >
-<!ATTLIST bezier
- p1x CDATA #REQUIRED
- p1y CDATA #REQUIRED
- p2x CDATA #REQUIRED
- p2y CDATA #REQUIRED
->
-
-
-<!--
- default linear bezier curve for interpolation.
- p0=(0, 0) p1=(20, 20) p2=(107, 107) p3=(127, 127)
--->
-<!ELEMENT defLinear EMPTY >
-
-
-<!--
- default ease-in-out bezier curve for interpolation.
- p0=(0, 0) p1=(64, 0) p2=(64, 127) p3=(127, 127)
--->
-<!ELEMENT defEaseInOut EMPTY >
-
-
-<!--
- model name.
--->
-<!ELEMENT modelName EMPTY>
-<!ATTLIST modelName name CDATA #REQUIRED>
-
-
-<!--
- bone motion sequence
--->
-<!ELEMENT boneMotionSequence (
- bonePart*
-) >
-
-
-<!--
- bone part grouped by bone-name
--->
-<!ELEMENT bonePart (
- boneMotion*
-) >
-<!ATTLIST bonePart name CDATA #REQUIRED>
-
-
-<!--
- bone motion
--->
-<!ELEMENT boneMotion (
- bonePosition?, ( boneRotQuat | boneRotEyxz )
-) >
-<!ATTLIST boneMotion frame CDATA #REQUIRED>
-
-
-<!--
- bone position
- with XYZ *3 interpolations.
--->
-<!ELEMENT bonePosition (
- ( ( bezier | defLinear | defEaseInOut ),
- ( bezier | defLinear | defEaseInOut ),
- ( bezier | defLinear | defEaseInOut ) )?
-) >
-<!ATTLIST bonePosition
- xPos CDATA #REQUIRED
- yPos CDATA #REQUIRED
- zPos CDATA #REQUIRED
->
-
-
-<!--
- bone rotation [Quaternion]
--->
-<!ELEMENT boneRotQuat (
- ( bezier | defLinear | defEaseInOut )?
-) >
-<!ATTLIST boneRotQuat
- qx CDATA #REQUIRED
- qy CDATA #REQUIRED
- qz CDATA #REQUIRED
- qw CDATA #REQUIRED
->
-
-
-<!--
- bone rotation [YXZ-Euler]
- degree but not radian
--->
-<!ELEMENT boneRotEyxz (
- ( bezier | defLinear | defEaseInOut )?
-) >
-<!ATTLIST boneRotEyxz
- xDeg CDATA #REQUIRED
- yDeg CDATA #REQUIRED
- zDeg CDATA #REQUIRED
->
-
-
-<!--
- morph sequence
--->
-<!ELEMENT morphSequence (
- morphPart*
-) >
-
-
-<!--
- morph part grouped by morph-name
--->
-<!ELEMENT morphPart (
- morphMotion*
-) >
-<!ATTLIST morphPart name CDATA #REQUIRED>
-
-
-<!--
- morph motion
- flex : morph flexible value. [0.0-1.0]
--->
-<!ELEMENT morphMotion EMPTY >
-<!ATTLIST morphMotion
- frame CDATA #REQUIRED
- flex CDATA #REQUIRED
->
-
-
-<!--
- camera sequence
--->
-<!ELEMENT cameraSequence (
- cameraMotion*
-) >
-
-
-<!--
- camera motion
--->
-<!ELEMENT cameraMotion (
- cameraTarget, cameraRotation, cameraRange, projection
-) >
-<!ATTLIST cameraMotion
- frame CDATA #REQUIRED
- hasPerspective ( true | false | 1 | 0 ) "true"
->
-
-
-<!--
- camera target position
- with XYZ *3 interpolations.
--->
-<!ELEMENT cameraTarget (
- ( ( bezier | defLinear | defEaseInOut ),
- ( bezier | defLinear | defEaseInOut ),
- ( bezier | defLinear | defEaseInOut ) )?
-) >
-<!ATTLIST cameraTarget
- xPos CDATA #REQUIRED
- yPos CDATA #REQUIRED
- zPos CDATA #REQUIRED
->
-
-
-<!--
- camera-rotation around camera-target
- with polar-coordinates parameters.
-
- xRad = -radian(UI_X) [latitude]
- yRad = radian(UI_Y) [longitude]
- zRad = radian(UI_Z) [roll]
--->
-<!ELEMENT cameraRotation (
- ( bezier | defLinear | defEaseInOut )?
-) >
-<!ATTLIST cameraRotation
- xRad CDATA #REQUIRED
- yRad CDATA #REQUIRED
- zRad CDATA #REQUIRED
->
-
-
-<!--
- camera range.
- sign was negated from UI_RANGE.
--->
-<!ELEMENT cameraRange (
- ( bezier | defLinear | defEaseInOut )?
-) >
-<!ATTLIST cameraRange range CDATA #REQUIRED >
-
-
-<!--
- screen-projection data.
- vertDeg : vertical screen-projection angle by degree.
--->
-<!ELEMENT projection (
- ( bezier | defLinear | defEaseInOut )?
-) >
-<!ATTLIST projection vertDeg CDATA #REQUIRED >
-
-
-<!--
- luminous sequence
--->
-<!ELEMENT luminousSequence (
- luminousAct*
-) >
-
-
-<!--
- luminous act
--->
-<!ELEMENT luminousAct (
- lumiColor, lumiDirection
-) >
-<!ATTLIST luminousAct frame CDATA #REQUIRED >
-
-
-<!--
- luminous color by RGB color space.
- color component value. [0.0-1.0]
--->
-<!ELEMENT lumiColor EMPTY >
-<!ATTLIST lumiColor
- rCol CDATA #REQUIRED
- gCol CDATA #REQUIRED
- bCol CDATA #REQUIRED
->
-
-
-<!--
- luminous direction by vector
- vector component [0.0-1.0]
--->
-<!ELEMENT lumiDirection EMPTY >
-<!ATTLIST lumiDirection
- xVec CDATA #REQUIRED
- yVec CDATA #REQUIRED
- zVec CDATA #REQUIRED
->
-
-
-<!--
- shadow sequence
--->
-<!ELEMENT shadowSequence (
- shadowAct*
-) >
-
-
-<!--
- shadow act
-
- mode : type of shadow
- + NONE : no self-shadow
- + MODE_1 : reduce shadow-quality suddenly at range
- + MODE_2 : reduce shadow-quality gradually with range
-
- rawParam : 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
--->
-<!ELEMENT shadowAct EMPTY >
-<!ATTLIST shadowAct
- frame CDATA #REQUIRED
- mode ( NONE | MODE_1 | MODE_2 ) #REQUIRED
- rawParam CDATA #REQUIRED
->
-
-
-<!-- EOF -->
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.vmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class CmdLineExceptionTest {
+
+ public CmdLineExceptionTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testSomeMethod() {
+
+ CmdLineException exp;
+
+ exp = new CmdLineException("abc");
+ assertEquals("abc", exp.getMessage());
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.vmd2xml;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class CmdLineTest {
+
+ public CmdLineTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of parse method, of class CmdLine.
+ */
+ @Test
+ public void testParse_StringArr() {
+ System.out.println("parse");
+
+ List<CmdLine> result;
+ CmdLine line;
+
+ result = CmdLine.parse();
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+
+ result = CmdLine.parse("");
+ assertEquals(1, result.size());
+ line = result.get(0);
+ assertNull(line.getOptSwitch());
+ assertEquals(1, line.getOptArgs().size());
+ assertEquals("", line.getOptArgs().get(0));
+
+ result = CmdLine.parse("-h");
+ assertEquals(1, result.size());
+ line = result.get(0);
+ assertEquals(OptSwitch.OPT_HELP, line.getOptSwitch());
+ assertEquals(1, line.getOptArgs().size());
+ assertEquals("-h", line.getOptArgs().get(0));
+
+ result = CmdLine.parse("-i", "infile");
+ assertEquals(1, result.size());
+ line = result.get(0);
+ assertEquals(OptSwitch.OPT_INFILE, line.getOptSwitch());
+ assertEquals(2, line.getOptArgs().size());
+ assertEquals("-i", line.getOptArgs().get(0));
+ assertEquals("infile", line.getOptArgs().get(1));
+
+ result = CmdLine.parse("-i");
+ assertEquals(1, result.size());
+ line = result.get(0);
+ assertEquals(OptSwitch.OPT_INFILE, line.getOptSwitch());
+ assertEquals(1, line.getOptArgs().size());
+ assertEquals("-i", line.getOptArgs().get(0));
+
+ result = CmdLine.parse("-h", "-i", "infile", "-f");
+ assertEquals(3, result.size());
+
+ line = result.get(0);
+ assertEquals(OptSwitch.OPT_HELP, line.getOptSwitch());
+ assertEquals(1, line.getOptArgs().size());
+ assertEquals("-h", line.getOptArgs().get(0));
+
+ line = result.get(1);
+ assertEquals(OptSwitch.OPT_INFILE, line.getOptSwitch());
+ assertEquals(2, line.getOptArgs().size());
+ assertEquals("-i", line.getOptArgs().get(0));
+ assertEquals("infile", line.getOptArgs().get(1));
+
+ line = result.get(2);
+ assertEquals(OptSwitch.OPT_FORCE, line.getOptSwitch());
+ assertEquals(1, line.getOptArgs().size());
+ assertEquals("-f", line.getOptArgs().get(0));
+
+ return;
+ }
+
+ /**
+ * Test of parse method, of class CmdLine.
+ */
+ @Test
+ public void testParse_List() {
+ System.out.println("parse");
+
+ List<CmdLine> result;
+ CmdLine line;
+
+ result = CmdLine.parse(Arrays.asList("-i", "infile"));
+ assertEquals(1, result.size());
+ line = result.get(0);
+ assertEquals(OptSwitch.OPT_INFILE, line.getOptSwitch());
+ assertEquals(2, line.getOptArgs().size());
+ assertEquals("-i", line.getOptArgs().get(0));
+ assertEquals("infile", line.getOptArgs().get(1));
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.vmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class MotionFileTypeTest {
+
+ public MotionFileTypeTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of values method, of class MotionFileType.
+ */
+ @Test
+ public void testValues() {
+ System.out.println("values");
+ assertEquals(3, MotionFileType.values().length);
+ return;
+ }
+
+ /**
+ * Test of valueOf method, of class MotionFileType.
+ */
+ @Test
+ public void testValueOf() {
+ System.out.println("valueOf");
+ assertSame(MotionFileType.NONE, MotionFileType.valueOf("NONE"));
+ return;
+ }
+
+ /**
+ * Test of isXml method, of class MotionFileType.
+ */
+ @Test
+ public void testIsXml() {
+ System.out.println("isXml");
+
+ assertFalse(MotionFileType.NONE.isXml());
+ assertFalse(MotionFileType.VMD.isXml());
+ assertTrue(MotionFileType.XML_110820.isXml());
+
+ return;
+ }
+
+ /**
+ * Test of isVmd method, of class MotionFileType.
+ */
+ @Test
+ public void testIsVmd() {
+ System.out.println("isVmd");
+
+ assertFalse(MotionFileType.NONE.isVmd());
+ assertTrue(MotionFileType.VMD.isVmd());
+ assertFalse(MotionFileType.XML_110820.isVmd());
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.vmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class OptInfoTest {
+
+ public OptInfoTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of parseOption method, of class OptInfo.
+ */
+ @Test
+ public void testParseOption() throws Exception {
+ System.out.println("parseOption");
+
+ OptInfo result;
+
+ try{
+ OptInfo.parseOption();
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You must specify input file with -i.", e.getMessage());
+ }
+
+ try{
+ OptInfo.parseOption("XXX");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("Unknown option : XXX", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-h");
+ assertTrue(result.needHelp());
+ assertEquals(Vmd2Xml.GENERATOR, result.getGenerator());
+ assertEquals("\n", result.getNewline());
+ assertSame(MotionFileType.NONE, result.getInFileType());
+ assertNull(result.getInFilename());
+ assertSame(MotionFileType.NONE, result.getOutFileType());
+ assertNull(result.getOutFilename());
+ assertTrue(result.isQuaterniomMode());
+ assertFalse(result.overwriteMode());
+
+ try{
+ OptInfo.parseOption("-i");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You need option arg with : -i", e.getMessage());
+ }
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You must specify output file with -o.", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml");
+ assertFalse(result.needHelp());
+ assertSame(MotionFileType.VMD, result.getInFileType());
+ assertEquals("test.vmd", result.getInFilename());
+ assertSame(MotionFileType.XML_110820, result.getOutFileType());
+ assertEquals("test.xml", result.getOutFilename());
+ assertEquals(Vmd2Xml.GENERATOR, result.getGenerator());
+ assertEquals("\n", result.getNewline());
+ assertTrue(result.isQuaterniomMode());
+ assertFalse(result.overwriteMode());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-i", "test2.vmd");
+ assertEquals("test2.vmd", result.getInFilename());
+
+
+ try{
+ OptInfo.parseOption("-i", "input", "-o", "test.xml");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You must specify input format with -iform.", e.getMessage());
+ }
+
+ try{
+ OptInfo.parseOption("-i", "input", "-o", "test.xml", "-iform", "ZZZ");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("Unknown format : \"ZZZ\" must be \"vmd\" or \"xml\" or \"xml110820\"", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-i", "input", "-o", "test.xml", "-iform", "vmd");
+ assertSame(MotionFileType.VMD, result.getInFileType());
+ assertEquals("input", result.getInFilename());
+
+ result = OptInfo.parseOption("-i", "input", "-o", "test.xml", "-iform", "xml");
+ assertSame(MotionFileType.XML_110820, result.getInFileType());
+
+ result = OptInfo.parseOption("-i", "input", "-o", "test.xml", "-iform", "xml110820");
+ assertSame(MotionFileType.XML_110820, result.getInFileType());
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd", "-o", "output");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You must specify output format with -oform.", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "output", "-oform", "vmd");
+ assertSame(MotionFileType.VMD, result.getOutFileType());
+ assertEquals("output", result.getOutFilename());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-f");
+ assertTrue(result.overwriteMode());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-eyxz");
+ assertFalse(result.isQuaterniomMode());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-quat");
+ assertTrue(result.isQuaterniomMode());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-eyxz", "-quat");
+ assertTrue(result.isQuaterniomMode());
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-nl");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You need option arg with : -nl", e.getMessage());
+ }
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-nl", "QQQ");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("Unknown newline : \"QQQ\" must be \"lf\" or \"crlf\"", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-nl", "lf");
+ assertEquals("\n", result.getNewline());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-nl", "crlf");
+ assertEquals("\r\n", result.getNewline());
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("You need option arg with : -genout", e.getMessage());
+ }
+
+ try{
+ OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "QQQ");
+ fail();
+ }catch(CmdLineException e){
+ assertEquals("Unknown switch : \"QQQ\" must be \"on\" or \"off\"", e.getMessage());
+ }
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "on");
+ assertEquals(Vmd2Xml.GENERATOR, result.getGenerator());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "true");
+ assertEquals(Vmd2Xml.GENERATOR, result.getGenerator());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "yes");
+ assertEquals(Vmd2Xml.GENERATOR, result.getGenerator());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "off");
+ assertNull(result.getGenerator());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "false");
+ assertNull(result.getGenerator());
+
+ result = OptInfo.parseOption("-i", "test.vmd", "-o", "test.xml", "-genout", "no");
+ assertNull(result.getGenerator());
+
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package jp.sfjp.mikutoga.vmd2xml;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class OptSwitchTest {
+
+ public OptSwitchTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of values method, of class OptSwitch.
+ */
+ @Test
+ public void testValues() {
+ System.out.println("values");
+ assertEquals(10, OptSwitch.values().length);
+ return;
+ }
+
+ /**
+ * Test of valueOf method, of class OptSwitch.
+ */
+ @Test
+ public void testValueOf() {
+ System.out.println("valueOf");
+ assertSame(OptSwitch.OPT_HELP, OptSwitch.valueOf("OPT_HELP"));
+ return;
+ }
+
+ /**
+ * Test of getConsoleHelp method, of class OptSwitch.
+ */
+ @Test
+ public void testGetConsoleHelp() {
+ System.out.println("getConsoleHelp");
+
+ String help = OptSwitch.getConsoleHelp();
+
+ assertNotNull(help);
+ assertFalse(help.isEmpty());
+
+ return;
+ }
+
+ /**
+ * Test of parse method, of class OptSwitch.
+ */
+ @Test
+ public void testParse() {
+ System.out.println("parse");
+
+ assertNull(OptSwitch.parse(null));
+ assertNull(OptSwitch.parse(""));
+ assertNull(OptSwitch.parse("XXX"));
+
+ assertEquals(OptSwitch.OPT_HELP, OptSwitch.parse("-h"));
+ assertEquals(OptSwitch.OPT_HELP, OptSwitch.parse("-help"));
+ assertEquals(OptSwitch.OPT_HELP, OptSwitch.parse("-?"));
+
+ assertEquals(OptSwitch.OPT_INFILE, OptSwitch.parse("-i"));
+ assertEquals(OptSwitch.OPT_OUTFILE, OptSwitch.parse("-o"));
+ assertEquals(OptSwitch.OPT_FORCE, OptSwitch.parse("-f"));
+ assertEquals(OptSwitch.OPT_NEWLINE, OptSwitch.parse("-nl"));
+ assertEquals(OptSwitch.OPT_GENOUT, OptSwitch.parse("-genout"));
+ assertEquals(OptSwitch.OPT_IFORM, OptSwitch.parse("-iform"));
+ assertEquals(OptSwitch.OPT_OFORM, OptSwitch.parse("-oform"));
+ assertEquals(OptSwitch.OPT_QUAT, OptSwitch.parse("-quat"));
+ assertEquals(OptSwitch.OPT_EYXZ, OptSwitch.parse("-eyxz"));
+
+ return;
+ }
+
+ /**
+ * Test of getExArgNum method, of class OptSwitch.
+ */
+ @Test
+ public void testGetExArgNum() {
+ System.out.println("getExArgNum");
+
+ for(OptSwitch sw : OptSwitch.values()){
+ switch(sw){
+ case OPT_HELP:
+ case OPT_FORCE:
+ case OPT_QUAT:
+ case OPT_EYXZ:
+ assertEquals(0, sw.getExArgNum());
+ break;
+ default:
+ assertEquals(1, sw.getExArgNum());
+ break;
+ }
+ }
+
+ return;
+ }
+
+}
String pmdResource,
String expXmlResource )
throws Exception{
- InputStream pmdis =
- klass.getResourceAsStream(pmdResource);
- assertNotNull(pmdis);
- pmdis = new BufferedInputStream(pmdis);
-
- File destFile = openTempFile();
- OutputStream destOut;
- destOut = new FileOutputStream(destFile);
- destOut = new BufferedOutputStream(destOut);
-
Vmd2XmlConv converter = new Vmd2XmlConv();
converter.setInType(MotionFileType.VMD);
converter.setOutType(MotionFileType.XML_110820);
converter.setNewline("\n");
converter.setGenerator(null);
- converter.convert(pmdis, destOut);
+ assertVmd2Xml(klass, pmdResource, expXmlResource, converter);
+
+ return;
+ }
+
+ /**
+ * VMDリソースをXMLに変換した結果がXMLリソースに等しいと表明する。
+ * @param klass リソース元クラス
+ * @param vmdResource PMDリソース名
+ * @param expXmlResource XMLリソース名
+ * @param converter コンバータ
+ * @throws Exception エラー
+ */
+ public static void assertVmd2Xml(
+ Class<?> klass,
+ String vmdResource,
+ String expXmlResource,
+ Vmd2XmlConv converter )
+ throws Exception{
+ InputStream vmdis =
+ klass.getResourceAsStream(vmdResource);
+ assertNotNull(vmdis);
+ vmdis = new BufferedInputStream(vmdis);
+
+ File destFile = openTempFile();
+ OutputStream destOut;
+ destOut = new FileOutputStream(destFile);
+ destOut = new BufferedOutputStream(destOut);
+
+ converter.convert(vmdis, destOut);
- pmdis.close();
+ vmdis.close();
destOut.close();
assertSameFile(klass, expXmlResource, destFile);
--- /dev/null
+/*
+ */
+
+package testdata.vmd110820.euler;
+
+import jp.sfjp.mikutoga.vmd2xml.MotionFileType;
+import jp.sfjp.mikutoga.vmd2xml.Vmd2XmlConv;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static testdata.CnvAssert.*;
+
+/**
+ *
+ */
+public class EulerTest {
+
+ static Class<?> THISCLASS = EulerTest.class;
+
+ public EulerTest() {
+ 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 vmd2xml() throws Exception{
+ System.out.println("vmd2xml");
+
+ Vmd2XmlConv converter = new Vmd2XmlConv();
+ converter.setInType(MotionFileType.VMD);
+ converter.setOutType(MotionFileType.XML_110820);
+ converter.setNewline("\n");
+ converter.setGenerator(null);
+ converter.setQuaterniomMode(false);
+
+ assertSame(MotionFileType.VMD, converter.getInTypes());
+ assertSame(MotionFileType.XML_110820, converter.getOutTypes());
+ assertEquals("\n", converter.getNewline());
+ assertNull(converter.getGenerator());
+ assertFalse(converter.isQuaterniomMode());
+
+ assertVmd2Xml(THISCLASS, "euler.vmd", "euler.xml", converter);
+
+ return;
+ }
+
+ @Test
+ public void xml2vmd() throws Exception{
+ System.out.println("xml2vmd");
+ assertXml2Vmd(THISCLASS, "euler.xml", "euler.vmd");
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package testdata.vmd110820.newvmd;
+
+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 NewVmdTest {
+
+ static Class<?> THISCLASS = NewVmdTest.class;
+
+ public NewVmdTest() {
+ 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 vmd2xml() throws Exception{
+ System.out.println("vmd2xml");
+ assertVmd2Xml(THISCLASS, "newvmd.vmd", "newvmd.xml");
+ return;
+ }
+
+}
--- /dev/null
+/*
+ */
+
+package testdata.vmd110820.xml;
+
+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 XmlTest {
+
+ static Class<?> THISCLASS = XmlTest.class;
+
+ public XmlTest() {
+ 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 xml2vmd() throws Exception{
+ System.out.println("xml2vmd");
+ assertXml2Vmd(THISCLASS, "namespace.xml", "onlyBone.vmd");
+ return;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ MikuMikuDance
+ motion-data(*.vmd) on XML
+-->
+
+
+<vmdMotion
+ xmlns="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820
+ http://mikutoga.sourceforge.jp/xml/xsd/vmdxml-110820.xsd"
+ version="110820"
+>
+
+<!-- ダミーボーン -->
+<modelName name="ダミーボーン" />
+
+<!--
+ bone-rotation has Quaternion parameters [boneRotQuat]
+ or YXZ-Euler angles [boneRotEyxz].
+ Quaternion form is strongly recommended if you are data-exchanging.
+-->
+<!--
+ motion-interpolation is described with Bezier-cubic-curve.
+ implicit bezier curve point : P0=(0,0) P3=(127,127)
+ defLinear : MMD default linear curve. P1=(20,20) P2=(107,107) [DEFAULT]
+ defEaseInOut : MMD default ease-in-out curve. P1=(64,0) P2=(64,127)
+-->
+<boneMotionSequence>
+
+ <!-- ボーン01 --> <!-- Perhaps : [bone01] -->
+ <bonePart name="ボーン01" >
+
+ <boneMotion frame="0" >
+ <boneRotEyxz
+ xDeg="20.0"
+ yDeg="20.0"
+ zDeg="20.0"
+ />
+ </boneMotion>
+
+ </bonePart>
+
+</boneMotionSequence>
+
+<morphSequence>
+</morphSequence>
+
+</vmdMotion>
+
+<!-- EOF -->
--- /dev/null
+[UTF8 Japanese]
+
+
+MikuMikuDance Ver7.39m および Ver7.39x64 あたりを境に
+新仕様となったVMDファイル。
+
+・マジックヘッダ部の末尾5byteが全て0x00で埋められるようになった。
+・ボーン補間情報で4回繰り返されるベジェ曲線情報間の隙間パッドの先頭が
+ 0x01ではなく0x00になった。
+
+※ XMLの改行コードはLF。ジェネレータ名は非表示。
+
+
+- newvmd.vmd Ver7.39mで生成されたモーションデータ。
+- newvmd.xml あるべき姿のXMLファイル。
+
+
+
+-- EOF --
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ MikuMikuDance
+ motion-data(*.vmd) on XML
+-->
+
+
+<vmdMotion
+ xmlns="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820
+ http://mikutoga.sourceforge.jp/xml/xsd/vmdxml-110820.xsd"
+ version="110820"
+>
+
+<!-- ダミーボーン -->
+<modelName name="ダミーボーン" />
+
+<!--
+ bone-rotation has Quaternion parameters [boneRotQuat]
+ or YXZ-Euler angles [boneRotEyxz].
+ Quaternion form is strongly recommended if you are data-exchanging.
+-->
+<!--
+ motion-interpolation is described with Bezier-cubic-curve.
+ implicit bezier curve point : P0=(0,0) P3=(127,127)
+ defLinear : MMD default linear curve. P1=(20,20) P2=(107,107) [DEFAULT]
+ defEaseInOut : MMD default ease-in-out curve. P1=(64,0) P2=(64,127)
+-->
+<boneMotionSequence>
+
+ <!-- ボーン01 --> <!-- Perhaps : [bone01] -->
+ <bonePart name="ボーン01" >
+
+ <boneMotion frame="0" >
+ <boneRotQuat
+ qx="0.0"
+ qy="0.0"
+ qz="0.0"
+ qw="1.0"
+ />
+ </boneMotion>
+
+ </bonePart>
+
+</boneMotionSequence>
+
+<morphSequence>
+</morphSequence>
+
+</vmdMotion>
+
+<!-- EOF -->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<testns:vmdMotion
+ xmlns:testns="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/110820
+ http://mikutoga.sourceforge.jp/xml/xsd/vmdxml-110820.xsd"
+ version="110820"
+>
+
+<testns:modelName name="model" />
+
+<testns:boneMotionSequence>
+
+ <testns:bonePart name="センター" >
+
+ <testns:boneMotion frame="0" >
+ <testns:boneRotQuat
+ qx="0.0"
+ qy="0.0"
+ qz="0.0"
+ qw="1.0"
+ />
+ </testns:boneMotion>
+
+ </testns:bonePart>
+
+</testns:boneMotionSequence>
+
+<testns:morphSequence>
+</testns:morphSequence>
+
+</testns:vmdMotion>
+
+<!-- EOF -->