2 * VMD camera motion parser
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sourceforge.mikutoga.vmd.parser;
10 import java.io.IOException;
11 import jp.sourceforge.mikutoga.parser.CommonParser;
12 import jp.sourceforge.mikutoga.parser.MmdFormatException;
13 import jp.sourceforge.mikutoga.parser.MmdInputStream;
14 import jp.sourceforge.mikutoga.vmd.VmdConst;
17 * VMDモーションファイルのカメラモーションパーサ。
19 class VmdCameraParser extends CommonParser{
21 private static final int BZ_SIZE = 4; // 4byte Bezier parameter
22 private static final int BZXYZ_SIZE = BZ_SIZE * 3; // XYZ Bezier
23 private static final int BZETC_SIZE = BZ_SIZE * 3; // etc. Bezier
26 private final byte[] xyzIntplt = new byte[BZXYZ_SIZE];
27 private final byte[] etcIntplt = new byte[BZETC_SIZE];
29 private VmdCameraHandler handler = null;
36 VmdCameraParser(MmdInputStream source){
43 * カメラワーク情報通知用ハンドラを登録する。
44 * @param cameraHandler ハンドラ
46 void setCameraHandler(VmdCameraHandler cameraHandler){
47 this.handler = cameraHandler;
53 * @throws IOException IOエラー
54 * @throws MmdFormatException フォーマットエラー
56 void parse() throws IOException, MmdFormatException {
57 int cameraMotionNo = parseLeInt();
59 if(this.handler == null){
60 skip(VmdConst.CAMERA_DATA_SZ * cameraMotionNo);
64 this.handler.loopStart(VmdCameraHandler.CAMERA_LIST, cameraMotionNo);
66 for(int ct = 0; ct < cameraMotionNo; ct++){
67 int keyFrameNo = parseLeInt();
68 this.handler.vmdCameraMotion(keyFrameNo);
70 float range = parseLeFloat();
71 this.handler.vmdCameraRange(range);
73 float xPos = parseLeFloat();
74 float yPos = parseLeFloat();
75 float zPos = parseLeFloat();
76 this.handler.vmdCameraPosition(xPos, yPos, zPos);
78 float latitude = parseLeFloat();
79 float longitude = parseLeFloat();
80 float roll = parseLeFloat();
81 this.handler.vmdCameraRotation(latitude, longitude, roll);
83 parseCameraXyzInterpolation();
84 parseCameraEtcInterpolation();
86 int angle = parseLeInt();
87 boolean hasPerspective = ! parseBoolean();
88 this.handler.vmdCameraProjection(angle, hasPerspective);
90 this.handler.loopNext(VmdCameraHandler.CAMERA_LIST);
93 this.handler.loopEnd(VmdCameraHandler.CAMERA_LIST);
99 * カメラターゲット補間データのパースと通知。
100 * @throws IOException IOエラー
101 * @throws MmdFormatException フォーマットエラー
103 private void parseCameraXyzInterpolation()
104 throws IOException, MmdFormatException{
105 if(this.handler == null){
106 skip(this.xyzIntplt.length);
110 parseByteArray(this.xyzIntplt);
114 byte xP1x = this.xyzIntplt[idx++];
115 byte xP2x = this.xyzIntplt[idx++];
116 byte xP1y = this.xyzIntplt[idx++];
117 byte xP2y = this.xyzIntplt[idx++];
119 byte yP1x = this.xyzIntplt[idx++];
120 byte yP2x = this.xyzIntplt[idx++];
121 byte yP1y = this.xyzIntplt[idx++];
122 byte yP2y = this.xyzIntplt[idx++];
124 byte zP1x = this.xyzIntplt[idx++];
125 byte zP2x = this.xyzIntplt[idx++];
126 byte zP1y = this.xyzIntplt[idx++];
127 byte zP2y = this.xyzIntplt[idx++];
129 assert idx == this.xyzIntplt.length;
131 this.handler.vmdCameraIntpltXpos(xP1x, xP1y, xP2x, xP2y);
132 this.handler.vmdCameraIntpltYpos(yP1x, yP1y, yP2x, yP2y);
133 this.handler.vmdCameraIntpltZpos(zP1x, zP1y, zP2x, zP2y);
139 * ターゲット位置以外の補間データのパースと通知。
140 * @throws IOException IOエラー
141 * @throws MmdFormatException フォーマットエラー
143 private void parseCameraEtcInterpolation()
144 throws IOException, MmdFormatException{
145 if(this.handler == null){
146 skip(this.etcIntplt.length);
150 parseByteArray(this.etcIntplt);
154 byte rP1x = this.etcIntplt[idx++];
155 byte rP2x = this.etcIntplt[idx++];
156 byte rP1y = this.etcIntplt[idx++];
157 byte rP2y = this.etcIntplt[idx++];
159 byte dP1x = this.etcIntplt[idx++];
160 byte dP2x = this.etcIntplt[idx++];
161 byte dP1y = this.etcIntplt[idx++];
162 byte dP2y = this.etcIntplt[idx++];
164 byte pP1x = this.etcIntplt[idx++];
165 byte pP2x = this.etcIntplt[idx++];
166 byte pP1y = this.etcIntplt[idx++];
167 byte pP2y = this.etcIntplt[idx++];
169 assert idx == this.etcIntplt.length;
171 this.handler.vmdCameraIntpltRotation (rP1x, rP1y, rP2x, rP2y);
172 this.handler.vmdCameraIntpltRange (dP1x, dP1y, dP2x, dP2y);
173 this.handler.vmdCameraIntpltProjection(pP1x, pP1y, pP2x, pP2y);