OSDN Git Service

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