2 * typical bone information
4 * License : The MIT License
5 * Copyright(c) 2011 MikuToga Partners
8 package jp.sourceforge.mikutoga.typical;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.LinkedList;
15 import java.util.List;
17 import javax.xml.parsers.ParserConfigurationException;
18 import org.w3c.dom.Element;
19 import org.w3c.dom.NodeList;
20 import org.xml.sax.SAXException;
24 * <p>各ボーン情報はひとつ以上のプライマリ名(≒日本語名)と
25 * ゼロ個以上のグローバル名(≒英語名)を持つ。
27 * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
29 public final class TypicalBone extends I18nAlias {
31 private static final Class<?> THISCLASS = TypicalBone.class;
32 private static final String BONE_XML = "resources/typicalBone.xml";
34 private static final List<TypicalBone> TYP_BONE_LIST =
35 new LinkedList<TypicalBone>();
36 private static final Map<String, TypicalBone> PRIMARY_MAP =
37 new HashMap<String, TypicalBone>();
38 private static final Map<String, TypicalBone> GLOBAL_MAP =
39 new HashMap<String, TypicalBone>();
41 private static final List<TypicalBone> TYP_BONE_UNMODLIST =
42 Collections.unmodifiableList(TYP_BONE_LIST);
45 InputStream is = THISCLASS.getResourceAsStream(BONE_XML);
48 top = I18nAlias.loadXml(is);
49 }catch(ParserConfigurationException e){
50 throw new ExceptionInInitializerError(e);
51 }catch(SAXException e){
52 throw new ExceptionInInitializerError(e);
53 }catch(IOException e){
54 throw new ExceptionInInitializerError(e);
66 * 状況に応じて伸長する連結リストが用意される。
67 * @param primaryNo プライマリ名初期数。
68 * @param globalNo グローバル名初期数。
70 private TypicalBone(int primaryNo, int globalNo){
71 super(primaryNo, globalNo);
80 private static void parse(Element top) {
81 NodeList boneList = top.getElementsByTagName("bone");
82 int boneNo = boneList.getLength();
83 for(int idx = 0; idx < boneNo; idx++){
84 Element bone = (Element) boneList.item(idx);
85 TypicalBone typBone = parseBone(bone);
86 TYP_BONE_LIST.add(typBone);
97 private static TypicalBone parseBone(Element bone){
98 NodeList primaryNodes = bone.getElementsByTagName("primary");
99 NodeList globalNodes = bone.getElementsByTagName("global");
100 int primaryNo = primaryNodes.getLength();
101 int globalNo = globalNodes.getLength();
103 TypicalBone typBone = new TypicalBone(primaryNo, globalNo);
105 for(int idx = 0; idx < primaryNo; idx++){
106 Element primary = (Element) primaryNodes.item(idx);
107 String name = primary.getAttribute("name");
108 typBone.addPrimaryName(name);
111 for(int idx = 0; idx < globalNo; idx++){
112 Element global = (Element) globalNodes.item(idx);
113 String name = global.getAttribute("name");
114 typBone.addGlobalName(name);
117 for(String primaryName : typBone.getPrimaryList()){
118 String key = normalize(primaryName).intern();
119 PRIMARY_MAP.put(key, typBone);
122 for(String globalName : typBone.getGlobalList()){
123 String key = normalize(globalName).intern();
124 GLOBAL_MAP.put(key, typBone);
131 * 全ボーン情報を一意に順序付ける設定を行う。
134 private static void numbering(){
136 for(TypicalBone bone : TYP_BONE_LIST){
137 bone.setOrderNo(order++);
147 public static List<TypicalBone> getBoneList(){
148 return TYP_BONE_UNMODLIST;
152 * プライマリ名の合致するボーン情報を返す。
153 * NFKCで正規化されたプライマリ名で検索される。
154 * @param primaryName プライマリ名
155 * @return モーフ情報。見つからなければnull
157 public static TypicalBone findWithPrimary(String primaryName){
158 String key = normalize(primaryName);
159 TypicalBone result = PRIMARY_MAP.get(key);
164 * グローバル名の合致するボーン情報を返す。
165 * NFKCで正規化されたグローバル名で検索される。
166 * @param globalName グローバル名
167 * @return モーフ情報。見つからなければnull
169 public static TypicalBone findWithGlobal(String globalName){
170 String key = normalize(globalName);
171 TypicalBone result = GLOBAL_MAP.get(key);
176 * プライマリ名をグローバル名に変換する。
177 * @param primaryName プライマリ名
178 * @return グローバル名。見つからなければnull
180 public static String primary2global(String primaryName){
181 TypicalBone bone = findWithPrimary(primaryName);
182 if(bone == null) return null;
183 String global = bone.getTopGlobalName();
188 * グローバル名をプライマリ名へ変換する。
189 * @param globalName グローバル名
190 * @return プライマリ名。見つからなければnull
192 public static String global2primary(String globalName){
193 TypicalBone bone = findWithGlobal(globalName);
194 if(bone == null) return null;
195 String primary = bone.getTopPrimaryName();