OSDN Git Service

Merge release/v3.121.2
[mikutoga/TogaGem.git] / src / main / java / jp / sfjp / mikutoga / vmd / parser / VmdBoolParser.java
1 /*
2  * VMD boolean data parser
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.vmd.parser;
9
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;
14 import jp.sfjp.mikutoga.bin.parser.TextDecoder;
15 import jp.sfjp.mikutoga.vmd.VmdConst;
16
17 /**
18  * VMDモーションファイルの各種ON/OFF情報(モデル表示・IK有効無効)
19  * パーサ。
20  * <p>MikuMikuDance Ver7.40以降でサポート
21  */
22 class VmdBoolParser extends ProxyParser {
23
24     private final TextDecoder decoderWin31j =
25             new TextDecoder(VmdBasicParser.CS_WIN31J);
26
27     private VmdBoolHandler handler = VmdUnifiedHandler.EMPTY;
28
29
30     /**
31      * コンストラクタ。
32      * @param parser 委譲先パーサ
33      */
34     VmdBoolParser(BinParser parser){
35         super(parser);
36         this.decoderWin31j.setZeroChopMode(true);
37         return;
38     }
39
40
41     /**
42      * ON/OFF情報通知用ハンドラを登録する。
43      * @param boolHandler ハンドラ
44      */
45     void setBoolHandler(VmdBoolHandler boolHandler){
46         if(boolHandler == null){
47             this.handler = VmdUnifiedHandler.EMPTY;
48         }else{
49             this.handler = boolHandler;
50         }
51
52         return;
53     }
54
55     /**
56      * データのパースと通知。
57      * @throws IOException IOエラー
58      * @throws MmdFormatException フォーマットエラー
59      */
60     void parse() throws IOException, MmdFormatException {
61         if( ! hasMore() ) return;
62
63         parseVmdModelSight();
64
65         return;
66     }
67
68     /**
69      * モデル表示フラグデータのパースと通知。
70      * @throws IOException IOエラー
71      * @throws MmdFormatException フォーマットエラー
72      */
73     private void parseVmdModelSight()
74             throws IOException, MmdFormatException{
75         int modelSightNo = parseLeInt();
76
77         this.handler.loopStart(VmdBoolHandler.MODELSIGHT_LIST,
78                                modelSightNo );
79
80         for(int ct = 0; ct < modelSightNo; ct++){
81             int keyFrameNo = parseLeInt();
82             boolean show = parseBoolean();
83             this.handler.vmdModelSight(show, keyFrameNo);
84
85             parseVmdIkSwitch(keyFrameNo);
86
87             this.handler.loopNext(VmdBoolHandler.MODELSIGHT_LIST);
88         }
89
90         this.handler.loopEnd(VmdBoolHandler.MODELSIGHT_LIST);
91
92         return;
93     }
94
95     /**
96      * IK有効スイッチデータのパースと通知。
97      * @param keyFrameNo キーフレーム番号
98      * @throws IOException IOエラー
99      * @throws MmdFormatException フォーマットエラー
100      */
101     private void parseVmdIkSwitch(int keyFrameNo)
102             throws IOException, MmdFormatException{
103         int ikSwitchNo = parseLeInt();
104
105         this.handler.loopStart(VmdBoolHandler.IKSW_LIST, ikSwitchNo);
106
107         for(int ct = 0; ct < ikSwitchNo; ct++){
108             String boneName = parseString(this.decoderWin31j,
109                                           VmdConst.IKSWBONENAME_MAX );
110             boolean valid = parseBoolean();
111             this.handler.vmdIkSwitch(boneName, valid, keyFrameNo);
112
113             this.handler.loopNext(VmdBoolHandler.IKSW_LIST);
114         }
115
116         this.handler.loopEnd(VmdBoolHandler.IKSW_LIST);
117
118         return;
119     }
120
121 }