OSDN Git Service

implement rigid body and constraint read/write.
authorousttrue <ousttrue@gmail.com>
Sun, 22 May 2011 15:44:06 +0000 (00:44 +0900)
committerousttrue <ousttrue@gmail.com>
Sun, 22 May 2011 15:44:06 +0000 (00:44 +0900)
blender25-meshio/export_pmd.py
blender25-meshio/import_pmd.py
blender25-meshio/pymeshio/mmd.py
blender25-meshio/pymeshio/pmd.py

index a39df3b..8fb08a5 100644 (file)
@@ -86,8 +86,8 @@ try:
 except ImportError:
     # full python
     from .pymeshio import englishmap
-    from .pymeshio import mmd as pmd
-    pmd.IO=pmd.PMDLoader
+    from .pymeshio import pmd
+
 
 # for 2.5
 import bpy
@@ -475,11 +475,11 @@ class OneSkinMesh(object):
         if len(copyMesh.vertices)>0:
             # apply transform
             copyObj.scale=obj.scale
-            bpy.ops.object.scale_apply()
+            bpy.ops.object.transform_apply(scale=True)
             copyObj.rotation_euler=obj.rotation_euler
-            bpy.ops.object.rotation_apply()
+            bpy.ops.object.transform_apply(rotation=True)
             copyObj.location=obj.location
-            bpy.ops.object.location_apply()
+            bpy.ops.object.transform_apply(location=True)
             # apply modifier
             for m in [m for m in copyObj.modifiers]:
                 if m.type=='SOLIDFY':
@@ -878,8 +878,8 @@ class PmdExporter(object):
 
     def write(self, path):
         io=pmd.IO()
-        io.setName(toCP932(self.name))
-        io.setComment(toCP932(self.comment))
+        io.name=self.name
+        io.comment=self.comment
         io.version=1.0
 
         # 頂点
@@ -913,9 +913,9 @@ class PmdExporter(object):
             textures=[os.path.basename(path) 
                 for path in bl.material.eachEnalbeTexturePath(m)]
             if len(textures)>0:
-                material.setTexture(toCP932('*'.join(textures)))
+                material.texture='*'.join(textures)
             else:
-                material.setTexture(toCP932(""))
+                material.texture=""
             # 面
             for i in indices:
                 assert(i<vertexCount)
@@ -936,14 +936,12 @@ class PmdExporter(object):
             if not v:
                 v=[b.name, b.name]
             assert(v)
-            cp932=v[1].encode('cp932')
-            assert(len(cp932)<20)
-            bone.setName(cp932)
+            bone.name=v[1]
 
             # english name
             bone_english_name=toCP932(b.name)
             assert(len(bone_english_name)<20)
-            bone.setEnglishName(bone_english_name)
+            bone.english_name=bone_english_name
 
             if len(v)>=3:
                 # has type
@@ -984,9 +982,8 @@ class PmdExporter(object):
             if not v:
                 v=[m.name, m.name, 0]
             assert(v)
-            cp932=v[1].encode('cp932')
-            morph.setName(cp932)
-            morph.setEnglishName(m.name.encode('cp932'))
+            morph.name=v[1]
+            morph.english_name=m.name
             m.type=v[2]
             morph.type=v[2]
             for index, offset in m.offsets:
@@ -1016,10 +1013,10 @@ class PmdExporter(object):
             name=englishmap.getUnicodeBoneGroupName(g[0])
             if not name:
                 name=g[0]
-            boneDisplayName.setName(toCP932(name+'\n'))
+            boneDisplayName.name=name+'\n'
             # english
             englishName=g[0]
-            boneDisplayName.setEnglishName(toCP932(englishName+'\n'))
+            boneDisplayName.english_name=englishName+'\n'
 
         # ボーングループメンバー
         for i, b in enumerate(self.skeleton.bones):
@@ -1032,8 +1029,8 @@ class PmdExporter(object):
         #assert(len(io.bones)==len(io.bone_display_list)+1)
 
         # English
