6 ###############################################################################
8 ###############################################################################
10 __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
11 def __init__(self, x=0, y=0, z=0, nx=0, ny=0, nz=0, u=0, v=0,
12 bone0=0, bone1=0, weight0=0, edge_flag=0):
13 self.pos=Vector3(x, y, z)
14 self.normal=Vector3(nx, ny, nz)
19 self.edge_flag=edge_flag
22 return "<%s %s %s, (%d, %d, %d)>" % (str(self.pos), str(self.normal), str(self.uv), self.bone0, self.bone1, self.weight0)
24 def __getitem__(self, key):
35 class Material(object):
37 'diffuse', 'shinness', 'specular',
38 'ambient', 'vertex_count', 'texture', 'toon_index', 'flag',
41 def __init__(self, dr=0, dg=0, db=0, alpha=1,
42 specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0):
43 self.diffuse=RGBA(dr, dg, db, alpha)
44 self.specular=RGBA(sr, sg, sb)
45 self.shinness=specular
46 self.ambient=RGBA(ar, ag, ab)
53 return "<Material [%f, %f, %f, %f]>" % (
54 self.diffuse[0], self.diffuse[1],
55 self.diffuse[2], self.diffuse[3],
58 def getTexture(self): return self.texture.decode('cp932')
59 def setTexture(self, u): self.texture=u
62 # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ
64 def material_per_face(materials):
66 for x in xrange(int(m.vertex_count/3)):
82 __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
83 'children', 'english_name', 'ik_index',
84 'parent_index', 'tail_index', 'tail',
86 def __init__(self, name='bone', type=0):
90 self.parent_index=0xFFFF
92 self.tail=Vector3(0, 0, 0)
95 self.pos=Vector3(0, 0, 0)
99 def getName(self): return self.name.decode('cp932')
100 def setName(self, u): self.name=u
101 def setEnglishName(self, u): self.english_name=u
104 return self.parent_index!=0xFFFF
107 return self.tail_index!=0
109 def display(self, indent=[]):
112 for i, is_end in enumerate(indent):
116 prefix+=' ' if is_end else ' |'
117 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
118 print(uni.encode(ENCODING))
120 uni='%s(%s)' % (unicode(self), self.english_name)
121 print(uni.encode(ENCODING))
123 child_count=len(self.children)
124 for i in xrange(child_count):
125 child=self.children[i]
127 child.display(indent+[False])
130 child.display(indent+[True])
133 class Bone_Rotate(Bone):
135 def __init__(self, name):
136 super(Bone_Rotate, self).__init__(name, 0)
138 return '<ROTATE %s>' % (self.name)
140 class Bone_RotateMove(Bone):
142 def __init__(self, name):
143 super(Bone_RotateMove, self).__init__(name, 1)
145 return '<ROTATE_MOVE %s>' % (self.name)
149 def __init__(self, name):
150 super(Bone_IK, self).__init__(name, 2)
152 return '<IK %s>' % (self.name)
154 class Bone_IKRotateInfl(Bone):
156 def __init__(self, name):
157 super(Bone_IKRotateInfl, self).__init__(name, 4)
159 return '<IK_ROTATE_INFL %s>' % (self.name)
161 class Bone_RotateInfl(Bone):
163 def __init__(self, name):
164 super(Bone_RotateInfl, self).__init__(name, 5)
166 return '<ROTATE_INFL %s>' % (self.name)
168 class Bone_IKTarget(Bone):
170 def __init__(self, name):
171 super(Bone_IKTarget, self).__init__(name, 6)
173 return '<IK_TARGET %s>' % (self.name)
175 class Bone_Unvisible(Bone):
177 def __init__(self, name):
178 super(Bone_Unvisible, self).__init__(name, 7)
180 return '<UNVISIBLE %s>' % (self.name)
182 class Bone_Rolling(Bone):
184 def __init__(self, name):
185 super(Bone_Rolling, self).__init__(name, 8)
187 return '<ROLLING %s>' % (self.name)
189 class Bone_Tweak(Bone):
191 def __init__(self, name):
192 super(Bone_Tweak, self).__init__(name, 9)
194 return '<TWEAK %s>' % (self.name)
197 def createBone(name, type):
199 return Bone_Rotate(name)
201 return Bone_RotateMove(name)
205 raise Exception("no used bone type: 3(%s)" % name)
207 return Bone_IKRotateInfl(name)
209 return Bone_RotateInfl(name)
211 return Bone_IKTarget(name)
213 return Bone_Unvisible(name)
215 return Bone_Rolling(name)
217 return Bone_Tweak(name)
219 raise Exception("unknown bone type: %d(%s)", type, name)
223 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
224 def __init__(self, index=0, target=0):
232 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))
235 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
237 def __init__(self, name='skin'):
245 def getName(self): return self.name.decode('cp932')
246 def setName(self, u): self.name=u
247 def setEnglishName(self, u): self.english_name=u
249 def append(self, index, x, y, z):
250 self.indices.append(index)
251 self.pos_list.append(Vector3(x, y, z))
254 return '<Skin name: "%s", type: %d, vertex: %d>' % (
255 self.name, self.type, len(self.indices))
258 class ToonTexture(object):
260 def __init__(self, name): self.name=name
261 def getName(self): return self.name.decode('cp932')
262 def setName(self, u): self.name=u
265 class BoneGroup(object):
266 __slots__=['name', 'english_name']
267 def __init__(self, name='group'): self.name=name; self.english_name='center'
268 def getName(self): return self.name.decode('cp932')
269 def setName(self, u): self.name=u
270 def getEnglishName(self): return self.english_name.decode('cp932')
271 def setEnglishName(self, u): self.english_name=u
274 class RigidBody(object):
275 __slots__=['name', 'boneIndex', 'group', 'target', 'shapeType',
276 'w', 'h', 'd', 'position', 'rotation', 'weight',
277 'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
279 def __init__(self, name):
283 class Constraint(object):
289 __slots__=['io', 'end', 'pos',
290 'version', 'name', 'comment',
291 'english_name', 'english_comment',
292 'vertices', 'indices', 'materials', 'bones',
293 'ik_list', 'morph_list',
294 'face_list', 'bone_group_list', 'bone_display_list',
297 'rigidbodies', 'constraints',
302 self.comment=b"default"
303 self.english_name=b'default'
304 self.english_comment=b'default'
313 self.bone_group_list=[]
314 self.bone_display_list=[]
317 ToonTexture(b'toon'), ToonTexture(b'toon'),
318 ToonTexture(b'toon'), ToonTexture(b'toon'),
319 ToonTexture(b'toon'), ToonTexture(b'toon'),
320 ToonTexture(b'toon'), ToonTexture(b'toon'),
321 ToonTexture(b'toon'), ToonTexture(b'toon'),
324 self.no_parent_bones=[]
329 def getName(self): return self.name.decode('cp932')
330 def setName(self, u): self.name=u
331 def getComment(self): return self.comment.decode('cp932')
332 def setComment(self, u): self.comment=u
333 def getEnglishName(self): return self.english_name.decode('cp932')
334 def setEnglishName(self, u): self.english_name=u
335 def getEnglishComment(self): return self.english_comment.decode('cp932')
336 def setEnglishComment(self, u): self.english_comment=u
338 def getToonTexture(self, i): return self.toon_textures[i]
339 def each_vertex(self): return self.vertices
340 def getUV(self, i): return self.vertices[i].uv
343 self.vertices.append(v)
345 def addMaterial(self):
347 self.materials.append(m)
355 self.ik_list.append(ik)
359 self.morph_list.append(s)
361 def addBoneGroup(self):
363 self.bone_group_list.append(g)
365 def addBoneDisplay(self, b, g):
366 self.bone_display_list.append((b, g))
369 return '<PMDLoader version: %g, model: "%s", vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
370 self.version, self.name, len(self.vertices), len(self.indices),
371 len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
373 def _check_position(self):
376 print(self.pos, self.io.tell()-self.pos)
378 self.pos=self.io.tell()
381 def read(self, path):
382 size=os.path.getsize(path)
384 return self.load(path, f, size)
386 def load(self, path, io, end):
388 self.pos=self.io.tell()
390 self._check_position()
392 if not self._loadHeader():
394 self._check_position()
396 if not self._loadVertex():
398 self._check_position()
400 if not self._loadFace():
402 self._check_position()
404 if not self._loadMaterial():
406 self._check_position()
408 if not self._loadBone():
410 self._check_position()
412 if not self._loadIK():
414 self._check_position()
416 if not self._loadSkin():
418 self._check_position()
420 if not self._loadSkinIndex():
422 self._check_position()
424 if not self._loadBoneName():
426 self._check_position()
428 if not self._loadBoneIndex():
430 self._check_position()
432 if not self._loadExtend():
433 print('fail to loadExtend')
437 if self.io.tell()!=self.end:
438 print("can not reach eof.")
439 print("current: %d, end: %d, remain: %d" % (
440 self.io.tell(), self.end, self.end-self.io.tell()))
443 for i, child in enumerate(self.bones):
444 if child.parent_index==0xFFFF:
446 self.no_parent_bones.append(child)
450 parent=self.bones[child.parent_index]
452 parent.children.append(child)
455 child.tail=self.bones[child.tail_index].pos
459 def write(self, path):
465 io.write(struct.pack("f", self.version))
466 io.write(struct.pack("20s", self.name))
467 io.write(struct.pack("256s", self.comment))
470 io.write(struct.pack("I", len(self.vertices)))
471 sVertex=struct.Struct("=8f2H2B") # 38byte
472 assert(sVertex.size==38)
473 for v in self.vertices:
475 v.pos[0], v.pos[1], v.pos[2],
476 v.normal[0], v.normal[1], v.normal[2],
478 v.bone0, v.bone1, v.weight0, v.edge_flag)
482 io.write(struct.pack("I", len(self.indices)))
483 io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
486 io.write(struct.pack("I", len(self.materials)))
487 sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
488 assert(sMaterial.size==70)
489 for m in self.materials:
490 io.write(sMaterial.pack(
491 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
493 m.specular[0], m.specular[1], m.specular[2],
494 m.ambient[0], m.ambient[1], m.ambient[2],
495 m.toon_index, m.flag,
501 io.write(struct.pack("H", len(self.bones)))
502 sBone=struct.Struct("=20sHHBH3f")
503 assert(sBone.size==39)
507 b.parent_index, b.tail_index, b.type, b.ik_index,
508 b.pos[0], b.pos[1], b.pos[2]))
511 io.write(struct.pack("H", len(self.ik_list)))
512 for ik in self.ik_list:
513 io.write(struct.pack("=2HBHf",
514 ik.index, ik.target, ik.length, ik.iterations, ik.weight
516 for c in ik.children:
517 io.write(struct.pack("H", c))
520 io.write(struct.pack("H", len(self.morph_list)))
521 for s in self.morph_list:
522 io.write(struct.pack("20sIB",
523 s.name, len(s.indices), s.type))
524 for i, v in zip(s.indices, s.pos_list):
525 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
528 io.write(struct.pack("B", len(self.face_list)))
529 for i in self.face_list:
530 io.write(struct.pack("H", i))
533 io.write(struct.pack("B", len(self.bone_group_list)))
534 for g in self.bone_group_list:
535 io.write(struct.pack("50s", g.name))
538 io.write(struct.pack("I", len(self.bone_display_list)))
539 for l in self.bone_display_list:
540 io.write(struct.pack("=HB", *l))
548 def _loadExtend(self):
549 ############################################################
550 # extend1: english name
551 ############################################################
552 if self.io.tell()>=self.end:
554 if struct.unpack("B", self.io.read(1))[0]==1:
555 if not self.loadEnglishName():
557 self._check_position()
559 ############################################################
560 # extend2: toon texture list
561 ############################################################
562 if self.io.tell()>=self.end:
564 if not self.loadToonTexture():
566 self._check_position()
568 ############################################################
570 ############################################################
571 if self.io.tell()>=self.end:
573 if not self.loadPhysics():
575 self._check_position()
579 def _loadHeader(self):
580 signature=struct.unpack("3s", self.io.read(3))[0]
582 if signature!=b"Pmd":
583 print("invalid signature", signature)
585 self.version=struct.unpack("f", self.io.read(4))[0]
586 self.name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
587 self.comment = truncate_zero(
588 struct.unpack("256s", self.io.read(256))[0])
591 def _loadVertex(self):
592 count = struct.unpack("I", self.io.read(4))[0]
593 for i in xrange(count):
594 self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
598 count = struct.unpack("I", self.io.read(4))[0]
599 for i in xrange(0, count, 3):
600 self.indices+=struct.unpack("HHH", self.io.read(6))
603 def _loadMaterial(self):
604 count = struct.unpack("I", self.io.read(4))[0]
605 for i in xrange(count):
606 material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
607 material.toon_index=struct.unpack("B", self.io.read(1))[0]
608 material.flag=struct.unpack("B", self.io.read(1))[0]
609 material.vertex_count=struct.unpack("I", self.io.read(4))[0]
610 texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
612 #material.texture=texture.split('*')[0]
613 material.texture=texture
614 self.materials.append(material)
618 size = struct.unpack("H", self.io.read(2))[0]
619 for i in xrange(size):
620 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
621 parent_index, tail_index = struct.unpack("HH", self.io.read(4))
622 type = struct.unpack("B", self.io.read(1))[0]
623 bone=createBone(name, type)
624 bone.parent_index=parent_index
625 bone.tail_index=tail_index
626 bone.ik_index = struct.unpack("H", self.io.read(2))[0]
627 bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
628 bone.english_name="bone%03d" % len(self.bones)
629 self.bones.append(bone)
633 size = struct.unpack("H", self.io.read(2))[0]
634 for i in xrange(size):
635 ik=IK(*struct.unpack("2H", self.io.read(4)))
636 ik.length = struct.unpack("B", self.io.read(1))[0]
637 ik.iterations = struct.unpack("H", self.io.read(2))[0]
638 ik.weight = struct.unpack("f", self.io.read(4))[0]
639 for j in xrange(ik.length):
640 ik.children.append(struct.unpack("H", self.io.read(2))[0])
641 self.ik_list.append(ik)
645 size = struct.unpack("H", self.io.read(2))[0]
646 for i in xrange(size):
647 skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
648 skin_size = struct.unpack("I", self.io.read(4))[0]
649 skin.type = struct.unpack("B", self.io.read(1))[0]
650 for j in xrange(skin_size):
651 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
652 skin.pos_list.append(
653 Vector3(*struct.unpack("3f", self.io.read(12))))
654 skin.english_name="skin%03d" % len(self.morph_list)
655 self.morph_list.append(skin)
658 def _loadSkinIndex(self):
659 size = struct.unpack("B", self.io.read(1))[0]
660 for i in xrange(size):
661 self.face_list.append(struct.unpack("H", self.io.read(2))[0])
664 def _loadBoneName(self):
665 size = struct.unpack("B", self.io.read(1))[0]
666 for i in xrange(size):
667 self.bone_group_list.append(BoneGroup(
668 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
671 def _loadBoneIndex(self):
672 size = struct.unpack("I", self.io.read(4))[0]
673 for i in xrange(size):
674 self.bone_display_list.append(struct.unpack("HB", self.io.read(3)))
677 def loadToonTexture(self):
682 self.toon_textures.append(ToonTexture(
683 truncate_zero(struct.unpack("100s", self.io.read(100))[0])))
686 def loadEnglishName(self):
688 self.english_name=truncate_zero(
689 struct.unpack("20s", self.io.read(20))[0])
690 self.english_comment=truncate_zero(
691 struct.unpack("256s", self.io.read(256))[0])
693 for bone in self.bones:
694 english_name=truncate_zero(
695 struct.unpack("20s", self.io.read(20))[0])
696 if english_name!=bone.name:
697 bone.english_name=english_name
699 #for index in self.face_list:
700 for skin in self.morph_list:
701 if skin.name=='base':
703 english_name=truncate_zero(
704 struct.unpack("20s", self.io.read(20))[0])
705 #skin=self.morph_list[index]
706 if english_name!=skin.name:
707 skin.english_name=english_name
709 for i in xrange(0, len(self.bone_group_list)):
710 self.bone_group_list[i].english_name=truncate_zero(
711 struct.unpack("50s", self.io.read(50))[0])
714 def loadPhysics(self):
716 count = struct.unpack("I", self.io.read(4))[0]
717 for i in xrange(count):
718 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
719 rigidbody=RigidBody(name)
720 struct.unpack("63s", self.io.read(63))[0]
721 self.rigidbodies.append(rigidbody)
724 count = struct.unpack("I", self.io.read(4))[0]
725 for i in xrange(count):
726 struct.unpack("124s", self.io.read(124))[0]
727 constraint=Constraint()
728 self.constraints.append(Constraint)