2 * VMD camera motion parser
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sfjp.mikutoga.vmd.parser;
10 import java.io.IOException;
11 import jp.sfjp.mikutoga.bin.parser.BinParser;
12 import jp.sfjp.mikutoga.bin.parser.MmdFormatException;
13 import jp.sfjp.mikutoga.bin.parser.ProxyParser;
16 * VMDモーションファイルのカメラモーションパーサ。
18 class VmdCameraParser extends ProxyParser{
20 private static final int BZ_SIZE = 4; // 4byte Bezier parameter
21 private static final int BZXYZ_SIZE = BZ_SIZE * 3; // XYZ Bezier
22 private static final int BZETC_SIZE = BZ_SIZE * 3; // etc. Bezier
25 private final byte[] xyzIntplt = new byte[BZXYZ_SIZE];
26 private final byte[] etcIntplt = new byte[BZETC_SIZE];
28 private VmdCameraHandler handler = VmdUnifiedHandler.EMPTY;
33 * @param parser 委譲先パーサ
35 VmdCameraParser(BinParser parser){
42 * カメラワーク情報通知用ハンドラを登録する。
43 * @param cameraHandler ハンドラ
45 void setCameraHandler(VmdCameraHandler cameraHandler){
46 if(cameraHandler == null){
47 this.handler = VmdUnifiedHandler.EMPTY;
49 this.handler = cameraHandler;
57 * @throws IOException IOエラー
58 * @throws MmdFormatException フォーマットエラー
60 void parse() throws IOException, MmdFormatException {
61 int cameraMotionNo = parseLeInt();
63 this.handler.loopStart(VmdCameraHandler.CAMERA_LIST, cameraMotionNo);
65 for(int ct = 0; ct < cameraMotionNo; ct++){
66 int keyFrameNo = parseLeInt();
67 this.handler.vmdCameraMotion(keyFrameNo);
69 float range = parseLeFloat();
70 this.handler.vmdCameraRange(range);
72 float xPos = parseLeFloat();
73 float yPos = parseLeFloat();
74 float zPos = parseLeFloat();
75 this.handler.vmdCameraPosition(xPos, yPos, zPos);
77 float latitude = parseLeFloat();
78 float longitude = parseLeFloat();
79 float roll = parseLeFloat();
80 this.handler.vmdCameraRotation(latitude, longitude, roll);
82 parseCameraXyzInterpolation();
83 parseCameraEtcInterpolation();
85 int angle = parseLeInt();
86 boolean hasPerspective = ! parseBoolean();
87 this.handler.vmdCameraProjection(angle, hasPerspective);
89 this.handler.loopNext(VmdCameraHandler.CAMERA_LIST);
92 this.handler.loopEnd(VmdCameraHandler.CAMERA_LIST);
98 * カメラターゲット補間データのパースと通知。
99 * @throws IOException IOエラー
100 * @throws MmdFormatException フォーマットエラー
102 private void parseCameraXyzInterpolation()
103 throws IOException, MmdFormatException{
104 parseByteArray(this.xyzIntplt);
108 byte xP1x = this.xyzIntplt[idx++];
109 byte xP2x = this.xyzIntplt[idx++];
110 byte xP1y = this.xyzIntplt[idx++];
111 byte xP2y = this.xyzIntplt[idx++];
113 byte yP1x = this.xyzIntplt[idx++];
114 byte yP2x = this.xyzIntplt[idx++];
115 byte yP1y = this.xyzIntplt[idx++];
116 byte yP2y = this.xyzIntplt[idx++];
118 byte zP1x = this.xyzIntplt[idx++];
119 byte zP2x = this.xyzIntplt[idx++];
120 byte zP1y = this.xyzIntplt[idx++];
121 byte zP2y = this.xyzIntplt[idx++];
123 assert idx == this.xyzIntplt.length;
125 this.handler.vmdCameraIntpltXpos(xP1x, xP1y, xP2x, xP2y);
126 this.handler.vmdCameraIntpltYpos(yP1x, yP1y, yP2x, yP2y);
127 this.handler.vmdCameraIntpltZpos(zP1x, zP1y, zP2x, zP2y);
133 * ターゲット位置以外の補間データのパースと通知。
134 * @throws IOException IOエラー
135 * @throws MmdFormatException フォーマットエラー
137 private void parseCameraEtcInterpolation()
138 throws IOException, MmdFormatException{
139 parseByteArray(this.etcIntplt);
143 byte rP1x = this.etcIntplt[idx++];
144 byte rP2x = this.etcIntplt[idx++];
145 byte rP1y = this.etcIntplt[idx++];
146 byte rP2y = this.etcIntplt[idx++];
148 byte dP1x = this.etcIntplt[idx++];
149 byte dP2x = this.etcIntplt[idx++];
150 byte dP1y = this.etcIntplt[idx++];
151 byte dP2y = this.etcIntplt[idx++];
153 byte pP1x = this.etcIntplt[idx++];
154 byte pP2x = this.etcIntplt[idx++];
155 byte pP1y = this.etcIntplt[idx++];
156 byte pP2y = this.etcIntplt[idx++];
158 assert idx == this.etcIntplt.length;
160 this.handler.vmdCameraIntpltRotation (rP1x, rP1y, rP2x, rP2y);
161 this.handler.vmdCameraIntpltRange (dP1x, dP1y, dP2x, dP2y);
162 this.handler.vmdCameraIntpltProjection(pP1x, pP1y, pP2x, pP2y);