2 * building bone information
4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sourceforge.mikutoga.pmd.model.binio;
10 import java.util.Iterator;
11 import java.util.LinkedList;
12 import java.util.List;
13 import jp.sourceforge.mikutoga.corelib.ListUtil;
14 import jp.sourceforge.mikutoga.math.MkPos3D;
15 import jp.sourceforge.mikutoga.parser.ParseStage;
16 import jp.sourceforge.mikutoga.pmd.BoneType;
17 import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
18 import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
19 import jp.sourceforge.mikutoga.pmd.model.IKChain;
20 import jp.sourceforge.mikutoga.pmd.model.PmdModel;
21 import jp.sourceforge.mikutoga.pmd.parser.PmdBoneHandler;
22 import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
27 class BoneBuilder implements PmdBoneHandler {
29 private final List<BoneInfo> boneList;
30 private Iterator<BoneInfo> boneIt;
31 private BoneInfo currentBone = null;
33 private final List<IKChain> ikChainList;
34 private Iterator<IKChain> ikChainIt;
35 private IKChain currentIkChain = null;
37 private final List<BoneGroup> boneGroupList;
38 private Iterator<BoneGroup> boneGroupIt;
39 private BoneGroup currentBoneGroup = null;
45 BoneBuilder(PmdModel model){
48 this.boneList = model.getBoneList();
49 this.ikChainList = model.getIKChainList();
50 this.boneGroupList = model.getBoneGroupList();
57 * @param stage {@inheritDoc}
58 * @param loops {@inheritDoc}
61 public void loopStart(ParseStage stage, int loops){
62 if(stage == PmdBoneHandler.BONE_LIST){
63 ListUtil.prepareDefConsList(this.boneList, BoneInfo.class, loops);
64 ListUtil.assignIndexedSerial(this.boneList);
66 this.boneIt = this.boneList.iterator();
67 if(this.boneIt.hasNext()){
68 this.currentBone = this.boneIt.next();
70 }else if(stage == PmdBoneHandler.IK_LIST){
71 ListUtil.prepareDefConsList(this.ikChainList,
75 this.ikChainIt = this.ikChainList.iterator();
76 if(this.ikChainIt.hasNext()){
77 this.currentIkChain = this.ikChainIt.next();
79 }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
81 }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
82 ListUtil.prepareDefConsList(this.boneGroupList,
85 ListUtil.assignIndexedSerial(this.boneGroupList);
87 this.boneGroupIt = this.boneGroupList.iterator();
89 assert this.boneGroupIt.hasNext();
90 this.boneGroupIt.next(); // デフォルトボーングループを読み飛ばす
92 if(this.boneGroupIt.hasNext()){
93 this.currentBoneGroup = this.boneGroupIt.next();
95 }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
99 throw new AssertionError();
107 * @param stage {@inheritDoc}
110 public void loopNext(ParseStage stage){
111 if(stage == PmdBoneHandler.BONE_LIST){
112 if(this.boneIt.hasNext()){
113 this.currentBone = this.boneIt.next();
115 }else if(stage == PmdBoneHandler.IK_LIST){
116 if(this.ikChainIt.hasNext()){
117 this.currentIkChain = this.ikChainIt.next();
119 }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
121 }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
122 if(this.boneGroupIt.hasNext()){
123 this.currentBoneGroup = this.boneGroupIt.next();
125 }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
129 throw new AssertionError();
136 * @param stage {@inheritDoc}
139 public void loopEnd(ParseStage stage){
140 if(stage == PmdBoneHandler.BONE_LIST){
142 }else if(stage == PmdBoneHandler.IK_LIST){
144 }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
146 }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
148 }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
152 throw new AssertionError();
158 * 所属グループの無いボーンをデフォルトボーングループへ登録する。
160 private void pickOrphanBone(){
161 List<BoneInfo> orpahnList = new LinkedList<BoneInfo>();
162 orpahnList.addAll(this.boneList);
163 for(BoneGroup group : this.boneGroupList){
164 orpahnList.removeAll(group.getBoneList());
167 BoneGroup defaultGroup = this.boneGroupList.get(0);
168 defaultGroup.getBoneList().addAll(orpahnList);
175 * @param boneName {@inheritDoc}
176 * @param boneKind {@inheritDoc}
179 public void pmdBoneInfo(String boneName, byte boneKind){
180 this.currentBone.getBoneName().setPrimaryText(boneName);
181 BoneType type = BoneType.decode(boneKind);
182 this.currentBone.setBoneType(type);
188 * @param parentId {@inheritDoc}
189 * @param tailId {@inheritDoc}
190 * @param ikId {@inheritDoc}
193 public void pmdBoneLink(int parentId, int tailId, int ikId){
194 BoneInfo prevBone = null;
195 if(0 <= parentId && parentId < PmdLimits.MAX_BONE){
196 prevBone = this.boneList.get(parentId);
199 BoneInfo nextBone = null;
201 nextBone = this.boneList.get(tailId);
204 BoneInfo ikBone = null;
205 if(this.currentBone.getBoneType() == BoneType.LINKEDROT){
208 this.currentBone.setRotationRatio(ratio);
209 }else if(0 < ikId && ikId < PmdLimits.MAX_BONE){
210 ikBone = this.boneList.get(ikId);
213 this.currentBone.setPrevBone(prevBone);
214 this.currentBone.setNextBone(nextBone);
215 this.currentBone.setIKBone(ikBone);
222 * @param xPos {@inheritDoc}
223 * @param yPos {@inheritDoc}
224 * @param zPos {@inheritDoc}
227 public void pmdBonePosition(float xPos, float yPos, float zPos){
228 MkPos3D position = this.currentBone.getPosition();
229 position.setXpos(xPos);
230 position.setYpos(yPos);
231 position.setZpos(zPos);
237 * @param boneId {@inheritDoc}
238 * @param targetId {@inheritDoc}
239 * @param depth {@inheritDoc}
240 * @param weight {@inheritDoc}
243 public void pmdIKInfo(int boneId, int targetId, int depth, float weight){
244 BoneInfo bone = this.boneList.get(boneId);
245 this.currentIkChain.setIkBone(bone);
247 BoneInfo target = this.boneList.get(targetId);
248 this.currentIkChain.getChainedBoneList().add(0, target);
250 this.currentIkChain.setIKDepth(depth);
251 this.currentIkChain.setIKWeight(weight);
258 * @param childId {@inheritDoc}
261 public void pmdIKChainInfo(int childId){
262 BoneInfo chain = this.boneList.get(childId);
263 this.currentIkChain.getChainedBoneList().add(chain);
269 * @param groupName {@inheritDoc}
272 public void pmdBoneGroupInfo(String groupName){
273 this.currentBoneGroup.getGroupName().setPrimaryText(groupName);
279 * @param boneId {@inheritDoc}
280 * @param groupId {@inheritDoc}
283 public void pmdGroupedBoneInfo(int boneId, int groupId){
284 BoneInfo bone = this.boneList.get(boneId);
285 BoneGroup group = this.boneGroupList.get(groupId);
286 group.getBoneList().add(bone);