4 Name: 'MikuMikuDance motion and shape (.vmd)...'
7 Tooltip: 'Import motion from MikuMikuDance motion file (.vmd)'
10 __url__ = ["http://gunload.web.fc2.com/blender/"]
11 __version__= '0.6 2010/05/06'
15 This script imports a vmd file into Blender.
18 0.2 2009/12/09 implement shape key
19 0.3 2010/03/05 use english name
20 0.4 2010/04/05 fix slerp
21 0.5 2010/04/16 add progress
22 0.6 2010/05/06 C extension.
23 0.7 2010/05/16 modify C extension interface.
31 from meshio import vmd, englishmap
34 FS_ENCODING=sys.getfilesystemencoding()
35 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
36 INTERNAL_ENCODING='utf-8'
38 INTERNAL_ENCODING=FS_ENCODING
41 class ProgressBar(object):
42 def __init__(self, base):
43 print "#### %s ####" % base
45 self.start=Blender.sys.time()
46 self.set('<start>', 0)
48 def advance(self, message, progress):
49 self.progress+=float(progress)
52 def set(self, message, progress):
53 self.progress=float(progress)
56 def _print(self, message):
58 message="%s: %s" % (self.base, message)
59 if message.__class__ is unicode:
60 message=message.encode(INTERNAL_ENCODING)
63 Blender.Window.DrawProgressBar(self.progress, message)
64 except AttributeError, error:
66 #print type(self.progress), self.progress, type(message), message
71 message='finished in %.2f sec' % (Blender.sys.time()-self.start)
72 self.set(message, 1.0)
74 def progress_start(base):
76 progressBar=ProgressBar(base)
78 def progress_finish():
82 def progress_print(message, progress=0.01):
84 progressBar.advance(message, progress)
86 def progress_set(message, progress):
88 progressBar.set(message, progress)
96 return x/math.pi * 180.0
104 q=Blender.Mathutils.Quaternion(l.w*r.w-(l.x*r.x+l.y*r.y+l.z*r.z), 0, 0, 0)
105 q.x=l.w*r.x+r.w*l.x+l.y*r.z-l.z*r.y
106 q.y=l.w*r.y+r.w*l.y+l.z*r.x-l.x*r.z
107 q.z=l.w*r.z+r.w*l.z+l.x*r.y-l.y*r.x
111 def import_motion_key(l, o, progressCount):
112 print 'import_motion_key: %s' % o.name
114 if not act: # Add a pose action if we dont have one
115 act = Armature.NLA.NewAction()
125 keyFrames=l.getBoneKeyFrameList(n)
127 boneName=englishmap.getEnglishBoneName(n).encode(INTERNAL_ENCODING)
132 poseBone=pose.bones[boneName]
133 bone=armature.bones[boneName]
135 armRotate=bone.matrix['ARMATURESPACE'].rotationPart()
137 armRotateQuaternion=armRotate.toQuat()
140 armRotateInv=Blender.Mathutils.Matrix(armRotate).transpose()
142 armRotateInvQuaternion=armRotateInv.toQuat()
147 for i in xrange(len(keyFrames.list)):
148 key=keyFrames.getKey(i)
152 if lastQ and lastQ.dot(key.q)<0:
153 reverseFlag=not reverseFlag
156 # convert left-handed y-up to right-handed z-up
158 # reverse quaternion for slerp
159 q=Blender.Mathutils.Quaternion(-key.q.w, 0, 0, 0)
164 q=Blender.Mathutils.Quaternion(key.q.w, 0, 0, 0)
170 multQuat(armRotateInvQuaternion,
171 multQuat(q, armRotateQuaternion)))
176 poseBone.loc = Blender.Mathutils.Vector(
177 float(key.pos.x), float(key.pos.z), float(key.pos.y))
180 poseBone.insertKey(o, keyFrames.getFrame(i),
181 [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],
183 last_frame=max(last_frame, keyFrames.getFrame(i))
186 if counter % progressCount==0:
189 except KeyError, msg:
190 not_found[boneName]=True
193 print "bone not exists"
194 for name in not_found.keys():
200 def IPO_CURVE_get_or_create(ipo, name):
204 return ipo.addCurve(name)
207 def import_shape_key(l, mesh, progressCount):
208 print 'import_shape_key: %s' % mesh.name
209 key = mesh.getData().key
211 Blender.Draw.PupMenu('selecting mesh not has a Key')
216 ipo = Blender.Ipo.New("Key", "ShapeKey")
222 for n in l.morphKeys:
223 keyFrames=l.getMorphKeyFrameList(n)
226 name=englishmap.getEnglishSkinName(n).encode(INTERNAL_ENCODING)
228 curve=IPO_CURVE_get_or_create(ipo, name)
229 except NameError, msg:
233 curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
234 for i in xrange(len(keyFrames.list)):
235 key=keyFrames.getKey(i)
236 frame=keyFrames.getFrame(i)
237 curve[frame]=key.weight
238 last_frame=max(last_frame, frame)
241 if counter % progressCount==0:
248 filename=filename.decode(INTERNAL_ENCODING)
251 progress_start('vmd_import')
252 print(INTERNAL_ENCODING, FS_ENCODING)
255 progress_set('load %s' % filename, 0.0)
257 if not l.read(filename.encode(FS_ENCODING)):
258 print "failt to load", filename
260 progress_set('loaded %s' % filename, 1.0)
262 scene=Blender.Scene.GetCurrent()
267 for o in scene.objects.selected:
268 if o.type=='Armature':
272 #keyCount=armtureCount*l.boneMap.Size()+shapeCount*l.morphMap.size()
273 #progressCount=int(keyCount/100)
278 for o in scene.objects.selected:
279 if o.type=='Armature':
280 last_frame=max(last_frame, import_motion_key(l, o, progressCount))
282 last_frame=max(last_frame, import_shape_key(l, o, progressCount))
285 scene.getRenderingContext().eFrame = last_frame
291 if __name__=="__main__":
292 if 0<len([o for o in Blender.Scene.GetCurrent().objects.selected if
293 o.type=='Armature' or o.type=='Mesh']):
294 Blender.Window.FileSelector(
297 Blender.sys.makename(ext='.vmd'))
299 Blender.Draw.PupMenu('select target armature and mesh objects.')