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.HashMap;
13 import java.util.LinkedList;
14 import java.util.List;
16 import javax.xml.parsers.ParserConfigurationException;
17 import org.w3c.dom.Element;
18 import org.w3c.dom.NodeList;
19 import org.xml.sax.SAXException;
23 * <p>各ボーン情報はひとつ以上のプライマリ名(≒日本語名)と
24 * ゼロ個以上のグローバル名(≒英語名)を持つ。
26 * <p>和英対訳はMMD Ver7.39の同梱モデルにほぼ準拠。
28 public final class TypicalBone extends TypicalObject {
30 private static final Class<?> THISCLASS = TypicalBone.class;
31 private static final String BONE_XML = "resources/typicalBone.xml";
33 private static final List<TypicalBone> TYP_BONE_LIST =
34 new LinkedList<TypicalBone>();
35 private static final Map<String, TypicalBone> PRIMARY_MAP =
36 new HashMap<String, TypicalBone>();
37 private static final Map<String, TypicalBone> GLOBAL_MAP =
38 new HashMap<String, TypicalBone>();
42 InputStream is = THISCLASS.getResourceAsStream(BONE_XML);
45 top = TypicalObject.loadXml(is);
46 }catch(ParserConfigurationException e){
47 throw new ExceptionInInitializerError(e);
48 }catch(SAXException e){
49 throw new ExceptionInInitializerError(e);
50 }catch(IOException e){
51 throw new ExceptionInInitializerError(e);
62 * <p>各初期数が0以下の場合は、状況に応じて伸長する連結リストが用意される。
63 * @param primaryNo プライマリ名初期数。
64 * @param globalNo グローバル名初期数。
66 private TypicalBone(int primaryNo, int globalNo){
67 super(primaryNo, globalNo);
76 private static void parse(Element top) {
77 NodeList boneList = top.getElementsByTagName("bone");
78 int boneNo = boneList.getLength();
79 for(int idx = 0; idx < boneNo; idx++){
80 Element bone = (Element) boneList.item(idx);
81 TypicalBone typBone = parseBone(bone);
82 TYP_BONE_LIST.add(typBone);
93 private static TypicalBone parseBone(Element bone){
94 NodeList primaryNodes = bone.getElementsByTagName("primary");
95 NodeList globalNodes = bone.getElementsByTagName("global");
96 int primaryNo = primaryNodes.getLength();
97 int globalNo = globalNodes.getLength();
99 TypicalBone typBone = new TypicalBone(primaryNo, globalNo);
101 for(int idx = 0; idx < primaryNo; idx++){
102 Element primary = (Element) primaryNodes.item(idx);
103 String name = primary.getAttribute("name");
104 typBone.primaryList.add(name);
107 for(int idx = 0; idx < globalNo; idx++){
108 Element global = (Element) globalNodes.item(idx);
109 String name = global.getAttribute("name");
110 typBone.globalList.add(name);
113 for(String primaryName : typBone.primaryList){
114 PRIMARY_MAP.put(primaryName, typBone);
117 for(String globalName : typBone.globalList){
118 GLOBAL_MAP.put(globalName, typBone);
125 * 全ボーン情報を一意に順序付ける設定を行う。
128 private static void numbering(){
130 for(TypicalBone bone : TYP_BONE_LIST){
131 bone.orderNo = order++;
138 * プライマリ名の合致するボーン情報を返す。
139 * @param primaryName プライマリ名
140 * @return モーフ情報。見つからなければnull
142 public static TypicalBone findWithPrimary(String primaryName){
143 TypicalBone result = PRIMARY_MAP.get(primaryName);
148 * グローバル名の合致するボーン情報を返す。
149 * @param globalName グローバル名
150 * @return モーフ情報。見つからなければnull
152 public static TypicalBone findWithGlobal(String globalName){
153 TypicalBone result = GLOBAL_MAP.get(globalName);
158 * プライマリ名をグローバル名に変換する。
159 * @param primaryName プライマリ名
160 * @return グローバル名。見つからなければnull
162 public static String primary2global(String primaryName){
163 TypicalBone bone = findWithPrimary(primaryName);
164 if(bone == null) return null;
165 String global = bone.getTopGlobalName();
170 * グローバル名をプライマリ名へ変換する。
171 * @param globalName グローバル名
172 * @return プライマリ名。見つからなければnull
174 public static String global2primary(String globalName){
175 TypicalBone bone = findWithGlobal(globalName);
176 if(bone == null) return null;
177 String primary = bone.getTopPrimaryName();