OSDN Git Service

refactoring
[meshio/pymeshio.git] / pymeshio / pmd.py
1 # coding: utf-8
2 """
3 PMDの読み込み
4 http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
5 """
6 import os
7 import sys
8 import struct
9 from .common import *
10 from .compatibility import *
11
12
13 class Vertex(object):
14     """pmd vertex struct.
15
16     Attributes:
17         pos: Vector3
18         normal: Vector3
19         uv: Vector2
20         bone0: bone index
21         bone1: bone index
22         weight0: bone0 influence
23         edge_flag: int flag
24     """
25     __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
26     def __init__(self, x=0, y=0, z=0, nx=0, ny=0, nz=0, u=0, v=0,
27             bone0=0, bone1=0, weight0=0, edge_flag=0):
28         self.pos=Vector3(x, y, z)
29         self.normal=Vector3(nx, ny, nz)
30         self.uv=Vector2(u, v)
31         self.bone0=bone0
32         self.bone1=bone1
33         self.weight0=weight0
34         self.edge_flag=edge_flag
35
36     def __str__(self):
37         return "<%s %s %s, (%d, %d, %d)>" % (
38                 str(self.pos), 
39                 str(self.normal), 
40                 str(self.uv), 
41                 self.bone0, self.bone1, self.weight0)
42
43     def __getitem__(self, key):
44         if key==0:
45             return self.pos.x
46         elif key==1:
47             return self.pos.y
48         elif key==2:
49             return self.pos.z
50         else:
51             assert(False)
52
53
54 class Material(object):
55     """pmd material struct.
56
57     Attributes:
58         diffuse: RGBA
59         shinness: float
60         specular: RGB
61         ambient: RGB
62         vertex_count: indices length
63         _texture: texture file path
64         toon_index: int
65         flag: int
66     """
67     __slots__=[
68             'diffuse', 'shinness', 'specular',
69             'ambient', 'vertex_count', '_texture', 'toon_index', 'flag',
70             ]
71     def getTexture(self): return from_str(self._texture)
72     def setTexture(self, texture): self._texture=to_str(texture)
73     texture=property(getTexture, setTexture)
74
75     def __init__(self, dr=0, dg=0, db=0, alpha=1, 
76             specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0):
77         self.diffuse=RGBA(dr, dg, db, alpha)
78         self.specular=RGBA(sr, sg, sb)
79         self.shinness=specular
80         self.ambient=RGBA(ar, ag, ab)
81         self.vertex_count=0
82         self.texture=''
83         self.toon_index=0
84         self.flag=0
85
86     def __str__(self):
87         return "<Material [%f, %f, %f, %f]>" % (
88                 self.diffuse[0], self.diffuse[1], 
89                 self.diffuse[2], self.diffuse[3],
90                 )
91
92
93 class Bone(object):
94     """pmd material struct.
95
96     Attributes:
97         _name: 
98         index:
99         type:
100         ik:
101         pos:
102         _english_name:
103         ik_index:
104         parent_index:
105         tail_index:
106
107         parent:
108         tail:
109         children:
110     """
111     # kinds
112     ROTATE = 0
113     ROTATE_MOVE = 1
114     IK = 2
115     IK_ROTATE_INFL = 4
116     ROTATE_INFL = 5
117     IK_TARGET = 6
118     UNVISIBLE = 7
119     # since v4.0
120     ROLLING=8 # ?
121     TWEAK=9
122     __slots__=['_name', 'index', 'type', 'parent', 'ik', 'pos',
123             'children', '_english_name', 'ik_index',
124             'parent_index', 'tail_index', 'tail',
125             ]
126     def getName(self): 
127         """
128         return str(multibyte) in python2
129         return bytes in python3
130         """
131         return from_str(self._name)
132     def setName(self, name): self._name=to_str(name)
133     name=property(getName, setName)
134     def getEnglishName(self): return from_str(self._english_name)
135     def setEnglishName(self, english_name): self._english_name=to_str(english_name)
136     english_name=property(getEnglishName, setEnglishName)
137
138     def __init__(self, name='bone', type=0):
139         self.name=name
140         self.index=0
141         self.type=type
142         self.parent_index=0xFFFF
143         self.tail_index=0
144         self.tail=Vector3(0, 0, 0)
145         self.parent=None
146         self.ik_index=0xFFFF
147         self.pos=Vector3(0, 0, 0)
148         self.children=[]
149         self.english_name=''
150
151     def hasParent(self):
152         return self.parent_index!=0xFFFF
153
154     def hasChild(self):
155         return self.tail_index!=0
156
157     def display(self, indent=[]):
158         if len(indent)>0:
159             prefix=''
160             for i, is_end in enumerate(indent):
161                 if i==len(indent)-1:
162                     break
163                 else:
164                     prefix+='  ' if is_end else ' |'
165             uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
166             print(uni.encode(ENCODING))
167         else:
168             uni='%s(%s)' % (unicode(self), self.english_name)
169             print(uni.encode(ENCODING))
170
171         child_count=len(self.children)
172         for i in range(child_count):
173             child=self.children[i]
174             if i<child_count-1:
175                 child.display(indent+[False])
176             else:
177                 # last
178                 child.display(indent+[True])
179
180 # 0
181 class Bone_Rotate(Bone):
182     __slots__=[]
183     def __init__(self, name):
184         super(Bone_Rotate, self).__init__(name, 0)
185     def __str__(self):
186         return '<ROTATE %s>' % (self.name)
187 # 1
188 class Bone_RotateMove(Bone):
189     __slots__=[]
190     def __init__(self, name):
191         super(Bone_RotateMove, self).__init__(name, 1)
192     def __str__(self):
193         return '<ROTATE_MOVE %s>' % (self.name)
194 # 2
195 class Bone_IK(Bone):
196     __slots__=[]
197     def __init__(self, name):
198         super(Bone_IK, self).__init__(name, 2)
199     def __str__(self):
200         return '<IK %s>' % (self.name)
201 # 4
202 class Bone_IKRotateInfl(Bone):
203     __slots__=[]
204     def __init__(self, name):
205         super(Bone_IKRotateInfl, self).__init__(name, 4)
206     def __str__(self):
207         return '<IK_ROTATE_INFL %s>' % (self.name)
208 # 5
209 class Bone_RotateInfl(Bone):
210     __slots__=[]
211     def __init__(self, name):
212         super(Bone_RotateInfl, self).__init__(name, 5)
213     def __str__(self):
214         return '<ROTATE_INFL %s>' % (self.name)
215 # 6
216 class Bone_IKTarget(Bone):
217     __slots__=[]
218     def __init__(self, name):
219         super(Bone_IKTarget, self).__init__(name, 6)
220     def __str__(self):
221         return '<IK_TARGET %s>' % (self.name)
222 # 7
223 class Bone_Unvisible(Bone):
224     __slots__=[]
225     def __init__(self, name):
226         super(Bone_Unvisible, self).__init__(name, 7)
227     def __str__(self):
228         return '<UNVISIBLE %s>' % (self.name)
229 # 8
230 class Bone_Rolling(Bone):
231     __slots__=[]
232     def __init__(self, name):
233         super(Bone_Rolling, self).__init__(name, 8)
234     def __str__(self):
235         return '<ROLLING %s>' % (self.name)
236 # 9
237 class Bone_Tweak(Bone):
238     __slots__=[]
239     def __init__(self, name):
240         super(Bone_Tweak, self).__init__(name, 9)
241     def __str__(self):
242         return '<TWEAK %s>' % (self.name)
243
244
245 def createBone(name, type):
246     if type==0:
247         return Bone_Rotate(name)
248     elif type==1:
249         return Bone_RotateMove(name)
250     elif type==2:
251         return Bone_IK(name)
252     elif type==3:
253         raise Exception("no used bone type: 3(%s)" % name)
254     elif type==4:
255         return Bone_IKRotateInfl(name)
256     elif type==5:
257         return Bone_RotateInfl(name)
258     elif type==6:
259         return Bone_IKTarget(name)
260     elif type==7:
261         return Bone_Unvisible(name)
262     elif type==8:
263         return Bone_Rolling(name)
264     elif type==9:
265         return Bone_Tweak(name)
266     else:
267         raise Exception("unknown bone type: %d(%s)", type, name)
268
269
270 class IK(object):
271     __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
272     def __init__(self, index=0, target=0):
273         self.index=index
274         self.target=target
275         self.iterations=None
276         self.weight=None
277         self.children=[]
278
279     def __str__(self):
280         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))
281
282
283 class Skin(object):
284     __slots__=['_name', 'type', 'indices', 'pos_list', '_english_name',
285             'vertex_count']
286     def getName(self): return from_str(self._name)
287     def setName(self, name): self._name=to_str(name)
288     name=property(getName, setName)
289     def getEnglishName(self): return from_str(self._english_name)
290     def setEnglishName(self, english_name): self._english_name=to_str(english_name)
291     english_name=property(getEnglishName, setEnglishName)
292
293     def __init__(self, name='skin'):
294         self.name=name
295         self.type=None
296         self.indices=[]
297         self.pos_list=[]
298         self.english_name=''
299         self.vertex_count=0
300
301     def append(self, index, x, y, z):
302         self.indices.append(index)
303         self.pos_list.append(Vector3(x, y, z))
304
305     def __str__(self):
306         return '<Skin name: "%s", type: %d, vertex: %d>' % (
307             self.name, self.type, len(self.indices))
308
309
310 class BoneGroup(object):
311     __slots__=['_name', '_english_name']
312     def getName(self): return from_str(self._name)
313     def setName(self, name): self._name=to_str(name)
314     name=property(getName, setName)
315     def getEnglishName(self): return from_str(self._english_name)
316     def setEnglishName(self, english_name): self._english_name=to_str(english_name)
317     english_name=property(getEnglishName, setEnglishName)
318
319     def __init__(self, name='group'): self._name=name; self._english_name='center'
320
321
322 SHAPE_SPHERE=0
323 SHAPE_BOX=1
324 SHAPE_CAPSULE=2
325
326 RIGIDBODY_KINEMATICS=0
327 RIGIDBODY_PHYSICS=1
328 RIGIDBODY_PHYSICS_WITH_BONE=2
329
330
331 class RigidBody(object):
332     __slots__=['_name', 'boneIndex', 'group', 'target', 'shapeType',
333             'w', 'h', 'd', 'position', 'rotation', 'weight',
334             'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
335             ]
336     def getName(self): return from_str(self._name)
337     def setName(self, name): self._name=to_str(name)
338     name=property(getName, setName)
339
340     def __init__(self, name):
341         self.name=name
342         self.position=Vector3()
343         self.rotation=Vector3()
344
345
346 class Constraint(object):
347     __slots__=[ '_name', 'rigidA', 'rigidB', 'pos', 'rot',
348             'constraintPosMin', 'constraintPosMax',
349             'constraintRotMin', 'constraintRotMax',
350             'springPos', 'springRot',
351             ]
352     def getName(self): return from_str(self._name)
353     def setName(self, name): self._name=to_str(name)
354     name=property(getName, setName)
355
356     def __init__(self, name):
357         self.name=name
358         self.pos=Vector3()
359         self.rot=Vector3()
360         self.constraintPosMin=Vector3()
361         self.constraintPosMax=Vector3()
362         self.constraintRotMin=Vector3()
363         self.constraintRotMax=Vector3()
364         self.springPos=Vector3()
365         self.springRot=Vector3()
366
367
368 class ToonTextures(object):
369     __slots__=['_toon_textures']
370     def __init__(self):
371         self._toon_textures=[]
372         for i in range(10):
373             self._toon_textures.append('toon%02d.bmp' % (i+1))
374
375     def __getitem__(self, key):
376         return from_str(self._toon_textures[key])
377
378     def __setitem__(self, key, value):
379         self._toon_textures[key]=to_str(value)
380
381     def __iter__(self):
382         for toon_texture in self._toon_textures:
383             yield from_str(toon_texture)
384
385
386 class IO(object):
387     """pmd loader class.
388
389     Attributes:
390         io: internal use.
391         end: internal use.
392         pos: internal user.
393
394         version: pmd version number
395         _name: internal
396     """
397     __slots__=['io', 'end', 'pos',
398             'version', '_name', '_comment',
399             '_english_name', '_english_comment',
400             'vertices', 'indices', 'materials', 'bones', 
401             'ik_list', 'morph_list',
402             'face_list', 'bone_group_list', 'bone_display_list',
403             'toon_textures',
404             'no_parent_bones',
405             'rigidbodies', 'constraints',
406             ]
407     def getName(self): return from_str(self._name)
408     def setName(self, name): self._name=to_str(name)
409     name=property(getName, setName)
410     def getEnglishName(self): return from_str(self._english_name)
411     def setEnglishName(self, english_name): self._english_name=to_str(english_name)
412     english_name=property(getEnglishName, setEnglishName)
413     def getComment(self): return from_str(self._comment)
414     def setComment(self, comment): self._comment=to_str(comment)
415     comment=property(getComment, setComment)
416     def getEnglishComment(self): return from_str(self._english_comment)
417     def setEnglishComment(self, english_comment): self._english_comment=to_str(english_comment)
418     english_comment=property(getEnglishComment, setEnglishComment)
419
420     def __init__(self):
421         self.version=1.0
422         self.name=''
423         self.comment=''
424         self.english_name=''
425         self.english_comment=''
426         self.vertices=[]
427         self.indices=[]
428         self.materials=[]
429         self.bones=[]
430         self.ik_list=[]
431         self.morph_list=[]
432         self.face_list=[]
433         self.bone_group_list=[]
434         self.bone_display_list=[]
435         # extend
436         self.toon_textures=ToonTextures()
437         self.rigidbodies=[]
438         self.constraints=[]
439         # innner use
440         self.no_parent_bones=[]
441
442     def each_vertex(self): return self.vertices
443     def getUV(self, i): return self.vertices[i].uv
444     def addVertex(self): 
445         v=Vertex()
446         self.vertices.append(v)
447         return v
448     def addMaterial(self):
449         m=Material()
450         self.materials.append(m)
451         return m
452     def addBone(self):
453         b=Bone()
454         self.bones.append(b)
455         return b
456     def addIK(self):
457         ik=IK()
458         self.ik_list.append(ik)
459         return ik
460     def addMorph(self):
461         s=Skin()
462         self.morph_list.append(s)
463         return s
464     def addBoneGroup(self):
465         g=BoneGroup()
466         self.bone_group_list.append(g)
467         return g
468     def addBoneDisplay(self, b, g):
469         self.bone_display_list.append((b, g))
470
471     def __str__(self):
472         return '<PMDLoader version: %g, model: "%s", vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
473             self.version, self.name, len(self.vertices), len(self.indices),
474             len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
475
476     def _check_position(self):
477         self.pos=self.io.tell()
478
479     def read(self, path):
480         size=os.path.getsize(path)
481         with open(path, "rb") as f:
482             return self.load(path, f, size)
483
484     def load(self, path, io, end):
485         self.io=io
486         self.pos=self.io.tell()
487         self.end=end
488         self._check_position()
489
490         if not self._loadHeader():
491             return False
492         self._check_position()
493
494         if not self._loadVertex():
495             return False
496         self._check_position()
497
498         if not self._loadFace():
499             return False
500         self._check_position()
501
502         if not self._loadMaterial():
503             return False
504         self._check_position()
505
506         if not self._loadBone():
507             return False
508         self._check_position()
509
510         if not self._loadIK():
511             return False
512         self._check_position()
513
514         if not self._loadSkin():
515             return False
516         self._check_position()
517
518         if not self._loadSkinIndex():
519             return False
520         self._check_position()
521
522         if not self._loadBoneName():
523             return False
524         self._check_position()
525
526         if not self._loadBoneIndex():
527             return False
528         self._check_position()
529
530         if not self._loadExtend():
531             print('fail to loadExtend')
532             return False
533
534         # 終端
535         if self.io.tell()!=self.end:
536             print("can not reach eof.")
537             print("current: %d, end: %d, remain: %d" % (
538                     self.io.tell(), self.end, self.end-self.io.tell()))
539
540         # build bone tree
541         for i, child in enumerate(self.bones):
542             if child.parent_index==0xFFFF:
543                 # no parent
544                 self.no_parent_bones.append(child)
545                 child.parent=None
546             else:
547                 # has parent
548                 parent=self.bones[child.parent_index]
549                 child.parent=parent
550                 parent.children.append(child)
551             # 後位置
552             if child.hasChild():
553                 child.tail=self.bones[child.tail_index].pos
554
555         return True
556
557     def write(self, path):
558         io=open(path, 'wb')
559         if not io:
560             return False
561         # Header
562         io.write(b"Pmd")
563         io.write(struct.pack("f", self.version))
564         io.write(struct.pack("20s", self.name))
565         io.write(struct.pack("256s", self.comment))
566
567         # Vertices
568         io.write(struct.pack("I", len(self.vertices)))
569         sVertex=struct.Struct("=8f2H2B") # 38byte
570         assert(sVertex.size==38)
571         for v in self.vertices:
572             data=sVertex.pack( 
573                 v.pos[0], v.pos[1], v.pos[2],
574                 v.normal[0], v.normal[1], v.normal[2],
575                 v.uv[0], v.uv[1],
576                 v.bone0, v.bone1, v.weight0, v.edge_flag)
577             io.write(data)
578
579         # Faces
580         io.write(struct.pack("I", len(self.indices)))
581         io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
582
583         # material
584         io.write(struct.pack("I", len(self.materials)))
585         sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
586         assert(sMaterial.size==70)
587         for m in self.materials:
588             io.write(sMaterial.pack(
589                 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
590                 m.shinness, 
591                 m.specular[0], m.specular[1], m.specular[2],
592                 m.ambient[0], m.ambient[1], m.ambient[2],
593                 m.toon_index, m.flag,
594                 m.vertex_count,
595                 m.texture
596                 ))
597
598         # bone
599         io.write(struct.pack("H", len(self.bones)))
600         sBone=struct.Struct("=20sHHBH3f")
601         assert(sBone.size==39)
602         for b in self.bones:
603             io.write(sBone.pack(
604                 b.name,
605                 b.parent_index, b.tail_index, b.type, b.ik_index,
606                 b.pos[0], b.pos[1], b.pos[2]))
607
608         # IK
609         io.write(struct.pack("H", len(self.ik_list)))
610         for ik in self.ik_list:
611             io.write(struct.pack("=2HBHf", 
612                 ik.index, ik.target, ik.length, ik.iterations, ik.weight
613                 ))
614             for c in ik.children:
615                 io.write(struct.pack("H", c))
616
617         # skin
618         io.write(struct.pack("H", len(self.morph_list)))
619         for s in self.morph_list:
620             io.write(struct.pack("20sIB", 
621                 s.name, len(s.indices), s.type))
622             for i, v in zip(s.indices, s.pos_list):
623                 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
624
625         # skin disp list
626         io.write(struct.pack("B", len(self.face_list)))
627         for i in self.face_list:
628             io.write(struct.pack("H", i))
629
630         # bone disp list
631         io.write(struct.pack("B", len(self.bone_group_list)))
632         for g in self.bone_group_list:
633             io.write(struct.pack("50s", g.name))
634
635         io.write(struct.pack("I", len(self.bone_display_list)))
636         for l in self.bone_display_list:
637             io.write(struct.pack("=HB", *l))
638
639         ############################################################
640         # extend data
641         ############################################################
642         io.write(struct.pack("B", 1))
643         # english name
644         io.write(struct.pack("=20s", self.english_name))
645         io.write(struct.pack("=256s", self.english_comment))
646         # english bone name
647         for bone in self.bones:
648             io.write(struct.pack("=20s", bone.english_name))
649         # english skin list
650         for skin in self.morph_list:
651             #print(skin.name)
652             if skin.name==b'base':
653                 continue
654             io.write(struct.pack("=20s", skin.english_name))
655         # english bone list
656         for bone_group in self.bone_group_list:
657             io.write(struct.pack("50s", bone_group.english_name))
658         # toon texture
659         for toon_texture in self.toon_textures:
660             io.write(struct.pack("=100s", toon_texture))
661         # rigid
662         io.write(struct.pack("I", len(self.rigidbodies)))
663         for r in self.rigidbodies:
664             io.write(struct.pack("=20sHBHB14fB",
665                 r.name, r.boneIndex, r.group, r.target, r.shapeType,
666                 r.w, r.h, r.d, 
667                 r.position.x, r.position.y, r.position.z, 
668                 r.rotation.x, r.rotation.y, r.rotation.z, 
669                 r.weight,
670                 r.linearDamping, r.angularDamping, r.restitution,
671                 r.friction, r.processType))
672
673         # constraint
674         io.write(struct.pack("I", len(self.constraints)))
675         for c in self.constraints:
676             io.write(struct.pack("=20sII24f",
677                 c.name, c.rigidA, c.rigidB,
678                 c.pos.x, c.pos.y, c.pos.z,
679                 c.rot.x, c.rot.y, c.rot.z,
680                 c.constraintPosMin.x, c.constraintPosMin.y, c.constraintPosMin.z,
681                 c.constraintPosMax.x, c.constraintPosMax.y, c.constraintPosMax.z,
682                 c.constraintRotMin.x, c.constraintRotMin.y, c.constraintRotMin.z,
683                 c.constraintRotMax.x, c.constraintRotMax.y, c.constraintRotMax.z,
684                 c.springPos.x, c.springPos.y, c.springPos.z,
685                 c.springRot.x, c.springRot.y, c.springRot.z
686                 ))
687
688         return True
689
690
691     def _loadExtend(self):
692         ############################################################
693         # extend1: english name
694         ############################################################
695         if self.io.tell()>=self.end:
696             return True
697         if struct.unpack("B", self.io.read(1))[0]==1:
698             if not self.loadEnglishName():
699                 return False
700         self._check_position()
701
702         ############################################################
703         # extend2: toon texture list
704         ############################################################
705         if self.io.tell()>=self.end:
706             return True
707         if not self.loadToonTexture():
708             return False
709         self._check_position()
710
711         ############################################################
712         # extend3: physics
713         ############################################################
714         if self.io.tell()>=self.end:
715             return True
716         if not self.loadPhysics():
717             return False
718         self._check_position()
719
720         return True
721
722     def _loadHeader(self):
723         signature=struct.unpack("3s", self.io.read(3))[0]
724         if signature!=b"Pmd":
725             print("invalid signature", signature)
726             return False
727         self.version=struct.unpack("f", self.io.read(4))[0]
728         self.name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
729         self.comment = truncate_zero(
730                 struct.unpack("256s", self.io.read(256))[0])
731         return True
732
733     def _loadVertex(self):
734         count = struct.unpack("I", self.io.read(4))[0]
735         for i in range(count):
736             self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
737         return True
738
739     def _loadFace(self):
740         count = struct.unpack("I", self.io.read(4))[0]
741         for i in range(0, count, 3):
742             self.indices+=struct.unpack("HHH", self.io.read(6))
743         return True
744
745     def _loadMaterial(self):
746         count = struct.unpack("I", self.io.read(4))[0]
747         for i in range(count):
748             material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
749             material.toon_index=struct.unpack("B", self.io.read(1))[0]
750             material.flag=struct.unpack("B", self.io.read(1))[0]
751             material.vertex_count=struct.unpack("I", self.io.read(4))[0]
752             texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
753             # todo sphere map
754             #material.texture=texture.split('*')[0]
755             material.texture=texture
756             self.materials.append(material)
757         return True
758
759     def _loadBone(self):
760         size = struct.unpack("H", self.io.read(2))[0]
761         for i in range(size):
762             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
763             parent_index, tail_index = struct.unpack("HH", self.io.read(4))
764             type = struct.unpack("B", self.io.read(1))[0]
765             bone=createBone(name, type)
766             bone.parent_index=parent_index
767             bone.tail_index=tail_index
768             bone.ik_index = struct.unpack("H", self.io.read(2))[0]
769             bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
770             bone.english_name="bone%03d" % len(self.bones)
771             self.bones.append(bone)
772         return True
773
774     def _loadIK(self):
775         size = struct.unpack("H", self.io.read(2))[0]
776         for i in range(size):
777             ik=IK(*struct.unpack("2H", self.io.read(4)))
778             ik.length = struct.unpack("B", self.io.read(1))[0]
779             ik.iterations = struct.unpack("H", self.io.read(2))[0]
780             ik.weight = struct.unpack("f", self.io.read(4))[0]
781             for j in range(ik.length):
782                 ik.children.append(struct.unpack("H", self.io.read(2))[0])
783             self.ik_list.append(ik)
784         return True
785
786     def _loadSkin(self):
787         size = struct.unpack("H", self.io.read(2))[0]
788         for i in range(size):
789             skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
790             skin_size = struct.unpack("I", self.io.read(4))[0]
791             skin.type = struct.unpack("B", self.io.read(1))[0]
792             for j in range(skin_size):
793                 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
794                 skin.pos_list.append(
795                         Vector3(*struct.unpack("3f", self.io.read(12))))
796             skin.english_name="skin%03d" % len(self.morph_list)
797             self.morph_list.append(skin)
798         return True
799
800     def _loadSkinIndex(self):
801         size = struct.unpack("B", self.io.read(1))[0]
802         for i in range(size):
803             self.face_list.append(struct.unpack("H", self.io.read(2))[0])
804         return True
805
806     def _loadBoneName(self):
807         size = struct.unpack("B", self.io.read(1))[0]
808         for i in range(size):
809             self.bone_group_list.append(BoneGroup(
810                 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
811         return True
812
813     def _loadBoneIndex(self):
814         size = struct.unpack("I", self.io.read(4))[0]
815         for i in range(size):
816             first=struct.unpack("H", self.io.read(2))[0]
817             second=struct.unpack("B", self.io.read(1))[0]
818             self.bone_display_list.append((first, second))
819         return True
820
821     def loadToonTexture(self):
822         """
823         100bytex10
824         """
825         for i in range(10):
826             self.toon_textures[i]=truncate_zero(struct.unpack("100s", self.io.read(100))[0])
827         return True
828
829     def loadEnglishName(self):
830         # english name
831         self.english_name=truncate_zero(
832                 struct.unpack("20s", self.io.read(20))[0])
833         self.english_comment=truncate_zero(
834                 struct.unpack("256s", self.io.read(256))[0])
835         self._check_position()
836         # english bone name
837         for bone in self.bones:
838             english_name=truncate_zero(
839                     struct.unpack("20s", self.io.read(20))[0])
840             bone.english_name=english_name
841         self._check_position()
842         # english skin list
843         for skin in self.morph_list:
844             if skin.name==b'base':
845                 continue
846             english_name=truncate_zero(
847                     struct.unpack("20s", self.io.read(20))[0])
848             #skin=self.morph_list[index]
849             if english_name!=skin.name:
850                 skin.english_name=english_name
851         self._check_position()
852         # english bone list
853         for i in range(0, len(self.bone_group_list)):
854             self.bone_group_list[i].english_name=truncate_zero(
855                     struct.unpack("50s", self.io.read(50))[0])
856         self._check_position()
857         return True
858
859     def loadPhysics(self):
860         # 剛体リスト
861         count = struct.unpack("I", self.io.read(4))[0]
862         for i in range(count):
863             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
864             rigidbody=RigidBody(name)
865             rigidbody.boneIndex=struct.unpack("H", self.io.read(2))[0]
866             rigidbody.group=struct.unpack("B", self.io.read(1))[0]
867             rigidbody.target=struct.unpack("H", self.io.read(2))[0]
868             rigidbody.shapeType=struct.unpack("B", self.io.read(1))[0]
869             rigidbody.w=struct.unpack("f", self.io.read(4))[0]
870             rigidbody.h=struct.unpack("f", self.io.read(4))[0]
871             rigidbody.d=struct.unpack("f", self.io.read(4))[0]
872             rigidbody.position.x=struct.unpack("f", self.io.read(4))[0]
873             rigidbody.position.y=struct.unpack("f", self.io.read(4))[0]
874             rigidbody.position.z=struct.unpack("f", self.io.read(4))[0]
875             rigidbody.rotation.x=struct.unpack("f", self.io.read(4))[0]
876             rigidbody.rotation.y=struct.unpack("f", self.io.read(4))[0]
877             rigidbody.rotation.z=struct.unpack("f", self.io.read(4))[0]
878             rigidbody.weight=struct.unpack("f", self.io.read(4))[0]
879             rigidbody.linearDamping=struct.unpack("f", self.io.read(4))[0]
880             rigidbody.angularDamping=struct.unpack("f", self.io.read(4))[0]
881             rigidbody.restitution=struct.unpack("f", self.io.read(4))[0]
882             rigidbody.friction=struct.unpack("f", self.io.read(4))[0]
883             rigidbody.processType=struct.unpack("B", self.io.read(1))[0]
884             self.rigidbodies.append(rigidbody)
885         self._check_position()
886
887         # ジョイントリスト
888         count = struct.unpack("I", self.io.read(4))[0]
889         for i in range(count):
890             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
891             constraint=Constraint(name)
892             constraint.rigidA=struct.unpack("I", self.io.read(4))[0]
893             constraint.rigidB=struct.unpack("I", self.io.read(4))[0]
894             constraint.pos.x=struct.unpack("f", self.io.read(4))[0]
895             constraint.pos.y=struct.unpack("f", self.io.read(4))[0]
896             constraint.pos.z=struct.unpack("f", self.io.read(4))[0]
897             constraint.rot.x=struct.unpack("f", self.io.read(4))[0]
898             constraint.rot.y=struct.unpack("f", self.io.read(4))[0]
899             constraint.rot.z=struct.unpack("f", self.io.read(4))[0]
900             constraint.constraintPosMin.x=struct.unpack("f", self.io.read(4))[0]
901             constraint.constraintPosMin.y=struct.unpack("f", self.io.read(4))[0]
902             constraint.constraintPosMin.z=struct.unpack("f", self.io.read(4))[0]
903             constraint.constraintPosMax.x=struct.unpack("f", self.io.read(4))[0]
904             constraint.constraintPosMax.y=struct.unpack("f", self.io.read(4))[0]
905             constraint.constraintPosMax.z=struct.unpack("f", self.io.read(4))[0]
906             constraint.constraintRotMin.x=struct.unpack("f", self.io.read(4))[0]
907             constraint.constraintRotMin.y=struct.unpack("f", self.io.read(4))[0]
908             constraint.constraintRotMin.z=struct.unpack("f", self.io.read(4))[0]
909             constraint.constraintRotMax.x=struct.unpack("f", self.io.read(4))[0]
910             constraint.constraintRotMax.y=struct.unpack("f", self.io.read(4))[0]
911             constraint.constraintRotMax.z=struct.unpack("f", self.io.read(4))[0]
912             constraint.springPos.x=struct.unpack("f", self.io.read(4))[0]
913             constraint.springPos.y=struct.unpack("f", self.io.read(4))[0]
914             constraint.springPos.z=struct.unpack("f", self.io.read(4))[0]
915             constraint.springRot.x=struct.unpack("f", self.io.read(4))[0]
916             constraint.springRot.y=struct.unpack("f", self.io.read(4))[0]
917             constraint.springRot.z=struct.unpack("f", self.io.read(4))[0]
918             self.constraints.append(constraint)
919         self._check_position()
920
921         return True
922