1
2
3 """
4 ========================
5 MikuMikuDance PMX format
6 ========================
7
8 file format
9 ~~~~~~~~~~~
10 * PMDEditor's Lib/PMX仕様/PMX仕様.txt
11
12 specs
13 ~~~~~
14 * textencoding: unicode
15 * coordinate: left handed y-up(DirectX)
16 * uv origin:
17 * face: only triangle
18 * backculling:
19
20 """
21 __author__="ousttrue"
22 __license__="zlib"
23 __versioon__="1.0.0"
24
25
26 import io
27 import os
28 import struct
29 from .. import common
30
31
32
35
36
38 - def _diff(self, rhs, key):
45
66
67
69 """ik info
70 """
71 __slots__=[
72 'target_index',
73 'loop',
74 'limit_radian',
75 'link',
76 ]
77 - def __init__(self, target_index, loop, limit_radian, link=None):
82
90
91 - def diff(self, rhs):
96
97
99 """ik link info
100 """
101 __slots__=[
102 'bone_index',
103 'limit_angle',
104 'limit_min',
105 'limit_max',
106 ]
107 - def __init__(self, bone_index, limit_angle, limit_min=None, limit_max=None):
112
120
121 - def diff(self, rhs):
122 self._diff(rhs, 'bone_index')
123 self._diff(rhs, 'limit_angle')
124 self._diff(rhs, 'limit_min')
125 self._diff(rhs, 'limit_max')
126
127
129 """material
130
131 Bone: see __init__
132 """
133 __slots__=[
134 'name',
135 'english_name',
136 'position',
137 'parent_index',
138 'layer',
139 'flag',
140
141 'tail_position',
142 'tail_index',
143 'effect_index',
144 'effect_factor',
145 'fixed_axis',
146 'local_x_vector',
147 'local_z_vector',
148 'external_key',
149 'ik',
150 ]
151 - def __init__(self,
152 name,
153 english_name,
154 position,
155 parent_index,
156 layer,
157 flag,
158 tail_position=None,
159 tail_index=-1,
160 effect_index=-1,
161 effect_factor=0.0,
162 fixed_axis=None,
163 local_x_vector=None,
164 local_z_vector=None,
165 external_key=-1,
166 ik=None
167 ):
183
193
195 return not self.__eq__(rhs)
196
197 - def diff(self, rhs):
198 self._diff(rhs, 'name')
199 self._diff(rhs, 'english_name')
200 self._diff(rhs, 'position')
201 self._diff(rhs, 'parent_index')
202
203 self._diff(rhs, 'flag')
204 self._diff(rhs, 'tail_position')
205 self._diff(rhs, 'tail_index')
206
207
208
209 self._diff(rhs, 'local_x_vector')
210 self._diff(rhs, 'local_z_vector')
211 self._diff(rhs, 'external_key')
212 if self.ik and rhs.ik:
213 self.ik.diff(rhs.ik)
214 else:
215 self._diff(rhs, 'ik')
216
218 return (self.flag & 0x0001)!=0
219
221 return (self.flag & 0x0008)!=0
222
224 return (self.flag & 0x0020)!=0
225
227 return (self.flag & 0x0100)!=0
228
230 return (self.flag & 0x0200)!=0
231
233 return (self.flag & 0x0400)!=0
234
236 return (self.flag & 0x0800)!=0
237
239 return (self.flag & 0x2000)!=0
240
241
243 """material
244
245 Attributes: see __init__
246 """
247 __slots__=[
248 'name',
249 'english_name',
250 'diffuse_color',
251 'alpha',
252 'specular_color',
253 'specular_factor',
254 'ambient_color',
255 'flag',
256 'edge_color',
257 'edge_size',
258 'texture_index',
259 'sphere_texture_index',
260 'sphere_mode',
261 'toon_sharing_flag',
262 'toon_texture_index',
263 'comment',
264 'vertex_count',
265 ]
266 - def __init__(self,
267 name,
268 english_name,
269 diffuse_color,
270 alpha,
271 specular_factor,
272 specular_color,
273 ambient_color,
274 flag,
275 edge_color,
276 edge_size,
277 texture_index,
278 sphere_texture_index,
279 sphere_mode,
280 toon_sharing_flag,
281 toon_texture_index=0,
282 comment=common.unicode(""),
283 vertex_count=0,
284 ):
302
323
324 - def diff(self, rhs):
325
326 self._diff(rhs, "english_name")
327 self._diff(rhs, "diffuse_color")
328 self._diff(rhs, "alpha")
329 self._diff(rhs, "specular_color")
330 self._diff(rhs, "specular_factor")
331 self._diff(rhs, "ambient_color")
332 self._diff(rhs, "flag")
333 self._diff(rhs, "edge_color")
334 self._diff(rhs, "edge_size")
335 self._diff(rhs, "texture_index")
336 self._diff(rhs, "sphere_texture_index")
337 self._diff(rhs, "sphere_mode")
338 self._diff(rhs, "toon_sharing_flag")
339 self._diff(rhs, "toon_texture_index")
340 self._diff(rhs, "comment")
341 self._diff(rhs, "vertex_count")
342
344 return not self.__eq__(rhs)
345
350
351
353 """bone deform. use a weight
354
355 Attributes: see __init__
356 """
357 __slots__=[ 'index0']
360
362 return "<Bdef1 {0}>".format(self.index0)
363
366
368 return not self.__eq__(rhs)
369
370
372 """bone deform. use two weights
373
374 Attributes: see __init__
375 """
376 __slots__=[ 'index0', 'index1', 'weight0']
377 - def __init__(self,
378 index0,
379 index1,
380 weight0):
384
387
395
397 return not self.__eq__(rhs)
398
399
401 """
402 ==========
403 pmx vertex
404 ==========
405
406 :IVariables:
407 position
408 Vector3
409 normal
410 Vector3
411 uv
412 Vector2
413 deform
414 Bdef1, Bdef2 or Bdef4
415 edge_factor
416 float
417 """
418 __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]
419 - def __init__(self,
420 position,
421 normal,
422 uv,
423 deform,
424 edge_factor):
430
435
444
446 return not self.__eq__(rhs)
447
448 - def diff(self, rhs):
449 self._diff(rhs, "position")
450 self._diff(rhs, "normal")
451 self._diff(rhs, "uv")
452 self._diff(rhs, "deform")
453 self._diff(rhs, "edge_factor")
454
455
457 """pmx morph
458
459 Attributes:
460 name:
461 english_name:
462 panel:
463 morph_type:
464 offsets:
465 """
466 __slots__=[
467 'name',
468 'english_name',
469 'panel',
470 'morph_type',
471 'offsets',
472 ]
473 - def __init__(self, name, english_name, panel, morph_type, offsets=None):
479
488
490 return not self.__eq__(rhs)
491
492 - def diff(self, rhs):
493 self._diff(rhs, 'name')
494 self._diff(rhs, 'english_name')
495
496 self._diff(rhs, 'morph_type')
497 self._diff_array(rhs, 'offsets')
498
499
501 """pmx vertex morph offset
502
503 Attributes:
504 vertex_index:
505 position_offset: Vector3
506 """
507 __slots__=[
508 'vertex_index',
509 'position_offset',
510 ]
511 - def __init__(self, vertex_index, position_offset):
514
520
522 return not self.__eq__(rhs)
523
524 - def diff(self, rhs):
525 self._diff(rhs, 'vertex_index')
526 self._diff(rhs, 'position_offset')
527
528
530 """pmx display slot
531
532 Attributes:
533 name:
534 english_name:
535 special_flag:
536 references: list of (ref_type, ref_index)
537 """
538 __slots__=[
539 'name',
540 'english_name',
541 'special_flag',
542 'references',
543 ]
544 - def __init__(self, name, english_name, special_flag, references=None):
549
551 return "<DisplaySlots %s(%d)>" % (self.name, len(self.references))
552
560
562 return not self.__eq__(rhs)
563
564 - def diff(self, rhs):
565 self._diff(rhs, 'name')
566 self._diff(rhs, 'english_name')
567 self._diff(rhs, 'special_flag')
568
569
570
571 -class RigidBodyParam(Diff):
572 """pmx rigidbody param(for bullet)
573
574 Attributes:
575 mass:
576 linear_damping:
577 angular_damping:
578 restitution:
579 friction:
580 """
581 __slots__=[
582 'mass',
583 'linear_damping',
584 'angular_damping',
585 'restitution',
586 'friction',
587 ]
588 - def __init__(self, mass,
589 linear_damping, angular_damping, restitution, friction):
595
596 - def __eq__(self, rhs):
597 return (
598 self.mass==rhs.mass
599 and self.linear_damping==rhs.linear_damping
600 and self.angular_damping==rhs.angular_damping
601 and self.restitution==rhs.restitution
602 and self.friction==rhs.friction
603 )
604
605 - def __ne__(self, rhs):
606 return not self.__eq__(rhs)
607
608 - def diff(self, rhs):
609 self._diff(rhs, 'mass')
610 self._diff(rhs, 'linear_damping')
611 self._diff(rhs, 'angular_damping')
612 self._diff_array(rhs, 'restitution')
613 self._diff_array(rhs, 'friction')
614
615
616 -class RigidBody(Diff):
617 """pmx rigidbody
618
619 Attributes:
620 name:
621 english_name:
622 bone_index:
623 collision_group:
624 no_collision_group:
625 shape:
626 param:
627 mode:
628 """
629 __slots__=[
630 'name',
631 'english_name',
632 'bone_index',
633 'collision_group',
634 'no_collision_group',
635 'shape_type',
636 'shape_size',
637 'shape_position',
638 'shape_rotation',
639 'param',
640 'mode',
641 ]
642 - def __init__(self,
643 name,
644 english_name,
645 bone_index,
646 collision_group,
647 no_collision_group,
648 shape_type,
649 shape_size,
650 shape_position,
651 shape_rotation,
652 mass,
653 linear_damping,
654 angular_damping,
655 restitution,
656 friction,
657 mode
658 ):
672
673 - def __eq__(self, rhs):
674 return (
675 self.name==rhs.name
676 and self.english_name==rhs.english_name
677 and self.bone_index==rhs.bone_index
678 and self.collision_group==rhs.collision_group
679 and self.no_collision_group==rhs.no_collision_group
680 and self.shape_type==rhs.shape_type
681 and self.shape_size==rhs.shape_size
682 and self.param==rhs.param
683 and self.mode==rhs.mode
684 )
685
686 - def __ne__(self, rhs):
687 return not self.__eq__(rhs)
688
689 - def diff(self, rhs):
690 self._diff(rhs, 'name')
691 self._diff(rhs, 'english_name')
692 self._diff(rhs, 'bone_index')
693 self._diff(rhs, 'collision_group')
694 self._diff(rhs, 'no_collision_group')
695 self._diff(rhs, 'shape_type')
696 self._diff(rhs, 'shape_size')
697 self._diff(rhs, 'shape_position')
698 self._diff(rhs, 'shape_rotation')
699 self._diff(rhs, 'param')
700 self._diff(rhs, 'mode')
701
702
704 """pmx joint
705
706 Attributes:
707 name:
708 english_name:
709 joint_type:
710 rigidbody_index_a:
711 rigidbody_index_b:
712 position: Vector3
713 rotation: Vector3
714 translation_limit_min: Vector3
715 translation_limit_max: Vector3
716 rotation_limit_min: Vector3
717 rotation_limit_max: Vector3
718 spring_constant_translation: Vector3
719 spring_constant_rotation: Vector3
720 """
721 __slots__=[
722 'name',
723 'english_name',
724 'joint_type',
725 'rigidbody_index_a',
726 'rigidbody_index_b',
727 'position',
728 'rotation',
729 'translation_limit_min',
730 'translation_limit_max',
731 'rotation_limit_min',
732 'rotation_limit_max',
733 'spring_constant_translation',
734 'spring_constant_rotation',
735 ]
736 - def __init__(self, name, english_name,
737 joint_type,
738 rigidbody_index_a,
739 rigidbody_index_b,
740 position,
741 rotation,
742 translation_limit_min,
743 translation_limit_max,
744 rotation_limit_min,
745 rotation_limit_max,
746 spring_constant_translation,
747 spring_constant_rotation
748 ):
762
779
781 return not self.__eq__(rhs)
782
783 - def diff(self, rhs):
784 self._diff(rhs, 'name')
785 self._diff(rhs, 'joint_type')
786 self._diff(rhs, 'rigidbody_index_a')
787 self._diff(rhs, 'rigidbody_index_b')
788 self._diff(rhs, 'position')
789 self._diff(rhs, 'rotation')
790 self._diff(rhs, 'translation_limit_min')
791 self._diff(rhs, 'translation_limit_max')
792 self._diff(rhs, 'rotation_limit_min')
793 self._diff(rhs, 'rotation_limit_max')
794 self._diff(rhs, 'spring_constant_translation')
795 self._diff(rhs, 'spring_constant_rotation')
796
797
799 """
800 ==========
801 pmx model
802 ==========
803
804 :IVariables:
805 version
806 pmx version(expected 2.0)
807 name
808 model name
809 english_name
810 model name
811 comment
812 comment
813 english_comment
814 comment
815 vertices
816 vertex list
817 textures
818 texture list
819 materials
820 material list
821 bones
822 bone list
823 morph
824 morph list
825 display_slots
826 display list for bone/morph grouping
827 rigidbodies
828 bullet physics rigidbody list
829 joints
830 bullet physics joint list
831 """
832 __slots__=[
833 'path',
834 'version',
835 'name',
836 'english_name',
837 'comment',
838 'english_comment',
839 'vertices',
840 'indices',
841 'textures',
842 'materials',
843 'bones',
844 'morphs',
845 'display_slots',
846 'rigidbodies',
847 'joints',
848 ]
865
872
890
892 return not self.__eq__(rhs)
893
894 - def diff(self, rhs):
895 self._diff(rhs, "version")
896 self._diff(rhs, "name")
897 self._diff(rhs, "english_name")
898 self._diff(rhs, "comment")
899 self._diff(rhs, "english_comment")
900 self._diff_array(rhs, "vertices")
901 self._diff_array(rhs, "indices")
902 self._diff_array(rhs, "textures")
903 self._diff_array(rhs, "materials")
904 self._diff_array(rhs, "bones")
905 self._diff_array(rhs, "morphs")
906 self._diff_array(rhs, "display_slots")
907 self._diff_array(rhs, "rigidbodies")
908 self._diff_array(rhs, "joints")
909