-        io.setEnglishName(toCP932(self.englishName))
-        io.setEnglishComment(toCP932(self.englishComment))
+        io.english_name=self.englishName
+        io.english_comment=self.englishComment
 
         # toon
         toonMeshObject=None
@@ -1050,20 +1047,19 @@ class PmdExporter(object):
             for i in range(10):
                 t=bl.material.getTexture(toonMaterial, i)
                 if t:
-                    io.getToonTexture(i).setName(toCP932(t.name))
+                    io.toon_textures[i]=pmd.encode_string(t.name)
                 else:
-                    io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i))
+                    io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i)
         else:
             for i in range(10):
-                io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i))
+                io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i)
 
         # rigid body
         rigidNameMap={}
         for i, obj in enumerate(self.oneSkinMesh.rigidbodies):
             name=obj[RIGID_NAME] if RIGID_NAME in obj else obj.name
-            print(name)
-            rigidBody=io.addRigidBody()
-            rigidBody.setName(name.encode('cp932'))
+            #print(name)
+            rigidBody=pmd.RigidBody(name)
             rigidNameMap[name]=i
             boneIndex=boneNameMap[obj[RIGID_BONE_NAME]]
             if boneIndex==0:
@@ -1092,6 +1088,8 @@ class PmdExporter(object):
             if obj[RIGID_SHAPE_TYPE]==0:
                 rigidBody.shapeType=pmd.SHAPE_SPHERE
                 rigidBody.w=obj.scale[0]
+                rigidBody.d=0
+                rigidBody.h=0
             elif obj[RIGID_SHAPE_TYPE]==1:
                 rigidBody.shapeType=pmd.SHAPE_BOX
                 rigidBody.w=obj.scale[0]
@@ -1101,11 +1099,12 @@ class PmdExporter(object):
                 rigidBody.shapeType=pmd.SHAPE_CAPSULE
                 rigidBody.w=obj.scale[0]
                 rigidBody.h=obj.scale[2]
+                rigidBody.d=0
+            io.rigidbodies.append(rigidBody)
 
         # constraint
         for obj in self.oneSkinMesh.constraints:
-            constraint=io.addConstraint()
-            constraint.setName(obj[CONSTRAINT_NAME].encode('cp932'))
+            constraint=pmd.Constraint(obj[CONSTRAINT_NAME])
             constraint.rigidA=rigidNameMap[obj[CONSTRAINT_A]]
             constraint.rigidB=rigidNameMap[obj[CONSTRAINT_B]]
             constraint.pos.x=obj.location[0]
@@ -1132,6 +1131,7 @@ class PmdExporter(object):
             constraint.springRot.x=obj[CONSTRAINT_SPRING_ROT][0]
             constraint.springRot.y=obj[CONSTRAINT_SPRING_ROT][1]
             constraint.springRot.z=obj[CONSTRAINT_SPRING_ROT][2]
+            io.constraints.append(constraint)
 
         # 書き込み
         bl.message('write: %s' % path)
index 79be446..c942c78 100644 (file)
@@ -167,21 +167,21 @@ def to_radian(degree):
 
 def get_bone_name(l, index):
     if index==0xFFFF:
-        return l.bones[0].getName()
+        return l.bones[0].name
 
     if index < len(l.bones):
-        name=englishmap.getEnglishBoneName(l.bones[index].getName())
+        name=englishmap.getEnglishBoneName(l.bones[index].name)
         if name:
             return name
-        return l.bones[index].getName()
+        return l.bones[index].name
     print('invalid bone index', index)
-    return l.bones[0].getName()
+    return l.bones[0].name
 
 
 def get_group_name(g):
-    group_name=englishmap.getEnglishBoneGroupName(g.getName().strip())
+    group_name=englishmap.getEnglishBoneGroupName(g.name.strip())
     if not group_name:
-        group_name=g.getName().strip()
+        group_name=g.name.strip()
     return group_name
 
 
@@ -189,9 +189,8 @@ def __importToonTextures(io, tex_dir):
     mesh, meshObject=bl.mesh.create(TOON_TEXTURE_OBJECT)
     material=bl.material.create(TOON_TEXTURE_OBJECT)
     bl.mesh.addMaterial(mesh, material)
