OSDN Git Service

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