OSDN Git Service

MmdSource廃止
[mikutoga/Vmd2XML.git] / src / main / java / jp / sourceforge / mikutoga / vmd / model / binio / BasicExporter.java
1 /*
2  * bone motion & morph exporter
3  *
4  * License : The MIT License
5  * Copyright(c) 2011 MikuToga Partners
6  */
7
8 package jp.sourceforge.mikutoga.vmd.model.binio;
9
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;
25
26 /**
27  * ボーンモーション及びモーフ情報のエクスポーター。
28  */
29 class BasicExporter extends BinaryExporter {
30
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;
35
36     private static final byte[] FDFILLER =
37         { (byte)0x00, (byte)0xfd };
38
39
40     private final byte[] motionIntplt = new byte[BZTOTAL_SIZE];
41
42
43     /**
44      * コンストラクタ。
45      * @param stream 出力ストリーム
46      */
47     BasicExporter(OutputStream stream){
48         super(stream);
49         return;
50     }
51
52
53     /**
54      * ボーンモーション情報を出力する。
55      * @param motion モーションデータ
56      * @throws IOException 出力エラー
57      * @throws IllegalTextExportException 不正なボーン名の出現
58      */
59     void dumpBoneMotion(VmdMotion motion)
60             throws IOException, IllegalTextExportException{
61         NamedListMap<BoneMotion> map = motion.getBonePartMap();
62         List<String> nameList = map.getNames();
63
64         List<BoneMotion> bmotionList = new LinkedList<BoneMotion>();
65
66         int count = 0;
67         for(String name : nameList){
68             List<BoneMotion> namedList = map.getNamedList(name);
69             for(BoneMotion boneMotion : namedList){
70                 bmotionList.add(boneMotion);
71                 count++;
72             }
73         }
74         dumpLeInt(count);
75
76         for(BoneMotion boneMotion : bmotionList){
77             String boneName = boneMotion.getBoneName();
78             dumpFixedW31j(boneName, VmdConst.BONENAME_MAX, FDFILLER);
79
80             int frame = boneMotion.getFrameNumber();
81             dumpLeInt(frame);
82
83             MkPos3D position = boneMotion.getPosition();
84             dumpBonePosition(position);
85
86             MkQuat rotation = boneMotion.getRotation();
87             dumpBoneRotation(rotation);
88
89             dumpBoneInterpolation(boneMotion);
90         }
91
92         return;
93     }
94
95     /**
96      * ボーン位置情報を出力する。
97      * @param position ボーン位置情報
98      * @throws IOException 出力エラー
99      */
100     private void dumpBonePosition(MkPos3D position)
101             throws IOException{
102         float xPos = (float) position.getXpos();
103         float yPos = (float) position.getYpos();
104         float zPos = (float) position.getZpos();
105
106         dumpLeFloat(xPos);
107         dumpLeFloat(yPos);
108         dumpLeFloat(zPos);
109
110         return;
111     }
112
113     /**
114      * ボーン回転情報を出力する。
115      * @param rotation ボーン回転情報
116      * @throws IOException 出力エラー
117      */
118     private void dumpBoneRotation(MkQuat rotation)
119             throws IOException{
120         float qx = (float) rotation.getQ1();
121         float qy = (float) rotation.getQ2();
122         float qz = (float) rotation.getQ3();
123         float qw = (float) rotation.getQW();
124
125         dumpLeFloat(qx);
126         dumpLeFloat(qy);
127         dumpLeFloat(qz);
128         dumpLeFloat(qw);
129
130         return;
131     }
132
133     /**
134      * ボーンモーションの補間情報を出力する。
135      * @param boneMotion ボーンモーション
136      * @throws IOException 出力エラー
137      */
138     private void dumpBoneInterpolation(BoneMotion boneMotion)
139             throws IOException{
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();
145
146         int idx = 0;
147
148         this.motionIntplt[idx++] = xCurve.getP1x();
149         this.motionIntplt[idx++] = yCurve.getP1x();
150         this.motionIntplt[idx++] = zCurve.getP1x();
151         this.motionIntplt[idx++] = rCurve.getP1x();
152
153         this.motionIntplt[idx++] = xCurve.getP1y();
154         this.motionIntplt[idx++] = yCurve.getP1y();
155         this.motionIntplt[idx++] = zCurve.getP1y();
156         this.motionIntplt[idx++] = rCurve.getP1y();
157
158         this.motionIntplt[idx++] = xCurve.getP2x();
159         this.motionIntplt[idx++] = yCurve.getP2x();
160         this.motionIntplt[idx++] = zCurve.getP2x();
161         this.motionIntplt[idx++] = rCurve.getP2x();
162
163         this.motionIntplt[idx++] = xCurve.getP2y();
164         this.motionIntplt[idx++] = yCurve.getP2y();
165         this.motionIntplt[idx++] = zCurve.getP2y();
166         this.motionIntplt[idx++] = rCurve.getP2y();
167
168         assert idx == BZXYZR_SIZE;
169
170         redundantCopy();
171
172         dumpByteArray(this.motionIntplt);
173
174         return;
175     }
176
177     /**
178      * 補間情報冗長部の組み立て。
179      */
180     private void redundantCopy(){
181         int lack = 1;
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;
186
187             System.arraycopy(this.motionIntplt, sourceIdx,
188                              this.motionIntplt, targetIdx,
189                              span );
190
191             int onePos = targetIdx + span;
192             this.motionIntplt[onePos] = (byte) 0x01;
193
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;
198             }
199
200             lack++;
201         }
202
203         return;
204     }
205
206     /**
207      * モーフ情報を出力する。
208      * @param motion モーションデータ
209      * @throws IOException 出力エラー
210      * @throws IllegalTextExportException 不正なモーフ名の出現
211      */
212     void dumpMorphMotion(VmdMotion motion)
213             throws IOException, IllegalTextExportException{
214         NamedListMap<MorphMotion> map = motion.getMorphPartMap();
215         List<String> nameList = map.getNames();
216
217         List<MorphMotion> morphList = new LinkedList<MorphMotion>();
218
219         int count = 0;
220         for(String name : nameList){
221             List<MorphMotion> namedList = map.getNamedList(name);
222             for(MorphMotion morphMotion : namedList){
223                 morphList.add(morphMotion);
224                 count++;
225             }
226         }
227         dumpLeInt(count);
228
229         for(MorphMotion morphMotion : morphList){
230             String morphName = morphMotion.getMorphName();
231             dumpFixedW31j(morphName, VmdConst.MORPHNAME_MAX, FDFILLER);
232
233             int frame = morphMotion.getFrameNumber();
234             dumpLeInt(frame);
235
236             float flex = morphMotion.getFlex();
237             dumpLeFloat(flex);
238         }
239
240         return;
241     }
242
243 }