1 #!/usr/bin/env python
\r
4 ========================
\r
5 MikuMikuDance PMX format
\r
6 ========================
\r
10 * PMDEditor's Lib/PMX仕様/PMX仕様.txt
\r
14 * textencoding: unicode
\r
15 * coordinate: left handed y-up(DirectX)
\r
17 * face: only triangle
\r
21 __author__="ousttrue"
\r
23 __versioon__="1.0.0"
\r
29 from pymeshio import common
\r
42 def __init__(self, target_index, loop, limit_radian):
\r
43 self.target_index=target_index
\r
45 self.limit_radian=limit_radian
\r
49 class IkLink(object):
\r
58 def __init__(self, bone_index, limit_angle):
\r
59 self.bone_index=bone_index
\r
60 self.limit_angle=limit_angle
\r
97 self.english_name=english_name
\r
98 self.position=position
\r
99 self.parent_index=parent_index
\r
103 def __eq__(self, rhs):
\r
105 self.name==rhs.name
\r
106 and self.english_name==rhs.english_name
\r
107 and self.position==rhs.position
\r
108 and self.parent_index==rhs.parent_index
\r
109 and self.layer==rhs.layer
\r
110 and self.flag==rhs.flag
\r
113 def getConnectionFlag(self):
\r
114 return self.flag & 0x0001
\r
116 def getIkFlag(self):
\r
117 return (self.flag & 0x0020) >> 5
\r
119 def getRotationFlag(self):
\r
120 return (self.flag & 0x0100) >> 8
\r
122 def getTranslationFlag(self):
\r
123 return (self.flag & 0x0200) >> 9
\r
125 def getFixedAxisFlag(self):
\r
126 return (self.flag & 0x0400) >> 10
\r
128 def getLocalCoordinateFlag(self):
\r
129 return (self.flag & 0x0800) >> 11
\r
131 def getExternalParentDeformFlag(self):
\r
132 return (self.flag & 0x2000) >> 13
\r
135 class Material(object):
\r
138 Attributes: see __init__
\r
152 'sphere_texture_index',
\r
154 'toon_sharing_flag',
\r
155 'toon_texture_index',
\r
171 sphere_texture_index,
\r
176 self.english_name=english_name
\r
177 self.diffuse_color=diffuse_color
\r
179 self.specular_color=specular_color
\r
180 self.specular_factor=specular_factor
\r
181 self.ambient_color=ambient_color
\r
183 self.edge_color=edge_color
\r
184 self.edge_size=edge_size
\r
185 self.texture_index=texture_index
\r
186 self.sphere_texture_index=sphere_texture_index
\r
187 self.sphere_mode=sphere_mode
\r
188 self.toon_sharing_flag=toon_sharing_flag
\r
190 self.toon_texture_index=None
\r
191 self.comment=name.__class__() # unicode
\r
192 self.vertex_count=0
\r
194 def __eq__(self, rhs):
\r
196 self.name==rhs.name
\r
197 and self.english_name==rhs.english_name
\r
198 and self.diffuse_color==rhs.diffuse_color
\r
199 and self.alpha==rhs.alpha
\r
200 and self.specular_color==rhs.specular_color
\r
201 and self.specular_factor==rhs.specular_factor
\r
202 and self.ambient_color==rhs.ambient_color
\r
203 and self.flag==rhs.flag
\r
204 and self.edge_color==rhs.edge_color
\r
205 and self.edge_size==rhs.edge_size
\r
206 and self.texture_index==rhs.texture_index
\r
207 and self.sphere_texture_index==rhs.sphere_texture_index
\r
208 and self.sphere_mode==rhs.sphere_mode
\r
209 and self.toon_sharing_flag==rhs.toon_sharing_flag
\r
210 and self.toon_texture_index==rhs.toon_texture_index
\r
211 and self.comment==rhs.comment
\r
212 and self.vertex_count==rhs.vertex_count
\r
216 return ("<pmx.Material {name}>".format(
\r
217 name=self.english_name
\r
221 class Deform(object):
\r
225 class Bdef1(object):
\r
226 """bone deform. use a weight
\r
228 Attributes: see __init__
\r
230 __slots__=[ 'index0']
\r
231 def __init__(self, index0):
\r
234 def __eq__(self, rhs):
\r
235 return self.index0==rhs.index0
\r
238 class Bdef2(object):
\r
239 """bone deform. use two weights
\r
241 Attributes: see __init__
\r
243 __slots__=[ 'index0', 'index1', 'weight0']
\r
244 def __init__(self,
\r
250 self.weight0=weight0
\r
252 def __eq__(self, rhs):
\r
254 self.index0==rhs.index0
\r
255 and self.index1==rhs.index1
\r
256 and self.weight0==rhs.weight0
\r
260 class Vertex(object):
\r
263 Attributes: see __init__
\r
265 __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]
\r
266 def __init__(self,
\r
272 self.position=position
\r
276 self.edge_factor=edge_factor
\r
278 def __eq__(self, rhs):
\r
280 self.position==rhs.position
\r
281 and self.normal==rhs.normal
\r
282 and self.uv==rhs.uv
\r
283 and self.deform==rhs.deform
\r
284 and self.edge_factor==rhs.edge_factor
\r
288 class Morph(object):
\r
305 def __init__(self, name, english_name, panel, morph_type):
\r
307 self.english_name=english_name
\r
309 self.morph_type=morph_type
\r
312 def __eq__(self, rhs):
\r
314 self.name==rhs.name
\r
315 and self.english_name==rhs.english_name
\r
316 and self.panel==rhs.panel
\r
317 and self.morph_type==rhs.morph_type
\r
318 and self.offsets==rhs.offsets
\r
322 class VerexMorphOffset(object):
\r
323 """pmx vertex morph offset
\r
327 position_offset: Vector3
\r
333 def __init__(self, vertex_index, position_offset):
\r
334 self.vertex_index=vertex_index
\r
335 self.position_offset=position_offset
\r
337 def __eq__(self, rhs):
\r
339 self.vertex_index==rhs.vertex_index
\r
340 and self.position_offset==rhs.position_offset
\r
344 class DisplaySlot(object):
\r
345 """pmx display slot
\r
351 refrences: list of (ref_type, ref_index)
\r
359 def __init__(self, name, english_name, special_flag):
\r
361 self.english_name=english_name
\r
362 self.special_flag=special_flag
\r
365 def __eq__(self, rhs):
\r
367 self.name==rhs.name
\r
368 and self.english_name==rhs.english_name
\r
369 and self.special_flag==rhs.special_flag
\r
370 and self.refrences==rhs.refrences
\r
374 class RigidBodyParam(object):
\r
375 """pmx rigidbody param(for bullet)
\r
391 def __init__(self, mass,
\r
392 linear_damping, angular_damping, restitution, friction):
\r
394 self.linear_damping=linear_damping
\r
395 self.angular_damping=angular_damping
\r
396 self.restitution=restitution
\r
397 self.friction=friction
\r
399 def __eq__(self, rhs):
\r
401 self.mass==rhs.mass
\r
402 and self.linear_damping==rhs.linear_damping
\r
403 and self.angular_damping==rhs.angular_damping
\r
404 and self.restitution==rhs.restitution
\r
405 and self.friction==rhs.friction
\r
409 class RigidBody(object):
\r
417 no_collision_group:
\r
427 'no_collision_group',
\r
440 no_collision_group,
\r
453 self.english_name=english_name
\r
454 self.bone_index=bone_index
\r
455 self.collision_group=collision_group
\r
456 self.no_collision_group=no_collision_group
\r
457 self.shape_type=shape_type
\r
458 self.shape_size=shape_size
\r
459 self.shape_position=shape_position
\r
460 self.shape_rotation=shape_rotation
\r
461 self.param=RigidBodyParam(mass,
\r
462 linear_damping, angular_damping,
\r
463 restitution, friction)
\r
466 def __eq__(self, rhs):
\r
468 self.name==rhs.name
\r
469 and self.english_name==rhs.english_name
\r
470 and self.bone_index==rhs.bone_index
\r
471 and self.collision_group==rhs.collision_group
\r
472 and self.no_collision_group==rhs.no_collision_group
\r
473 and self.shape_type==rhs.shape_type
\r
474 and self.shape_size==rhs.shape_size
\r
475 and self.param==rhs.param
\r
476 and self.mode==rhs.mode
\r
480 class Joint(object):
\r
491 translation_limit_min: Vector3
\r
492 translation_limit_max: Vector3
\r
493 rotation_limit_min: Vector3
\r
494 rotation_limit_max: Vector3
\r
495 spring_constant_translation: Vector3
\r
496 spring_constant_rotation: Vector3
\r
502 'rigidbody_index_a',
\r
503 'rigidbody_index_b',
\r
506 'translation_limit_min',
\r
507 'translation_limit_max',
\r
508 'rotation_limit_min',
\r
509 'rotation_limit_max',
\r
510 'spring_constant_translation',
\r
511 'spring_constant_rotation',
\r
513 def __init__(self, name, english_name,
\r
519 translation_limit_min,
\r
520 translation_limit_max,
\r
521 rotation_limit_min,
\r
522 rotation_limit_max,
\r
523 spring_constant_translation,
\r
524 spring_constant_rotation
\r
527 self.english_name=english_name
\r
528 self.joint_type=joint_type
\r
529 self.rigidbody_index_a=rigidbody_index_a
\r
530 self.rigidbody_index_b=rigidbody_index_b
\r
531 self.position=position
\r
532 self.rotation=rotation
\r
533 self.translation_limit_min=translation_limit_min
\r
534 self.translation_limit_max=translation_limit_max
\r
535 self.rotation_limit_min=rotation_limit_min
\r
536 self.rotation_limit_max=rotation_limit_max
\r
537 self.spring_constant_translation=spring_constant_translation
\r
538 self.spring_constant_rotation=spring_constant_rotation
\r
540 def __eq__(self, rhs):
\r
542 self.name==rhs.name
\r
543 and self.english_name==rhs.english_name
\r
544 and self.joint_type==rhs.joint_type
\r
545 and self.rigidbody_index_a==rhs.rigidbody_index_a
\r
546 and self.rigidbody_index_b==rhs.rigidbody_index_b
\r
547 and self.position==rhs.position
\r
548 and self.rotation==rhs.rotation
\r
549 and self.translation_limit_min==rhs.translation_limit_min
\r
550 and self.translation_limit_max==rhs.translation_limit_max
\r
551 and self.rotation_limit_min==rhs.rotation_limit_min
\r
552 and self.rotation_limit_max==rhs.rotation_limit_max
\r
553 and self.spring_constant_translation==rhs.spring_constant_translation
\r
554 and self.spring_constant_rotation==rhs.spring_constant_rotation
\r
558 class Model(object):
\r
559 """pmx data representation
\r
562 version: pmx version(expected 2.0)
\r
577 'version', # pmx version
\r
578 'name', # model name
\r
579 'english_name', # model name in english
\r
580 'comment', # model comment
\r
581 'english_comment', # model comment in english
\r
592 def __init__(self, version):
\r
593 self.version=version
\r
595 self.english_name=''
\r
597 self.english_comment=''
\r
604 self.display_slots=[]
\r
605 self.rigidbodies=[]
\r
609 return ('<pmx-{version} "{name}" {vertices}vertices>'.format(
\r
610 version=self.version,
\r
611 name=self.english_name,
\r
612 vertices=len(self.vertices)
\r
615 def __eq__(self, rhs):
\r
617 self.version==rhs.version
\r
618 and self.name==rhs.name
\r
619 and self.english_name==rhs.english_name
\r
620 and self.comment==rhs.comment
\r
621 and self.english_comment==rhs.english_comment
\r
622 and self.vertices==rhs.vertices
\r
623 and self.indices==rhs.indices
\r
624 and self.textures==rhs.textures
\r
625 and self.materials==rhs.materials
\r
626 and self.bones==rhs.bones
\r
627 and self.morphs==rhs.morphs
\r
628 and self.display_slots==rhs.display_slots
\r
629 and self.rigidbodies==rhs.rigidbodies
\r
630 and self.joints==rhs.joints
\r