-    for i in range(10):
-        t=io.getToonTexture(i)
-        path=os.path.join(tex_dir, t.getName())
+    for toon in (io.toon_textures[i] for i in range(10)):
+        path=os.path.join(tex_dir, toon)
         texture, image=bl.texture.create(path)
         bl.material.addTexture(material, texture, False)
     return meshObject, material
@@ -234,9 +233,9 @@ def __importShape(obj, l, vertex_map):
             continue
 
         # name
-        name=englishmap.getEnglishSkinName(s.getName())
+        name=englishmap.getEnglishSkinName(s.name)
         if not name:
-            name=s.getName()
+            name=s.name
 
         # 25
         new_shape_key=bl.object.addShapeKey(obj, name)
@@ -263,9 +262,9 @@ def __importShape(obj, l, vertex_map):
 
 
 def __build(armature, b, p, parent):
-    name=englishmap.getEnglishBoneName(b.getName())
+    name=englishmap.getEnglishBoneName(b.name)
     if not name:
-        name=b.getName()
+        name=b.name
 
     bone=bl.armature.createBone(armature, name)
 
@@ -320,9 +319,9 @@ def __importArmature(l):
     pose = bl.object.getPose(armature_object)
     for ik in l.ik_list:
         target=l.bones[ik.target]
-        name = englishmap.getEnglishBoneName(target.getName())
+        name = englishmap.getEnglishBoneName(target.name)
         if not name:
-            name=target.getName()
+            name=target.name
         p_bone = pose.bones[name]
         if not p_bone:
             print('not found', name)
@@ -331,9 +330,9 @@ def __importArmature(l):
             print('over MAX_CHAINLEN', ik, len(ik.children))
             continue
         effector_name=englishmap.getEnglishBoneName(
-                l.bones[ik.index].getName())
+                l.bones[ik.index].name)
         if not effector_name:
-            effector_name=l.bones[ik.index].getName()
+            effector_name=l.bones[ik.index].name
 
         constraint=bl.armature.createIkConstraint(armature_object,
                 p_bone, effector_name, ik)
@@ -351,9 +350,9 @@ def __importArmature(l):
     for b_index, g_index in l.bone_display_list:
         # bone
         b=l.bones[b_index]
-        bone_name=englishmap.getEnglishBoneName(b.getName())
+        bone_name=englishmap.getEnglishBoneName(b.name)
         if not bone_name:
-            bone_name=b.getName()
+            bone_name=b.name
         # group
         g=l.bone_group_list[g_index-1]
         group_name=get_group_name(g)
@@ -389,7 +388,7 @@ def __import16MaerialAndMesh(meshObject, l,
         material=createPmdMaterial(m, material_index)
 
         # main texture
-        texture_name=m.getTexture()
+        texture_name=m.texture
         if texture_name!='':
             for i, t in enumerate(texture_name.split('*')):
                 if t in textureMap:
@@ -623,7 +622,7 @@ def __importMaterialAndMesh(io, tex_dir, toon_material):
 def __importConstraints(io):
     print("create constraint")
     container=bl.object.createEmpty('Constraints')
-    layer=[
+    layers=[
         True, False, False, False, False, False, False, False, False, False,
         False, False, False, False, False, False, False, False, False, False,
             ]
@@ -633,10 +632,10 @@ def __importConstraints(io):
     for i, c in enumerate(io.constraints):
         bpy.ops.mesh.primitive_uv_sphere_add(
                 segments=8,
-                rings=4,
+                ring_count=4,
                 size=0.1,
                 location=(c.pos.x, c.pos.z, c.pos.y),
-                layer=layer
+                layers=layers
                 )
         meshObject=bl.object.getActive()
         constraintMeshes.append(meshObject)
@@ -645,13 +644,13 @@ def __importConstraints(io):
         meshObject.name='c_%d' % i
         #meshObject.draw_transparent=True
         #meshObject.draw_wire=True
-        meshObject.max_draw_type='SOLID'
+        meshObject.draw_type='SOLID'
         rot=c.rot
         meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
 
-        meshObject[CONSTRAINT_NAME]=c.getName()
-        meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].getName()
-        meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].getName()
+        meshObject[CONSTRAINT_NAME]=c.name
+        meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].name
+        meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].name
         meshObject[CONSTRAINT_POS_MIN]=VtoV(c.constraintPosMin)
         meshObject[CONSTRAINT_POS_MAX]=VtoV(c.constraintPosMax)
         meshObject[CONSTRAINT_ROT_MIN]=VtoV(c.constraintRotMin)
