・ベジェ補間パラメータ冗長部がMMDの版により異なるため、検査をやめた。
・プロセス終了コードの変更。
・DOMからSAXへの移行。
+ ・MikuMikuDance Ver7.40以降の新VMDファイルフォーマットに対応
1.101.2 (2011-08-25)
<dependency>
<groupId>jp.sourceforge.mikutoga</groupId>
<artifactId>togagem</artifactId>
- <version>2.102.5-SNAPSHOT</version>
+ <version>2.102.7-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
--- /dev/null
+/*
+ * IK ON/OFF switch
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model;
+
+import java.text.MessageFormat;
+
+/**
+ * IK ON/OFF の管理を行う。
+ */
+public class IkSwitch {
+
+ private static final String MSG_TXT =
+ "IKbone {0} : {1}";
+
+
+ private String boneName = "";
+ private boolean valid = true;
+
+
+ /**
+ * コンストラクタ。
+ */
+ public IkSwitch(){
+ super();
+ return;
+ }
+
+
+ /**
+ * ボーン名を返す。
+ * @return ボーン名
+ */
+ public String getBoneName(){
+ return this.boneName;
+ }
+
+ /**
+ * ボーン名を設定する。
+ * @param boneNameArg ボーン名
+ * @throws NullPointerException 引数がnull
+ */
+ public void setBoneName(String boneNameArg) throws NullPointerException{
+ if(boneNameArg == null) throw new NullPointerException();
+ this.boneName = boneNameArg;
+ return;
+ }
+
+ /**
+ * IK処理が有効か否か返す。
+ * @return 有効ならtrue
+ */
+ public boolean isValid(){
+ return this.valid;
+ }
+
+ /**
+ * IK処理が有効か否か設定する。
+ * @param validArg 有効ならtrue
+ */
+ public void setValid(boolean validArg){
+ this.valid = validArg;
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ String msg;
+ msg = MessageFormat.format(MSG_TXT, this.boneName, this.valid);
+ return msg;
+ }
+
+}
--- /dev/null
+/*
+ * model presence switch
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jp.sfjp.mikutoga.vmd.AbstractNumbered;
+
+/**
+ * フレーム番号が付けられた各種モーションフラグの管理を行う。
+ */
+public class NumberedVmdFlag
+ extends AbstractNumbered
+ implements Iterable<IkSwitch> {
+
+ private static final String MSG_TXT =
+ "#{0} model precense : {1}";
+
+
+ private boolean shown = true;
+ private List<IkSwitch> ikSwList = new LinkedList<IkSwitch>();
+
+
+ /**
+ * コンストラクタ。
+ * <p>モデル表示ありの状態で初期化される。
+ */
+ public NumberedVmdFlag(){
+ super();
+ return;
+ }
+
+
+ /**
+ * モデルを表示するか否か返す。
+ * @return 表示するならtrue
+ */
+ public boolean isModelShown(){
+ return this.shown;
+ }
+
+ /**
+ * モデルを表示するか否か設定する。
+ * @param shownArg 表示するならtrue
+ */
+ public void setModelShown(boolean shownArg){
+ this.shown = shownArg;
+ return;
+ }
+
+ /**
+ * 個別IKボーンフラグのリストを返す。
+ * @return 個別IKボーンフラグのリスト
+ */
+ public List<IkSwitch> getIkSwitchList(){
+ return this.ikSwList;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public Iterator<IkSwitch> iterator(){
+ return this.ikSwList.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ String msg;
+ msg = MessageFormat.format(MSG_TXT, getFrameNumber(), this.shown);
+
+ StringBuilder submsg = new StringBuilder(msg);
+ for(IkSwitch sw : this.ikSwList){
+ submsg.append('\n').append("\u0020").append(sw.toString());
+ }
+
+ return submsg.toString();
+ }
+
+}
public class VmdMotion {
private static final String MSG_TXT =
- "model name : {0}\n"
- + "bone#{1} morph#{2} camera#{3} luminous#{4} shadow#{5}";
+ "model name : {0}\n"
+ + "bone#{1} morph#{2} camera#{3} luminous#{4} shadow#{5} flag#{6}";
private String modelName = VmdUniq.MODELNAME_STAGEACT;
private final Map<String, List<BoneMotion>> bonePartMap;
private final Map<String, List<MorphMotion>> morphPartMap;
- private final List<CameraMotion> cameraMotionList;
- private final List<LuminousMotion> luminousMotionList;
- private final List<ShadowMotion> shadowMotionList;
+ private final List<CameraMotion> cameraMotionList;
+ private final List<LuminousMotion> luminousMotionList;
+ private final List<ShadowMotion> shadowMotionList;
+ private final List<NumberedVmdFlag> flagList;
/**
this.cameraMotionList = new LinkedList<CameraMotion>();
this.luminousMotionList = new LinkedList<LuminousMotion>();
this.shadowMotionList = new LinkedList<ShadowMotion>();
+ this.flagList = new LinkedList<NumberedVmdFlag>();
return;
}
}
/**
+ * 各種フレーム番号付きフラグのリストを返す。
+ * @return フレーム番号付きフラグのリスト
+ */
+ public List<NumberedVmdFlag> getNumberedFlagList(){
+ return this.flagList;
+ }
+
+ /**
* ボーンモーションを追加する。
* 追加順は保持される。
* @param motion ボーンモーション
Collections.sort(this.cameraMotionList, FrameNumbered.COMPARATOR);
Collections.sort(this.luminousMotionList, FrameNumbered.COMPARATOR);
Collections.sort(this.shadowMotionList, FrameNumbered.COMPARATOR);
+ Collections.sort(this.flagList, FrameNumbered.COMPARATOR);
return;
}
int cameraNo = this.cameraMotionList .size();
int luminousNo = this.luminousMotionList.size();
int shadowNo = this.shadowMotionList .size();
+ int flagNo = this.flagList .size();
String msg;
msg = MessageFormat.format(MSG_TXT,
this.modelName,
- boneNo, morphNo, cameraNo, luminousNo, shadowNo );
+ boneNo, morphNo, cameraNo, luminousNo, shadowNo, flagNo );
return msg;
}
--- /dev/null
+/*
+ * boolean information exporter
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.binio;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import jp.sfjp.mikutoga.bin.export.BinaryExporter;
+import jp.sfjp.mikutoga.bin.export.IllegalTextExportException;
+import jp.sfjp.mikutoga.vmd.VmdConst;
+import jp.sfjp.mikutoga.vmd.model.IkSwitch;
+import jp.sfjp.mikutoga.vmd.model.NumberedVmdFlag;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+
+/**
+ * フラグ情報のエクスポーター。
+ * <p>MikuMikuDance Ver7.40以降でサポート
+ */
+class BoolExporter extends BinaryExporter{
+
+ private static final byte[] FDFILLER =
+ { (byte)0x00, (byte)0xfd };
+
+
+ /**
+ * コンストラクタ。
+ * @param stream 出力ストリーム
+ */
+ BoolExporter(OutputStream stream){
+ super(stream);
+ return;
+ }
+
+
+ /**
+ * フラグ情報を出力する。
+ * @param motion モーションデータ
+ * @throws IOException 出力エラー
+ * @throws IllegalTextExportException 不正な文字列が指定された。
+ */
+ void dumpNumberedFlagMotion(VmdMotion motion)
+ throws IOException, IllegalTextExportException {
+ List<NumberedVmdFlag> list = motion.getNumberedFlagList();
+
+ if(list.isEmpty()) return;
+
+ int count = list.size();
+ dumpLeInt(count);
+
+ for(NumberedVmdFlag flag : list){
+ int frameNo = flag.getFrameNumber();
+ dumpLeInt(frameNo);
+
+ byte showModel;
+ if(flag.isModelShown()) showModel = 0x01;
+ else showModel = 0x00;
+ dumpByte(showModel);
+
+ dumpIkSwitch(flag);
+ }
+
+
+ return;
+ }
+
+ /**
+ * IK有効フラグを出力する。
+ * @param flag フラグ情報
+ * @throws IOException 出力エラー
+ * @throws IllegalTextExportException 不正な文字列が指定された。
+ */
+ private void dumpIkSwitch(NumberedVmdFlag flag)
+ throws IOException, IllegalTextExportException {
+ List<IkSwitch> swList = flag.getIkSwitchList();
+ int swNo = swList.size();
+ dumpLeInt(swNo);
+
+ for(IkSwitch ikSwitch : swList){
+ String boneName = ikSwitch.getBoneName();
+ dumpFixedW31j(boneName, VmdConst.IKSWBONENAME_MAX, FDFILLER);
+
+ byte ikValid;
+ if(ikSwitch.isValid()) ikValid = 0x01;
+ else ikValid = 0x00;
+ dumpByte(ikValid);
+ }
+
+ return;
+ }
+
+}
--- /dev/null
+/*
+ * boolean information builder
+ *
+ * License : The MIT License
+ * Copyright(c) 2013 MikuToga Partners
+ */
+
+package jp.sfjp.mikutoga.vmd.model.binio;
+
+import java.util.List;
+import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
+import jp.sfjp.mikutoga.bin.parser.ParseStage;
+import jp.sfjp.mikutoga.vmd.model.IkSwitch;
+import jp.sfjp.mikutoga.vmd.model.NumberedVmdFlag;
+import jp.sfjp.mikutoga.vmd.model.VmdMotion;
+import jp.sfjp.mikutoga.vmd.parser.VmdBoolHandler;
+
+/**
+ * フラグ情報のビルダ。
+ * <p>MikuMikuDance Ver7.40以降でサポート
+ */
+public class BoolLoader implements VmdBoolHandler{
+
+ private final List<NumberedVmdFlag> flagList;
+
+ private NumberedVmdFlag currentFlag;
+ private IkSwitch currentSwitch;
+
+ /**
+ * コンストラクタ。
+ * @param vmdMotion モーションデータの格納先。
+ */
+ BoolLoader(VmdMotion vmdMotion){
+ super();
+ this.flagList = vmdMotion.getNumberedFlagList();
+ return;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @param stage {@inheritDoc}
+ * @param loops {@inheritDoc}
+ * @throws MmdFormatException {@inheritDoc}
+ */
+ @Override
+ public void loopStart(ParseStage stage, int loops)
+ throws MmdFormatException{
+ if(stage == VmdBoolHandler.MODELSIGHT_LIST){
+ this.currentFlag = new NumberedVmdFlag();
+ }else if(stage == VmdBoolHandler.IKSW_LIST){
+ this.currentSwitch = new IkSwitch();
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param stage {@inheritDoc}
+ * @throws MmdFormatException {@inheritDoc}
+ */
+ @Override
+ public void loopNext(ParseStage stage)
+ throws MmdFormatException{
+ if(stage == VmdBoolHandler.MODELSIGHT_LIST){
+ this.flagList.add(this.currentFlag);
+ this.currentFlag = new NumberedVmdFlag();
+ }else if(stage == VmdBoolHandler.IKSW_LIST){
+ List<IkSwitch> swList = this.currentFlag.getIkSwitchList();
+ swList.add(this.currentSwitch);
+ this.currentSwitch = new IkSwitch();
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param stage {@inheritDoc}
+ * @throws MmdFormatException {@inheritDoc}
+ */
+ @Override
+ public void loopEnd(ParseStage stage)
+ throws MmdFormatException{
+ if(stage == VmdBoolHandler.MODELSIGHT_LIST){
+ this.currentFlag = null;
+ }else if(stage == VmdBoolHandler.IKSW_LIST){
+ this.currentSwitch = null;
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param show {@inheritDoc}
+ * @param keyFrameNo {@inheritDoc}
+ * @throws MmdFormatException {@inheritDoc}
+ */
+ @Override
+ public void vmdModelSight(boolean show, int keyFrameNo)
+ throws MmdFormatException {
+ this.currentFlag.setModelShown(show);
+ this.currentFlag.setFrameNumber(keyFrameNo);
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param boneName {@inheritDoc}
+ * @param validIk {@inheritDoc}
+ * @param keyFrameNo {@inheritDoc}
+ * @throws MmdFormatException {@inheritDoc}
+ */
+ @Override
+ public void vmdIkSwitch(String boneName,
+ boolean validIk,
+ int keyFrameNo )
+ throws MmdFormatException {
+ this.currentSwitch.setBoneName(boneName);
+ this.currentSwitch.setValid(validIk);
+ return;
+ }
+
+}
private BasicExporter basicExporter = null;
private CameraExporter cameraExporter = null;
private LightingExporter lightingExporter = null;
+ private BoolExporter boolExporter = null;
/**
this.basicExporter = new BasicExporter(ostream);
this.cameraExporter = new CameraExporter(ostream);
this.lightingExporter = new LightingExporter(ostream);
+ this.boolExporter = new BoolExporter(ostream);
try{
dumpVmdMotionImpl(motion);
this.lightingExporter.dumpLuminousMotion(motion);
this.lightingExporter.dumpShadowMotion(motion);
+ if(motion.getNumberedFlagList().isEmpty()) return;
+ try{
+ this.boolExporter.dumpNumberedFlagMotion(motion);
+ }catch(IllegalTextExportException e){
+ throw new IllegalVmdDataException(e);
+ }
+
return;
}
private boolean loaded = false;
private boolean hasMoreData = true;
- private boolean ignoreName = true;
private boolean redundantCheck = false;
}
/**
- * カメラ・ライティングデータのパースを試みるか否かの判断で、
- * 特殊モデル名判定を無視するか否か設定する。
- * デフォルトではモデル名を無視。
- * <p>※MMDVer7.30前後のVMD出力不具合を回避したい場合は、
- * オフにするとパースに成功する場合がある。
- * @param mode モデル名を無視してパースを強行するならtrue
- */
- public void setIgnoreName(boolean mode){
- this.ignoreName = mode;
- return;
- }
-
- /**
* ボーンモーション補間情報冗長部のチェックを行うか否か設定する。
* デフォルトではチェックを行わない。
* <p>※MMDVer7.30前後のVMD出力不具合を回避したい場合は、
* オフにするとパースに成功する場合がある。
+ * <p>※MMD Ver7.39x64以降はチェック回避必須。
* @param mode チェックさせたければtrue
*/
public void setRedundantCheck(boolean mode){
VmdParser parser = new VmdParser(source);
- parser.setIgnoreName(this.ignoreName);
parser.setRedundantCheck(this.redundantCheck);
BasicLoader basicBuilder = new BasicLoader(motion);
CameraLoader cameraBuilder = new CameraLoader(motion);
LightingLoader lightingBuilder = new LightingLoader(motion);
+ BoolLoader boolBuilder = new BoolLoader(motion);
parser.setBasicHandler(basicBuilder);
parser.setCameraHandler(cameraBuilder);
parser.setLightingHandler(lightingBuilder);
+ parser.setBoolHandler(boolBuilder);
try{
parser.parseVmd();
/**
* XSD各種型のSAX属性値をJavaプリミティブ型へ変換する。
*/
-final class SaxXsdUtil {
+public final class SaxAttr {
/**
* 隠しコンストラクタ。
*/
- private SaxXsdUtil(){
+ private SaxAttr(){
assert false;
throw new AssertionError();
}
/**
+ * 属性名に対応する属性値があるか否か判定する。
+ * @param attr 属性群
+ * @param name 属性名
+ * @return 属性名に対応する属性値がある場合はtrue
+ */
+ public static boolean hasAttr(Attributes attr, String name){
+ if(attr.getValue(name) == null) return false;
+ return true;
+ }
+
+ /**
* xsd:string型属性値の読み込み。
* @param attr 属性群
* @param name 属性名
* @return 属性値。該当する属性が無ければnull。
*/
- static String getStringAttr(Attributes attr, String name){
+ public static String getStringAttr(Attributes attr, String name){
String attrVal = attr.getValue(name);
return attrVal;
}
* @return 属性値。
* @throws IllegalArgumentException boolean型表記ではない
*/
- static boolean getBooleanAttr(Attributes attr, String name)
+ public static boolean getBooleanAttr(Attributes attr, String name)
throws IllegalArgumentException{
String attrVal = attr.getValue(name);
boolean bVal;
* @return 属性値。
* @throws IllegalArgumentException boolean型表記ではない
*/
- static boolean getBooleanAttr(Attributes attr, String name, boolean def)
+ public static boolean getBooleanAttr(Attributes attr,
+ String name,
+ boolean def )
throws IllegalArgumentException{
String attrVal = attr.getValue(name);
if(attrVal == null) return def;
* @return 属性値。
* @throws NumberFormatException byte型表記ではない
*/
- static byte getByteAttr(Attributes attr, String name)
+ public static byte getByteAttr(Attributes attr, String name)
throws NumberFormatException{
String attrVal = attr.getValue(name);
byte bVal;
* @return 属性値。
* @throws NumberFormatException float型表記ではない
*/
- static float getFloatAttr(Attributes attr, String name)
+ public static float getFloatAttr(Attributes attr, String name)
throws NumberFormatException {
String attrVal = attr.getValue(name);
float fVal;
* @return 属性値。
* @throws NumberFormatException int型表記ではない
*/
- static int getIntAttr(Attributes attr, String name)
+ public static int getIntAttr(Attributes attr, String name)
throws NumberFormatException {
String attrVal = attr.getValue(name);
int iVal;
private void openCameraMotion(Attributes attr){
this.currentCamera = new CameraMotion();
- int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME);
this.currentCamera.setFrameNumber(frameNo);
boolean hasPerspective =
- SaxXsdUtil.getBooleanAttr(attr,
- XmlAttr.ATTR_HAS_PERSPECTIVE,
- true );
+ SaxAttr.getBooleanAttr(attr,
+ XmlAttr.ATTR_HAS_PERSPECTIVE,
+ true );
this.currentCamera.setPerspectiveMode(hasPerspective);
return;
private void openCameraTarget(Attributes attr){
MkPos3D targetPos = this.currentCamera.getCameraTarget();
- float xPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_POS);
- float yPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_POS);
- float zPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_POS);
+ float xPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_POS);
+ float yPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_POS);
+ float zPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_POS);
targetPos.setPosition(xPos, yPos, zPos);
CameraRotation cameraRotation =
this.currentCamera.getCameraRotation();
- float latitude = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_RAD);
- float longitude = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_RAD);
- float roll = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_RAD);
+ float latitude = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_RAD);
+ float longitude = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_RAD);
+ float roll = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_RAD);
cameraRotation.setLatitude(latitude);
cameraRotation.setLongitude(longitude);
* @param attr 属性群
*/
private void openCameraRange(Attributes attr){
- float range = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RANGE);
+ float range = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_RANGE);
this.currentCamera.setRange(range);
BezierParam bez = this.currentCamera.getIntpltRange();
* @param attr 属性群
*/
private void openProjection(Attributes attr){
- int vertDeg = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_VERT_DEG);
+ int vertDeg = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_VERT_DEG);
this.currentCamera.setProjectionAngle(vertDeg);
BezierParam bez = this.currentCamera.getIntpltProjection();
private void openLumiAct(Attributes attr){
this.currentLuminous = new LuminousMotion();
- int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME);
this.currentLuminous.setFrameNumber(frameNo);
return;
private void openLumiColor(Attributes attr){
LuminousColor color = this.currentLuminous.getColor();
- float rCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_R_COL);
- float gCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_G_COL);
- float bCol = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_B_COL);
+ float rCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_R_COL);
+ float gCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_G_COL);
+ float bCol = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_B_COL);
color.setColR(rCol);
color.setColG(gCol);
private void openLumiDirection(Attributes attr){
MkVec3D vec = this.currentLuminous.getDirection();
- float xVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_VEC);
- float yVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_VEC);
- float zVec = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_VEC);
+ float xVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_VEC);
+ float yVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_VEC);
+ float zVec = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_VEC);
vec.setXVal(xVec);
vec.setYVal(yVec);
private void openShadowAct(Attributes attr){
ShadowMotion shadowMotion = new ShadowMotion();
- int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME);
shadowMotion.setFrameNumber(frameNo);
float rawParam =
- SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_RAW_PARAM);
+ SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_RAW_PARAM);
shadowMotion.setRawScopeParam(rawParam);
String modeAttr =
- SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_MODE);
+ SaxAttr.getStringAttr(attr, XmlAttr.ATTR_MODE);
ShadowMode mode = ShadowMode.valueOf(modeAttr);
shadowMotion.setShadowMode(mode);
* @param attr 属性群
*/
private void openBonePart(Attributes attr){
- this.boneName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ this.boneName = SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME);
return;
}
this.boneMotion = new BoneMotion();
this.boneMotion.setBoneName(this.boneName);
- int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME);
this.boneMotion.setFrameNumber(frameNo);
return;
private void openBonePosition(Attributes attr){
MkPos3D position = this.boneMotion.getPosition();
- float xPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_POS);
- float yPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_POS);
- float zPos = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_POS);
+ float xPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_POS);
+ float yPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_POS);
+ float zPos = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_POS);
position.setXpos(xPos);
position.setYpos(yPos);
private void openBoneRotQuat(Attributes attr){
MkQuat rotation = this.boneMotion.getRotation();
- float qx = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QX);
- float qy = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QY);
- float qz = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QZ);
- float qw = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_QW);
+ float qx = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QX);
+ float qy = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QY);
+ float qz = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QZ);
+ float qw = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_QW);
rotation.setQ1(qx);
rotation.setQ2(qy);
private void openBoneRotEyxz(Attributes attr){
MkQuat rotation = this.boneMotion.getRotation();
- float xDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_X_DEG);
- float yDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Y_DEG);
- float zDeg = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_Z_DEG);
+ float xDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_X_DEG);
+ float yDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Y_DEG);
+ float zDeg = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_Z_DEG);
float xRad = (float)StrictMath.toRadians(xDeg);
float yRad = (float)StrictMath.toRadians(yDeg);
* @param attr 属性群
*/
private void openMorphPart(Attributes attr){
- this.morphName = SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ this.morphName = SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME);
return;
}
private void openMorphMotion(Attributes attr){
MorphMotion morphMotion = new MorphMotion();
- int frameNo = SaxXsdUtil.getIntAttr(attr, XmlAttr.ATTR_FRAME);
- float flex = SaxXsdUtil.getFloatAttr(attr, XmlAttr.ATTR_FLEX);
+ int frameNo = SaxAttr.getIntAttr(attr, XmlAttr.ATTR_FRAME);
+ float flex = SaxAttr.getFloatAttr(attr, XmlAttr.ATTR_FLEX);
morphMotion.setMorphName(this.morphName);
morphMotion.setFrameNumber(frameNo);
* @param attr 属性群
*/
protected void openBezier(Attributes attr){
- byte p1x = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P1X);
- byte p1y = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P1Y);
- byte p2x = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P2X);
- byte p2y = SaxXsdUtil.getByteAttr(attr, XmlAttr.ATTR_P2Y);
+ byte p1x = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P1X);
+ byte p1y = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P1Y);
+ byte p2x = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P2X);
+ byte p2y = SaxAttr.getByteAttr(attr, XmlAttr.ATTR_P2Y);
putBezier(p1x, p1y, p2x, p2y);
if(tag == VmdTag.MODEL_NAME){
String modelName =
- SaxXsdUtil.getStringAttr(attr, XmlAttr.ATTR_NAME);
+ SaxAttr.getStringAttr(attr, XmlAttr.ATTR_NAME);
this.vmdMotion.setModelName(modelName);
return;
}
throws IOException, MmdFormatException{
VmdLoader loader = new VmdLoader();
- loader.setIgnoreName(true);
loader.setRedundantCheck(false);
VmdMotion motion = loader.load(is);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ MikuMikuDance
+ motion-data(*.vmd) on XML
+ schema definition
+
+ License : The MIT License
+ Copyright(c) 2013 MikuToga Partners
+-->
+
+
+<!DOCTYPE xsd:schema [
+ <!ENTITY schemaVer "130609A" >
+ <!ENTITY schemaNS "http://mikutoga.sourceforge.jp/xml/ns/vmdxml/130609A" >
+]>
+
+
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
+ targetNamespace="&schemaNS;"
+ xmlns:tns ="&schemaNS;"
+
+ elementFormDefault="qualified"
+ version="&schemaVer;"
+>
+
+ <xsd:annotation>
+ <xsd:documentation>
+ MikuMikuDance motion-data(*.vmd) on XML.
+ License : The MIT License
+ Copyright(c) 2013 MikuToga Partners
+ </xsd:documentation>
+ </xsd:annotation>
+
+
+ <!-- ROOT element for motion -->
+ <xsd:element name="vmdMotion" >
+ <xsd:annotation>
+ <xsd:documentation>
+ Root element.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:meta"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:choice>
+ <xsd:sequence> <!-- model motion -->
+ <xsd:element ref="tns:modelName" />
+ <xsd:element ref="tns:boneMotionSequence" />
+ <xsd:element ref="tns:morphSequence" />
+ <xsd:element ref="tns:flagSequence" />
+ </xsd:sequence>
+ <xsd:sequence> <!-- stage act -->
+ <xsd:element ref="tns:cameraSequence" />
+ <xsd:element ref="tns:luminousSequence" />
+ <xsd:element ref="tns:shadowSequence" />
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute
+ name="version"
+ type="xsd:token"
+ use="required"
+ fixed="&schemaVer;" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:simpleType name="FrameNo" >
+ <xsd:annotation>
+ <xsd:documentation>
+ frame No.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:int" >
+<!--
+ <xsd:minInclusive value="0" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="MorphFlex" >
+ <xsd:annotation>
+ <xsd:documentation>
+ morph flexible value. [0.0-1.0]
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:float" >
+ <xsd:minInclusive value="-0.0" />
+<!--
+ <xsd:maxInclusive value="1.0" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="ProjectionAngle" >
+ <xsd:annotation>
+ <xsd:documentation>
+ screen-projection angle(degree).
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:int" >
+<!--
+ <xsd:minInclusive value="-0" />
+ <xsd:maxInclusive value="+180" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="ColorComponent" >
+ <xsd:annotation>
+ <xsd:documentation>
+ color component value.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:float" >
+<!--
+ <xsd:minInclusive value="-0.0" />
+ <xsd:maxInclusive value="1.0" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="DirVecComponent" >
+ <xsd:annotation>
+ <xsd:documentation>
+ direction vector component value.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:float" >
+<!--
+ <xsd:minInclusive value="-1.0" />
+ <xsd:maxInclusive value="+1.0" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="ShadowType" >
+ <xsd:annotation>
+ <xsd:documentation>
+ type of shadow
+ + NONE : no self-shadow
+ + MODE_1 : reduce shadow-quality suddenly at range
+ + MODE_2 : reduce shadow-quality gradually with range
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:string" >
+ <xsd:enumeration value="NONE" />
+ <xsd:enumeration value="MODE_1" />
+ <xsd:enumeration value="MODE_2" />
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="ShadowRawParam" >
+ <xsd:annotation>
+ <xsd:documentation>
+ 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
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:float" >
+<!--
+ <xsd:minInclusive value="-0.0" />
+ <xsd:maxInclusive value="0.1" />
+-->
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="BezPt" >
+ <xsd:annotation>
+ <xsd:documentation>
+ Bezier points coordinates value. [XY:0-127]
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:restriction base="xsd:byte" >
+ <xsd:minInclusive value= "0" />
+ <xsd:maxInclusive value="127" />
+ </xsd:restriction>
+
+ </xsd:simpleType>
+
+
+ <xsd:complexType name="FrameNumbered" >
+ <xsd:annotation>
+ <xsd:documentation>
+ frame numbered type.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:attribute name="frame" type="tns:FrameNo" use="required" />
+
+ </xsd:complexType>
+
+
+ <xsd:complexType name="BezParam" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bezier cubic curve parameters.
+ p0=(0, 0) p3=(127, 127) [implicit points]
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:attribute name="p1x" type="tns:BezPt" use="optional" />
+ <xsd:attribute name="p1y" type="tns:BezPt" use="optional" />
+ <xsd:attribute name="p2x" type="tns:BezPt" use="optional" />
+ <xsd:attribute name="p2y" type="tns:BezPt" use="optional" />
+
+ </xsd:complexType>
+
+
+ <xsd:element name="bezier" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bezier cubic curve parameters.
+ p0=(0, 0) p3=(127, 127) [implicit points]
+ P1 and P2 points are required.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:restriction base="tns:BezParam" >
+ <xsd:attribute name="p1x" type="tns:BezPt" use="required" />
+ <xsd:attribute name="p1y" type="tns:BezPt" use="required" />
+ <xsd:attribute name="p2x" type="tns:BezPt" use="required" />
+ <xsd:attribute name="p2y" type="tns:BezPt" use="required" />
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="defLinear" >
+ <xsd:annotation>
+ <xsd:documentation>
+ default linear bezier curve.
+ p0=(0, 0) p1=(20, 20) p2=(107, 107) p3=(127, 127)
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:restriction base="tns:BezParam" >
+ <xsd:attribute name="p1x" use="prohibited" fixed= "20" />
+ <xsd:attribute name="p1y" use="prohibited" fixed= "20" />
+ <xsd:attribute name="p2x" use="prohibited" fixed="107" />
+ <xsd:attribute name="p2y" use="prohibited" fixed="107" />
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="defEaseInOut" >
+ <xsd:annotation>
+ <xsd:documentation>
+ default ease-in-out bezier curve.
+ p0=(0, 0) p1=(64, 0) p2=(64, 127) p3=(127, 127)
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:restriction base="tns:BezParam" >
+ <xsd:attribute name="p1x" use="prohibited" fixed= "64" />
+ <xsd:attribute name="p1y" use="prohibited" fixed= "0" />
+ <xsd:attribute name="p2x" use="prohibited" fixed= "64" />
+ <xsd:attribute name="p2y" use="prohibited" fixed="127" />
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:complexType name="InterpolationSingle" >
+ <xsd:annotation>
+ <xsd:documentation>
+ has single interpolation curve.
+ If omitted, it means default linear curve.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:choice minOccurs="0" >
+ <xsd:element ref="tns:bezier" />
+ <xsd:element ref="tns:defLinear" />
+ <xsd:element ref="tns:defEaseInOut" />
+ </xsd:choice>
+
+ </xsd:complexType>
+
+
+ <xsd:complexType name="PosWithInterpolation" >
+ <xsd:annotation>
+ <xsd:documentation>
+ 3D-position with XYZ-interpolation curve.
+ If omitted, it means default linear curve *3 [XYZ].
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:sequence minOccurs="0" maxOccurs="1" >
+ <xsd:choice minOccurs="3" maxOccurs="3" >
+ <xsd:element ref="tns:bezier" />
+ <xsd:element ref="tns:defLinear" />
+ <xsd:element ref="tns:defEaseInOut" />
+ </xsd:choice>
+ </xsd:sequence>
+
+ <xsd:attribute name="xPos" type="xsd:float" use="required" />
+ <xsd:attribute name="yPos" type="xsd:float" use="required" />
+ <xsd:attribute name="zPos" type="xsd:float" use="required" />
+
+ </xsd:complexType>
+
+
+ <xsd:element name="meta" >
+ <xsd:annotation>
+ <xsd:documentation>
+ Meta-information of motion.
+ Use free.
+ but, some meta-name has recommended usage.
+ + "generator" (Generator application name)
+ + "siteURL" (about motion creator)
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:attribute
+ name="name"
+ type="xsd:NCName"
+ use="required" />
+ <xsd:attribute
+ name="content"
+ type="xsd:string"
+ use="required" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="modelName" >
+ <xsd:annotation>
+ <xsd:documentation>
+ name of motion-model.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:attribute
+ name="name"
+ type="xsd:string"
+ use="required" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="boneMotionSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone motion data sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:bonePart"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="BoneName" >
+ <xsd:selector xpath="./tns:bonePart" />
+ <xsd:field xpath="@name" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="bonePart" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone motion data group by bone-name.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:boneMotion"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+
+ <xsd:attribute
+ name="name"
+ type="xsd:string"
+ use="required" />
+ </xsd:complexType>
+
+ <xsd:unique name="BoneFrameNo" >
+ <xsd:selector xpath="./tns:boneMotion" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="boneMotion" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone motion data.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:bonePosition"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:choice>
+ <xsd:element ref="tns:boneRotQuat" />
+ <xsd:element ref="tns:boneRotEyxz" />
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="bonePosition" type="tns:PosWithInterpolation" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone position.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ </xsd:element>
+
+
+ <xsd:element name="boneRotQuat" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone rotation. (Quaternion parameters)
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:InterpolationSingle" >
+ <xsd:attribute name="qx" type="xsd:float" use="required" />
+ <xsd:attribute name="qy" type="xsd:float" use="required" />
+ <xsd:attribute name="qz" type="xsd:float" use="required" />
+ <xsd:attribute name="qw" type="xsd:float" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="boneRotEyxz" >
+ <xsd:annotation>
+ <xsd:documentation>
+ bone rotation. (YXZ-Euler rotation parameters)
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:InterpolationSingle" >
+ <xsd:attribute name="xDeg" type="xsd:float" use="required" />
+ <xsd:attribute name="yDeg" type="xsd:float" use="required" />
+ <xsd:attribute name="zDeg" type="xsd:float" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="morphSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ morphing data sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:morphPart"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="MorphName" >
+ <xsd:selector xpath="./tns:morphPart" />
+ <xsd:field xpath="@name" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="morphPart" >
+ <xsd:annotation>
+ <xsd:documentation>
+ morphing data group by morph-name.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:morphMotion"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+
+ <xsd:attribute
+ name="name"
+ type="xsd:string"
+ use="required" />
+ </xsd:complexType>
+
+ <xsd:unique name="MorphFrameNo" >
+ <xsd:selector xpath="./tns:morphMotion" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="morphMotion" >
+ <xsd:annotation>
+ <xsd:documentation>
+ morphing data.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:attribute
+ name="flex"
+ type="tns:MorphFlex"
+ use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="cameraSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ camera sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:cameraMotion"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="CameraFrameNo" >
+ <xsd:selector xpath="./tns:cameraMotion" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="cameraMotion" >
+ <xsd:annotation>
+ <xsd:documentation>
+ camera data.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:sequence>
+ <xsd:element ref="tns:cameraTarget" />
+ <xsd:element ref="tns:cameraRotation" />
+ <xsd:element ref="tns:cameraRange" />
+ <xsd:element ref="tns:projection" />
+ </xsd:sequence>
+ <xsd:attribute
+ name="hasPerspective"
+ type="xsd:boolean"
+ use="optional"
+ default="true" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="cameraTarget" type="tns:PosWithInterpolation" >
+ <xsd:annotation>
+ <xsd:documentation>
+ camera target.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ </xsd:element>
+
+
+ <xsd:element name="cameraRotation" >
+ <xsd:annotation>
+ <xsd:documentation>
+ camera-rotation around camera-target
+ with polar-coordinates parameters.
+
+ xRad = -radian(UI_X) [latitude]
+ yRad = radian(UI_Y) [longitude]
+ zRad = radian(UI_Z) [roll]
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:InterpolationSingle" >
+ <xsd:attribute name="xRad" type="xsd:float" use="required" />
+ <xsd:attribute name="yRad" type="xsd:float" use="required" />
+ <xsd:attribute name="zRad" type="xsd:float" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="cameraRange" >
+ <xsd:annotation>
+ <xsd:documentation>
+ camera range.
+ sign was negated from UI_RANGE.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:InterpolationSingle" >
+ <xsd:attribute
+ name="range"
+ type="xsd:float"
+ use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="projection" >
+ <xsd:annotation>
+ <xsd:documentation>
+ projection data.
+ vertDeg : vertical screen-projection angle by degree.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:InterpolationSingle" >
+ <xsd:attribute
+ name="vertDeg"
+ type="tns:ProjectionAngle"
+ use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="luminousSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ luminous sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:luminousAct"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="LuminousFrameNo" >
+ <xsd:selector xpath="./tns:luminousAct" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="luminousAct" >
+ <xsd:annotation>
+ <xsd:documentation>
+ luminous data.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:sequence>
+ <xsd:element ref="tns:lumiColor" />
+ <xsd:element ref="tns:lumiDirection" />
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="lumiColor" >
+ <xsd:annotation>
+ <xsd:documentation>
+ luminous color by RGB color space.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:attribute
+ name="rCol"
+ type="tns:ColorComponent"
+ use="required" />
+ <xsd:attribute
+ name="gCol"
+ type="tns:ColorComponent"
+ use="required" />
+ <xsd:attribute
+ name="bCol"
+ type="tns:ColorComponent"
+ use="required" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="lumiDirection" >
+ <xsd:annotation>
+ <xsd:documentation>
+ luminous direction by vector.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:attribute
+ name="xVec"
+ type="tns:DirVecComponent"
+ use="required" />
+ <xsd:attribute
+ name="yVec"
+ type="tns:DirVecComponent"
+ use="required" />
+ <xsd:attribute
+ name="zVec"
+ type="tns:DirVecComponent"
+ use="required" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="shadowSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ shadow sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:shadowAct"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="ShadowFrameNo" >
+ <xsd:selector xpath="./tns:shadowAct" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="shadowAct" >
+ <xsd:annotation>
+ <xsd:documentation>
+ shadow data.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:attribute
+ name="mode"
+ type="tns:ShadowType"
+ use="required" />
+ <xsd:attribute
+ name="rawParam"
+ type="tns:ShadowRawParam"
+ use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+ <xsd:element name="flagSequence" >
+ <xsd:annotation>
+ <xsd:documentation>
+ numbered flag sequence.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:flagMotion"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:unique name="FlagFrameNo" >
+ <xsd:selector xpath="./tns:flagMotion" />
+ <xsd:field xpath="@frame" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="flagMotion" >
+ <xsd:annotation>
+ <xsd:documentation>
+ numbered motion flags.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="tns:FrameNumbered" >
+ <xsd:sequence>
+ <xsd:element
+ ref="tns:ikSwitch"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute
+ name="showModel"
+ type="xsd:boolean"
+ use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:unique name="IkBoneName" >
+ <xsd:selector xpath="./tns:ikSwitch" />
+ <xsd:field xpath="@name" />
+ </xsd:unique>
+
+ </xsd:element>
+
+
+ <xsd:element name="ikSwitch" >
+ <xsd:annotation>
+ <xsd:documentation>
+ IK ON/OFF switch for each IK-Bone.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType>
+ <xsd:attribute
+ name="name"
+ type="xsd:string"
+ use="required" />
+ <xsd:attribute
+ name="valid"
+ type="xsd:boolean"
+ use="required" />
+ </xsd:complexType>
+
+ </xsd:element>
+
+
+</xsd:schema>
+
+
+<!-- EOF -->
assertEquals(
"model name : カメラ・照明\n"
- +"bone#0 morph#0 camera#0 luminous#0 shadow#0",
+ +"bone#0 morph#0 camera#0 luminous#0 shadow#0 flag#0",
motion.toString());
motion.setModelName("model");
motion.getShadowMotionList().add(new ShadowMotion());
motion.getShadowMotionList().add(new ShadowMotion());
motion.getShadowMotionList().add(new ShadowMotion());
+ motion.getNumberedFlagList().add(new NumberedVmdFlag());
+ motion.getNumberedFlagList().add(new NumberedVmdFlag());
+ motion.getNumberedFlagList().add(new NumberedVmdFlag());
+ motion.getNumberedFlagList().add(new NumberedVmdFlag());
+ motion.getNumberedFlagList().add(new NumberedVmdFlag());
assertEquals(
"model name : model\n"
- +"bone#1 morph#2 camera#3 luminous#4 shadow#5",
+ +"bone#1 morph#2 camera#3 luminous#4 shadow#5 flag#5",
motion.toString());
return;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ MikuMikuDance
+ motion-data(*.vmd) on XML
+-->
+
+
+<vmdMotion
+ xmlns="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/130609A"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/130609A
+ http://mikutoga.sourceforge.jp/xml/xsd/vmdxml-130609A.xsd"
+ version="130609A"
+>
+
+<!-- [NAMELESS] -->
+<modelName name="" />
+
+<boneMotionSequence>
+</boneMotionSequence>
+
+<morphSequence>
+</morphSequence>
+
+<flagSequence>
+</flagSequence>
+
+</vmdMotion>
+
+<!-- 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/130609A"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://mikutoga.sourceforge.jp/xml/ns/vmdxml/130609A
+ http://mikutoga.sourceforge.jp/xml/xsd/vmdxml-130609A.xsd"
+ version="130609A"
+>
+
+<!-- [NAMELESS] -->
+<modelName name="" />
+
+<boneMotionSequence>
+</boneMotionSequence>
+
+<morphSequence>
+</morphSequence>
+
+<flagSequence>
+ <flagMotion frame="9" showModel="true" />
+ <flagMotion frame="99" showModel="false">
+ <ikSwitch name="IKBONE1" valid="true" />
+ <ikSwitch name="IKBONE2" valid="false" />
+ </flagMotion>
+</flagSequence>
+
+</vmdMotion>
+
+<!-- EOF -->