OSDN Git Service

8e1634adbcf6ffa22c12c8e9f666c32e1e4bd525
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / vmd / parser / VmdCameraParser.java
1 /*
2  * VMD camera motion parser
3  *
4  * License : The MIT License
5  * Copyright(c) 2011 MikuToga Partners
6  */
7
8 package jp.sourceforge.mikutoga.vmd.parser;
9
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;
15
16 /**
17  * VMDモーションファイルのカメラモーションパーサ。
18  */
19 class VmdCameraParser extends CommonParser{
20
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
24
25
26     private final byte[] xyzIntplt = new byte[BZXYZ_SIZE];
27     private final byte[] etcIntplt = new byte[BZETC_SIZE];
28
29     private VmdCameraHandler handler = null;
30
31
32     /**
33      * コンストラクタ。
34      * @param source 入力ソース
35      */
36     VmdCameraParser(MmdInputStream source){
37         super(source);
38         return;
39     }
40
41
42     /**
43      * カメラワーク情報通知用ハンドラを登録する。
44      * @param cameraHandler ハンドラ
45      */
46     void setCameraHandler(VmdCameraHandler cameraHandler){
47         this.handler = cameraHandler;
48         return;
49     }
50
51     /**
52      * カメラモーションデータのパースと通知。
53      * @throws IOException IOエラー
54      * @throws MmdFormatException フォーマットエラー
55      */
56     void parse() throws IOException, MmdFormatException {
57         int cameraMotionNo = parseLeInt();
58
59         if(this.handler == null){
60             skip(VmdConst.CAMERA_DATA_SZ * cameraMotionNo);
61             return;
62         }
63
64         this.handler.loopStart(VmdCameraHandler.CAMERA_LIST, cameraMotionNo);
65
66         for(int ct = 0; ct < cameraMotionNo; ct++){
67             int keyFrameNo = parseLeInt();
68             this.handler.vmdCameraMotion(keyFrameNo);
69
70             float range = parseLeFloat();
71             this.handler.vmdCameraRange(range);
72
73             float xPos = parseLeFloat();
74             float yPos = parseLeFloat();
75             float zPos = parseLeFloat();
76             this.handler.vmdCameraPosition(xPos, yPos, zPos);
77
78             float latitude  = parseLeFloat();
79             float longitude = parseLeFloat();
80             float roll      = parseLeFloat();
81             this.handler.vmdCameraRotation(latitude, longitude, roll);
82
83             parseCameraXyzInterpolation();
84             parseCameraEtcInterpolation();
85
86             int angle = parseLeInt();
87             boolean hasPerspective = ! parseBoolean();
88             this.handler.vmdCameraProjection(angle, hasPerspective);
89
90             this.handler.loopNext(VmdCameraHandler.CAMERA_LIST);
91         }
92
93         this.handler.loopEnd(VmdCameraHandler.CAMERA_LIST);
94
95         return;
96     }
97
98     /**
99      * カメラターゲット補間データのパースと通知。
100      * @throws IOException IOエラー
101      * @throws MmdFormatException フォーマットエラー
102      */
103     private void parseCameraXyzInterpolation()
104             throws IOException, MmdFormatException{
105         if(this.handler == null){
106             skip(this.xyzIntplt.length);
107             return;
108         }
109
110         parseByteArray(this.xyzIntplt);
111
112         int idx = 0;
113
114         byte xP1x = this.xyzIntplt[idx++];
115         byte xP2x = this.xyzIntplt[idx++];
116         byte xP1y = this.xyzIntplt[idx++];
117         byte xP2y = this.xyzIntplt[idx++];
118
119         byte yP1x = this.xyzIntplt[idx++];
120         byte yP2x = this.xyzIntplt[idx++];
121         byte yP1y = this.xyzIntplt[idx++];
122         byte yP2y = this.xyzIntplt[idx++];
123
124         byte zP1x = this.xyzIntplt[idx++];
125         byte zP2x = this.xyzIntplt[idx++];
126         byte zP1y = this.xyzIntplt[idx++];
127         byte zP2y = this.xyzIntplt[idx++];
128
129         assert idx == this.xyzIntplt.length;
130
131         this.handler.vmdCameraIntpltXpos(xP1x, xP1y, xP2x, xP2y);
132         this.handler.vmdCameraIntpltYpos(yP1x, yP1y, yP2x, yP2y);
133         this.handler.vmdCameraIntpltZpos(zP1x, zP1y, zP2x, zP2y);
134
135         return;
136     }
137
138     /**
139      * ターゲット位置以外の補間データのパースと通知。
140      * @throws IOException IOエラー
141      * @throws MmdFormatException フォーマットエラー
142      */
143     private void parseCameraEtcInterpolation()
144             throws IOException, MmdFormatException{
145         if(this.handler == null){
146             skip(this.etcIntplt.length);
147             return;
148         }
149
150         parseByteArray(this.etcIntplt);
151
152         int idx = 0;
153
154         byte rP1x = this.etcIntplt[idx++];
155         byte rP2x = this.etcIntplt[idx++];
156         byte rP1y = this.etcIntplt[idx++];
157         byte rP2y = this.etcIntplt[idx++];
158
159         byte dP1x = this.etcIntplt[idx++];
160         byte dP2x = this.etcIntplt[idx++];
161         byte dP1y = this.etcIntplt[idx++];
162         byte dP2y = this.etcIntplt[idx++];
163
164         byte pP1x = this.etcIntplt[idx++];
165         byte pP2x = this.etcIntplt[idx++];
166         byte pP1y = this.etcIntplt[idx++];
167         byte pP2y = this.etcIntplt[idx++];
168
169         assert idx == this.etcIntplt.length;
170
171         this.handler.vmdCameraIntpltRotation  (rP1x, rP1y, rP2x, rP2y);
172         this.handler.vmdCameraIntpltRange     (dP1x, dP1y, dP2x, dP2y);
173         this.handler.vmdCameraIntpltProjection(pP1x, pP1y, pP2x, pP2y);
174
175         return;
176     }
177
178 }