OSDN Git Service

fix bone.
authorousttrue <ousttrue@gmail.com>
Thu, 27 May 2010 22:53:53 +0000 (07:53 +0900)
committerousttrue <ousttrue@gmail.com>
Thu, 27 May 2010 22:53:53 +0000 (07:53 +0900)
swig/blender24/pmd_export.py
swig/blender24/pmd_import.py
swig/englishmap.py

index 36f37e9..60ec6e0 100644 (file)
@@ -390,14 +390,20 @@ class OneSkinMesh(object):
 
 
 class Bone(object):
-    __slots__=['index', 'name', 'pos', 'parent_index', 'tail_index', 'type']
-    def __init__(self, name, pos):
+    __slots__=['index', 'name', 
+            'pos', 'tail', 'parent_index', 'tail_index', 'type', 'isConnect']
+    def __init__(self, name, pos, tail):
         self.index=-1
         self.name=name
-        self.pos=[pos.x, pos.y, pos.z]
+        self.pos=pos
+        self.tail=tail
         self.parent_index=None
         self.tail_index=None
         self.type=0
+        self.isConnect=False
+
+    def __eq__(self, rhs):
+        return self.index==rhs.index
 
     def __str__(self):
         return "<Bone %s %d>" % (self.name, self.type)
@@ -410,22 +416,49 @@ class BoneBuilder(object):
         self.ik_list=[]
 
     def build(self, armatureObj):
-        if armatureObj:
-            armature=armatureObj.getData()
-            for b in armature.bones.values():
-                if b.name=='center':
-                    # root bone
-                    bone=Bone(b.name, b.head['ARMATURESPACE'])
-                    self.__addBone(bone)
-                    self.__getBone(bone, b)
-
-            for b in armature.bones.values():
-                if not b.parent and b.name!='center':
-                    # root bone
-                    bone=Bone(b.name, b.head['ARMATURESPACE'])
-                    self.__addBone(bone)
-                    self.__getBone(bone, b)
+        if not armatureObj:
+            return
 
+        print("gather bones")
+        armature=armatureObj.getData()
+        for b in armature.bones.values():
+            if b.name=='center':
+                # root bone
+                bone=Bone(b.name, 
+                        b.head['ARMATURESPACE'][0:3], 
+                        b.tail['ARMATURESPACE'][0:3])
+                self.__addBone(bone)
+                self.__getBone(bone, b)
+
+        for b in armature.bones.values():
+            if not b.parent and b.name!='center':
+                # root bone
+                bone=Bone(b.name, 
+                        b.head['ARMATURESPACE'][0:3], 
+                        b.tail['ARMATURESPACE'][0:3])
+                self.__addBone(bone)
+                self.__getBone(bone, b)
+
+        print("check connection")
+        for b in armature.bones.values():
+            if not b.parent:
+                self.__checkConnection(b, None)
+
+        print("create tail")
+        before=self.bones[:]
+        for b in before:
+            if not b.isConnect:
+                # 末端の非表示ボーン
+                if not b.tail:
+                    print(b.name)
+                    assert(False)
+                bone=Bone(b.name+'_t', b.tail, None)
+                bone.type=7
+                self.__addBone(bone)
+                bone.parent_index=b.index
+                b.tail_index=bone.index
+
+        print("gather ik")
         pose = armatureObj.getPose()
         cSetting=Blender.Constraint.Settings
         for b in pose.bones.values():
@@ -465,12 +498,44 @@ class BoneBuilder(object):
                     if target_tail.type!=7:
                         target_bone=armature.bones[target.name]
                         bone=Bone(target.name+'_t', 
-                                target_bone.tail['ARMATURESPACE'])
+                                target_bone.tail['ARMATURESPACE'][0:3],
+                                None)
                         bone.type=7
                         self.__addBone(bone)
                         bone.parent_index=target.index
                         target.tail_index=bone.index
 
