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)
225 self.english_name=b''
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=None):
251 for i, is_end in enumerate(indent):
255 prefix+=' ' if is_end else ' |'
256 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
257 print(uni.encode(ENCODING))
259 uni='%s(%s)' % (unicode(self), self.english_name)
260 print(uni.encode(ENCODING))
262 child_count=len(self.children)
263 for i in range(child_count):
264 child=self.children[i]
266 child.display(indent+[False])
269 child.display(indent+[True])
272 class Bone_Rotate(Bone):
274 def __init__(self, name):
275 super(Bone_Rotate, self).__init__(name, 0)
277 return '<ROTATE %s>' % (self.name)
279 class Bone_RotateMove(Bone):
281 def __init__(self, name):
282 super(Bone_RotateMove, self).__init__(name, 1)
284 return '<ROTATE_MOVE %s>' % (self.name)
288 def __init__(self, name):
289 super(Bone_IK, self).__init__(name, 2)
291 return '<IK %s>' % (self.name)
293 class Bone_IKRotateInfl(Bone):
295 def __init__(self, name):
296 super(Bone_IKRotateInfl, self).__init__(name, 4)
298 return '<IK_ROTATE_INFL %s>' % (self.name)
300 class Bone_RotateInfl(Bone):
302 def __init__(self, name):
303 super(Bone_RotateInfl, self).__init__(name, 5)
305 return '<ROTATE_INFL %s>' % (self.name)
307 class Bone_IKTarget(Bone):
309 def __init__(self, name):
310 super(Bone_IKTarget, self).__init__(name, 6)
312 return '<IK_TARGET %s>' % (self.name)
314 class Bone_Unvisible(Bone):
316 def __init__(self, name):
317 super(Bone_Unvisible, self).__init__(name, 7)
319 return '<UNVISIBLE %s>' % (self.name)
321 class Bone_Rolling(Bone):
323 def __init__(self, name):
324 super(Bone_Rolling, self).__init__(name, 8)
326 return '<ROLLING %s>' % (self.name)
328 class Bone_Tweak(Bone):
330 def __init__(self, name):
331 super(Bone_Tweak, self).__init__(name, 9)
333 return '<TWEAK %s>' % (self.name)
336 def createBone(name, type):
338 return Bone_Rotate(name)
340 return Bone_RotateMove(name)
344 raise Exception("no used bone type: 3(%s)" % name)
346 return Bone_IKRotateInfl(name)
348 return Bone_RotateInfl(name)
350 return Bone_IKTarget(name)
352 return Bone_Unvisible(name)
354 return Bone_Rolling(name)
356 return Bone_Tweak(name)
358 raise Exception("unknown bone type: %d(%s)", type, name)
362 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
363 def __init__(self, index=0, target=0):
371 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))
373 def __eq__(self, rhs):
375 self.index==rhs.index
376 and self.target==rhs.target
377 and self.iterations==rhs.iterations
378 and self.weight==rhs.weight
379 and self.children==rhs.children
384 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
386 def __init__(self, name):
391 self.english_name=b''
394 def append(self, index, x, y, z):
395 self.indices.append(index)
396 self.pos_list.append(common.Vector3(x, y, z))
399 return '<Skin name: "%s", type: %d, vertex: %d>' % (
400 self.name, self.type, len(self.indices))
402 def __eq__(self, rhs):
405 and self.type==rhs.type
406 and self.indices==rhs.indices
407 and self.pos_list==rhs.pos_list
408 and self.english_name==rhs.english_name
409 and self.vertex_count==rhs.vertex_count
413 class BoneGroup(object):
414 __slots__=['name', 'english_name']
415 def __init__(self, name=b'group', english_name=b'center'):
417 self.english_name=english_name
419 def __eq__(self, rhs):
420 return self.name==rhs.name and self.english_name==rhs.english_name
427 RIGIDBODY_KINEMATICS=0
429 RIGIDBODY_PHYSICS_WITH_BONE=2
432 class RigidBody(object):
436 'no_collision_group',
448 def __init__(self, name,
464 self.bone_index=bone_index
465 self.collision_group=collision_group
466 self.no_collision_group=no_collision_group
467 self.shape_type=shape_type
468 self.shape_size=shape_size
469 self.shape_position=shape_position
470 self.shape_rotation=shape_rotation
472 self.linear_damping=linear_damping
473 self.angular_damping=angular_damping
474 self.restitution=restitution
475 self.friction=friction
478 def __eq__(self, rhs):
481 and self.bone_index==rhs.bone_index
482 and self.collision_group==rhs.collision_group
483 and self.no_collision_group==rhs.no_collision_group
484 and self.shape_type==rhs.shape_type
485 and self.shape_size==rhs.shape_size
486 and self.shape_position==rhs.shape_position
487 and self.shape_rotation==rhs.shape_rotation
488 and self.mass==rhs.mass
489 and self.linear_damping==rhs.linear_damping
490 and self.angular_damping==rhs.angular_damping
491 and self.restitution==rhs.restitution
492 and self.friction==rhs.friction
493 and self.mode==rhs.mode
498 __slots__=[ 'name', 'rigidbody_index_a', 'rigidbody_index_b',
499 'position', 'rotation',
500 'translation_limit_max', 'translation_limit_min',
501 'rotation_limit_max', 'rotation_limit_min',
502 'spring_constant_translation', 'spring_constant_rotation',
504 def __init__(self, name,
505 rigidbody_index_a, rigidbody_index_b,
507 translation_limit_max, translation_limit_min,
508 rotation_limit_max, rotation_limit_min,
509 spring_constant_translation, spring_constant_rotation
512 self.rigidbody_index_a=rigidbody_index_a
513 self.rigidbody_index_b=rigidbody_index_b
514 self.position=position
515 self.rotation=rotation
516 self.translation_limit_max=translation_limit_max
517 self.translation_limit_min=translation_limit_min
518 self.rotation_limit_max=rotation_limit_max
519 self.rotation_limit_min=rotation_limit_min
520 self.spring_constant_translation=spring_constant_translation
521 self.spring_constant_rotation=spring_constant_rotation
523 def __eq__(self, rhs):
526 and self.rigidbody_index_a==rhs.rigidbody_index_a
527 and self.rigidbody_index_b==rhs.rigidbody_index_b
528 and self.position==rhs.position
529 and self.rotation==rhs.rotation
530 and self.translation_limit_max==rhs.translation_limit_max
531 and self.translation_limit_min==rhs.translation_limit_min
532 and self.rotation_limit_max==rhs.rotation_limit_max
533 and self.rotation_limit_min==rhs.rotation_limit_min
534 and self.spring_constant_translation==rhs.spring_constant_translation
535 and self.spring_constant_rotation==rhs.spring_constant_rotation
547 version: pmd version number
552 'version', 'name', 'comment',
553 'english_name', 'english_comment',
554 'vertices', 'indices', 'materials', 'bones',
556 'morph_indices', 'bone_group_list', 'bone_display_list',
558 'rigidbodies', 'joints',
562 def __init__(self, version=1.0):
567 self.english_name=b''
568 self.english_comment=b''
575 self.morph_indices=[]
576 self.bone_group_list=[]
577 self.bone_display_list=[]
579 self.toon_textures=[b'']*10
583 self.no_parent_bones=[]
585 def each_vertex(self): return self.vertices
586 def getUV(self, i): return self.vertices[i].uv
589 return '<pmd-%g, "%s" vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
590 self.version, self.name, len(self.vertices), len(self.indices),
591 len(self.materials), len(self.bones), len(self.ik_list), len(self.morphs))
593 def __eq__(self, rhs):
596 and self.comment==rhs.comment
597 and self.english_name==rhs.english_name
598 and self.english_comment==rhs.english_comment
599 and self.vertices==rhs.vertices
600 and self.indices==rhs.indices
601 and self.materials==rhs.materials
602 and self.bones==rhs.bones
603 and self.ik_list==rhs.ik_list
604 and self.morphs==rhs.morphs
605 and self.morph_indices==rhs.morph_indices
606 and self.bone_group_list==rhs.bone_group_list
607 and self.bone_display_list==rhs.bone_display_list
608 and self.toon_textures==rhs.toon_textures
609 and self.rigidbodies==rhs.rigidbodies
610 and self.joints==rhs.joints
614 if self.name!=rhs.name:
615 print(self.name, rhs.name)
617 if self.comment!=rhs.comment:
618 print(self.comment, rhs.comment)
620 if self.english_name!=rhs.english_name:
621 print(self.english_name, rhs.english_name)
623 if self.english_comment!=rhs.english_comment:
624 print(self.english_comment, rhs.english_comment)
626 if self.vertices!=rhs.vertices:
627 print(self.vertices, rhs.vertices)
629 if self.indices!=rhs.indices:
630 print(self.indices, rhs.indices)
632 if self.materials!=rhs.materials:
633 print(self.materials, rhs.materials)
635 if self.bones!=rhs.bones:
636 print(self.bones, rhs.bones)
638 if self.ik_list!=rhs.ik_list:
639 print(self.ik_list, rhs.ik_list)
641 if self.morphs!=rhs.morphs:
642 print(self.morphs, rhs.morphs)
644 if self.morph_indices!=rhs.morph_indices:
645 print(self.morph_indices, rhs.morph_indices)
647 if self.bone_group_list!=rhs.bone_group_list:
648 print(self.bone_group_list, rhs.bone_group_list)
650 if self.bone_display_list!=rhs.bone_display_list:
651 print(self.bone_display_list, rhs.bone_display_list)
653 if self.toon_textures!=rhs.toon_textures:
654 print(self.toon_textures, rhs.toon_textures)
656 if self.rigidbodies!=rhs.rigidbodies:
657 print(self.rigidbodies, rhs.rigidbodies)
659 if self.joints!=rhs.joints:
660 print(self.joints, rhs.joints)