1
2 """
3 ========================
4 MikuMikuDance PMD format
5 ========================
6
7 file format
8 ~~~~~~~~~~~
9 * http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
10
11 specs
12 ~~~~~
13 * textencoding: bytes(cp932)
14 * coordinate: left handed y-up(DirectX)
15 * uv origin:
16 * face: only triangle
17 * backculling:
18
19 """
20 import os
21 import sys
22 import struct
23 import warnings
24 from .. import common
25
26
28 """
29 ==========
30 pmd vertex
31 ==========
32 two bone weighted vertex with normal and uv.
33
34 format
35 ~~~~~~
36 * http://blog.goo.ne.jp/torisu_tetosuki/e/5a1b16e2f61067838dfc66d010389707
37
38 :IVariables:
39 pos
40 Vector3
41 normal
42 Vector3
43 uv
44 Vector2
45 bone0
46 bone index
47 bone1
48 bone index
49 weight0
50 bone0 influence. min: 0, max: 100
51 edge_flag
52 int flag. 0: edge on, 1: edge off
53 """
54 __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
55 - def __init__(self, pos, normal, uv,
56 bone0, bone1, weight0, edge_flag):
64
71
82
84 if key==0:
85 return self.pos.x
86 elif key==1:
87 return self.pos.y
88 elif key==2:
89 return self.pos.z
90 else:
91 assert(False)
92
93
95 """
96 ============
97 pmd material
98 ============
99
100 format
101 ~~~~~~
102 * http://blog.goo.ne.jp/torisu_tetosuki/e/ea0bb1b1d4c6ad98a93edbfe359dac32
103
104 :IVariables:
105 diffuse_color
106 RGB
107 alpha
108 float
109 specular_factor
110 float
111 specular_color
112 RGB
113 ambient_color
114 RGB
115 toon_index
116 int
117 edge_flag
118 int
119 vertex_count
120 indices length
121 texture_file
122 texture file path
123 """
124 __slots__=[
125 'diffuse_color', 'alpha',
126 'specular_factor', 'specular_color', 'ambient_color',
127 'toon_index', 'edge_flag',
128 'vertex_count', 'texture_file',
129 ]
130 - def __init__(self, diffuse_color, alpha,
131 specular_factor, specular_color, ambient_color,
132 toon_index, edge_flag, vertex_count, texture_file):
142
148
161
162
164 """
165 ==========
166 pmd bone
167 ==========
168
169 format
170 ~~~~~~
171 * http://blog.goo.ne.jp/torisu_tetosuki/e/638463f52d0ad6ca1c46fd315a9b17d0
172
173 :IVariables:
174 name
175 bone name
176 english_name
177 bone english_name
178 index
179 boen index(append for internal use)
180 type
181 bone type
182 ik
183 ik(append for internal use)
184 pos
185 bone head position
186 ik_index
187 ik target bone index
188 parent_index
189 parent bone index
190 tail_index
191 tail bone index
192 parent
193 parent bone(append for internal use)
194 tail
195 tail bone(append for internal use)
196 children
197 children bone(append for internal use)
198 """
199
200 ROTATE = 0
201 ROTATE_MOVE = 1
202 IK = 2
203 IK_ROTATE_INFL = 4
204 ROTATE_INFL = 5
205 IK_TARGET = 6
206 UNVISIBLE = 7
207
208 ROLLING=8
209 TWEAK=9
210 __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
211 'children', 'english_name', 'ik_index',
212 'parent_index', 'tail_index', 'tail',
213 ]
226
240
243
246
248 indent=indent or []
249 if len(indent)>0:
250 prefix=''
251 for i, is_end in enumerate(indent):
252 if i==len(indent)-1:
253 break
254 else:
255 prefix+=' ' if is_end else ' |'
256 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
257 print(uni.encode(ENCODING))
258 else:
259 uni='%s(%s)' % (unicode(self), self.english_name)
260 print(uni.encode(ENCODING))
261
262 child_count=len(self.children)
263 for i in range(child_count):
264 child=self.children[i]
265 if i<child_count-1:
266 child.display(indent+[False])
267 else:
268
269 child.display(indent+[True])
270
271
273 __slots__=[]
277 return '<ROTATE %s>' % (self.name)
278
280 __slots__=[]
284 return '<ROTATE_MOVE %s>' % (self.name)
285
287 __slots__=[]
291 return '<IK %s>' % (self.name)
292
294 __slots__=[]
298 return '<IK_ROTATE_INFL %s>' % (self.name)
299
301 __slots__=[]
305 return '<ROTATE_INFL %s>' % (self.name)
306
308 __slots__=[]
312 return '<IK_TARGET %s>' % (self.name)
313
315 __slots__=[]
319 return '<UNVISIBLE %s>' % (self.name)
320
322 __slots__=[]
326 return '<ROLLING %s>' % (self.name)
327
329 __slots__=[]
333 return '<TWEAK %s>' % (self.name)
334
335
359
360
362 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
369
372
381
382
384 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
385 'vertex_count']
393
394 - def append(self, index, x, y, z):
397
399 return '<Skin name: "%s", type: %d, vertex: %d>' % (
400 self.name, self.type, len(self.indices))
401
411
412
418
421
422
423 SHAPE_SPHERE=0
424 SHAPE_BOX=1
425 SHAPE_CAPSULE=2
426
427 RIGIDBODY_KINEMATICS=0
428 RIGIDBODY_PHYSICS=1
429 RIGIDBODY_PHYSICS_WITH_BONE=2
430
431
432 -class RigidBody(object):
433 __slots__=['name',
434 'bone_index',
435 'collision_group',
436 'no_collision_group',
437 'shape_type',
438 'shape_size',
439 'shape_position',
440 'shape_rotation',
441 'mass',
442 'linear_damping',
443 'angular_damping',
444 'restitution',
445 'friction',
446 'mode'
447 ]
448 - def __init__(self, name,
449 bone_index,
450 collision_group,
451 no_collision_group,
452 shape_type,
453 shape_size,
454 shape_position,
455 shape_rotation,
456 mass,
457 linear_damping,
458 angular_damping,
459 restitution,
460 friction,
461 mode
462 ):
477
478 - def __eq__(self, rhs):
495
496
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',
503 ]
504 - def __init__(self, name,
505 rigidbody_index_a, rigidbody_index_b,
506 position, rotation,
507 translation_limit_max, translation_limit_min,
508 rotation_limit_max, rotation_limit_min,
509 spring_constant_translation, spring_constant_rotation
510 ):
522
537
538
540 """pmd loader class.
541
542 Attributes:
543 io: internal use.
544 end: internal use.
545 pos: internal user.
546
547 version: pmd version number
548 _name: internal
549 """
550 __slots__=[
551 'path',
552 'version', 'name', 'comment',
553 'english_name', 'english_comment',
554 'vertices', 'indices', 'materials', 'bones',
555 'ik_list', 'morphs',
556 'morph_indices', 'bone_group_list', 'bone_display_list',
557 'toon_textures',
558 'rigidbodies', 'joints',
559
560 'no_parent_bones',
561 ]
584
587
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))
592
612
613 - def diff(self, rhs):
614 if self.name!=rhs.name:
615 print(self.name, rhs.name)
616 return
617 if self.comment!=rhs.comment:
618 print(self.comment, rhs.comment)
619 return
620 if self.english_name!=rhs.english_name:
621 print(self.english_name, rhs.english_name)
622 return
623 if self.english_comment!=rhs.english_comment:
624 print(self.english_comment, rhs.english_comment)
625 return
626 if self.vertices!=rhs.vertices:
627 print(self.vertices, rhs.vertices)
628 return
629 if self.indices!=rhs.indices:
630 print(self.indices, rhs.indices)
631 return
632 if self.materials!=rhs.materials:
633 print(self.materials, rhs.materials)
634 return
635 if self.bones!=rhs.bones:
636 print(self.bones, rhs.bones)
637 return
638 if self.ik_list!=rhs.ik_list:
639 print(self.ik_list, rhs.ik_list)
640 return
641 if self.morphs!=rhs.morphs:
642 print(self.morphs, rhs.morphs)
643 return
644 if self.morph_indices!=rhs.morph_indices:
645 print(self.morph_indices, rhs.morph_indices)
646 return
647 if self.bone_group_list!=rhs.bone_group_list:
648 print(self.bone_group_list, rhs.bone_group_list)
649 return
650 if self.bone_display_list!=rhs.bone_display_list:
651 print(self.bone_display_list, rhs.bone_display_list)
652 return
653 if self.toon_textures!=rhs.toon_textures:
654 print(self.toon_textures, rhs.toon_textures)
655 return
656 if self.rigidbodies!=rhs.rigidbodies:
657 print(self.rigidbodies, rhs.rigidbodies)
658 return
659 if self.joints!=rhs.joints:
660 print(self.joints, rhs.joints)
661 return
662