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):
34 class Material(object):
36 'diffuse', 'shinness', 'specular',
37 'ambient', 'vertex_count', 'texture', 'toon_index', 'flag',
40 def __init__(self, dr=0, dg=0, db=0, alpha=1,
41 specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0):
42 self.diffuse=RGBA(dr, dg, db, alpha)
43 self.specular=RGBA(sr, sg, sb)
44 self.shinness=specular
45 self.ambient=RGBA(ar, ag, ab)
52 return "<Material [%f, %f, %f, %f]>" % (
53 self.diffuse[0], self.diffuse[1],
54 self.diffuse[2], self.diffuse[3],
57 def getTexture(self): return self.texture.decode('cp932')
58 def setTexture(self, u): self.texture=u
60 # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ
62 def material_per_face(materials):
64 for x in xrange(int(m.vertex_count/3)):
79 __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
80 'children', 'english_name', 'ik_index',
81 'parent_index', 'tail_index', 'tail',
83 def __init__(self, name='bone', type=0):
87 self.parent_index=0xFFFF
89 self.tail=Vector3(0, 0, 0)
92 self.pos=Vector3(0, 0, 0)
96 def getName(self): return self.name.decode('cp932')
97 def setName(self, u): self.name=u
98 def setEnglishName(self, u): self.english_name=u
101 return self.parent_index!=0xFFFF
104 return self.tail_index!=0
106 def display(self, indent=[]):
109 for i, is_end in enumerate(indent):
113 prefix+=' ' if is_end else ' |'
114 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
115 print(uni.encode(ENCODING))
117 uni='%s(%s)' % (unicode(self), self.english_name)
118 print(uni.encode(ENCODING))
120 child_count=len(self.children)
121 for i in xrange(child_count):
122 child=self.children[i]
124 child.display(indent+[False])
127 child.display(indent+[True])
130 class Bone_Rotate(Bone):
132 def __init__(self, name):
133 super(Bone_Rotate, self).__init__(name, 0)
135 return '<ROTATE %s>' % (self.name)
137 class Bone_RotateMove(Bone):
139 def __init__(self, name):
140 super(Bone_RotateMove, self).__init__(name, 1)
142 return '<ROTATE_MOVE %s>' % (self.name)
146 def __init__(self, name):
147 super(Bone_IK, self).__init__(name, 2)
149 return '<IK %s>' % (self.name)
151 class Bone_IKRotateInfl(Bone):
153 def __init__(self, name):
154 super(Bone_IKRotateInfl, self).__init__(name, 4)
156 return '<IK_ROTATE_INFL %s>' % (self.name)
158 class Bone_RotateInfl(Bone):
160 def __init__(self, name):
161 super(Bone_RotateInfl, self).__init__(name, 5)
163 return '<ROTATE_INFL %s>' % (self.name)
165 class Bone_IKTarget(Bone):
167 def __init__(self, name):
168 super(Bone_IKTarget, self).__init__(name, 6)
170 return '<IK_TARGET %s>' % (self.name)
172 class Bone_Unvisible(Bone):
174 def __init__(self, name):
175 super(Bone_Unvisible, self).__init__(name, 7)
177 return '<UNVISIBLE %s>' % (self.name)
179 class Bone_Rolling(Bone):
181 def __init__(self, name):
182 super(Bone_Rolling, self).__init__(name, 8)
184 return '<ROLLING %s>' % (self.name)
186 class Bone_Tweak(Bone):
188 def __init__(self, name):
189 super(Bone_Tweak, self).__init__(name, 9)
191 return '<TWEAK %s>' % (self.name)
194 def createBone(name, type):
196 return Bone_Rotate(name)
198 return Bone_RotateMove(name)
202 raise Exception("no used bone type: 3(%s)" % name)
204 return Bone_IKRotateInfl(name)
206 return Bone_RotateInfl(name)
208 return Bone_IKTarget(name)
210 return Bone_Unvisible(name)
212 return Bone_Rolling(name)
214 return Bone_Tweak(name)
216 raise Exception("unknown bone type: %d(%s)", type, name)
220 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
221 def __init__(self, index=0, target=0):
229 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))
232 __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
234 def __init__(self, name='skin'):
242 def getName(self): return self.name.decode('cp932')
243 def setName(self, u): self.name=u
244 def setEnglishName(self, u): self.english_name=u
246 def append(self, index, x, y, z):
247 self.indices.append(index)
248 self.pos_list.append(Vector3(x, y, z))
251 return '<Skin name: "%s", type: %d, vertex: %d>' % (
252 self.name, self.type, len(self.indices))
254 class ToonTexture(object):
256 def __init__(self, name): self.name=name
257 def getName(self): return self.name.decode('cp932')
258 def setName(self, u): self.name=u
260 class BoneGroup(object):
261 __slots__=['name', 'english_name']
262 def __init__(self, name='group'): self.name=name; self.english_name='center'
263 def getName(self): return self.name.decode('cp932')
264 def setName(self, u): self.name=u
265 def getEnglishName(self): return self.english_name.decode('cp932')
266 def setEnglishName(self, u): self.english_name=u
269 __slots__=['io', 'end', 'pos',
270 'version', 'model_name', 'comment',
271 'english_model_name', 'english_comment',
272 'vertices', 'indices', 'materials', 'bones',
273 'ik_list', 'morph_list',
274 'face_list', 'bone_group_list', 'bone_display_list',
277 'rigidbodies', 'constraints',
281 self.model_name=b"default"
282 self.comment=b"default"
283 self.english_model_name=b'default'
284 self.english_comment=b'default'
293 self.bone_group_list=[]
294 self.bone_display_list=[]
297 ToonTexture(b'toon'), ToonTexture(b'toon'),
298 ToonTexture(b'toon'), ToonTexture(b'toon'),
299 ToonTexture(b'toon'), ToonTexture(b'toon'),
300 ToonTexture(b'toon'), ToonTexture(b'toon'),
301 ToonTexture(b'toon'), ToonTexture(b'toon'),
304 self.no_parent_bones=[]
309 def getName(self): return self.model_name.decode('cp932')
310 def setName(self, u): self.model_name=u
311 def getComment(self): return self.comment.decode('cp932')
312 def setComment(self, u): self.comment=u
313 def getEnglishName(self): return self.english_model_name.decode('cp932')
314 def setEnglishName(self, u): self.english_model_name=u
315 def getEnglishComment(self): return self.english_comment.decode('cp932')
316 def setEnglishComment(self, u): self.english_comment=u
318 def getToonTexture(self, i): return self.toon_textures[i]
319 def each_vertex(self): return self.vertices
320 def getUV(self, i): return self.vertices[i].uv
323 self.vertices.append(v)
325 def addMaterial(self):
327 self.materials.append(m)
335 self.ik_list.append(ik)
339 self.morph_list.append(s)
341 def addBoneGroup(self):
343 self.bone_group_list.append(g)
345 def addBoneDisplay(self, b, g):
346 self.bone_display_list.append((b, g))
349 return '<PMDLoader version: %g, model: "%s", vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
350 self.version, self.model_name, len(self.vertices), len(self.indices),
351 len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
353 def _check_position(self):
356 print(self.pos, self.io.tell()-self.pos)
358 self.pos=self.io.tell()
361 def read(self, path):
362 size=os.path.getsize(path)
364 return self.load(path, f, size)
366 def load(self, path, io, end):
368 self.pos=self.io.tell()
370 self._check_position()
372 if not self._loadHeader():
374 self._check_position()
376 if not self._loadVertex():
378 self._check_position()
380 if not self._loadFace():
382 self._check_position()
384 if not self._loadMaterial():
386 self._check_position()
388 if not self._loadBone():
390 self._check_position()
392 if not self._loadIK():
394 self._check_position()
396 if not self._loadSkin():
398 self._check_position()
400 if not self._loadSkinIndex():
402 self._check_position()
404 if not self._loadBoneName():
406 self._check_position()
408 if not self._loadBoneIndex():
410 self._check_position()
412 if not self._loadExtend():
413 print('fail to loadExtend')
417 if self.io.tell()!=self.end:
418 print("can not reach eof.")
419 print("current: %d, end: %d, remain: %d" % (
420 self.io.tell(), self.end, self.end-self.io.tell()))
423 for i, child in enumerate(self.bones):
424 if child.parent_index==0xFFFF:
426 self.no_parent_bones.append(child)
430 parent=self.bones[child.parent_index]
432 parent.children.append(child)
435 child.tail=self.bones[child.tail_index].pos
439 def write(self, path):
445 io.write(struct.pack("f", self.version))
446 io.write(struct.pack("20s", self.model_name))
447 io.write(struct.pack("256s", self.comment))
450 io.write(struct.pack("I", len(self.vertices)))
451 sVertex=struct.Struct("=8f2H2B") # 38byte
452 assert(sVertex.size==38)
453 for v in self.vertices:
455 v.pos[0], v.pos[1], v.pos[2],
456 v.normal[0], v.normal[1], v.normal[2],
458 v.bone0, v.bone1, v.weight0, v.edge_flag)
462 io.write(struct.pack("I", len(self.indices)))
463 io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
466 io.write(struct.pack("I", len(self.materials)))
467 sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
468 assert(sMaterial.size==70)
469 for m in self.materials:
470 io.write(sMaterial.pack(
471 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
473 m.specular[0], m.specular[1], m.specular[2],
474 m.ambient[0], m.ambient[1], m.ambient[2],
475 m.toon_index, m.flag,
481 io.write(struct.pack("H", len(self.bones)))
482 sBone=struct.Struct("=20sHHBH3f")
483 assert(sBone.size==39)
487 b.parent_index, b.tail_index, b.type, b.ik_index,
488 b.pos[0], b.pos[1], b.pos[2]))
491 io.write(struct.pack("H", len(self.ik_list)))
492 for ik in self.ik_list:
493 io.write(struct.pack("=2HBHf",
494 ik.index, ik.target, ik.length, ik.iterations, ik.weight
496 for c in ik.children:
497 io.write(struct.pack("H", c))
500 io.write(struct.pack("H", len(self.morph_list)))
501 for s in self.morph_list:
502 io.write(struct.pack("20sIB",
503 s.name, len(s.indices), s.type))
504 for i, v in zip(s.indices, s.pos_list):
505 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
508 io.write(struct.pack("B", len(self.face_list)))
509 for i in self.face_list:
510 io.write(struct.pack("H", i))
513 io.write(struct.pack("B", len(self.bone_group_list)))
514 for g in self.bone_group_list:
515 io.write(struct.pack("50s", g.name))
518 io.write(struct.pack("I", len(self.bone_display_list)))
519 for l in self.bone_display_list:
520 io.write(struct.pack("=HB", *l))
528 def _loadExtend(self):
529 ############################################################
530 # extend1: english name
531 ############################################################
532 if self.io.tell()>=self.end:
534 if struct.unpack("B", self.io.read(1))[0]==1:
535 if not self.loadEnglishName():
537 self._check_position()
539 ############################################################
540 # extend2: toon texture list
541 ############################################################
542 if self.io.tell()>=self.end:
544 if not self.loadToonTexture():
546 self._check_position()
548 ############################################################
550 ############################################################
551 if self.io.tell()>=self.end:
553 #if not self.loadPhysics():
555 self._check_position()
559 def _loadHeader(self):
560 signature=struct.unpack("3s", self.io.read(3))[0]
562 if signature!=b"Pmd":
563 print("invalid signature", signature)
565 self.version=struct.unpack("f", self.io.read(4))[0]
566 self.model_name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
567 self.comment = truncate_zero(
568 struct.unpack("256s", self.io.read(256))[0])
571 def _loadVertex(self):
572 count = struct.unpack("I", self.io.read(4))[0]
573 for i in xrange(count):
574 self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
578 count = struct.unpack("I", self.io.read(4))[0]
579 for i in xrange(0, count, 3):
580 self.indices+=struct.unpack("HHH", self.io.read(6))
583 def _loadMaterial(self):
584 count = struct.unpack("I", self.io.read(4))[0]
585 for i in xrange(count):
586 material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
587 material.toon_index=struct.unpack("B", self.io.read(1))[0]
588 material.flag=struct.unpack("B", self.io.read(1))[0]
589 material.vertex_count=struct.unpack("I", self.io.read(4))[0]
590 texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
592 #material.texture=texture.split('*')[0]
593 material.texture=texture
594 self.materials.append(material)
598 size = struct.unpack("H", self.io.read(2))[0]
599 for i in xrange(size):
600 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
601 parent_index, tail_index = struct.unpack("HH", self.io.read(4))
602 type = struct.unpack("B", self.io.read(1))[0]
603 bone=createBone(name, type)
604 bone.parent_index=parent_index
605 bone.tail_index=tail_index
606 bone.ik_index = struct.unpack("H", self.io.read(2))[0]
607 bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
608 bone.english_name="bone%03d" % len(self.bones)
609 self.bones.append(bone)
613 size = struct.unpack("H", self.io.read(2))[0]
614 for i in xrange(size):
615 ik=IK(*struct.unpack("2H", self.io.read(4)))
616 ik.length = struct.unpack("B", self.io.read(1))[0]
617 ik.iterations = struct.unpack("H", self.io.read(2))[0]
618 ik.weight = struct.unpack("f", self.io.read(4))[0]
619 for j in xrange(ik.length):
620 ik.children.append(struct.unpack("H", self.io.read(2))[0])
621 self.ik_list.append(ik)
625 size = struct.unpack("H", self.io.read(2))[0]
626 for i in xrange(size):
627 skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
628 skin_size = struct.unpack("I", self.io.read(4))[0]
629 skin.type = struct.unpack("B", self.io.read(1))[0]
630 for j in xrange(skin_size):
631 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
632 skin.pos_list.append(
633 Vector3(*struct.unpack("3f", self.io.read(12))))
634 skin.english_name="skin%03d" % len(self.morph_list)
635 self.morph_list.append(skin)
638 def _loadSkinIndex(self):
639 size = struct.unpack("B", self.io.read(1))[0]
640 for i in xrange(size):
641 self.face_list.append(struct.unpack("H", self.io.read(2))[0])
644 def _loadBoneName(self):
645 size = struct.unpack("B", self.io.read(1))[0]
646 for i in xrange(size):
647 self.bone_group_list.append(BoneGroup(
648 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
651 def _loadBoneIndex(self):
652 size = struct.unpack("I", self.io.read(4))[0]
653 for i in xrange(size):
654 self.bone_display_list.append(struct.unpack("HB", self.io.read(3)))
657 def loadToonTexture(self):
662 self.toon_textures.append(ToonTexture(
663 truncate_zero(struct.unpack("100s", self.io.read(100))[0])))
666 def loadEnglishName(self):
668 self.english_model_name=truncate_zero(
669 struct.unpack("20s", self.io.read(20))[0])
670 self.english_comment=truncate_zero(
671 struct.unpack("256s", self.io.read(256))[0])
673 for bone in self.bones:
674 english_name=truncate_zero(
675 struct.unpack("20s", self.io.read(20))[0])
676 if english_name!=bone.name:
677 bone.english_name=english_name
679 #for index in self.face_list:
680 for skin in self.morph_list:
681 if skin.name=='base':
683 english_name=truncate_zero(
684 struct.unpack("20s", self.io.read(20))[0])
685 #skin=self.morph_list[index]
686 if english_name!=skin.name:
687 skin.english_name=english_name
689 for i in xrange(0, len(self.bone_group_list)):
690 self.bone_group_list[i].english_name=truncate_zero(
691 struct.unpack("50s", self.io.read(50))[0])
694 def loadPhysics(self):
696 count = struct.unpack("I", self.io.read(4))[0]
697 for i in xrange(count):
698 struct.unpack("83s", self.io.read(83))[0]
700 count = struct.unpack("I", self.io.read(4))[0]
701 for i in xrange(count):
702 struct.unpack("124s", self.io.read(124))[0]