OSDN Git Service

4d3b0f77b5ed0f8a16853f4ae8093cb799c14328
[meshio/pymeshio.git] / blender25-meshio / pymeshio / pmd.py
1 # coding: utf-8
2 import os
3 import struct
4 from mmd import *
5
6 ###############################################################################
7 # PMD
8 ###############################################################################
9 class Vertex(object):
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)
15         self.uv=Vector2(u, v)
16         self.bone0=bone0
17         self.bone1=bone1
18         self.weight0=weight0
19         self.edge_flag=edge_flag
20
21     def __str__(self):
22         return "<%s %s %s, (%d, %d, %d)>" % (str(self.pos), str(self.normal), str(self.uv), self.bone0, self.bone1, self.weight0)
23
24     def __getitem__(self, key):
25         if key==0:
26             return self.pos.x
27         elif key==1:
28             return self.pos.y
29         elif key==2:
30             return self.pos.z
31         else:
32             assert(False)
33
34
35 class Material(object):
36     __slots__=[
37             'diffuse', 'shinness', 'specular',
38             'ambient', 'vertex_count', 'texture', 'toon_index', 'flag',
39             ]
40
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)
47         self.vertex_count=0
48         self.texture=''
49         self.toon_index=0
50         self.flag=0
51
52     def __str__(self):
53         return "<Material [%f, %f, %f, %f]>" % (
54                 self.diffuse[0], self.diffuse[1], 
55                 self.diffuse[2], self.diffuse[3],
56                 )
57
58     def getTexture(self): return self.texture.decode('cp932')
59     def setTexture(self, u): self.texture=u
60
61
62 # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ
63 # マテリアル自身を返す
64 def material_per_face(materials):
65     for m in materials:
66         for x in xrange(int(m.vertex_count/3)):
67             yield m
68
69
70 class Bone(object):
71     # kinds
72     ROTATE = 0
73     ROTATE_MOVE = 1
74     IK = 2
75     IK_ROTATE_INFL = 4
76     ROTATE_INFL = 5
77     IK_TARGET = 6
78     UNVISIBLE = 7
79     # since v4.0
80     ROLLING=8 # ?
81     TWEAK=9
82     __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos',
83             'children', 'english_name', 'ik_index',
84             'parent_index', 'tail_index', 'tail',
85             ]
86     def __init__(self, name='bone', type=0):
87         self.name=name
88         self.index=0
89         self.type=type
90         self.parent_index=0xFFFF
91         self.tail_index=0
92         self.tail=Vector3(0, 0, 0)
93         self.parent=None
94         self.ik_index=0xFFFF
95         self.pos=Vector3(0, 0, 0)
96         self.children=[]
97         self.english_name=''
98
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
102
103     def hasParent(self):
104         return self.parent_index!=0xFFFF
105
106     def hasChild(self):
107         return self.tail_index!=0
108
109     def display(self, indent=[]):
110         if len(indent)>0:
111             prefix=''
112             for i, is_end in enumerate(indent):
113                 if i==len(indent)-1:
114                     break
115                 else:
116                     prefix+='  ' if is_end else ' |'
117             uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
118             print(uni.encode(ENCODING))
119         else:
120             uni='%s(%s)' % (unicode(self), self.english_name)
121             print(uni.encode(ENCODING))
122
123         child_count=len(self.children)
124         for i in xrange(child_count):
125             child=self.children[i]
126             if i<child_count-1:
127                 child.display(indent+[False])
128             else:
129                 # last
130                 child.display(indent+[True])
131
132 # 0
133 class Bone_Rotate(Bone):
134     __slots__=[]
135     def __init__(self, name):
136         super(Bone_Rotate, self).__init__(name, 0)
137     def __str__(self):
138         return '<ROTATE %s>' % (self.name)
139 # 1
140 class Bone_RotateMove(Bone):
141     __slots__=[]
142     def __init__(self, name):
143         super(Bone_RotateMove, self).__init__(name, 1)
144     def __str__(self):
145         return '<ROTATE_MOVE %s>' % (self.name)
146 # 2
147 class Bone_IK(Bone):
148     __slots__=[]
149     def __init__(self, name):
150         super(Bone_IK, self).__init__(name, 2)
151     def __str__(self):
152         return '<IK %s>' % (self.name)
153 # 4
154 class Bone_IKRotateInfl(Bone):
155     __slots__=[]
156     def __init__(self, name):
157         super(Bone_IKRotateInfl, self).__init__(name, 4)
158     def __str__(self):
159         return '<IK_ROTATE_INFL %s>' % (self.name)
160 # 5
161 class Bone_RotateInfl(Bone):
162     __slots__=[]
163     def __init__(self, name):
164         super(Bone_RotateInfl, self).__init__(name, 5)
165     def __str__(self):
166         return '<ROTATE_INFL %s>' % (self.name)
167 # 6
168 class Bone_IKTarget(Bone):
169     __slots__=[]
170     def __init__(self, name):
171         super(Bone_IKTarget, self).__init__(name, 6)
172     def __str__(self):
173         return '<IK_TARGET %s>' % (self.name)
174 # 7
175 class Bone_Unvisible(Bone):
176     __slots__=[]
177     def __init__(self, name):
178         super(Bone_Unvisible, self).__init__(name, 7)
179     def __str__(self):
180         return '<UNVISIBLE %s>' % (self.name)
181 # 8
182 class Bone_Rolling(Bone):
183     __slots__=[]
184     def __init__(self, name):
185         super(Bone_Rolling, self).__init__(name, 8)
186     def __str__(self):
187         return '<ROLLING %s>' % (self.name)
188 # 9
189 class Bone_Tweak(Bone):
190     __slots__=[]
191     def __init__(self, name):
192         super(Bone_Tweak, self).__init__(name, 9)
193     def __str__(self):
194         return '<TWEAK %s>' % (self.name)
195
196
197 def createBone(name, type):
198     if type==0:
199         return Bone_Rotate(name)
200     elif type==1:
201         return Bone_RotateMove(name)
202     elif type==2:
203         return Bone_IK(name)
204     elif type==3:
205         raise Exception("no used bone type: 3(%s)" % name)
206     elif type==4:
207         return Bone_IKRotateInfl(name)
208     elif type==5:
209         return Bone_RotateInfl(name)
210     elif type==6:
211         return Bone_IKTarget(name)
212     elif type==7:
213         return Bone_Unvisible(name)
214     elif type==8:
215         return Bone_Rolling(name)
216     elif type==9:
217         return Bone_Tweak(name)
218     else:
219         raise Exception("unknown bone type: %d(%s)", type, name)
220
221
222 class IK(object):
223     __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
224     def __init__(self, index=0, target=0):
225         self.index=index
226         self.target=target
227         self.iterations=None
228         self.weight=None
229         self.children=[]
230
231     def __str__(self):
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))
233
234
235 class Skin(object):
236     __slots__=['name', 'type', 'indices', 'pos_list', 'english_name',
237             'vertex_count']
238     def __init__(self, name='skin'):
239         self.name=name
240         self.type=None
241         self.indices=[]
242         self.pos_list=[]
243         self.english_name=''
244         self.vertex_count=0
245
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
249
250     def append(self, index, x, y, z):
251         self.indices.append(index)
252         self.pos_list.append(Vector3(x, y, z))
253
254     def __str__(self):
255         return '<Skin name: "%s", type: %d, vertex: %d>' % (
256             self.name, self.type, len(self.indices))
257
258
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
266
267
268 class RigidBody(object):
269     __slots__=['name', 'boneIndex', 'group', 'target', 'shapeType',
270             'w', 'h', 'd', 'position', 'rotation', 'weight',
271             'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
272             ]
273     def __init__(self, name):
274         self.name=name
275         self.position=Vector3()
276         self.rotation=Vector3()
277
278
279 class Constraint(object):
280     __slots__=[ 'name', 'rigidA', 'rigidB', 'pos', 'rot',
281             'constraintPosMin', 'constraintPosMax',
282             'constraintRotMin', 'constraintRotMax',
283             'springPos', 'springRot',
284             ]
285     def __init__(self, name):
286         self.name=name
287         self.pos=Vector3()
288         self.rot=Vector3()
289         self.constraintPosMin=Vector3()
290         self.constraintPosMax=Vector3()
291         self.constraintRotMin=Vector3()
292         self.constraintRotMax=Vector3()
293         self.springPos=Vector3()
294         self.springRot=Vector3()
295
296
297 class IO(object):
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',
304             'toon_textures',
305             'no_parent_bones',
306             'rigidbodies', 'constraints',
307             ]
308     def __init__(self):
309         self.version=1.0
310         self.name=b"default"
311         self.comment=b"default"
312         self.english_name=b'default'
313         self.english_comment=b'default'
314         self.vertices=[]
315         self.indices=[]
316         self.materials=[]
317         self.bones=[]
318         self.ik_list=[]
319         self.morph_list=[]
320
321         self.face_list=[]
322         self.bone_group_list=[]
323         self.bone_display_list=[]
324
325         self.toon_textures=[
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',
331                 ]
332
333         self.no_parent_bones=[]
334
335         self.rigidbodies=[]
336         self.constraints=[]
337
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
346
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
350     def addVertex(self): 
351         v=Vertex()
352         self.vertices.append(v)
353         return v
354     def addMaterial(self):
355         m=Material()
356         self.materials.append(m)
357         return m
358     def addBone(self):
359         b=Bone()
360         self.bones.append(b)
361         return b
362     def addIK(self):
363         ik=IK()
364         self.ik_list.append(ik)
365         return ik
366     def addMorph(self):
367         s=Skin()
368         self.morph_list.append(s)
369         return s
370     def addBoneGroup(self):
371         g=BoneGroup()
372         self.bone_group_list.append(g)
373         return g
374     def addBoneDisplay(self, b, g):
375         self.bone_display_list.append((b, g))
376
377     def __str__(self):
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))
381
382     def _check_position(self):
383         """
384         if self.pos:
385             print(self.pos, self.io.tell()-self.pos)
386         """
387         self.pos=self.io.tell()
388         pass
389
390     def read(self, path):
391         size=os.path.getsize(path)
392         f=open(path, "rb")
393         return self.load(path, f, size)
394
395     def load(self, path, io, end):
396         self.io=io
397         self.pos=self.io.tell()
398         self.end=end
399         self._check_position()
400
401         if not self._loadHeader():
402             return False
403         self._check_position()
404
405         if not self._loadVertex():
406             return False
407         self._check_position()
408
409         if not self._loadFace():
410             return False
411         self._check_position()
412
413         if not self._loadMaterial():
414             return False
415         self._check_position()
416
417         if not self._loadBone():
418             return False
419         self._check_position()
420
421         if not self._loadIK():
422             return False
423         self._check_position()
424
425         if not self._loadSkin():
426             return False
427         self._check_position()
428
429         if not self._loadSkinIndex():
430             return False
431         self._check_position()
432
433         if not self._loadBoneName():
434             return False
435         self._check_position()
436
437         if not self._loadBoneIndex():
438             return False
439         self._check_position()
440
441         if not self._loadExtend():
442             print('fail to loadExtend')
443             return False
444
445         # 終端
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()))
450
451         # build bone tree
452         for i, child in enumerate(self.bones):
453             if child.parent_index==0xFFFF:
454                 # no parent
455                 self.no_parent_bones.append(child)
456                 child.parent=None
457             else:
458                 # has parent
459                 parent=self.bones[child.parent_index]
460                 child.parent=parent
461                 parent.children.append(child)
462             # 後位置
463             if child.hasChild():
464                 child.tail=self.bones[child.tail_index].pos
465
466         return True
467
468     def write(self, path):
469         io=open(path, 'wb')
470         if not io:
471             return False
472         # Header
473         io.write(b"Pmd")        
474         io.write(struct.pack("f", self.version))
475         io.write(struct.pack("20s", self.name))
476         io.write(struct.pack("256s", self.comment))
477
478         # Vertices
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:
483             data=sVertex.pack( 
484                 v.pos[0], v.pos[1], v.pos[2],
485                 v.normal[0], v.normal[1], v.normal[2],
486                 v.uv[0], v.uv[1],
487                 v.bone0, v.bone1, v.weight0, v.edge_flag)
488             io.write(data)
489
490         # Faces
491         io.write(struct.pack("I", len(self.indices)))
492         io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
493
494         # material
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],
501                 m.shinness, 
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,
505                 m.vertex_count,
506                 m.texture
507                 ))
508
509         # bone
510         io.write(struct.pack("H", len(self.bones)))
511         sBone=struct.Struct("=20sHHBH3f")
512         assert(sBone.size==39)
513         for b in self.bones:
514             io.write(sBone.pack(
515                 b.name,
516                 b.parent_index, b.tail_index, b.type, b.ik_index,
517                 b.pos[0], b.pos[1], b.pos[2]))
518
519         # IK
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
524                 ))
525             for c in ik.children:
526                 io.write(struct.pack("H", c))
527
528         # skin
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]))
535
536         # skin list
537         io.write(struct.pack("B", len(self.face_list)))
538         for i in self.face_list:
539             io.write(struct.pack("H", i))
540
541         # bone name
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))
545
546         # bone list
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))
550
551         # ToDo
552         # Extend Data
553
554         return True
555
556
557     def _loadExtend(self):
558         ############################################################
559         # extend1: english name
560         ############################################################
561         if self.io.tell()>=self.end:
562             return True
563         if struct.unpack("B", self.io.read(1))[0]==1:
564             if not self.loadEnglishName():
565                 return False
566         self._check_position()
567
568         ############################################################
569         # extend2: toon texture list
570         ############################################################
571         if self.io.tell()>=self.end:
572             return True
573         if not self.loadToonTexture():
574             return False
575         self._check_position()
576
577         ############################################################
578         # extend3: physics
579         ############################################################
580         if self.io.tell()>=self.end:
581             return True
582         if not self.loadPhysics():
583             return False
584         self._check_position()
585
586         return True
587
588     def _loadHeader(self):
589         signature=struct.unpack("3s", self.io.read(3))[0]
590         #print(signature)
591         if signature!=b"Pmd":
592             print("invalid signature", signature)
593             return False
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])
598         return True
599
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))))
604         return True
605
606     def _loadFace(self):
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))
610         return True
611
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])
620             # todo sphere map
621             #material.texture=texture.split('*')[0]
622             material.texture=texture
623             self.materials.append(material)
624         return True
625
626     def _loadBone(self):
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)
639         return True
640
641     def _loadIK(self):
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)
651         return True
652
653     def _loadSkin(self):
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)
665         return True
666
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])
671         return True
672
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])))
678         return True
679
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))
686         return True
687
688     def loadToonTexture(self):
689         """
690         100bytex10
691         """
692         for i in xrange(10):
693             self.toon_textures.append(
694                     truncate_zero(struct.unpack("100s", self.io.read(100))[0]))
695         return True
696
697     def loadEnglishName(self):
698         # english name
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])
703         # english bone name
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
708         # english skin list
709         #for index in self.face_list:
710         for skin in self.morph_list:
711             if skin.name=='base':
712                 continue
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
718         # english bone list
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])
722         return True
723
724     def loadPhysics(self):
725         # 剛体リスト
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)
750
751         # ジョイントリスト
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)
783         return True
784