OSDN Git Service

28a00ea80a7f984b7f1c50192520e61560458025
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / pmd / pmdloader / BoneBuilder.java
1 /*
2  * building bone information
3  *
4  * License : The MIT License
5  * Copyright(c) 2010 MikuToga Partners
6  */
7
8 package jp.sourceforge.mikutoga.pmd.pmdloader;
9
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.parser.ParseStage;
15 import jp.sourceforge.mikutoga.parser.pmd.PmdBoneHandler;
16 import jp.sourceforge.mikutoga.parser.pmd.PmdLimits;
17 import jp.sourceforge.mikutoga.pmd.BoneGroup;
18 import jp.sourceforge.mikutoga.pmd.BoneInfo;
19 import jp.sourceforge.mikutoga.pmd.BoneType;
20 import jp.sourceforge.mikutoga.pmd.IKChain;
21 import jp.sourceforge.mikutoga.pmd.PmdModel;
22 import jp.sourceforge.mikutoga.pmd.Pos3d;
23
24 /**
25  * ボーン関係の通知をパーサから受け取る。
26  */
27 class BoneBuilder implements PmdBoneHandler {
28
29     private final List<BoneInfo> boneList;
30     private Iterator<BoneInfo> boneIt;
31     private BoneInfo currentBone = null;
32
33     private final List<IKChain> ikChainList;
34     private Iterator<IKChain> ikChainIt;
35     private IKChain currentIkChain = null;
36
37     private final List<BoneGroup> boneGroupList;
38     private Iterator<BoneGroup> boneGroupIt;
39     private BoneGroup currentBoneGroup = null;
40
41     /**
42      * コンストラクタ。
43      * @param model モデル
44      */
45     BoneBuilder(PmdModel model){
46         super();
47
48         this.boneList      = model.getBoneList();
49         this.ikChainList   = model.getIKChainList();
50         this.boneGroupList = model.getBoneGroupList();
51
52         return;
53     }
54
55     /**
56      * {@inheritDoc}
57      * @param stage {@inheritDoc}
58      * @param loops {@inheritDoc}
59      */
60     @Override
61     public void loopStart(ParseStage stage, int loops){
62         assert stage instanceof PmdBoneStage;
63
64         if(stage == PmdBoneHandler.BONE_LIST){
65             ListUtil.prepareDefConsList(this.boneList, BoneInfo.class, loops);
66             ListUtil.assignIndexedSerial(this.boneList);
67
68             this.boneIt = this.boneList.iterator();
69             if(this.boneIt.hasNext()){
70                 this.currentBone = this.boneIt.next();
71             }
72         }else if(stage == PmdBoneHandler.IK_LIST){
73             ListUtil.prepareDefConsList(this.ikChainList,
74                                         IKChain.class,
75                                         loops );
76
77             this.ikChainIt = this.ikChainList.iterator();
78             if(this.ikChainIt.hasNext()){
79                 this.currentIkChain = this.ikChainIt.next();
80             }
81         }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
82             //NOTHING
83         }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
84             ListUtil.prepareDefConsList(this.boneGroupList,
85                                         BoneGroup.class,
86                                         loops + 1 );
87             ListUtil.assignIndexedSerial(this.boneGroupList);
88
89             this.boneGroupIt = this.boneGroupList.iterator();
90
91             assert this.boneGroupIt.hasNext();
92             this.boneGroupIt.next();     // デフォルトボーングループを読み飛ばす
93
94             if(this.boneGroupIt.hasNext()){
95                 this.currentBoneGroup = this.boneGroupIt.next();
96             }
97         }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
98             //NOTHING
99         }else{
100             assert false;
101             throw new AssertionError();
102         }
103
104         return;
105     }
106
107     /**
108      * {@inheritDoc}
109      * @param stage {@inheritDoc}
110      */
111     @Override
112     public void loopNext(ParseStage stage){
113         assert stage instanceof PmdBoneStage;
114
115         if(stage == PmdBoneHandler.BONE_LIST){
116             if(this.boneIt.hasNext()){
117                 this.currentBone = this.boneIt.next();
118             }
119         }else if(stage == PmdBoneHandler.IK_LIST){
120             if(this.ikChainIt.hasNext()){
121                 this.currentIkChain = this.ikChainIt.next();
122             }
123         }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
124             //NOTHING
125         }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
126             if(this.boneGroupIt.hasNext()){
127                 this.currentBoneGroup = this.boneGroupIt.next();
128             }
129         }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
130             //NOTHING
131         }else{
132             assert false;
133             throw new AssertionError();
134         }
135         return;
136     }
137
138     /**
139      * {@inheritDoc}
140      * @param stage {@inheritDoc}
141      */
142     @Override
143     public void loopEnd(ParseStage stage){
144         assert stage instanceof PmdBoneStage;
145
146         if(stage == PmdBoneHandler.BONE_LIST){
147             //NOTHING
148         }else if(stage == PmdBoneHandler.IK_LIST){
149             //NOTHING
150         }else if(stage == PmdBoneHandler.IKCHAIN_LIST){
151             //NOTHING
152         }else if(stage == PmdBoneHandler.BONEGROUP_LIST){
153             //NOTHING
154         }else if(stage == PmdBoneHandler.GROUPEDBONE_LIST){
155             pickOrphanBone();
156         }else{
157             assert false;
158             throw new AssertionError();
159         }
160         return;
161     }
162
163     /**
164      * 所属グループの無いボーンをデフォルトボーングループへ登録する。
165      */
166     private void pickOrphanBone(){
167         List<BoneInfo> orpahnList = new LinkedList<BoneInfo>();
168         orpahnList.addAll(this.boneList);
169         for(BoneGroup group : this.boneGroupList){
170             orpahnList.removeAll(group.getBoneList());
171         }
172
173         BoneGroup defaultGroup = this.boneGroupList.get(0);
174         defaultGroup.getBoneList().addAll(orpahnList);
175
176         return;
177     }
178
179     /**
180      * {@inheritDoc}
181      * @param boneName {@inheritDoc}
182      * @param boneKind {@inheritDoc}
183      */
184     @Override
185     public void pmdBoneInfo(String boneName, byte boneKind){
186         this.currentBone.getBoneName().setPrimaryText(boneName);
187         BoneType type = BoneType.decode(boneKind);
188         this.currentBone.setBoneType(type);
189         return;
190     }
191
192     /**
193      * {@inheritDoc}
194      * @param parentId {@inheritDoc}
195      * @param tailId {@inheritDoc}
196      * @param ikId {@inheritDoc}
197      */
198     @Override
199     public void pmdBoneLink(int parentId, int tailId, int ikId){
200         BoneInfo prevBone = null;
201         if(0 <= parentId && parentId < PmdLimits.MAX_BONE){
202             prevBone = this.boneList.get(parentId);
203         }
204
205         BoneInfo nextBone = null;
206         if(tailId != 0){
207             nextBone = this.boneList.get(tailId);
208         }
209
210         BoneInfo ikBone = null;
211         if(this.currentBone.getBoneType() == BoneType.LINKEDROT){
212             ikBone = null;
213             int ratio = ikId;
214             this.currentBone.setRotationRatio(ratio);
215         }else if(0 < ikId && ikId < PmdLimits.MAX_BONE){
216             ikBone = this.boneList.get(ikId);
217         }
218
219         this.currentBone.setPrevBone(prevBone);
220         this.currentBone.setNextBone(nextBone);
221         this.currentBone.setIKBone(ikBone);
222
223         return;
224     }
225
226     /**
227      * {@inheritDoc}
228      * @param xPos {@inheritDoc}
229      * @param yPos {@inheritDoc}
230      * @param zPos {@inheritDoc}
231      */
232     @Override
233     public void pmdBonePosition(float xPos, float yPos, float zPos){
234         Pos3d position = this.currentBone.getPosition();
235         position.setXPos(xPos);
236         position.setYPos(yPos);
237         position.setZPos(zPos);
238         return;
239     }
240
241     /**
242      * {@inheritDoc}
243      * @param boneId {@inheritDoc}
244      * @param targetId {@inheritDoc}
245      * @param depth {@inheritDoc}
246      * @param weight {@inheritDoc}
247      */
248     @Override
249     public void pmdIKInfo(int boneId, int targetId, int depth, float weight){
250         BoneInfo bone = this.boneList.get(boneId);
251         this.currentIkChain.setIkBone(bone);
252
253         BoneInfo target = this.boneList.get(targetId);
254         this.currentIkChain.getChainedBoneList().add(0, target);
255
256         this.currentIkChain.setIKDepth(depth);
257         this.currentIkChain.setIKWeight(weight);
258
259         return;
260     }
261
262     /**
263      * {@inheritDoc}
264      * @param childId {@inheritDoc}
265      */
266     @Override
267     public void pmdIKChainInfo(int childId){
268         BoneInfo chain = this.boneList.get(childId);
269         this.currentIkChain.getChainedBoneList().add(chain);
270         return;
271     }
272
273     /**
274      * {@inheritDoc}
275      * @param groupName {@inheritDoc}
276      */
277     @Override
278     public void pmdBoneGroupInfo(String groupName){
279         this.currentBoneGroup.getGroupName().setPrimaryText(groupName);
280         return;
281     }
282
283     /**
284      * {@inheritDoc}
285      * @param boneId {@inheritDoc}
286      * @param groupId {@inheritDoc}
287      */
288     @Override
289     public void pmdGroupedBoneInfo(int boneId, int groupId){
290         BoneInfo bone = this.boneList.get(boneId);
291         BoneGroup group = this.boneGroupList.get(groupId);
292         group.getBoneList().add(bone);
293         return;
294     }
295
296 }