+    def __checkConnection(self, b, p):
+        if Blender.Armature.CONNECTED in b.options:
+            parent=self.__boneByName(p.name)
+            parent.isConnect=True
+
+        for c in b.children:
+            self.__checkConnection(c, b)
+
+    def sortBy(self, boneMap):
+        """
+        boneMap順に並べ替える
+        """
+        original=self.bones[:]
+        def getIndex(bone):
+            for i, k_v in enumerate(boneMap):
+                if k_v[0]==bone.name:
+                    return i
+            print(bone)
+
+        self.bones.sort(lambda l, r: getIndex(l)-getIndex(r))
+        sortMap={}
+        for i, b in enumerate(self.bones):
+            src=original.index(b)
+            sortMap[src]=i
+        for b in self.bones:
+            b.index=sortMap[b.index]
+            if b.parent_index:
+                b.parent_index=sortMap[b.parent_index]
+            if b.tail_index:
+                b.tail_index=sortMap[b.tail_index]
+
     def getIndex(self, bone):
         for i, b in enumerate(self.bones):
             if b==bone:
@@ -481,22 +546,10 @@ class BoneBuilder(object):
         return self.bones[self.boneMap[name]]
                     
     def __getBone(self, parent, b):
-        if not Blender.Armature.CONNECTED in b.options:
-            #print b, b.options
-            pass
-
-        if len(b.children)==0:
-            # 末端の非表示ボーン
-            bone=Bone(b.name+'_t', b.tail['ARMATURESPACE'])
-            bone.type=7
-            self.__addBone(bone)
-            assert(parent)
-            bone.parent_index=parent.index
-            parent.tail_index=bone.index
-            return
-
         for i, c in enumerate(b.children):
-            bone=Bone(c.name, c.head['ARMATURESPACE'])
+            bone=Bone(c.name, 
+                    c.head['ARMATURESPACE'][0:3], 
+                    c.tail['ARMATURESPACE'][0:3])
             self.__addBone(bone)
             if parent:
                 bone.parent_index=parent.index
@@ -532,6 +585,11 @@ class PmdExporter(object):
         print(self.oneSkinMesh)
         self.name=root.o.name
 
+        # skeleton
+        self.builder=BoneBuilder()
+        self.builder.build(self.armatureObj)
+        self.builder.sortBy(englishmap.boneMap)
+
     def __createOneSkinMesh(self, node):
         ############################################################
         # search armature modifier
@@ -556,10 +614,6 @@ class PmdExporter(object):
         io.comment="blender export"
         io.version=1.0
 
-        # skeleton
-        builder=BoneBuilder()
-        builder.build(self.armatureObj)
-
         # 頂点
         for pos, normal, uv, b0, b1, weight in self.oneSkinMesh.vertexArray.zip():
             # convert right-handed z-up to left-handed y-up
@@ -572,8 +626,8 @@ class PmdExporter(object):
             v.normal.z=normal[1]
             v.uv.x=uv[0]
             v.uv.y=uv[1]
-            v.bone0=builder.boneMap[b0] if b0 in builder.boneMap else 0
-            v.bone1=builder.boneMap[b1] if b1 in builder.boneMap else 0
+            v.bone0=self.builder.boneMap[b0] if b0 in self.builder.boneMap else 0
+            v.bone1=self.builder.boneMap[b1] if b1 in self.builder.boneMap else 0
             v.weight0=int(100*weight)
             v.edge_flag=0 # edge flag, 0: enable edge, 1: not edge
 
@@ -613,14 +667,18 @@ class PmdExporter(object):
                 #io.indices.append(indices[i+2])
 
         # bones
-        for b in builder.bones:
+        for b in self.builder.bones:
+            if b.name.endswith("_t"):
+                if b.name.startswith("arm twist1_") or b.name.startswith("arm twist2_"):
+                    # skip
+                    print "skip %s" % b.name
+                    continue
+
             bone=io.addBone()
 
