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 motion.
15 from bpy.props import *
20 from meshio import vmd, englishmap
28 return x/math.pi * 180.0
36 q=mathutils.Quaternion()
37 q.w=l.w*r.w-(l.x*r.x+l.y*r.y+l.z*r.z)
38 q.x=l.w*r.x+r.w*l.x+l.y*r.z-l.z*r.y
39 q.y=l.w*r.y+r.w*l.y+l.z*r.x-l.x*r.z
40 q.z=l.w*r.z+r.w*l.z+l.x*r.y-l.y*r.x
44 def import_motion_key(l, o):
45 print('import_motion_key: %s' % o.name)
55 keyFrames=l.getBoneKeyFrameList(n)
56 boneName=englishmap.getEnglishBoneName(n)
58 bone=armature.bones[boneName]
60 armRotate=bone.matrix_local.rotation_part()
62 armRotateQuaternion=armRotate.to_quat()
63 #if armRotateQuaternion.w<0:
64 # armRotateQuaternion.w=-armRotateQuaternion.w
65 # armRotateQuaternion.x=-armRotateQuaternion.x
66 # armRotateQuaternion.y=-armRotateQuaternion.y
67 # armRotateQuaternion.z=-armRotateQuaternion.z
70 armRotateInv=mathutils.Matrix(armRotate).transpose()
72 armRotateInvQuaternion=armRotateInv.to_quat()
73 #if armRotateInvQuaternion.w<0:
74 # armRotateInvQuaternion.w=-armRotateInvQuaternion.w
75 # armRotateInvQuaternion.x=-armRotateInvQuaternion.x
76 # armRotateInvQuaternion.y=-armRotateInvQuaternion.y
77 # armRotateInvQuaternion.z=-armRotateInvQuaternion.z
82 poseBone=pose.bones[boneName]
83 for i in range(len(keyFrames.list)):
84 key=keyFrames.getKey(i)
88 if lastQ and lastQ.dot(key.q)<0:
89 reverseFlag=not reverseFlag
92 # convert left-handed y-up to right-handed z-up
94 # reverse quaternion for slerp
95 q=mathutils.Quaternion()
101 q=mathutils.Quaternion()
107 poseBone.rotation_quaternion=multQuat(
108 armRotateInvQuaternion,
109 multQuat(q, armRotateQuaternion))
114 poseBone.location = mathutils.Vector(
115 (float(key.pos.x), float(key.pos.z), float(key.pos.y)))
118 poseBone.keyframe_insert(
119 'location', -1, keyFrames.getFrame(i))
120 poseBone.keyframe_insert(
121 'rotation_quaternion', -1, keyFrames.getFrame(i))
123 last_frame=max(last_frame, keyFrames.getFrame(i))
126 except KeyError as msg:
127 not_found[boneName]=True
130 print("bone not exists")
131 for name in not_found.keys():
137 def IPO_CURVE_get_or_create(ipo, name):
141 return ipo.addCurve(name)
144 def import_shape_key(l, mesh):
145 print('import_shape_key: %s' % mesh.name)
148 key = mesh.getData().key
150 Draw.PupMenu('selecting mesh not has a Key')
155 ipo = Blender.Ipo.New("Key", "ShapeKey")
161 for n in l.morphKeys:
162 keyFrames=l.getMorphKeyFrameList(n)
165 name=englishmap.getEnglishSkinName(n)
167 curve=IPO_CURVE_get_or_create(ipo, name)
168 except NameError as msg:
169 print(NameError, msg)
172 curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
173 for i in xrange(len(keyFrames.list)):
174 key=keyFrames.getKey(i)
175 frame=keyFrames.getFrame(i)
176 curve[frame]=key.weight
177 last_frame=max(last_frame, frame)
184 def load(filename, context):
186 load vmd file to context.
189 if not io.read(filename):
190 print("fail to read", filename)
197 for o in scene.objects:
199 if o.data.__class__ is bpy.types.Armature:
201 last_frame, import_motion_key(io, o))
202 elif o.data.__class__ is bpy.types.Mesh:
204 last_frame, import_shape_key(io, o))
207 scene.frame_end = last_frame
208 print("last frame: %d" % last_frame)
216 ###############################################################################
218 ###############################################################################
219 class IMPORT_OT_vmd(bpy.types.Operator):
220 bl_idname = "import_anim.vmd"
221 bl_label = 'Import VMD'
223 # List of operator properties, the attributes will be assigned
224 # to the class instance from the operator settings before calling.
225 path = StringProperty(
227 description="File path used for importing the VMD file",
228 maxlen= 1024, default= "")
229 filename = StringProperty(
231 description="Name of the file.")
232 directory = StringProperty(
234 description="Directory of the file.")
236 def execute(self, context):
237 load(self.properties.path, context)
240 def invoke(self, context, event):
242 wm.add_fileselect(self)
243 return {'RUNNING_MODAL'}
246 ###############################################################################
248 ###############################################################################
249 def menu_func(self, context):
250 self.layout.operator(IMPORT_OT_vmd.bl_idname,
251 text="MikuMikuDance motion (.vmd)")
254 bpy.types.register(IMPORT_OT_vmd)
255 bpy.types.INFO_MT_file_import.append(menu_func)
258 bpy.types.unregister(IMPORT_OT_vmd)
259 bpy.types.INFO_MT_file_import.remove(menu_func)
262 if __name__=="__main__":