2 * bone listener from XML
4 * License : The MIT License
5 * Copyright(c) 2013 MikuToga Partners
8 package jp.sfjp.mikutoga.pmd.model.xml;
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;
38 * ボーン関連のXML要素出現イベントを受信する。
40 class SaxBoneListener extends SaxListener{
42 private final RefHelper helper;
44 private BoneInfo currentBone = null;
46 private BoneGroup currentBoneGroup = null;
48 private IKChain currentIkChain = null;
55 SaxBoneListener(RefHelper helper) {
63 * boneInfoタグ開始の通知を受け取る。
65 @OpenXmlMark(PmdTag.BONE)
67 this.currentBone = new BoneInfo();
69 String nameAttr = getStringAttr(PmdAttr.NAME);
70 I18nText boneName = this.currentBone.getBoneName();
71 boneName.setPrimaryText(nameAttr);
73 String boneId = getStringAttr(PmdAttr.BONE_ID);
74 this.helper.addBoneId(boneId, this.currentBone);
76 String typeAttr = getStringAttr(PmdAttr.TYPE);
77 BoneType boneType = BoneType.valueOf(typeAttr);
78 this.currentBone.setBoneType(boneType);
84 * boneInfoタグ終了の通知を受け取る。
86 @CloseXmlMark(PmdTag.BONE)
88 List<BoneInfo> boneList = getPmdModel().getBoneList();
89 boneList.add(this.currentBone);
91 this.currentBone = null;
97 * i18nTextタグ開始の通知を受け取る。
99 @OpenXmlMark(PmdTag.I18N_NAME)
102 if(this.currentBone != null){
103 i18nName = this.currentBone.getBoneName();
104 }else if(this.currentBoneGroup != null){
105 i18nName = this.currentBoneGroup.getGroupName();
110 String lang = getStringAttr(PmdAttr.LANG);
111 String name = getStringAttr(PmdAttr.NAME);
113 i18nName.setI18nText(lang, name);
119 * boneListタグ終了の通知を受け取る。
121 @CloseXmlMark(PmdTag.BONE_LIST)
122 void closeBoneList(){
123 this.helper.resolveSrcBoneIdRef();
124 this.helper.resolveBoneChainIdRef();
126 List<BoneInfo> boneList = getPmdModel().getBoneList();
127 ListUtil.assignIndexedSerial(boneList);
133 * positionタグ開始の通知を受け取る。
135 @OpenXmlMark(PmdTag.POSITION)
137 float x = getFloatAttr(PmdAttr.X);
138 float y = getFloatAttr(PmdAttr.Y);
139 float z = getFloatAttr(PmdAttr.Z);
141 MkPos3D pos = this.currentBone.getPosition();
142 pos.setPosition(x, y, z);
148 * rotationRatioタグ開始の通知を受け取る。
150 @OpenXmlMark(PmdTag.ROTATION_RATIO)
151 void openRotationRatio(){
152 int ratio = getIntAttr(PmdAttr.RATIO);
153 this.currentBone.setRotationRatio(ratio);
158 * ikBoneタグ開始の通知を受け取る。
159 * ※ 101009版スキーマでしか出現しない。
161 @OpenXmlMark(PmdTag.IK_BONE) // 101009 only
168 * sourceBoneタグ開始の通知を受け取る。
169 * ※ 130128版スキーマでしか出現しない。
171 @OpenXmlMark(PmdTag.SOURCE_BONE) // 130128 only
173 String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
174 this.helper.addSrcBoneIdRef(this.currentBone, boneIdRef);
179 * boneChainタグ開始の通知を受け取る。
181 @OpenXmlMark(PmdTag.BONE_CHAIN)
182 void openBoneChain(){
183 String prevBoneIdRef = getStringAttr(PmdAttr.PREV_BONE_IDREF);
184 String nextBoneIdRef = getStringAttr(PmdAttr.NEXT_BONE_IDREF);
186 this.helper.addBoneChain(this.currentBone,
187 prevBoneIdRef, nextBoneIdRef );
193 * boneGroupListタグ開始の通知を受け取る。
194 * 暗黙のデフォルトボーングループが無条件に格納される。
196 @OpenXmlMark(PmdTag.BONE_GROUP_LIST)
197 void openBoneGroupList(){
198 BoneGroup defaultBoneGroup = new BoneGroup();
199 defaultBoneGroup.setSerialNumber(0);
201 List<BoneGroup> boneGroupList =
202 this.getPmdModel().getBoneGroupList();
203 boneGroupList.add(defaultBoneGroup);
209 * boneGroupListタグ終了の通知を受け取る。
211 @CloseXmlMark(PmdTag.BONE_GROUP_LIST)
212 void closeBoneGroupList(){
213 List<BoneGroup> boneGroupList = getPmdModel().getBoneGroupList();
214 ListUtil.assignIndexedSerial(boneGroupList);
219 * boneGroupタグ開始の通知を受け取る。
221 @OpenXmlMark(PmdTag.BONE_GROUP)
222 void openBoneGroup(){
223 this.currentBoneGroup = new BoneGroup();
225 String nameAttr = getStringAttr(PmdAttr.NAME);
226 I18nText groupName = this.currentBoneGroup.getGroupName();
227 groupName.setPrimaryText(nameAttr);
233 * boneGroupタグ終了の通知を受け取る。
235 @CloseXmlMark(PmdTag.BONE_GROUP)
236 void closeBoneGroup(){
237 List<BoneGroup> boneGroupList = getPmdModel().getBoneGroupList();
238 boneGroupList.add(this.currentBoneGroup);
240 this.currentBoneGroup = null;
246 * boneGroupMemberタグ開始の通知を受け取る。
248 @OpenXmlMark(PmdTag.BONE_GROUP_MEMBER)
249 void openBoneGroupMember(){
250 String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
252 BoneInfo bone = this.helper.findBoneId(boneIdRef);
254 List<BoneInfo> boneList = this.currentBoneGroup.getBoneList();
261 * ikChainタグ開始の通知を受け取る。
263 @OpenXmlMark(PmdTag.IK_CHAIN)
265 this.currentIkChain = new IKChain();
267 String ikBoneIdRef = getStringAttr(PmdAttr.IK_BONE_IDREF);
268 BoneInfo bone = this.helper.findBoneId(ikBoneIdRef);
269 this.currentIkChain.setIkBone(bone);
271 int depth = getIntAttr(PmdAttr.RECURSIVE_DEPTH);
272 this.currentIkChain.setIKDepth(depth);
274 float weight = getFloatAttr(PmdAttr.WEIGHT);
275 this.currentIkChain.setIKWeight(weight);
281 * ikChainタグ終了の通知を受け取る。
283 @CloseXmlMark(PmdTag.IK_CHAIN)
285 List<IKChain> ikChainList = getPmdModel().getIKChainList();
286 ikChainList.add(this.currentIkChain);
288 this.currentIkChain = null;
294 * chainOrderタグ開始の通知を受け取る。
296 @OpenXmlMark(PmdTag.CHAIN_ORDER)
297 void openChainOrder(){
298 String boneIdRef = getStringAttr(PmdAttr.BONE_IDREF);
299 BoneInfo bone = this.helper.findBoneId(boneIdRef);
301 List<BoneInfo> chainList = this.currentIkChain.getChainedBoneList();