3 __author__= ['ousttrue']
5 __version__= '20100515 0.2:'
9 This script imports a vmd into Blender for editing.
10 0.1 2010/05/15 first implement.
11 0.2 2010/05/16 implement bone animation.
12 0.3 2010/05/16 implement shape key animation.
16 from bpy.props import *
21 from meshio import vmd, englishmap
29 return x/math.pi * 180.0
37 q=mathutils.Quaternion()
38 q.w=l.w*r.w-(l.x*r.x+l.y*r.y+l.z*r.z)
39 q.x=l.w*r.x+r.w*l.x+l.y*r.z-l.z*r.y
40 q.y=l.w*r.y+r.w*l.y+l.z*r.x-l.x*r.z
41 q.z=l.w*r.z+r.w*l.z+l.x*r.y-l.y*r.x
45 def import_motion_key(l, o):
46 print('import_motion_key: %s' % o.name)
56 keyFrames=l.getBoneKeyFrameList(n)
57 boneName=englishmap.getEnglishBoneName(n)
59 bone=armature.bones[boneName]
61 armRotate=bone.matrix_local.rotation_part()
63 armRotateQuaternion=armRotate.to_quat()
66 armRotateInv=mathutils.Matrix(armRotate).transpose()
68 armRotateInvQuaternion=armRotateInv.to_quat()
73 poseBone=pose.bones[boneName]
74 for i in range(len(keyFrames.list)):
75 key=keyFrames.getKey(i)
79 if lastQ and lastQ.dot(key.q)<0:
80 reverseFlag=not reverseFlag
83 # convert left-handed y-up to right-handed z-up
85 # reverse quaternion for slerp
86 q=mathutils.Quaternion()
92 q=mathutils.Quaternion()
98 poseBone.rotation_quaternion=multQuat(
99 armRotateInvQuaternion,
100 multQuat(q, armRotateQuaternion))
105 poseBone.location = mathutils.Vector(
106 (float(key.pos.x), float(key.pos.z), float(key.pos.y)))
109 poseBone.keyframe_insert(
110 'location', -1, keyFrames.getFrame(i))
111 poseBone.keyframe_insert(
112 'rotation_quaternion', -1, keyFrames.getFrame(i))
114 last_frame=max(last_frame, keyFrames.getFrame(i))
117 except KeyError as msg:
118 not_found[boneName]=True
121 print("bone not exists")
122 for name in not_found.keys():
128 def IPO_CURVE_get_or_create(ipo, name):
132 return ipo.addCurve(name)
135 def getKey(mesh, name):
136 for shapeKey in mesh.shape_keys.keys:
137 if shapeKey.name==name:
141 def import_shape_key(l, meshObject):
142 print('import_shape_key: %s' % meshObject.name)
148 for n in l.morphKeys:
149 keyFrames=l.getMorphKeyFrameList(n)
152 name=englishmap.getEnglishSkinName(n)
156 shapeKey=getKey(meshObject.data, name)
159 print("not found shapeKey: %s" % name)
162 for i in range(len(keyFrames.list)):
163 key=keyFrames.getKey(i)
164 shapeKey.value=key.weight
165 frame=keyFrames.getFrame(i)
166 shapeKey.keyframe_insert("value", -1, frame)
168 last_frame=max(last_frame, frame)
175 def load(filename, context):
177 load vmd file to context.
180 if not io.read(filename):
181 print("fail to read", filename)
188 for o in scene.objects:
190 if o.data.__class__ is bpy.types.Armature:
192 last_frame, import_motion_key(io, o))
193 elif o.data.__class__ is bpy.types.Mesh:
195 last_frame, import_shape_key(io, o))
198 scene.frame_end = last_frame
199 print("last frame: %d" % last_frame)
207 ###############################################################################
209 ###############################################################################
210 class IMPORT_OT_vmd(bpy.types.Operator):
211 bl_idname = "import_anim.vmd"
212 bl_label = 'Import VMD'
214 # List of operator properties, the attributes will be assigned
215 # to the class instance from the operator settings before calling.
216 path = StringProperty(
218 description="File path used for importing the VMD file",
219 maxlen= 1024, default= "")
220 filename = StringProperty(
222 description="Name of the file.")
223 directory = StringProperty(
225 description="Directory of the file.")
227 def execute(self, context):
228 load(self.properties.path, context)
231 def invoke(self, context, event):
233 wm.add_fileselect(self)
234 return {'RUNNING_MODAL'}
237 ###############################################################################
239 ###############################################################################
240 def menu_func(self, context):
241 self.layout.operator(IMPORT_OT_vmd.bl_idname,
242 text="MikuMikuDance motion (.vmd)")
245 bpy.types.register(IMPORT_OT_vmd)
246 bpy.types.INFO_MT_file_import.append(menu_func)
249 bpy.types.unregister(IMPORT_OT_vmd)
250 bpy.types.INFO_MT_file_import.remove(menu_func)
253 if __name__=="__main__":