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))
236 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
238 def __init__(self, name='skin'):
246 def getName(self): return self.name.decode('cp932')
247 def setName(self, u): self.name=u
248 def setEnglishName(self, u): self.english_name=u
250 def append(self, index, x, y, z):
251 self.indices.append(index)
252 self.pos_list.append(Vector3(x, y, z))
255 return '<Skin name: "%s", type: %d, vertex: %d>' % (
256 self.name, self.type, len(self.indices))
259 class BoneGroup(object):
260 __slots__=['name', 'english_name']
261 def __init__(self, name='group'): self.name=name; self.english_name='center'
262 def getName(self): return self.name.decode('cp932')
263 def setName(self, u): self.name=u
264 def getEnglishName(self): return self.english_name.decode('cp932')
265 def setEnglishName(self, u): self.english_name=u
268 class RigidBody(object):
269 __slots__=['name', 'boneIndex', 'group', 'target', 'shapeType',
270 'w', 'h', 'd', 'position', 'rotation', 'weight',
271 'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
273 def __init__(self, name):
275 self.position=Vector3()
276 self.rotation=Vector3()
279 class Constraint(object):
280 __slots__=[ 'name', 'rigidA', 'rigidB', 'pos', 'rot',
281 'constraintPosMin', 'constraintPosMax',
282 'constraintRotMin', 'constraintRotMax',
283 'springPos', 'springRot',
285 def __init__(self, name):
289 self.constraintPosMin=Vector3()
290 self.constraintPosMax=Vector3()
291 self.constraintRotMin=Vector3()
292 self.constraintRotMax=Vector3()
293 self.springPos=Vector3()
294 self.springRot=Vector3()
298 __slots__=['io', 'end', 'pos',
299 'version', 'name', 'comment',
300 'english_name', 'english_comment',
301 'vertices', 'indices', 'materials', 'bones',
302 'ik_list', 'morph_list',
303 'face_list', 'bone_group_list', 'bone_display_list',
306 'rigidbodies', 'constraints',
311 self.comment=b"default"
312 self.english_name=b'default'
313 self.english_comment=b'default'
322 self.bone_group_list=[]
323 self.bone_display_list=[]
326 b'toon01.bmp', b'toon02.bmp',
327 b'toon03.bmp', b'toon04.bmp',
328 b'toon05.bmp', b'toon06.bmp',
329 b'toon07.bmp', b'toon08.bmp',
330 b'toon09.bmp', b'toon10.bmp',
333 self.no_parent_bones=[]
338 def getName(self): return self.name.decode('cp932')
339 def setName(self, u): self.name=u
340 def getComment(self): return self.comment.decode('cp932')
341 def setComment(self, u): self.comment=u
342 def getEnglishName(self): return self.english_name.decode('cp932')
343 def setEnglishName(self, u): self.english_name=u
344 def getEnglishComment(self): return self.english_comment.decode('cp932')
345 def setEnglishComment(self, u): self.english_comment=u
347 def getToonTexture(self, i): return self.toon_textures[i]
348 def each_vertex(self): return self.vertices
349 def getUV(self, i): return self.vertices[i].uv
352 self.vertices.append(v)
354 def addMaterial(self):
356 self.materials.append(m)
364 self.ik_list.append(ik)
368 self.morph_list.append(s)
370 def addBoneGroup(self):
372 self.bone_group_list.append(g)
374 def addBoneDisplay(self, b, g):
375 self.bone_display_list.append((b, g))
378 return '<PMDLoader version: %g, model: "%s", vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
379 self.version, self.name, len(self.vertices), len(self.indices),
380 len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
382 def _check_position(self):
385 print(self.pos, self.io.tell()-self.pos)
387 self.pos=self.io.tell()
390 def read(self, path):
391 size=os.path.getsize(path)
393 return self.load(path, f, size)
395 def load(self, path, io, end):
397 self.pos=self.io.tell()
399 self._check_position()
401 if not self._loadHeader():
403 self._check_position()
405 if not self._loadVertex():
407 self._check_position()
409 if not self._loadFace():
411 self._check_position()
413 if not self._loadMaterial():
415 self._check_position()
417 if not self._loadBone():
419 self._check_position()
421 if not self._loadIK():
423 self._check_position()
425 if not self._loadSkin():
427 self._check_position()
429 if not self._loadSkinIndex():
431 self._check_position()
433 if not self._loadBoneName():
435 self._check_position()
437 if not self._loadBoneIndex():
439 self._check_position()
441 if not self._loadExtend():
442 print('fail to loadExtend')
446 if self.io.tell()!=self.end:
447 print("can not reach eof.")
448 print("current: %d, end: %d, remain: %d" % (
449 self.io.tell(), self.end, self.end-self.io.tell()))
452 for i, child in enumerate(self.bones):
453 if child.parent_index==0xFFFF:
455 self.no_parent_bones.append(child)
459 parent=self.bones[child.parent_index]
461 parent.children.append(child)
464 child.tail=self.bones[child.tail_index].pos
468 def write(self, path):
474 io.write(struct.pack("f", self.version))
475 io.write(struct.pack("20s", self.name))
476 io.write(struct.pack("256s", self.comment))
479 io.write(struct.pack("I", len(self.vertices)))
480 sVertex=struct.Struct("=8f2H2B") # 38byte
481 assert(sVertex.size==38)
482 for v in self.vertices:
484 v.pos[0], v.pos[1], v.pos[2],
485 v.normal[0], v.normal[1], v.normal[2],
487 v.bone0, v.bone1, v.weight0, v.edge_flag)
491 io.write(struct.pack("I", len(self.indices)))
492 io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
495 io.write(struct.pack("I", len(self.materials)))
496 sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
497 assert(sMaterial.size==70)
498 for m in self.materials:
499 io.write(sMaterial.pack(
500 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
502 m.specular[0], m.specular[1], m.specular[2],
503 m.ambient[0], m.ambient[1], m.ambient[2],
504 m.toon_index, m.flag,
510 io.write(struct.pack("H", len(self.bones)))
511 sBone=struct.Struct("=20sHHBH3f")
512 assert(sBone.size==39)
516 b.parent_index, b.tail_index, b.type, b.ik_index,
517 b.pos[0], b.pos[1], b.pos[2]))
520 io.write(struct.pack("H", len(self.ik_list)))
521 for ik in self.ik_list:
522 io.write(struct.pack("=2HBHf",
523 ik.index, ik.target, ik.length, ik.iterations, ik.weight
525 for c in ik.children:
526 io.write(struct.pack("H", c))
529 io.write(struct.pack("H", len(self.morph_list)))
530 for s in self.morph_list:
531 io.write(struct.pack("20sIB",
532 s.name, len(s.indices), s.type))
533 for i, v in zip(s.indices, s.pos_list):
534 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
537 io.write(struct.pack("B", len(self.face_list)))
538 for i in self.face_list:
539 io.write(struct.pack("H", i))
542 io.write(struct.pack("B", len(self.bone_group_list)))
543 for g in self.bone_group_list:
544 io.write(struct.pack("50s", g.name))
547 io.write(struct.pack("I", len(self.bone_display_list)))
548 for l in self.bone_display_list:
549 io.write(struct.pack("=HB", *l))
557 def _loadExtend(self):
558 ############################################################
559 # extend1: english name
560 ############################################################
561 if self.io.tell()>=self.end:
563 if struct.unpack("B", self.io.read(1))[0]==1:
564 if not self.loadEnglishName():
566 self._check_position()
568 ############################################################
569 # extend2: toon texture list
570 ############################################################
571 if self.io.tell()>=self.end:
573 if not self.loadToonTexture():
575 self._check_position()
577 ############################################################
579 ############################################################
580 if self.io.tell()>=self.end:
582 if not self.loadPhysics():
584 self._check_position()
588 def _loadHeader(self):
589 signature=struct.unpack("3s", self.io.read(3))[0]
591 if signature!=b"Pmd":
592 print("invalid signature", signature)
594 self.version=struct.unpack("f", self.io.read(4))[0]
595 self.name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
596 self.comment = truncate_zero(
597 struct.unpack("256s", self.io.read(256))[0])
600 def _loadVertex(self):
601 count = struct.unpack("I", self.io.read(4))[0]
602 for i in xrange(count):
603 self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
607 count = struct.unpack("I", self.io.read(4))[0]
608 for i in xrange(0, count, 3):
609 self.indices+=struct.unpack("HHH", self.io.read(6))
612 def _loadMaterial(self):
613 count = struct.unpack("I", self.io.read(4))[0]
614 for i in xrange(count):
615 material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
616 material.toon_index=struct.unpack("B", self.io.read(1))[0]
617 material.flag=struct.unpack("B", self.io.read(1))[0]
618 material.vertex_count=struct.unpack("I", self.io.read(4))[0]
619 texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
621 #material.texture=texture.split('*')[0]
622 material.texture=texture
623 self.materials.append(material)
627 size = struct.unpack("H", self.io.read(2))[0]
628 for i in xrange(size):
629 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
630 parent_index, tail_index = struct.unpack("HH", self.io.read(4))
631 type = struct.unpack("B", self.io.read(1))[0]
632 bone=createBone(name, type)
633 bone.parent_index=parent_index
634 bone.tail_index=tail_index
635 bone.ik_index = struct.unpack("H", self.io.read(2))[0]
636 bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
637 bone.english_name="bone%03d" % len(self.bones)
638 self.bones.append(bone)
642 size = struct.unpack("H", self.io.read(2))[0]
643 for i in xrange(size):
644 ik=IK(*struct.unpack("2H", self.io.read(4)))
645 ik.length = struct.unpack("B", self.io.read(1))[0]
646 ik.iterations = struct.unpack("H", self.io.read(2))[0]
647 ik.weight = struct.unpack("f", self.io.read(4))[0]
648 for j in xrange(ik.length):
649 ik.children.append(struct.unpack("H", self.io.read(2))[0])
650 self.ik_list.append(ik)
654 size = struct.unpack("H", self.io.read(2))[0]
655 for i in xrange(size):
656 skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
657 skin_size = struct.unpack("I", self.io.read(4))[0]
658 skin.type = struct.unpack("B", self.io.read(1))[0]
659 for j in xrange(skin_size):
660 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
661 skin.pos_list.append(
662 Vector3(*struct.unpack("3f", self.io.read(12))))
663 skin.english_name="skin%03d" % len(self.morph_list)
664 self.morph_list.append(skin)
667 def _loadSkinIndex(self):
668 size = struct.unpack("B", self.io.read(1))[0]
669 for i in xrange(size):
670 self.face_list.append(struct.unpack("H", self.io.read(2))[0])
673 def _loadBoneName(self):
674 size = struct.unpack("B", self.io.read(1))[0]
675 for i in xrange(size):
676 self.bone_group_list.append(BoneGroup(
677 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
680 def _loadBoneIndex(self):
681 size = struct.unpack("I", self.io.read(4))[0]
682 for i in xrange(size):
683 first=struct.unpack("H", self.io.read(2))[0]
684 second=struct.unpack("B", self.io.read(1))[0]
685 self.bone_display_list.append((first, second))
688 def loadToonTexture(self):
693 self.toon_textures.append(
694 truncate_zero(struct.unpack("100s", self.io.read(100))[0]))
697 def loadEnglishName(self):
699 self.english_name=truncate_zero(
700 struct.unpack("20s", self.io.read(20))[0])
701 self.english_comment=truncate_zero(
702 struct.unpack("256s", self.io.read(256))[0])
704 for bone in self.bones:
705 english_name=truncate_zero(
706 struct.unpack("20s", self.io.read(20))[0])
707 bone.english_name=english_name
709 #for index in self.face_list:
710 for skin in self.morph_list:
711 if skin.name=='base':
713 english_name=truncate_zero(
714 struct.unpack("20s", self.io.read(20))[0])
715 #skin=self.morph_list[index]
716 if english_name!=skin.name:
717 skin.english_name=english_name
719 for i in xrange(0, len(self.bone_group_list)):
720 self.bone_group_list[i].english_name=truncate_zero(
721 struct.unpack("50s", self.io.read(50))[0])
724 def loadPhysics(self):
726 count = struct.unpack("I", self.io.read(4))[0]
727 for i in xrange(count):
728 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
729 rigidbody=RigidBody(name)
730 rigidbody.boneIndex=struct.unpack("H", self.io.read(2))[0]
731 rigidbody.group=struct.unpack("B", self.io.read(1))[0]
732 rigidbody.target=struct.unpack("H", self.io.read(2))[0]
733 rigidbody.shapeType=struct.unpack("B", self.io.read(1))[0]
734 rigidbody.w=struct.unpack("f", self.io.read(4))[0]
735 rigidbody.h=struct.unpack("f", self.io.read(4))[0]
736 rigidbody.d=struct.unpack("f", self.io.read(4))[0]
737 rigidbody.position.x=struct.unpack("f", self.io.read(4))[0]
738 rigidbody.position.y=struct.unpack("f", self.io.read(4))[0]
739 rigidbody.position.z=struct.unpack("f", self.io.read(4))[0]
740 rigidbody.rotation.x=struct.unpack("f", self.io.read(4))[0]
741 rigidbody.rotation.y=struct.unpack("f", self.io.read(4))[0]
742 rigidbody.rotation.z=struct.unpack("f", self.io.read(4))[0]
743 rigidbody.weight=struct.unpack("f", self.io.read(4))[0]
744 rigidbody.linearDamping=struct.unpack("f", self.io.read(4))[0]
745 rigidbody.angularDamping=struct.unpack("f", self.io.read(4))[0]
746 rigidbody.restitution=struct.unpack("f", self.io.read(4))[0]
747 rigidbody.friction=struct.unpack("f", self.io.read(4))[0]
748 rigidbody.processType=struct.unpack("B", self.io.read(1))[0]
749 self.rigidbodies.append(rigidbody)
752 count = struct.unpack("I", self.io.read(4))[0]
753 for i in xrange(count):
754 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
755 constraint=Constraint(name)
756 constraint.rigidA=struct.unpack("I", self.io.read(4))[0]
757 constraint.rigidB=struct.unpack("I", self.io.read(4))[0]
758 constraint.pos.x=struct.unpack("f", self.io.read(4))[0]
759 constraint.pos.y=struct.unpack("f", self.io.read(4))[0]
760 constraint.pos.z=struct.unpack("f", self.io.read(4))[0]
761 constraint.rot.x=struct.unpack("f", self.io.read(4))[0]
762 constraint.rot.y=struct.unpack("f", self.io.read(4))[0]
763 constraint.rot.z=struct.unpack("f", self.io.read(4))[0]
764 constraint.constraintPosMin.x=struct.unpack("f", self.io.read(4))[0]
765 constraint.constraintPosMin.y=struct.unpack("f", self.io.read(4))[0]
766 constraint.constraintPosMin.z=struct.unpack("f", self.io.read(4))[0]
767 constraint.constraintPosMax.x=struct.unpack("f", self.io.read(4))[0]
768 constraint.constraintPosMax.y=struct.unpack("f", self.io.read(4))[0]
769 constraint.constraintPosMax.z=struct.unpack("f", self.io.read(4))[0]
770 constraint.constraintRotMin.x=struct.unpack("f", self.io.read(4))[0]
771 constraint.constraintRotMin.y=struct.unpack("f", self.io.read(4))[0]
772 constraint.constraintRotMin.z=struct.unpack("f", self.io.read(4))[0]
773 constraint.constraintRotMax.x=struct.unpack("f", self.io.read(4))[0]
774 constraint.constraintRotMax.y=struct.unpack("f", self.io.read(4))[0]
775 constraint.constraintRotMax.z=struct.unpack("f", self.io.read(4))[0]
776 constraint.springPos.x=struct.unpack("f", self.io.read(4))[0]
777 constraint.springPos.y=struct.unpack("f", self.io.read(4))[0]
778 constraint.springPos.z=struct.unpack("f", self.io.read(4))[0]
779 constraint.springRot.x=struct.unpack("f", self.io.read(4))[0]
780 constraint.springRot.y=struct.unpack("f", self.io.read(4))[0]
781 constraint.springRot.z=struct.unpack("f", self.io.read(4))[0]
782 self.constraints.append(constraint)