2 * bone motion & morph exporter
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sourceforge.mikutoga.vmd.model.binio;
10 import java.io.IOException;
11 import java.io.OutputStream;
12 import java.util.LinkedList;
13 import java.util.List;
14 import jp.sourceforge.mikutoga.binio.BinaryExporter;
15 import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
16 import jp.sourceforge.mikutoga.math.MkPos3D;
17 import jp.sourceforge.mikutoga.math.MkQuat;
18 import jp.sourceforge.mikutoga.vmd.VmdConst;
19 import jp.sourceforge.mikutoga.vmd.model.BezierParam;
20 import jp.sourceforge.mikutoga.vmd.model.BoneMotion;
21 import jp.sourceforge.mikutoga.vmd.model.MorphMotion;
22 import jp.sourceforge.mikutoga.vmd.model.NamedListMap;
23 import jp.sourceforge.mikutoga.vmd.model.PosCurve;
24 import jp.sourceforge.mikutoga.vmd.model.VmdMotion;
27 * ボーンモーション及びモーフ情報のエクスポーター。
29 class BasicExporter extends BinaryExporter {
31 private static final int BZ_SIZE = 4; // 4byte Bezier parameter
32 private static final int BZXYZR_SIZE = BZ_SIZE * 4; // XYZR Bezier
33 private static final int BZ_REDUNDANT = 4; // redundant spare
34 private static final int BZTOTAL_SIZE = BZXYZR_SIZE * BZ_REDUNDANT;
36 private static final byte[] FDFILLER =
37 { (byte)0x00, (byte)0xfd };
40 private final byte[] motionIntplt = new byte[BZTOTAL_SIZE];
45 * @param stream 出力ストリーム
47 BasicExporter(OutputStream stream){
55 * @param motion モーションデータ
56 * @throws IOException 出力エラー
57 * @throws IllegalTextExportException 不正なボーン名の出現
59 void dumpBoneMotion(VmdMotion motion)
60 throws IOException, IllegalTextExportException{
61 NamedListMap<BoneMotion> map = motion.getBonePartMap();
62 List<String> nameList = map.getNames();
64 List<BoneMotion> bmotionList = new LinkedList<BoneMotion>();
67 for(String name : nameList){
68 List<BoneMotion> namedList = map.getNamedList(name);
69 for(BoneMotion boneMotion : namedList){
70 bmotionList.add(boneMotion);
76 for(BoneMotion boneMotion : bmotionList){
77 String boneName = boneMotion.getBoneName();
78 dumpFixedW31j(boneName, VmdConst.BONENAME_MAX, FDFILLER);
80 int frame = boneMotion.getFrameNumber();
83 MkPos3D position = boneMotion.getPosition();
84 dumpBonePosition(position);
86 MkQuat rotation = boneMotion.getRotation();
87 dumpBoneRotation(rotation);
89 dumpBoneInterpolation(boneMotion);
97 * @param position ボーン位置情報
98 * @throws IOException 出力エラー
100 private void dumpBonePosition(MkPos3D position)
102 float xPos = (float) position.getXpos();
103 float yPos = (float) position.getYpos();
104 float zPos = (float) position.getZpos();
115 * @param rotation ボーン回転情報
116 * @throws IOException 出力エラー
118 private void dumpBoneRotation(MkQuat rotation)
120 float qx = (float) rotation.getQ1();
121 float qy = (float) rotation.getQ2();
122 float qz = (float) rotation.getQ3();
123 float qw = (float) rotation.getQW();
134 * ボーンモーションの補間情報を出力する。
135 * @param boneMotion ボーンモーション
136 * @throws IOException 出力エラー
138 private void dumpBoneInterpolation(BoneMotion boneMotion)
140 PosCurve posCurve = boneMotion.getPosCurve();
141 BezierParam xCurve = posCurve.getIntpltXpos();
142 BezierParam yCurve = posCurve.getIntpltYpos();
143 BezierParam zCurve = posCurve.getIntpltZpos();
144 BezierParam rCurve = boneMotion.getIntpltRotation();
148 this.motionIntplt[idx++] = xCurve.getP1x();
149 this.motionIntplt[idx++] = yCurve.getP1x();
150 this.motionIntplt[idx++] = zCurve.getP1x();
151 this.motionIntplt[idx++] = rCurve.getP1x();
153 this.motionIntplt[idx++] = xCurve.getP1y();
154 this.motionIntplt[idx++] = yCurve.getP1y();
155 this.motionIntplt[idx++] = zCurve.getP1y();
156 this.motionIntplt[idx++] = rCurve.getP1y();
158 this.motionIntplt[idx++] = xCurve.getP2x();
159 this.motionIntplt[idx++] = yCurve.getP2x();
160 this.motionIntplt[idx++] = zCurve.getP2x();
161 this.motionIntplt[idx++] = rCurve.getP2x();
163 this.motionIntplt[idx++] = xCurve.getP2y();
164 this.motionIntplt[idx++] = yCurve.getP2y();
165 this.motionIntplt[idx++] = zCurve.getP2y();
166 this.motionIntplt[idx++] = rCurve.getP2y();
168 assert idx == BZXYZR_SIZE;
172 dumpByteArray(this.motionIntplt);
180 private void redundantCopy(){
182 for(int ct = 1; ct < BZ_REDUNDANT; ct++){
183 int sourceIdx = 0 + lack;
184 int targetIdx = BZXYZR_SIZE * ct;
185 int span = BZXYZR_SIZE - lack;
187 System.arraycopy(this.motionIntplt, sourceIdx,
188 this.motionIntplt, targetIdx,
191 int onePos = targetIdx + span;
192 this.motionIntplt[onePos] = (byte) 0x01;
194 int zeroPosStart = onePos + 1;
195 int zeroPosEnd = targetIdx + BZXYZR_SIZE;
196 for(int idx = zeroPosStart; idx < zeroPosEnd; idx++){
197 this.motionIntplt[idx] = (byte) 0x00;
208 * @param motion モーションデータ
209 * @throws IOException 出力エラー
210 * @throws IllegalTextExportException 不正なモーフ名の出現
212 void dumpMorphMotion(VmdMotion motion)
213 throws IOException, IllegalTextExportException{
214 NamedListMap<MorphMotion> map = motion.getMorphPartMap();
215 List<String> nameList = map.getNames();
217 List<MorphMotion> morphList = new LinkedList<MorphMotion>();
220 for(String name : nameList){
221 List<MorphMotion> namedList = map.getNamedList(name);
222 for(MorphMotion morphMotion : namedList){
223 morphList.add(morphMotion);
229 for(MorphMotion morphMotion : morphList){
230 String morphName = morphMotion.getMorphName();
231 dumpFixedW31j(morphName, VmdConst.MORPHNAME_MAX, FDFILLER);
233 int frame = morphMotion.getFrameNumber();
236 float flex = morphMotion.getFlex();