@@ -669,7 +668,7 @@ def __importRigidBodies(io):
     print("create rigid bodies")
 
     container=bl.object.createEmpty('RigidBodies')
-    layer=[
+    layers=[
         True, False, False, False, False, False, False, False, False, False,
         False, False, False, False, False, False, False, False, False, False,
             ]
@@ -686,21 +685,21 @@ def __importRigidBodies(io):
         if rigid.shapeType==pmd.SHAPE_SPHERE:
             bpy.ops.mesh.primitive_ico_sphere_add(
                     location=(pos.x, pos.z, pos.y),
-                    layer=layer
+                    layers=layers
                     )
             bpy.ops.transform.resize(
                     value=(rigid.w, rigid.w, rigid.w))
         elif rigid.shapeType==pmd.SHAPE_BOX:
             bpy.ops.mesh.primitive_cube_add(
                     location=(pos.x, pos.z, pos.y),
-                    layer=layer
+                    layers=layers
                     )
             bpy.ops.transform.resize(
                     value=(rigid.w, rigid.d, rigid.h))
         elif rigid.shapeType==pmd.SHAPE_CAPSULE:
-            bpy.ops.mesh.primitive_tube_add(
+            bpy.ops.mesh.primitive_cylinder_add(
                     location=(pos.x, pos.z, pos.y),
-                    layer=layer
+                    layers=layers
                     )
             bpy.ops.transform.resize(
                     value=(rigid.w, rigid.w, rigid.h))
@@ -712,10 +711,10 @@ def __importRigidBodies(io):
         rigidMeshes.append(meshObject)
         bl.mesh.addMaterial(mesh, material)
         meshObject.name='r_%d' % i
-        meshObject[RIGID_NAME]=rigid.getName()
+        meshObject[RIGID_NAME]=rigid.name
         #meshObject.draw_transparent=True
         #meshObject.draw_wire=True
-        meshObject.max_draw_type='WIRE'
+        meshObject.draw_type='WIRE'
         rot=rigid.rotation
         meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
 
@@ -723,9 +722,9 @@ def __importRigidBodies(io):
         meshObject[RIGID_SHAPE_TYPE]=rigid.shapeType
         meshObject[RIGID_PROCESS_TYPE]=rigid.processType
 
-        bone_name = englishmap.getEnglishBoneName(bone.getName())
+        bone_name = englishmap.getEnglishBoneName(bone.name)
         if not bone_name:
-            bone_name=bone.getName()
+            bone_name=bone.name
         meshObject[RIGID_BONE_NAME]=bone_name
 
         meshObject[RIGID_GROUP]=rigid.group
@@ -757,13 +756,13 @@ def _execute(filepath=""):
     bl.progress_set('loaded', 0.1)
 
     # create root object
-    model_name=io.getEnglishName()
+    model_name=io.english_name
     if len(model_name)==0:
-        model_name=io.getName()
+        model_name=io.name
     root=bl.object.createEmpty(model_name)
-    root[MMD_MB_NAME]=io.getName()
-    root[MMD_MB_COMMENT]=io.getComment()
-    root[MMD_COMMENT]=io.getEnglishComment()
+    root[MMD_MB_NAME]=io.name
+    root[MMD_MB_COMMENT]=io.comment
+    root[MMD_COMMENT]=io.english_comment
 
     # toon textures
     tex_dir=os.path.dirname(filepath)
index fbbc71f..44ef524 100644 (file)
@@ -109,6 +109,9 @@ class Vector3(object):
     def to_tuple(self):
         return (self.x, self.y, self.z)
 
+    def __add__(l, r):
+        return Vector3(l.x+r.x, l.y+r.y, l.z+r.z)
+
 
 class Quaternion(object):
     __slots__=['x', 'y', 'z', 'w']
index afb0654..d7a4a27 100644 (file)
@@ -6,6 +6,16 @@ from .mmd import *
 ###############################################################################
 # PMD
 ###############################################################################
+def encode_string(src):
+    t=type(src)
+    if t==str:
+        return src.encode('cp932')
+    elif t==bytes:
+        return src
+    else:
+        raise "INVALID str: %s" % t
+
+
 class Vertex(object):
     __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
     def __init__(self, x=0, y=0, z=0, nx=0, ny=0, nz=0, u=0, v=0,
@@ -35,8 +45,11 @@ class Vertex(object):
 class Material(object):
     __slots__=[
             'diffuse', 'shinness', 'specular',
-            'ambient', 'vertex_count', 'texture', 'toon_index', 'flag',
+            'ambient', 'vertex_count', '_texture', 'toon_index', 'flag',
             ]
+    def getTexture(self): return self._texture
+    def setTexture(self, texture): self._texture=encode_string(texture)
+    texture=property(getTexture, setTexture)
 
     def __init__(self, dr=0, dg=0, db=0, alpha=1, 
             specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0):
@@ -45,7 +58,7 @@ class Material(object):
         self.shinness=specular
         self.ambient=RGBA(ar, ag, ab)
         self.vertex_count=0
-        self.texture=''
+        self._texture=''
         self.toon_index=0
         self.flag=0
 
@@ -55,15 +68,12 @@ class Material(object):
                 self.diffuse[2], self.diffuse[3],
                 )
 
-    def getTexture(self): return self.texture.decode('cp932')
-    def setTexture(self, u): self.texture=u
-
 
 # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ
 # マテリアル自身を返す
 def material_per_face(materials):
     for m in materials:
-        for x in xrange(int(m.vertex_count/3)):
+        for x in range(int(m.vertex_count/3)):
             yield m
 
 
@@ -79,10 +89,17 @@ class Bone(object):
     # since v4.0
     ROLLING=8 # ?
     TWEAK=9
-    __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
-            'children', 'english_name', 'ik_index',
+    __slots__=['_name', 'index', 'type', 'parent', 'ik', 'pos',
+            'children', '_english_name', 'ik_index',
             'parent_index', 'tail_index', 'tail',
             ]
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+    def getEnglishName(self): return self._english_name
+    def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
+    english_name=property(getEnglishName, setEnglishName)
+
     def __init__(self, name='bone', type=0):
         self.name=name
         self.index=0
@@ -96,10 +113,6 @@ class Bone(object):
         self.children=[]
         self.english_name=''
 
-    def getName(self): return self.name.decode('cp932')
-    def setName(self, u): self.name=u
-    def setEnglishName(self, u): self.english_name=u
-
     def hasParent(self):
         return self.parent_index!=0xFFFF
 
@@ -121,7 +134,7 @@ class Bone(object):
             print(uni.encode(ENCODING))
 
         child_count=len(self.children)
-        for i in xrange(child_count):
+        for i in range(child_count):
             child=self.children[i]
             if i<child_count-1:
                 child.display(indent+[False])
@@ -233,8 +246,15 @@ class IK(object):
 
 
 class Skin(object):
-    __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
+    __slots__=['_name', 'type', 'indices', 'pos_list', '_english_name',
             'vertex_count']
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+    def getEnglishName(self): return self._english_name
+    def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
+    english_name=property(getEnglishName, setEnglishName)
+
     def __init__(self, name='skin'):
         self.name=name
         self.type=None
@@ -243,10 +263,6 @@ class Skin(object):
         self.english_name=''
         self.vertex_count=0
 
-    def getName(self): return self.name.decode('cp932')
-    def setName(self, u): self.name=u
-    def setEnglishName(self, u): self.english_name=u
-
     def append(self, index, x, y, z):
         self.indices.append(index)
         self.pos_list.append(Vector3(x, y, z))
@@ -257,19 +273,35 @@ class Skin(object):
 
 
 class BoneGroup(object):
-    __slots__=['name', 'english_name']
-    def __init__(self, name='group'): self.name=name; self.english_name='center'
-    def getName(self): return self.name.decode('cp932')
-    def setName(self, u): self.name=u
-    def getEnglishName(self): return self.english_name.decode('cp932')
-    def setEnglishName(self, u): self.english_name=u
+    __slots__=['_name', '_english_name']
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+    def getEnglishName(self): return self._english_name
+    def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
+    english_name=property(getEnglishName, setEnglishName)
+
+    def __init__(self, name='group'): self._name=name; self._english_name='center'
+
+
+SHAPE_SPHERE=0
+SHAPE_BOX=1
+SHAPE_CAPSULE=2
+
+RIGIDBODY_KINEMATICS=0
+RIGIDBODY_PHYSICS=1
+RIGIDBODY_PHYSICS_WITH_BONE=2
 
 
 class RigidBody(object):
-    __slots__=['name', 'boneIndex', 'group', 'target', 'shapeType',
+    __slots__=['_name', 'boneIndex', 'group', 'target', 'shapeType',
             'w', 'h', 'd', 'position', 'rotation', 'weight',
             'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
             ]
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+
     def __init__(self, name):
         self.name=name
         self.position=Vector3()
@@ -277,11 +309,15 @@ class RigidBody(object):
 
 
 class Constraint(object):
-    __slots__=[ 'name', 'rigidA', 'rigidB', 'pos', 'rot',
+    __slots__=[ '_name', 'rigidA', 'rigidB', 'pos', 'rot',
             'constraintPosMin', 'constraintPosMax',
             'constraintRotMin', 'constraintRotMax',
             'springPos', 'springRot',
             ]
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+
     def __init__(self, name):
         self.name=name
         self.pos=Vector3()
@@ -296,8 +332,8 @@ class Constraint(object):
 
 class IO(object):
     __slots__=['io', 'end', 'pos',
-            'version', 'name', 'comment',
-            'english_name', 'english_comment',
+            'version', '_name', '_comment',
+            '_english_name', '_english_comment',
             'vertices', 'indices', 'materials', 'bones', 
             'ik_list', 'morph_list',
             'face_list', 'bone_group_list', 'bone_display_list',
@@ -305,12 +341,25 @@ class IO(object):
             'no_parent_bones',
             'rigidbodies', 'constraints',
             ]
+    def getName(self): return self._name
+    def setName(self, name): self._name=encode_string(name)
+    name=property(getName, setName)
+    def getEnglishName(self): return self._english_name
+    def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
+    english_name=property(getEnglishName, setEnglishName)
+    def getComment(self): return self._comment
+    def setComment(self, comment): self._comment=encode_string(comment)
+    comment=property(getComment, setComment)
+    def getEnglishComment(self): return self._english_comment
+    def setEnglishComment(self, english_comment): self._english_comment=encode_string(english_comment)
+    english_comment=property(getEnglishComment, setEnglishComment)
+
     def __init__(self):
         self.version=1.0
-        self.name=b"default"
-        self.comment=b"default"
-        self.english_name=b'default'
-        self.english_comment=b'default'
+        self.name="default"
+        self.comment="default"
+        self.english_name='default'
+        self.english_comment='default'
         self.vertices=[]
         self.indices=[]
         self.materials=[]
@@ -323,11 +372,11 @@ class IO(object):
         self.bone_display_list=[]
 
         self.toon_textures=[
-                'toon01.bmp', 'toon02.bmp',
-                'toon03.bmp', 'toon04.bmp',
-                'toon05.bmp', 'toon06.bmp',
-                'toon07.bmp', 'toon08.bmp',
-                'toon09.bmp', 'toon10.bmp',
+                b'toon01.bmp', b'toon02.bmp',
+                b'toon03.bmp', b'toon04.bmp',
+                b'toon05.bmp', b'toon06.bmp',
+                b'toon07.bmp', b'toon08.bmp',
+                b'toon09.bmp', b'toon10.bmp',
                 ]
 
         self.no_parent_bones=[]
@@ -335,16 +384,6 @@ class IO(object):
         self.rigidbodies=[]
         self.constraints=[]
 
-    def getName(self): return self.name.decode('cp932')
-    def setName(self, u): self.name=u
-    def getComment(self): return self.comment.decode('cp932')
-    def setComment(self, u): self.comment=u
-    def getEnglishName(self): return self.english_name.decode('cp932')
-    def setEnglishName(self, u): self.english_name=u
-    def getEnglishComment(self): return self.english_comment.decode('cp932')
-    def setEnglishComment(self, u): self.english_comment=u
-
-    def getToonTexture(self, i): return self.toon_textures[i]
     def each_vertex(self): return self.vertices
     def getUV(self, i): return self.vertices[i].uv
     def addVertex(self): 
@@ -528,21 +567,69 @@ class IO(object):
             for i, v in zip(s.indices, s.pos_list):
                 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
 
-        # skin list
+        # skin disp list
         io.write(struct.pack("B", len(self.face_list)))
         for i in self.face_list:
             io.write(struct.pack("H", i))
 
-        # bone name
+        # bone disp list
         io.write(struct.pack("B", len(self.bone_group_list)))
         for g in self.bone_group_list:
             io.write(struct.pack("50s", g.name))
 
-        # bone list
         io.write(struct.pack("I", len(self.bone_display_list)))
         for l in self.bone_display_list:
             io.write(struct.pack("=HB", *l))
 
+        ############################################################
+        # extend data
+        ############################################################
+        io.write(struct.pack("B", 1))
+        # english name
+        io.write(struct.pack("=20s", self.english_name))
+        io.write(struct.pack("=256s", self.english_comment))
+        # english bone name
+        for bone in self.bones:
+            io.write(struct.pack("=20s", bone.english_name))
+        # english skin list
+        for skin in self.morph_list:
+            print(skin.name)
+            if skin.name==b'base':
+                continue
+            io.write(struct.pack("=20s", skin.english_name))
+        # english bone list
+        for bone_group in self.bone_group_list:
+            io.write(struct.pack("50s", bone_group.english_name))
+        # toon texture
+        for i in range(10):
+            io.write(struct.pack("=100s", self.toon_textures[i]))
+        # rigid
+        io.write(struct.pack("I", len(self.rigidbodies)))
+        for r in self.rigidbodies:
+            io.write(struct.pack("=20sHBHB14fB",
+                r.name, r.boneIndex, r.group, r.target, r.shapeType,
+                r.w, r.h, r.d, 
+                r.position.x, r.position.y, r.position.z, 
+                r.rotation.x, r.rotation.y, r.rotation.z, 
+                r.weight,
+                r.linearDamping, r.angularDamping, r.restitution,
+                r.friction, r.processType))
+
+        # constraint
+        io.write(struct.pack("I", len(self.constraints)))
+        for c in self.constraints:
+            io.write(struct.pack("=20sII24f",
+                c.name, c.rigidA, c.rigidB,
+                c.pos.x, c.pos.y, c.pos.z,
+                c.rot.x, c.rot.y, c.rot.z,
+                c.constraintPosMin.x, c.constraintPosMin.y, c.constraintPosMin.z,
+                c.constraintPosMax.x, c.constraintPosMax.y, c.constraintPosMax.z,
+                c.constraintRotMin.x, c.constraintRotMin.y, c.constraintRotMin.z,
+                c.constraintRotMax.x, c.constraintRotMax.y, c.constraintRotMax.z,
+                c.springPos.x, c.springPos.y, c.springPos.z,
+                c.springRot.x, c.springRot.y, c.springRot.z
+                ))
+
         return True
 
 
@@ -590,19 +677,19 @@ class IO(object):
 
     def _loadVertex(self):
         count = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(count):
+        for i in range(count):
             self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
         return True
 
     def _loadFace(self):
         count = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(0, count, 3):
+        for i in range(0, count, 3):
             self.indices+=struct.unpack("HHH", self.io.read(6))
         return True
 
     def _loadMaterial(self):
         count = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(count):
+        for i in range(count):
             material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
             material.toon_index=struct.unpack("B", self.io.read(1))[0]
             material.flag=struct.unpack("B", self.io.read(1))[0]
@@ -616,7 +703,7 @@ class IO(object):
 
     def _loadBone(self):
         size = struct.unpack("H", self.io.read(2))[0]
-        for i in xrange(size):
+        for i in range(size):
             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
             parent_index, tail_index = struct.unpack("HH", self.io.read(4))
             type = struct.unpack("B", self.io.read(1))[0]
@@ -631,23 +718,23 @@ class IO(object):
 
     def _loadIK(self):
         size = struct.unpack("H", self.io.read(2))[0]
-        for i in xrange(size):
+        for i in range(size):
             ik=IK(*struct.unpack("2H", self.io.read(4)))
             ik.length = struct.unpack("B", self.io.read(1))[0]
             ik.iterations = struct.unpack("H", self.io.read(2))[0]
             ik.weight = struct.unpack("f", self.io.read(4))[0]
-            for j in xrange(ik.length):
+            for j in range(ik.length):
                 ik.children.append(struct.unpack("H", self.io.read(2))[0])
             self.ik_list.append(ik)
         return True
 
     def _loadSkin(self):
         size = struct.unpack("H", self.io.read(2))[0]
-        for i in xrange(size):
+        for i in range(size):
             skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
             skin_size = struct.unpack("I", self.io.read(4))[0]
             skin.type = struct.unpack("B", self.io.read(1))[0]
-            for j in xrange(skin_size):
+            for j in range(skin_size):
                 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
                 skin.pos_list.append(
                         Vector3(*struct.unpack("3f", self.io.read(12))))
@@ -657,20 +744,20 @@ class IO(object):
 
     def _loadSkinIndex(self):
         size = struct.unpack("B", self.io.read(1))[0]
-        for i in xrange(size):
+        for i in range(size):
             self.face_list.append(struct.unpack("H", self.io.read(2))[0])
         return True
 
     def _loadBoneName(self):
         size = struct.unpack("B", self.io.read(1))[0]
-        for i in xrange(size):
+        for i in range(size):
             self.bone_group_list.append(BoneGroup(
                 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
         return True
 
     def _loadBoneIndex(self):
         size = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(size):
+        for i in range(size):
             first=struct.unpack("H", self.io.read(2))[0]
             second=struct.unpack("B", self.io.read(1))[0]
             self.bone_display_list.append((first, second))
@@ -680,7 +767,7 @@ class IO(object):
         """
         100bytex10
         """
-        for i in xrange(10):
+        for i in range(10):
             self.toon_textures.append(
                     truncate_zero(struct.unpack("100s", self.io.read(100))[0]))
         return True
@@ -709,7 +796,7 @@ class IO(object):
                 skin.english_name=english_name
         self._check_position()
         # english bone list
-        for i in xrange(0, len(self.bone_group_list)):
+        for i in range(0, len(self.bone_group_list)):
             self.bone_group_list[i].english_name=truncate_zero(
                     struct.unpack("50s", self.io.read(50))[0])
         self._check_position()
@@ -718,7 +805,7 @@ class IO(object):
     def loadPhysics(self):
         # 剛体リスト
         count = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(count):
+        for i in range(count):
             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
             rigidbody=RigidBody(name)
             rigidbody.boneIndex=struct.unpack("H", self.io.read(2))[0]
@@ -745,7 +832,7 @@ class IO(object):
 
         # ジョイントリスト
         count = struct.unpack("I", self.io.read(4))[0]
-        for i in xrange(count):
+        for i in range(count):
             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
             constraint=Constraint(name)
             constraint.rigidA=struct.unpack("I", self.io.read(4))[0]