3 __author__= ['ousttrue']
5 __version__= '20100515 0.1:'
9 This script imports a vmd into Blender for editing.
13 from bpy.props import *
18 from meshio import vmd, englishmap
26 return x/math.pi * 180.0
34 q=mathutils.Quaternion((0, 0, 0), l.w*r.w-(l.x*r.x+l.y*r.y+l.z*r.z))
35 q.x=l.w*r.x+r.w*l.x+l.y*r.z-l.z*r.y
36 q.y=l.w*r.y+r.w*l.y+l.z*r.x-l.x*r.z
37 q.z=l.w*r.z+r.w*l.z+l.x*r.y-l.y*r.x
41 def import_motion_key(l, o):
42 print('import_motion_key: %s' % o.name)
51 keyFrames=l.getBoneKeyFrameList(n)
52 boneName=englishmap.getEnglishBoneName(n)
54 poseBone=pose.bones[boneName]
55 bone=armature.bones[boneName]
57 armRotate=bone.matrix_local.rotation_part()
59 armRotateQuaternion=armRotate.to_quat()
60 if armRotateQuaternion.w<0:
61 armRotateQuaternion.w=-armRotateQuaternion.w
62 armRotateQuaternion.x=-armRotateQuaternion.x
63 armRotateQuaternion.y=-armRotateQuaternion.y
64 armRotateQuaternion.z=-armRotateQuaternion.z
67 armRotateInv=mathutils.Matrix(armRotate).transpose()
69 armRotateInvQuaternion=armRotateInv.to_quat()
70 if armRotateInvQuaternion.w<0:
71 armRotateInvQuaternion.w=-armRotateInvQuaternion.w
72 armRotateInvQuaternion.x=-armRotateInvQuaternion.x
73 armRotateInvQuaternion.y=-armRotateInvQuaternion.y
74 armRotateInvQuaternion.z=-armRotateInvQuaternion.z
79 for i in range(len(keyFrames.list)):
80 key=keyFrames.getKey(i)
84 if lastQ and lastQ.dot(key.q)<0:
85 reverseFlag=not reverseFlag
88 # convert left-handed y-up to right-handed z-up
90 # reverse quaternion for slerp
91 q=mathutils.Quaternion((0, 0, 0), -key.q.w)
96 q=mathutils.Quaternion((0, 0, 0), key.q.w)
101 poseBone.rotation_quaternion=multQuat(
102 armRotateInvQuaternion,
103 multQuat(q, armRotateQuaternion))
108 poseBone.location = mathutils.Vector(
109 (float(key.pos.x), float(key.pos.z), float(key.pos.y)))
112 poseBone.keyframe_insert('rotation_quaternion', -1, keyFrames.getFrame(i))
113 poseBone.keyframe_insert('location', -1, keyFrames.getFrame(i))
114 last_frame=max(last_frame, keyFrames.getFrame(i))
118 except KeyError as msg:
119 not_found[boneName]=True
122 print("bone not exists")
123 for name in not_found.keys():
129 def IPO_CURVE_get_or_create(ipo, name):
133 return ipo.addCurve(name)
136 def import_shape_key(l, mesh):
137 print('import_shape_key: %s' % mesh.name)
140 key = mesh.getData().key
142 Draw.PupMenu('selecting mesh not has a Key')
147 ipo = Blender.Ipo.New("Key", "ShapeKey")
153 for n in l.morphKeys:
154 keyFrames=l.getMorphKeyFrameList(n)
157 name=englishmap.getEnglishSkinName(n)
159 curve=IPO_CURVE_get_or_create(ipo, name)
160 except NameError as msg:
161 print(NameError, msg)
164 curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
165 for i in xrange(len(keyFrames.list)):
166 key=keyFrames.getKey(i)
167 frame=keyFrames.getFrame(i)
168 curve[frame]=key.weight
169 last_frame=max(last_frame, frame)
176 def load(filename, context):
178 load vmd file to context.
181 if not io.read(filename):
182 print("fail to read", filename)
189 for o in scene.objects:
191 if o.data.__class__ is bpy.types.Armature:
193 last_frame, import_motion_key(io, o))
194 elif o.data.__class__ is bpy.types.Mesh:
196 last_frame, import_shape_key(io, o))
199 scene.frame_end = last_frame
200 print("last frame: %d" % last_frame)
208 ###############################################################################
210 ###############################################################################
211 class IMPORT_OT_vmd(bpy.types.Operator):
212 bl_idname = "import_anim.vmd"
213 bl_label = 'Import VMD'
215 # List of operator properties, the attributes will be assigned
216 # to the class instance from the operator settings before calling.
217 path = StringProperty(
219 description="File path used for importing the VMD file",
220 maxlen= 1024, default= "")
221 filename = StringProperty(
223 description="Name of the file.")
224 directory = StringProperty(
226 description="Directory of the file.")
228 def execute(self, context):
229 load(self.properties.path, context)
232 def invoke(self, context, event):
234 wm.add_fileselect(self)
235 return {'RUNNING_MODAL'}
238 ###############################################################################
240 ###############################################################################
241 def menu_func(self, context):
242 self.layout.operator(IMPORT_OT_vmd.bl_idname,
243 text="MikuMikuDance motion (.vmd)")
246 bpy.types.register(IMPORT_OT_vmd)
247 bpy.types.INFO_MT_file_import.append(menu_func)
250 bpy.types.unregister(IMPORT_OT_vmd)
251 bpy.types.INFO_MT_file_import.remove(menu_func)
254 if __name__=="__main__":