-            unicode=englishmap.getUnicodeBoneName(b.name)
-            if unicode:
-                cp932=unicode.encode('cp932')
-            else:
-                cp932=b.name
+            v=englishmap.getUnicodeBoneName(b.name)
+            assert(v)
+            cp932=v[1].encode('cp932')
             bone_name="%s\n" % cp932
             assert(len(bone_name)<20)
             bone.name=bone_name
@@ -629,9 +687,19 @@ class PmdExporter(object):
             assert(len(bone_english_name)<20)
             bone.english_name=bone_english_name
 
-            bone.type=b.type
+            if len(v)>=3:
+                bone.type=v[2]
+            else:
+                bone.type=b.type
             bone.parent_index=b.parent_index if b.parent_index!=None else 0xFFFF
-            bone.tail_index=b.tail_index if b.tail_index!=None else 0
+
+            if b.tail_index!=None:
+                if bone.type==9:
+                    bone.tail_index=0
+                else:
+                    bone.tail_index=b.tail_index
+            else:
+                bone.tail_index=0
             # ToDo
             bone.ik_index=0xFFFF
             # convert right-handed z-up to left-handed y-up
@@ -640,15 +708,15 @@ class PmdExporter(object):
             bone.pos.z=b.pos[1]
 
         # IK
-        for ik in builder.ik_list:
+        for ik in self.builder.ik_list:
             solver=io.addIK()
-            solver.index=builder.getIndex(ik.target)
-            solver.target=builder.getIndex(ik.effector)
+            solver.index=self.builder.getIndex(ik.target)
+            solver.target=self.builder.getIndex(ik.effector)
             solver.length=ik.length
-            b=builder.bones[ik.effector.parent_index]
+            b=self.builder.bones[ik.effector.parent_index]
             for i in xrange(solver.length):
-                solver.children.append(builder.getIndex(b))
-                b=builder.bones[b.parent_index]
+                solver.children.append(self.builder.getIndex(b))
+                b=self.builder.bones[b.parent_index]
             solver.iterations=ik.iterations
             solver.weight=ik.weight
 
@@ -680,7 +748,7 @@ class PmdExporter(object):
         boneDisplayName.name="bones\n"
         boneDisplayName.english_name="bones\n"
         displayIndex=1
-        for i, b in enumerate(builder.bones):
+        for i, b in enumerate(self.builder.bones):
             if b.type in [6, 7]:
                 io.addBoneDisplay(i, displayIndex)
 
index 25093f4..a13cc4a 100644 (file)
@@ -331,38 +331,79 @@ def import16MaerialAndMesh(mesh, l, material_order, face_map, tex_dir):
     return vertex_map
 
 
-def build_bone(armature, b, parent=None):
-    if b.tail_index==0:
-        return
+def validParent(parent):
+    if parent==None:
+        return False
+    if parent.name.startswith("arm twist"):
+        return False
+    if parent.name.startswith("wrist twist"):
+        return False
+    return True
+
+
+class Builder(object):
+    def __init__(self):
+        self.boneMap={}
+
+    def build(self, armature, bones):
+        for b in bones:
+            if not b.parent:
+                self.__build(armature, b, None, None)
+
+    def __build(self, armature, b, p, parent):
+        name=englishmap.getEnglishBoneName(b.getName())
+        if not name:
+            name=b.getName().encode(INTERNAL_ENCODING)
+        self.boneMap[name]=b
+
+        if b.tail_index==0:
+            return
+
+        bone=Blender.Armature.Editbone()
+        bone.name=name
+        armature.bones[name] = bone
+
+        if bone.name=='center':
+            # center
+            pos=Mathutils.Vector(*convert_coord(b.pos))
+            bone.tail = pos
+            bone.head = pos-Mathutils.Vector(0, 0.01, 0)
+        else:
+            bone.head = Mathutils.Vector(*convert_coord(b.pos))
+            bone.tail = Mathutils.Vector(*convert_coord(b.tail))
+
+            if validParent(parent):
+                bone.parent=parent
+                if parent.tail==bone.head:
+                    bone.parent=parent
+                    bone.options=[Blender.Armature.CONNECTED]
 
