OSDN Git Service

Merge release/v1.203.2
[mikutoga/Pmd2XML.git] / src / main / java / jp / sfjp / mikutoga / pmd / model / xml / SaxBoneListener.java
1 /*
2  * bone listener from XML
3  *
4  * License : The MIT License
5  * Copyright(c) 2013 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.pmd.model.xml;
9
10 import java.util.List;
11 import jp.sfjp.mikutoga.corelib.I18nText;
12 import jp.sfjp.mikutoga.math.MkPos3D;
13 import jp.sfjp.mikutoga.pmd.BoneType;
14 import jp.sfjp.mikutoga.pmd.model.BoneGroup;
15 import jp.sfjp.mikutoga.pmd.model.BoneInfo;
16 import jp.sfjp.mikutoga.pmd.model.IKChain;
17 import jp.sfjp.mikutoga.pmd.model.ListUtil;
18
19 /*
20     + boneList
21         + bone
22             + i18nName
23             + position
24             + rotationRatio
25             + ikBone
26             + sourceBone
27             + boneChain
28     + boneGroupList
29         + boneGroup
30             + i18nName
31             + boneGroupMember
32     + ikChainList
33         + ikChain
34             + chainOrder
35 */
36
37 /**
38  * ボーン関連のXML要素出現イベントを受信する。
39  */
40 class SaxBoneListener extends SaxListener{
41
42     private final RefHelper helper;
43
44     private BoneInfo currentBone = null;
45
46     private BoneGroup currentBoneGroup = null;
47
48     private IKChain currentIkChain = null;
49
50
51     /**
52      * コンストラクタ。
53      * @param helper 参照ヘルパ
54      */
55     SaxBoneListener(RefHelper helper) {
56         super();
57         this.helper = helper;
58         return;
59     }
60
61
62     /**
63      * boneInfoタグ開始の通知を受け取る。
64      */
65     @OpenXmlMark(PmdTag.BONE)
66     void openBoneInfo(){
67         this.currentBone = new BoneInfo();
68
69         String nameAttr = getStringAttr(PmdAttr.NAME);
70         I18nText boneName = this.currentBone.getBoneName();
71         boneName.setPrimaryText(nameAttr);
72
73         String boneId = getStringAttr(PmdAttr.BONE_ID);
74         this.helper.addBoneId(boneId, this.currentBone);
75
76         String typeAttr = getStringAttr(PmdAttr.TYPE);
77         BoneType boneType = BoneType.valueOf(typeAttr);
78         this.currentBone.setBoneType(boneType);
79
80         return;
81     }
82
83     /**
84      * boneInfoタグ終了の通知を受け取る。
85      */
86     @CloseXmlMark(PmdTag.BONE)
87     void closeBoneInfo(){
88         List<BoneInfo> boneList = getPmdModel().getBoneList();
89         boneList.add(this.currentBone);
90
91         this.currentBone = null;
92
93         return;
94     }
95
96     /**
97      * i18nTextタグ開始の通知を受け取る。
98      */
99     @OpenXmlMark(PmdTag.I18N_NAME)
100     void openI18nText(){
101         I18nText i18nName;
102         if(this.currentBone != null){
103             i18nName = this.currentBone.getBoneName();
104         }else if(this.currentBoneGroup != null){
105             i18nName = this.currentBoneGroup.getGroupName();
106         }else{
107             return;
108         }
109
110         String lang = getStringAttr(PmdAttr.LANG);
111         String name = getStringAttr(PmdAttr.NAME);
112
113         i18nName.setI18nText(lang, name);
114
115         return;
116     }
117
118     /**
119      * boneListタグ終了の通知を受け取る。
120      */
121     @CloseXmlMark(PmdTag.BONE_LIST)
122     void closeBoneList(){
123         this.helper.resolveSrcBoneIdRef();
124         this.helper.resolveBoneChainIdRef();
125
126         List<BoneInfo> boneList = getPmdModel().getBoneList();
127         ListUtil.assignIndexedSerial(boneList);
128
129         return;
130     }
131
132     /**
133      * positionタグ開始の通知を受け取る。
134      */
135     @OpenXmlMark(PmdTag.POSITION)
136     void openPosition(){
137         float x = getFloatAttr(PmdAttr.X);
138         float y = getFloatAttr(PmdAttr.Y);
139         float z = getFloatAttr(PmdAttr.Z);
140
141         MkPos3D pos = this.currentBone.getPosition();
142         pos.setPosition(x, y, z);
143
144         return;
145     }
146
147     /**
148      * rotationRatioタグ開始の通知を受け取る。
149      */
150     @OpenXmlMark(PmdTag.ROTATION_RATIO)
151     void openRotationRatio(){
152         int ratio = getIntAttr(PmdAttr.RATIO);
153         this.currentBone.setRotationRatio(ratio);
154         return;
155     }
156
157     /**
158      * ikBoneタグ開始の通知を受け取る。
159      * ※ 101009版スキーマでしか出現しない。
160      */
161     @OpenXmlMark(PmdTag.IK_BONE) // 101009 only
162     void openIkBone(){
163         openSrcBone();
164         return;
165     }
166
167     /**
168      * sourceBoneタグ開始の通知を受け取る。
169      * ※ 130128版スキーマでしか出現しない。
170      */
171     @OpenXmlMark(PmdTag.SOURCE_BONE) // 130128 only
172     void openSrcBone(){
173         String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
174         this.helper.addSrcBoneIdRef(this.currentBone, boneIdRef);
175         return;
176     }
177
178     /**
179      * boneChainタグ開始の通知を受け取る。
180      */
181     @OpenXmlMark(PmdTag.BONE_CHAIN)
182     void openBoneChain(){
183         String prevBoneIdRef = getStringAttr(PmdAttr.PREV_BONE_IDREF);
184         String nextBoneIdRef = getStringAttr(PmdAttr.NEXT_BONE_IDREF);
185
186         this.helper.addBoneChain(this.currentBone,
187                                  prevBoneIdRef, nextBoneIdRef );
188
189         return;
190     }
191
192     /**
193      * boneGroupListタグ開始の通知を受け取る。
194      * 暗黙のデフォルトボーングループが無条件に格納される。
195      */
196     @OpenXmlMark(PmdTag.BONE_GROUP_LIST)
197     void openBoneGroupList(){
198         BoneGroup defaultBoneGroup = new BoneGroup();
199         defaultBoneGroup.setSerialNumber(0);
200
201         List<BoneGroup> boneGroupList =
202                 this.getPmdModel().getBoneGroupList();
203         boneGroupList.add(defaultBoneGroup);
204
205         return;
206     }
207
208     /**
209      * boneGroupListタグ終了の通知を受け取る。
210      */
211     @CloseXmlMark(PmdTag.BONE_GROUP_LIST)
212     void closeBoneGroupList(){
213         List<BoneGroup> boneGroupList = getPmdModel().getBoneGroupList();
214         ListUtil.assignIndexedSerial(boneGroupList);
215         return;
216     }
217
218     /**
219      * boneGroupタグ開始の通知を受け取る。
220      */
221     @OpenXmlMark(PmdTag.BONE_GROUP)
222     void openBoneGroup(){
223         this.currentBoneGroup = new BoneGroup();
224
225         String nameAttr = getStringAttr(PmdAttr.NAME);
226         I18nText groupName = this.currentBoneGroup.getGroupName();
227         groupName.setPrimaryText(nameAttr);
228
229         return;
230     }
231
232     /**
233      * boneGroupタグ終了の通知を受け取る。
234      */
235     @CloseXmlMark(PmdTag.BONE_GROUP)
236     void closeBoneGroup(){
237         List<BoneGroup> boneGroupList = getPmdModel().getBoneGroupList();
238         boneGroupList.add(this.currentBoneGroup);
239
240         this.currentBoneGroup = null;
241
242         return;
243     }
244
245     /**
246      * boneGroupMemberタグ開始の通知を受け取る。
247      */
248     @OpenXmlMark(PmdTag.BONE_GROUP_MEMBER)
249     void openBoneGroupMember(){
250         String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
251
252         BoneInfo bone = this.helper.findBoneId(boneIdRef);
253
254         List<BoneInfo> boneList = this.currentBoneGroup.getBoneList();
255         boneList.add(bone);
256
257         return;
258     }
259
260     /**
261      * ikChainタグ開始の通知を受け取る。
262      */
263     @OpenXmlMark(PmdTag.IK_CHAIN)
264     void openIkChain(){
265         this.currentIkChain = new IKChain();
266
267         String ikBoneIdRef = getStringAttr(PmdAttr.IK_BONE_IDREF);
268         BoneInfo bone = this.helper.findBoneId(ikBoneIdRef);
269         this.currentIkChain.setIkBone(bone);
270
271         int depth = getIntAttr(PmdAttr.RECURSIVE_DEPTH);
272         this.currentIkChain.setIKDepth(depth);
273
274         float weight = getFloatAttr(PmdAttr.WEIGHT);
275         this.currentIkChain.setIKWeight(weight);
276
277         return;
278     }
279
280     /**
281      * ikChainタグ終了の通知を受け取る。
282      */
283     @CloseXmlMark(PmdTag.IK_CHAIN)
284     void closeIkChain(){
285         List<IKChain> ikChainList = getPmdModel().getIKChainList();
286         ikChainList.add(this.currentIkChain);
287
288         this.currentIkChain = null;
289
290         return;
291     }
292
293     /**
294      * chainOrderタグ開始の通知を受け取る。
295      */
296     @OpenXmlMark(PmdTag.CHAIN_ORDER)
297     void openChainOrder(){
298         String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
299         BoneInfo bone = this.helper.findBoneId(boneIdRef);
300
301         List<BoneInfo> chainList = this.currentIkChain.getChainedBoneList();
302         chainList.add(bone);
303
304         return;
305     }
306
307 }