OSDN Git Service

add import_anim_vmd.py.
authorousttrue <ousttrue@gmail.com>
Sat, 15 May 2010 21:31:31 +0000 (06:31 +0900)
committerousttrue <ousttrue@gmail.com>
Sat, 15 May 2010 21:31:31 +0000 (06:31 +0900)
swig/blender25/import_anim_vmd.py [new file with mode: 0644]

diff --git a/swig/blender25/import_anim_vmd.py b/swig/blender25/import_anim_vmd.py
new file mode 100644 (file)
index 0000000..eb43ee5
--- /dev/null
@@ -0,0 +1,256 @@
+# coding: utf-8
+
+__author__= ['ousttrue']
+__url__ = ("")
+__version__= '20100515 0.1:'
+__bpydoc__= '''\
+vmd Importer
+
+This script imports a vmd into Blender for editing.
+'''
+
+import bpy
+from bpy.props import *
+import mathutils
+import sys
+import os
+import math
+from meshio import vmd, englishmap
+
+
+EPSILON=1e-5
+THRESHOLD=-0.85
+
+
+def ToDegree(x):
+    return x/math.pi * 180.0
+
+
+def clampDegree(d):
+    return d % 360
+
+
+def multQuat(l, r):
+    q=mathutils.Quaternion((0, 0, 0), l.w*r.w-(l.x*r.x+l.y*r.y+l.z*r.z))
+    q.x=l.w*r.x+r.w*l.x+l.y*r.z-l.z*r.y
+    q.y=l.w*r.y+r.w*l.y+l.z*r.x-l.x*r.z
+    q.z=l.w*r.z+r.w*l.z+l.x*r.y-l.y*r.x
+    return q
+
+
+def import_motion_key(l, o):
+    print('import_motion_key: %s' % o.name)
+    
+    armature = o.data
+    pose = o.pose
+    not_in_map={}
+    not_found={}
+    counter=0
+    last_frame=0
+    for n in l.boneKeys:
+        keyFrames=l.getBoneKeyFrameList(n)
+        boneName=englishmap.getEnglishBoneName(n)
+        try:
+            poseBone=pose.bones[boneName]
+            bone=armature.bones[boneName]
+            # rot
+            armRotate=bone.matrix_local.rotation_part()
+            # quat
+            armRotateQuaternion=armRotate.to_quat()
+            if armRotateQuaternion.w<0:
+                armRotateQuaternion.w=-armRotateQuaternion.w
+                armRotateQuaternion.x=-armRotateQuaternion.x
+                armRotateQuaternion.y=-armRotateQuaternion.y
+                armRotateQuaternion.z=-armRotateQuaternion.z
+
+            # inv
+            armRotateInv=mathutils.Matrix(armRotate).transpose()
+            # quat
+            armRotateInvQuaternion=armRotateInv.to_quat()
+            if armRotateInvQuaternion.w<0:
+                armRotateInvQuaternion.w=-armRotateInvQuaternion.w
+                armRotateInvQuaternion.x=-armRotateInvQuaternion.x
+                armRotateInvQuaternion.y=-armRotateInvQuaternion.y
+                armRotateInvQuaternion.z=-armRotateInvQuaternion.z
+
+            reverseFlag=False
+            lastQ=None
+
+            for i in range(len(keyFrames.list)):
+                key=keyFrames.getKey(i)
+                ####################
+                # rotation
+                ####################
+                if lastQ and lastQ.dot(key.q)<0:
+                    reverseFlag=not reverseFlag
+                lastQ=key.q
+
+                # convert left-handed y-up to right-handed z-up
+                if reverseFlag:
+                    # reverse quaternion for slerp
+                    q=mathutils.Quaternion((0, 0, 0), -key.q.w)
+                    q.x=key.q.x
+                    q.y=key.q.z
+                    q.z=key.q.y
+                else:
+                    q=mathutils.Quaternion((0, 0, 0), key.q.w)
+                    q.x=-key.q.x
+                    q.y=-key.q.z
+                    q.z=-key.q.y
+
+                poseBone.rotation_quaternion=multQuat(
+                        armRotateInvQuaternion, 
+                        multQuat(q, armRotateQuaternion))
+
+                ####################
+                # location
+                ####################
+                poseBone.location = mathutils.Vector(
+                        (float(key.pos.x), float(key.pos.z), float(key.pos.y)))
+
+                # insert
+                poseBone.keyframe_insert('rotation_quaternion', -1, keyFrames.getFrame(i))
+                poseBone.keyframe_insert('location', -1, keyFrames.getFrame(i))
+                last_frame=max(last_frame, keyFrames.getFrame(i))
+
+                counter+=1
+
+        except KeyError as msg:
+            not_found[boneName]=True
+            continue
+            
+    print("bone not exists")
+    for name in not_found.keys():
+        print(name)
+
+    return last_frame
+
+
+def IPO_CURVE_get_or_create(ipo, name):
+    for c in ipo:
+        if c.name == name:
+            return c
+    return ipo.addCurve(name)
+
+
+def import_shape_key(l, mesh):
+    print('import_shape_key: %s' % mesh.name)
+    return 0
+    # ToDo
+    key = mesh.getData().key
+    if key is None:
+        Draw.PupMenu('selecting mesh not has a Key')
+        return
+    # get or create IPO  
+    ipo = key.getIpo()
+    if ipo == None:
+        ipo = Blender.Ipo.New("Key", "ShapeKey")
+        key.ipo = ipo
+
+    # insert shape keys
+    counter=0
+    last_frame=0
+    for n in l.morphKeys:
+        keyFrames=l.getMorphKeyFrameList(n)
+        if n=='base':
+            continue
+        name=englishmap.getEnglishSkinName(n)
+        try:
+            curve=IPO_CURVE_get_or_create(ipo, name)
+        except NameError as msg:
+            print(NameError, msg)
+            print(n, name)
+            continue
+        curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
+        for i in xrange(len(keyFrames.list)):
+            key=keyFrames.getKey(i)
+            frame=keyFrames.getFrame(i)
+            curve[frame]=key.weight
+            last_frame=max(last_frame, frame)
+
+            counter+=1
+
+    return last_frame
+
+
+def load(filename, context):
+    """
+    load vmd file to context.
+    """
+    io=vmd.IO()
+    if not io.read(filename):
+        print("fail to read", filename)
+        return
+
+    scene=context.scene
+
+    # import
+    last_frame=0
+    for o in scene.objects:
+        if o.selected:
+            if o.data.__class__ is bpy.types.Armature:
+                last_frame=max(
+                        last_frame, import_motion_key(io, o))
+            elif o.data.__class__ is bpy.types.Mesh:
+                last_frame=max(
+                        last_frame, import_shape_key(io, o))
+
+    # set end frame
+    scene.frame_end = last_frame
+    print("last frame: %d" % last_frame)
+
+    # redraw
+    scene.update()
+
+    print("finised")
+
+
+###############################################################################
+# import operator
+###############################################################################
+class IMPORT_OT_vmd(bpy.types.Operator):
+    bl_idname = "import_anim.vmd"
+    bl_label = 'Import VMD'
+
+    # List of operator properties, the attributes will be assigned
+    # to the class instance from the operator settings before calling.
+    path = StringProperty(
+            name="File Path", 
+            description="File path used for importing the VMD file", 
+            maxlen= 1024, default= "")
+    filename = StringProperty(
+            name="File Name", 
+            description="Name of the file.")
+    directory = StringProperty(
+            name="Directory", 
+            description="Directory of the file.")
+
+    def execute(self, context):
+        load(self.properties.path, context)
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        wm = context.manager
+        wm.add_fileselect(self)
+        return {'RUNNING_MODAL'}
+
+
+###############################################################################
+# register menu
+###############################################################################
+def menu_func(self, context):
+    self.layout.operator(IMPORT_OT_vmd.bl_idname, 
+            text="MikuMikuDance motion (.vmd)")
+
+def register():
+    bpy.types.register(IMPORT_OT_vmd)
+    bpy.types.INFO_MT_file_import.append(menu_func)
+
+def unregister():
+    bpy.types.unregister(IMPORT_OT_vmd)
+    bpy.types.INFO_MT_file_import.remove(menu_func)
+
+
+if __name__=="__main__":
+    register()
+