3 ========================
4 MikuMikuDance PMD format
5 ========================
9 * http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
13 * textencoding: bytes(cp932)
14 * coordinate: left handed y-up(DirectX)
32 two bone weighted vertex with normal and uv.
36 * http://blog.goo.ne.jp/torisu_tetosuki/e/5a1b16e2f61067838dfc66d010389707
50 bone0 influence. min: 0, max: 100
52 int flag. 0: edge on, 1: edge off
54 __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
55 def __init__(self, pos, normal, uv,
56 bone0, bone1, weight0, edge_flag):
63 self.edge_flag=edge_flag
66 return "<%s %s %s, (%d, %d, %d)>" % (
70 self.bone0, self.bone1, self.weight0)
72 def __eq__(self, rhs):
75 and self.normal==rhs.normal
77 and self.bone0==rhs.bone0
78 and self.bone1==rhs.bone1
79 and self.weight0==rhs.weight0
80 and self.edge_flag==rhs.edge_flag
83 def __getitem__(self, key):
94 class Material(object):
102 * http://blog.goo.ne.jp/torisu_tetosuki/e/ea0bb1b1d4c6ad98a93edbfe359dac32
125 'diffuse_color', 'alpha',
126 'specular_factor', 'specular_color', 'ambient_color',
127 'toon_index', 'edge_flag',
128 'vertex_count', 'texture_file',
130 def __init__(self, diffuse_color, alpha,
131 specular_factor, specular_color, ambient_color,
132 toon_index, edge_flag, vertex_count, texture_file):
133 self.diffuse_color=diffuse_color
135 self.specular_factor=specular_factor
136 self.specular_color=specular_color
137 self.ambient_color=ambient_color
138 self.toon_index=toon_index
139 self.edge_flag=edge_flag
140 self.vertex_count=vertex_count
141 self.texture_file=texture_file
144 return "<Material [%f, %f, %f, %f]>" % (
145 self.diffuse[0], self.diffuse[1],
146 self.diffuse[2], self.diffuse[3],
149 def __eq__(self, rhs):
151 self.diffuse_color==rhs.diffuse_color
152 and self.alpha==rhs.alpha
153 and self.specular_factor==rhs.specular_factor
154 and self.specular_color==rhs.specular_color
155 and self.ambient_color==rhs.ambient_color
156 and self.toon_index==rhs.toon_index
157 and self.edge_flag==rhs.edge_flag
158 and self.vertex_count==rhs.vertex_count
159 and self.texture_file==rhs.texture_file
171 * http://blog.goo.ne.jp/torisu_tetosuki/e/638463f52d0ad6ca1c46fd315a9b17d0
179 boen index(append for internal use)
183 ik(append for internal use)
193 parent bone(append for internal use)
195 tail bone(append for internal use)
197 children bone(append for internal use)
210 __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
211 'children', 'english_name', 'ik_index',
212 'parent_index', 'tail_index', 'tail',
214 def __init__(self, name=b'bone', type=0):
218 self.parent_index=0xFFFF
220 self.tail=common.Vector3(0, 0, 0)
223 self.pos=common.Vector3(0, 0, 0)
227 def __eq__(self, rhs):
230 and self.index==rhs.index
231 and self.type==rhs.type
232 and self.parent_index==rhs.parent_index
233 and self.tail_index==rhs.tail_index
234 and self.tail==rhs.tail
235 and self.ik_index==rhs.ik_index
236 and self.pos==rhs.pos
237 and self.children==rhs.children
238 and self.english_name==rhs.english_name
242 return self.parent_index!=0xFFFF
245 return self.tail_index!=0
247 def display(self, indent=[]):
250 for i, is_end in enumerate(indent):
254 prefix+=' ' if is_end else ' |'
255 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
256 print(uni.encode(ENCODING))
258 uni='%s(%s)' % (unicode(self), self.english_name)
259 print(uni.encode(ENCODING))
261 child_count=len(self.children)
262 for i in range(child_count):
263 child=self.children[i]
265 child.display(indent+[False])
268 child.display(indent+[True])
271 class Bone_Rotate(Bone):
273 def __init__(self, name):
274 super(Bone_Rotate, self).__init__(name, 0)
276 return '<ROTATE %s>' % (self.name)
278 class Bone_RotateMove(Bone):
280 def __init__(self, name):
281 super(Bone_RotateMove, self).__init__(name, 1)
283 return '<ROTATE_MOVE %s>' % (self.name)
287 def __init__(self, name):
288 super(Bone_IK, self).__init__(name, 2)
290 return '<IK %s>' % (self.name)
292 class Bone_IKRotateInfl(Bone):
294 def __init__(self, name):
295 super(Bone_IKRotateInfl, self).__init__(name, 4)
297 return '<IK_ROTATE_INFL %s>' % (self.name)
299 class Bone_RotateInfl(Bone):
301 def __init__(self, name):
302 super(Bone_RotateInfl, self).__init__(name, 5)
304 return '<ROTATE_INFL %s>' % (self.name)
306 class Bone_IKTarget(Bone):
308 def __init__(self, name):
309 super(Bone_IKTarget, self).__init__(name, 6)
311 return '<IK_TARGET %s>' % (self.name)
313 class Bone_Unvisible(Bone):
315 def __init__(self, name):
316 super(Bone_Unvisible, self).__init__(name, 7)
318 return '<UNVISIBLE %s>' % (self.name)
320 class Bone_Rolling(Bone):
322 def __init__(self, name):
323 super(Bone_Rolling, self).__init__(name, 8)
325 return '<ROLLING %s>' % (self.name)
327 class Bone_Tweak(Bone):
329 def __init__(self, name):
330 super(Bone_Tweak, self).__init__(name, 9)
332 return '<TWEAK %s>' % (self.name)
335 def createBone(name, type):
337 return Bone_Rotate(name)
339 return Bone_RotateMove(name)
343 raise Exception("no used bone type: 3(%s)" % name)
345 return Bone_IKRotateInfl(name)
347 return Bone_RotateInfl(name)
349 return Bone_IKTarget(name)
351 return Bone_Unvisible(name)
353 return Bone_Rolling(name)
355 return Bone_Tweak(name)
357 raise Exception("unknown bone type: %d(%s)", type, name)
361 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
362 def __init__(self, index=0, target=0):
370 return "<IK index: %d, target: %d, iterations: %d, weight: %f, children: %s(%d)>" %(self.index, self.target, self.iterations, self.weight, '-'.join([str(i) for i in self.children]), len(self.children))
372 def __eq__(self, rhs):
374 self.index==rhs.index
375 and self.target==rhs.target
376 and self.iterations==rhs.iterations
377 and self.weight==rhs.weight
378 and self.children==rhs.children
383 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
385 def __init__(self, name):
393 def append(self, index, x, y, z):
394 self.indices.append(index)
395 self.pos_list.append(common.Vector3(x, y, z))
398 return '<Skin name: "%s", type: %d, vertex: %d>' % (
399 self.name, self.type, len(self.indices))
401 def __eq__(self, rhs):
404 and self.type==rhs.type
405 and self.indices==rhs.indices
406 and self.pos_list==rhs.pos_list
407 and self.english_name==rhs.english_name
408 and self.vertex_count==rhs.vertex_count
412 class BoneGroup(object):
413 __slots__=['name', 'english_name']
414 def __init__(self, name=b'group', english_name=b'center'):
416 self.english_name=english_name
418 def __eq__(self, rhs):
419 return self.name==rhs.name and self.english_name==rhs.english_name
426 RIGIDBODY_KINEMATICS=0
428 RIGIDBODY_PHYSICS_WITH_BONE=2
431 class RigidBody(object):
435 'no_collision_group',
447 def __init__(self, name,
463 self.bone_index=bone_index
464 self.collision_group=collision_group
465 self.no_collision_group=no_collision_group
466 self.shape_type=shape_type
467 self.shape_size=shape_size
468 self.shape_position=shape_position
469 self.shape_rotation=shape_rotation
471 self.linear_damping=linear_damping
472 self.angular_damping=angular_damping
473 self.restitution=restitution
474 self.friction=friction
477 def __eq__(self, rhs):
480 and self.bone_index==rhs.bone_index
481 and self.collision_group==rhs.collision_group
482 and self.no_collision_group==rhs.no_collision_group
483 and self.shape_type==rhs.shape_type
484 and self.shape_size==rhs.shape_size
485 and self.shape_position==rhs.shape_position
486 and self.shape_rotation==rhs.shape_rotation
487 and self.mass==rhs.mass
488 and self.linear_damping==rhs.linear_damping
489 and self.angular_damping==rhs.angular_damping
490 and self.restitution==rhs.restitution
491 and self.friction==rhs.friction
492 and self.mode==rhs.mode
497 __slots__=[ 'name', 'rigidbody_index_a', 'rigidbody_index_b',
498 'position', 'rotation',
499 'translation_limit_max', 'translation_limit_min',
500 'rotation_limit_max', 'rotation_limit_min',
501 'spring_constant_translation', 'spring_constant_rotation',
503 def __init__(self, name,
504 rigidbody_index_a, rigidbody_index_b,
506 translation_limit_max, translation_limit_min,
507 rotation_limit_max, rotation_limit_min,
508 spring_constant_translation, spring_constant_rotation
511 self.rigidbody_index_a=rigidbody_index_a
512 self.rigidbody_index_b=rigidbody_index_b
513 self.position=position
514 self.rotation=rotation
515 self.translation_limit_max=translation_limit_max
516 self.translation_limit_min=translation_limit_min
517 self.rotation_limit_max=rotation_limit_max
518 self.rotation_limit_min=rotation_limit_min
519 self.spring_constant_translation=spring_constant_translation
520 self.spring_constant_rotation=spring_constant_rotation
522 def __eq__(self, rhs):
525 and self.rigidbody_index_a==rhs.rigidbody_index_a
526 and self.rigidbody_index_b==rhs.rigidbody_index_b
527 and self.position==rhs.position
528 and self.rotation==rhs.rotation
529 and self.translation_limit_max==rhs.translation_limit_max
530 and self.translation_limit_min==rhs.translation_limit_min
531 and self.rotation_limit_max==rhs.rotation_limit_max
532 and self.rotation_limit_min==rhs.rotation_limit_min
533 and self.spring_constant_translation==rhs.spring_constant_translation
534 and self.spring_constant_rotation==rhs.spring_constant_rotation
546 version: pmd version number
551 'version', 'name', 'comment',
552 'english_name', 'english_comment',
553 'vertices', 'indices', 'materials', 'bones',
555 'morph_indices', 'bone_group_list', 'bone_display_list',
557 'rigidbodies', 'joints',
561 def __init__(self, version=1.0):
566 self.english_name=b''
567 self.english_comment=b''
574 self.morph_indices=[]
575 self.bone_group_list=[]
576 self.bone_display_list=[]
578 self.toon_textures=[b'']*10
582 self.no_parent_bones=[]
584 def each_vertex(self): return self.vertices
585 def getUV(self, i): return self.vertices[i].uv
588 return '<pmd-%g, "%s" vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
589 self.version, self.name, len(self.vertices), len(self.indices),
590 len(self.materials), len(self.bones), len(self.ik_list), len(self.morphs))
592 def __eq__(self, rhs):
595 and self.comment==rhs.comment
596 and self.english_name==rhs.english_name
597 and self.english_comment==rhs.english_comment
598 and self.vertices==rhs.vertices
599 and self.indices==rhs.indices
600 and self.materials==rhs.materials
601 and self.bones==rhs.bones
602 and self.ik_list==rhs.ik_list
603 and self.morphs==rhs.morphs
604 and self.morph_indices==rhs.morph_indices
605 and self.bone_group_list==rhs.bone_group_list
606 and self.bone_display_list==rhs.bone_display_list
607 and self.toon_textures==rhs.toon_textures
608 and self.rigidbodies==rhs.rigidbodies
609 and self.joints==rhs.joints
613 if self.name!=rhs.name:
614 print(self.name, rhs.name)
616 if self.comment!=rhs.comment:
617 print(self.comment, rhs.comment)
619 if self.english_name!=rhs.english_name:
620 print(self.english_name, rhs.english_name)
622 if self.english_comment!=rhs.english_comment:
623 print(self.english_comment, rhs.english_comment)
625 if self.vertices!=rhs.vertices:
626 print(self.vertices, rhs.vertices)
628 if self.indices!=rhs.indices:
629 print(self.indices, rhs.indices)
631 if self.materials!=rhs.materials:
632 print(self.materials, rhs.materials)
634 if self.bones!=rhs.bones:
635 print(self.bones, rhs.bones)
637 if self.ik_list!=rhs.ik_list:
638 print(self.ik_list, rhs.ik_list)
640 if self.morphs!=rhs.morphs:
641 print(self.morphs, rhs.morphs)
643 if self.morph_indices!=rhs.morph_indices:
644 print(self.morph_indices, rhs.morph_indices)
646 if self.bone_group_list!=rhs.bone_group_list:
647 print(self.bone_group_list, rhs.bone_group_list)
649 if self.bone_display_list!=rhs.bone_display_list:
650 print(self.bone_display_list, rhs.bone_display_list)
652 if self.toon_textures!=rhs.toon_textures:
653 print(self.toon_textures, rhs.toon_textures)
655 if self.rigidbodies!=rhs.rigidbodies:
656 print(self.rigidbodies, rhs.rigidbodies)
658 if self.joints!=rhs.joints:
659 print(self.joints, rhs.joints)