-    bone = Blender.Armature.Editbone()
-    name=englishmap.getEnglishBoneName(b.getName())
-    bone.name = name if name else b.getName().encode(
-            INTERNAL_ENCODING)
-    armature.bones[bone.name] = bone
-    if parent:
-        bone.head = Mathutils.Vector(*convert_coord(b.pos))
-        bone.parent=parent
-        options=[]
-        if parent.tail==bone.head:
-            options.append(Blender.Armature.CONNECTED)
-        bone.options=options
-        bone.tail = Mathutils.Vector(*convert_coord(b.tail))
-        if bone.head==bone.tail:
-            bone.tail=bone.head-Mathutils.Vector(0, 1, 0)
-    elif b.type==pmd.BONE_IK:
-        bone.head = Mathutils.Vector(*convert_coord(b.pos))
-        bone.tail = Mathutils.Vector(*convert_coord(b.tail))
-    else:
-        # center
-        print(bone.name)
-        pos=Mathutils.Vector(*convert_coord(b.pos))
-        bone.tail = pos
-        bone.head = pos-Mathutils.Vector(0, 0.01, 0)
-
-    for child in b.children:
-        build_bone(armature, child, bone)
+            if bone.head==bone.tail:
+                bone.tail=bone.head-Mathutils.Vector(0, 1, 0)
 
+        for c in b.children:
+            self.__build(armature, c, b, bone)
+
+    def connect(self, armature):
+        def getKey(index):
+            for key, value in self.boneMap.items():
+                if index==value.index:
+                    return key
+
+        for k, b in self.boneMap.items():
+            if b.tail_index==0:
+                continue
+            bone=armature.bones[k]
+            key=getKey(b.tail_index)
+            if not key:
+                return
+            try:
+                tail=armature.bones[key]
+                # connect
+                tail.parent=bone
+                tail.options=[Blender.Armature.CONNECTED]
+            except:
+                pass
 
 def importArmature(scene, l):
     # create armature
@@ -383,9 +424,11 @@ def importArmature(scene, l):
 
     # create armature
     armature.makeEditable()
-    for b in l.bones:
-        if not b.parent:
-            build_bone(armature, b)
+
+    builder=Builder()
+    builder.build(armature, l.bones)
+    builder.connect(armature)
+
     armature.update()
 
     ############################################################
index 0a5a116..fb83fee 100644 (file)
@@ -5,161 +5,168 @@ import sys
 ###############################################################################
 # 日本語名との変換マップ
 ###############################################################################
-boneMap={
-"center":"センター",
-"upper body":"上半身",
-"neck":"首",
-"head":"頭",
-"eye_L":"左目",
-"eye_R":"右目",
-"necktie1":"ネクタイ1",
-"necktie2":"ネクタイ2",
-"necktie3":"ネクタイ3",
-"lower body":"下半身",
-"waist accessory":"腰飾り",
-"hair1_L":"左髪1",
-"hair2_L":"左髪2",
-"hair3_L":"左髪3",
-"hair4_L":"左髪4",
-"hair5_L":"左髪5",
-"hair6_L":"左髪6",
-"shoulder_L":"左肩",
-"arm_L":"左腕",
-"arm twist_L":"左腕捩",
-"elbow_L":"左ひじ",
-"wrist twist_L":"左手捩",
-"wrist_L":"左手首",
-"sleeve_L":"左袖",
-"thumb1_L":"左親指1",
-"thumb2_L":"左親指2",
-"fore1_L":"左人指1",
-"fore2_L":"左人指2",
-"fore3_L":"左人指3",
-"middle1_L":"左中指1",
-"middle2_L":"左中指2",
-"middle3_L":"左中指3",
-"third1_L":"左薬指1",
-"third2_L":"左薬指2",
-"third3_L":"左薬指3",
-"little1_L":"左小指1",
-"little2_L":"左小指2",
-"little3_L":"左小指3",
-"front skirt_L":"左スカート前",
-"back skirt_L":"左スカート後",
-"leg_L":"左足",
-"knee_L":"左ひざ",
-"ankle_L":"左足首",
-"hair1_R":"右髪1",
-"hair2_R":"右髪2",
-"hair3_R":"右髪3",
-"hair4_R":"右髪4",
-"hair5_R":"右髪5",
-"hair6_R":"右髪6",
-"shoulder_R":"右肩",
-"arm_R":"右腕",
-"arm twist_R":"右腕捩",
-"elbow_R":"右ひじ",
-"wrist twist_R":"右手捩",
-"wrist_R":"右手首",
-"sleeve_R":"右袖",
-"thumb1_R":"右親指1",
-"thumb2_R":"右親指2",
-"fore1_R":"右人指1",
-"fore2_R":"右人指2",
-"fore3_R":"右人指3",
-"middle1_R":"右中指1",
-"middle2_R":"右中指2",
-"middle3_R":"右中指3",
-"third1_R":"右薬指1",
-"third2_R":"右薬指2",
-"third3_R":"右薬指3",
-"little1_R":"右小指1",
-"little2_R":"右小指2",
-"little3_R":"右小指3",
-"front skirt_R":"右スカート前",
-"back skirt_R":"右スカート後",
-"leg_R":"右足",
-"knee_R":"右ひざ",
-"ankle_R":"右足首",
-"eyes":"両目",
-"front hair1":"前髪1",
-"front hair2":"前髪2",
-"front hair3":"前髪3",
-"eyelight_L":"左目光",
-"eyelight_R":"右目光",
-"necktie4":"ネクタイ4",
-"hair7_L":"左髪7",
-"hair7_R":"右髪7",
-"toe_L":"左つま先",
-"toe_R":"右つま先",
-"necktie IK":"ネクタイIK",
-"hair IK_L":"左髪IK",
-"hair IK_R":"右髪IK",
-"leg IK_L":"左足IK",
-"leg IK_R":"右足IK",
-"toe IK_L":"左つま先IK",
-"toe IK_R":"右つま先IK",
-"bone093":"下半身先",
-"bone094":"頭先",
-"bone095":"左目先",
-"bone096":"右目先",
-"bone097":"腰飾り先",
-"bone098":"左袖先",
-"bone099":"左手先",
-"bone100":"左親指先",
-"bone101":"左人差指先",
-"bone102":"左中指先",
-"bone103":"左薬指先",
-"bone104":"左小指先",
-"bone105":"左スカート前先",
-"bone106":"左スカート後先",
-"bone107":"右袖先",
-"bone108":"右手先",
-"bone109":"右親指先",
-"bone110":"右人差指先",
-"bone111":"右中指先",
-"bone112":"右薬指先",
-"bone113":"右小指先",
-"bone114":"右スカート前先",
-"bone115":"右スカート後先",
-"bone116":"センター先",
-"bone117":"両目先",
-"bone118":"ネクタイIK先",
-"bone119":"左髪IK先",
-"bone120":"右髪IK先",
-"bone121":"左足IK先",
-"bone122":"右足IK先",
-"bone123":"左つま先IK先",
-"bone124":"右つま先IK先",
-"bone125":"前髪1先",
-"bone126":"前髪2先",
-"bone127":"前髪3先",
-"bone128":"左目光先",
-"bone129":"右目光先",
-"bone130":"左腕捩先",
-"bone131":"左手捩先",
-"bone132":"右腕捩先",
-"bone133":"右手捩先",
-"ude hineri1_L":"左腕捩1",
-"ude hineri2_L":"左腕捩2",
-"ude hineri3_L":"左腕捩3",
-"ude hineri1_R":"右腕捩1",
-"ude hineri2_R":"右腕捩2",
-"ude hineri3_R":"右腕捩3",
-}
+boneMap=[
+("center", "センター", 1),
+("upper body", "上半身"),
+("neck", "首"),
+("head", "頭"),
+("eye_L", "左目", 5),
+("eye_R", "右目", 5),
+("necktie1", "ネクタイ1"),
+("necktie2", "ネクタイ2"),
+("necktie3", "ネクタイ3"),
+("lower body", "下半身"),
+("waist accessory", "腰飾り"),
+("hair1_L", "左髪1"),
+("hair2_L", "左髪2"),
+("hair3_L", "左髪3"),
+("hair4_L", "左髪4"),
+("hair5_L", "左髪5"),
+("hair6_L", "左髪6"),
+("shoulder_L", "左肩"),
+("arm_L", "左腕"),
+("arm twist_L", "左腕捩", 8),
+("elbow_L", "左ひじ"),
+("wrist twist_L", "左手捩", 8),
+("wrist_L", "左手首"),
+("sleeve_L", "左袖", 1),
+("thumb1_L", "左親指1"),
+("thumb2_L", "左親指2"),
+("fore1_L", "左人指1"),
+("fore2_L", "左人指2"),
+("fore3_L", "左人指3"),
+("middle1_L", "左中指1"),
+("middle2_L", "左中指2"),
+("middle3_L", "左中指3"),
+("third1_L", "左薬指1"),
+("third2_L", "左薬指2"),
+("third3_L", "左薬指3"),
+("little1_L", "左小指1"),
+("little2_L", "左小指2"),
+("little3_L", "左小指3"),
+("front skirt_L", "左スカート前"),
+("back skirt_L", "左スカート後"),
+("leg_L", "左足"),
+("knee_L", "左ひざ"),
+("ankle_L", "左足首"),
+("hair1_R", "右髪1"),
+("hair2_R", "右髪2"),
+("hair3_R", "右髪3"),
+("hair4_R", "右髪4"),
+("hair5_R", "右髪5"),
+("hair6_R", "右髪6"),
+("shoulder_R", "右肩"),
+("arm_R", "右腕"),
+("arm twist_R", "右腕捩", 8),
+("elbow_R", "右ひじ"),
+("wrist twist_R", "右手捩", 8),
+("wrist_R", "右手首"),
+("sleeve_R", "右袖", 1),
+("thumb1_R", "右親指1"),
+("thumb2_R", "右親指2"),
+("fore1_R", "右人指1"),
+("fore2_R", "右人指2"),
+("fore3_R", "右人指3"),
+("middle1_R", "右中指1"),
+("middle2_R", "右中指2"),
+("middle3_R", "右中指3"),
+("third1_R", "右薬指1"),
+("third2_R", "右薬指2"),
+("third3_R", "右薬指3"),
+("little1_R", "右小指1"),
+("little2_R", "右小指2"),
+("little3_R", "右小指3"),
+("front skirt_R", "右スカート前"),
+("back skirt_R", "右スカート後"),
+("leg_R", "右足"),
+("knee_R", "右ひざ"),
+("ankle_R", "右足首"),
+("eyes", "両目"),
+("front hair1", "前髪1"),
+("front hair2", "前髪2"),
+("front hair3", "前髪3"),
+("eyelight_L", "左目光"),
+("eyelight_R", "右目光"),
+("necktie3_t", "ネクタイ4"),
+("hair6_L_t", "左髪7"),
+("hair6_R_t", "右髪7"),
+("ankle_L_t", "左つま先"),
+("ankle_R_t", "右つま先"),
+("necktie IK", "ネクタイIK"),
+("hair IK_L", "左髪IK"),
+("hair IK_R", "右髪IK"),
+("leg IK_L", "左足IK"),
+("leg IK_R", "右足IK"),
+("toe IK_L", "左つま先IK"),
+("toe IK_R", "右つま先IK"),
+
+("lower body_t", "下半身先"),
+("head_t", "頭先"),
+("eye_L_t", "左目先"),
+("eye_R_t", "右目先"),
+("waist accessory_t", "腰飾り先"),
+
+("sleeve_L_t", "左袖先"),
+("wrist_L_t", "左手先"),
+("thumb2_L_t", "左親指先"),
+("fore3_L_t", "左人差指先"),
+("middle3_L_t", "左中指先"),
+("third3_L_t", "左薬指先"),
+("little3_L_t", "左小指先"),
+("front skirt_L_t", "左スカート前先"),
+("back skirt_L_t", "左スカート後先"),
+
+("sleeve_R_t", "右袖先"),
+("wrist_R_t", "右手先"),
+("thumb2_R_t", "右親指先"),
+("fore3_R_t", "右人差指先"),
+("middle3_R_t", "右中指先"),
+("third3_R_t", "右薬指先"),
+("little3_R_t", "右小指先"),
+("front skirt_R_t", "右スカート前先"),
+("back skirt_R_t", "右スカート後先"),
+
+("center_t", "センター先"),
+("eyes_t", "両目先"),
+("necktie IK_t", "ネクタイIK先"),
+("hair IK_L_t", "左髪IK先"),
+("hair IK_R_t", "右髪IK先"),
+("leg IK_L_t", "左足IK先"),
+("leg IK_R_t", "右足IK先"),
+("toe IK_L_t", "左つま先IK先"),
+("toe IK_R_t", "右つま先IK先"),
+("front hair1_t", "前髪1先"),
+("front hair2_t", "前髪2先"),
+("front hair3_t", "前髪3先"),
+("eyelight_L_t", "左目光先"),
+("eyelight_R_t", "右目光先"),
+("arm twist_L_t", "左腕捩先"),
+("wrist twist_L_t", "左手捩先"),
+("arm twist_R_t", "右腕捩先"),
+("wrist twist_R_t", "右手捩先"),
+("arm twist1_L", "左腕捩1", 9),
+("arm twist2_L", "左腕捩2", 9),
+("arm twist3_L", "左腕捩3", 9),
+("arm twist1_R", "右腕捩1", 9),
+("arm twist2_R", "右腕捩2", 9),
+("arm twist3_R", "右腕捩3", 9),
+#
+("arm twist1_L_t", "左腕捩1先"),
+("arm twist2_L_t", "左腕捩2先"),
+("arm twist3_L_t", "左腕捩3先"),
+("arm twist1_R_t", "右腕捩1先"),
+("arm twist2_R_t", "右腕捩2先"),
+("arm twist3_R_t", "右腕捩3先"),
+]
 def getEnglishBoneName(name):
-    for k, v in boneMap.items():
-        if v==name:
-            return k
+    for v in boneMap:
+        if v[1]==name:
+            return v[0]
 
 def getUnicodeBoneName(name):
-    if name.endswith('_t'):
-        name=name[:-2]
-        if name in boneMap:
-            return boneMap[name]+(u'先' if sys.version_info[0]<3 else '先')
-    else:
-        if name in boneMap:
-            return boneMap[name]
+    for v in boneMap:
+        if v[0]==name:
+            return v
 
 skinMap={
 "skin000":"base",
@@ -207,8 +214,15 @@ if sys.version_info[0]<3:
     print 'convert boneMap and skinMap to unicode...',
     # python2.x
     # unicodeに変換
-    for k in boneMap.keys():
-        boneMap[k]=boneMap[k].decode('utf-8')
+    for i, l in enumerate(boneMap):
+        replace=[]
+        for j, m in enumerate(l):
+            if j==1:
+                replace.append(m.decode('utf-8'))
+            else:
+                replace.append(m)
+        boneMap[i]=replace
+
     for k in skinMap.keys():
         skinMap[k]=skinMap[k].decode('utf-8')
     print('done')