OSDN Git Service

fix for python3
[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         self.pos=self.io.tell()
384
385     def read(self, path):
386         size=os.path.getsize(path)
387         with open(path, "rb") as f:
388             return self.load(path, f, size)
389
390     def load(self, path, io, end):
391         self.io=io
392         self.pos=self.io.tell()
393         self.end=end
394         self._check_position()
395
396         if not self._loadHeader():
397             return False
398         self._check_position()
399
400         if not self._loadVertex():
401             return False
402         self._check_position()
403
404         if not self._loadFace():
405             return False
406         self._check_position()
407
408         if not self._loadMaterial():
409             return False
410         self._check_position()
411
412         if not self._loadBone():
413             return False
414         self._check_position()
415
416         if not self._loadIK():
417             return False
418         self._check_position()
419
420         if not self._loadSkin():
421             return False
422         self._check_position()
423
424         if not self._loadSkinIndex():
425             return False
426         self._check_position()
427
428         if not self._loadBoneName():
429             return False
430         self._check_position()
431
432         if not self._loadBoneIndex():
433             return False
434         self._check_position()
435
436         if not self._loadExtend():
437             print('fail to loadExtend')
438             return False
439
440         # 終端
441         if self.io.tell()!=self.end:
442             print("can not reach eof.")
443             print("current: %d, end: %d, remain: %d" % (
444                     self.io.tell(), self.end, self.end-self.io.tell()))
445
446         # build bone tree
447         for i, child in enumerate(self.bones):
448             if child.parent_index==0xFFFF:
449                 # no parent
450                 self.no_parent_bones.append(child)
451                 child.parent=None
452             else:
453                 # has parent
454                 parent=self.bones[child.parent_index]
455                 child.parent=parent
456                 parent.children.append(child)
457             # 後位置
458             if child.hasChild():
459                 child.tail=self.bones[child.tail_index].pos
460
461         return True
462
463     def write(self, path):
464         io=open(path, 'wb')
465         if not io:
466             return False
467         # Header
468         io.write(b"Pmd")        
469         io.write(struct.pack("f", self.version))
470         io.write(struct.pack("20s", self.name))
471         io.write(struct.pack("256s", self.comment))
472
473         # Vertices
474         io.write(struct.pack("I", len(self.vertices)))
475         sVertex=struct.Struct("=8f2H2B") # 38byte
476         assert(sVertex.size==38)
477         for v in self.vertices:
478             data=sVertex.pack( 
479                 v.pos[0], v.pos[1], v.pos[2],
480                 v.normal[0], v.normal[1], v.normal[2],
481                 v.uv[0], v.uv[1],
482                 v.bone0, v.bone1, v.weight0, v.edge_flag)
483             io.write(data)
484
485         # Faces
486         io.write(struct.pack("I", len(self.indices)))
487         io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
488
489         # material
490         io.write(struct.pack("I", len(self.materials)))
491         sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
492         assert(sMaterial.size==70)
493         for m in self.materials:
494             io.write(sMaterial.pack(
495                 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
496                 m.shinness, 
497                 m.specular[0], m.specular[1], m.specular[2],
498                 m.ambient[0], m.ambient[1], m.ambient[2],
499                 m.toon_index, m.flag,
500                 m.vertex_count,
501                 m.texture
502                 ))
503
504         # bone
505         io.write(struct.pack("H", len(self.bones)))
506         sBone=struct.Struct("=20sHHBH3f")
507         assert(sBone.size==39)
508         for b in self.bones:
509             io.write(sBone.pack(
510                 b.name,
511                 b.parent_index, b.tail_index, b.type, b.ik_index,
512                 b.pos[0], b.pos[1], b.pos[2]))
513
514         # IK
515         io.write(struct.pack("H", len(self.ik_list)))
516         for ik in self.ik_list:
517             io.write(struct.pack("=2HBHf", 
518                 ik.index, ik.target, ik.length, ik.iterations, ik.weight
519                 ))
520             for c in ik.children:
521                 io.write(struct.pack("H", c))
522
523         # skin
524         io.write(struct.pack("H", len(self.morph_list)))
525         for s in self.morph_list:
526             io.write(struct.pack("20sIB", 
527                 s.name, len(s.indices), s.type))
528             for i, v in zip(s.indices, s.pos_list):
529                 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
530
531         # skin list
532         io.write(struct.pack("B", len(self.face_list)))
533         for i in self.face_list:
534             io.write(struct.pack("H", i))
535
536         # bone name
537         io.write(struct.pack("B", len(self.bone_group_list)))
538         for g in self.bone_group_list:
539             io.write(struct.pack("50s", g.name))
540
541         # bone list
542         io.write(struct.pack("I", len(self.bone_display_list)))
543         for l in self.bone_display_list:
544             io.write(struct.pack("=HB", *l))
545
546         return True
547
548
549     def _loadExtend(self):
550         ############################################################
551         # extend1: english name
552         ############################################################
553         if self.io.tell()>=self.end:
554             return True
555         if struct.unpack("B", self.io.read(1))[0]==1:
556             if not self.loadEnglishName():
557                 return False
558         self._check_position()
559
560         ############################################################
561         # extend2: toon texture list
562         ############################################################
563         if self.io.tell()>=self.end:
564             return True
565         if not self.loadToonTexture():
566             return False
567         self._check_position()
568
569         ############################################################
570         # extend3: physics
571         ############################################################
572         if self.io.tell()>=self.end:
573             return True
574         if not self.loadPhysics():
575             return False
576         self._check_position()
577
578         return True
579
580     def _loadHeader(self):
581         signature=struct.unpack("3s", self.io.read(3))[0]
582         if signature!=b"Pmd":
583             print("invalid signature", signature)
584             return False
585         self.version=struct.unpack("f", self.io.read(4))[0]
586         self.name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
587         self.comment = truncate_zero(
588                 struct.unpack("256s", self.io.read(256))[0])
589         return True
590
591     def _loadVertex(self):
592         count = struct.unpack("I", self.io.read(4))[0]
593         for i in xrange(count):
594             self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
595         return True
596
597     def _loadFace(self):
598         count = struct.unpack("I", self.io.read(4))[0]
599         for i in xrange(0, count, 3):
600             self.indices+=struct.unpack("HHH", self.io.read(6))
601         return True
602
603     def _loadMaterial(self):
604         count = struct.unpack("I", self.io.read(4))[0]
605         for i in xrange(count):
606             material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
607             material.toon_index=struct.unpack("B", self.io.read(1))[0]
608             material.flag=struct.unpack("B", self.io.read(1))[0]
609             material.vertex_count=struct.unpack("I", self.io.read(4))[0]
610             texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
611             # todo sphere map
612             #material.texture=texture.split('*')[0]
613             material.texture=texture
614             self.materials.append(material)
615         return True
616
617     def _loadBone(self):
618         size = struct.unpack("H", self.io.read(2))[0]
619         for i in xrange(size):
620             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
621             parent_index, tail_index = struct.unpack("HH", self.io.read(4))
622             type = struct.unpack("B", self.io.read(1))[0]
623             bone=createBone(name, type)
624             bone.parent_index=parent_index
625             bone.tail_index=tail_index
626             bone.ik_index = struct.unpack("H", self.io.read(2))[0]
627             bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
628             bone.english_name="bone%03d" % len(self.bones)
629             self.bones.append(bone)
630         return True
631
632     def _loadIK(self):
633         size = struct.unpack("H", self.io.read(2))[0]
634         for i in xrange(size):
635             ik=IK(*struct.unpack("2H", self.io.read(4)))
636             ik.length = struct.unpack("B", self.io.read(1))[0]
637             ik.iterations = struct.unpack("H", self.io.read(2))[0]
638             ik.weight = struct.unpack("f", self.io.read(4))[0]
639             for j in xrange(ik.length):
640                 ik.children.append(struct.unpack("H", self.io.read(2))[0])
641             self.ik_list.append(ik)
642         return True
643
644     def _loadSkin(self):
645         size = struct.unpack("H", self.io.read(2))[0]
646         for i in xrange(size):
647             skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
648             skin_size = struct.unpack("I", self.io.read(4))[0]
649             skin.type = struct.unpack("B", self.io.read(1))[0]
650             for j in xrange(skin_size):
651                 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
652                 skin.pos_list.append(
653                         Vector3(*struct.unpack("3f", self.io.read(12))))
654             skin.english_name="skin%03d" % len(self.morph_list)
655             self.morph_list.append(skin)
656         return True
657
658     def _loadSkinIndex(self):
659         size = struct.unpack("B", self.io.read(1))[0]
660         for i in xrange(size):
661             self.face_list.append(struct.unpack("H", self.io.read(2))[0])
662         return True
663
664     def _loadBoneName(self):
665         size = struct.unpack("B", self.io.read(1))[0]
666         for i in xrange(size):
667             self.bone_group_list.append(BoneGroup(
668                 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
669         return True
670
671     def _loadBoneIndex(self):
672         size = struct.unpack("I", self.io.read(4))[0]
673         for i in xrange(size):
674             first=struct.unpack("H", self.io.read(2))[0]
675             second=struct.unpack("B", self.io.read(1))[0]
676             self.bone_display_list.append((first, second))
677         return True
678
679     def loadToonTexture(self):
680         """
681         100bytex10
682         """
683         for i in xrange(10):
684             self.toon_textures.append(
685                     truncate_zero(struct.unpack("100s", self.io.read(100))[0]))
686         return True
687
688     def loadEnglishName(self):
689         # english name
690         self.english_name=truncate_zero(
691                 struct.unpack("20s", self.io.read(20))[0])
692         self.english_comment=truncate_zero(
693                 struct.unpack("256s", self.io.read(256))[0])
694         self._check_position()
695         # english bone name
696         for bone in self.bones:
697             english_name=truncate_zero(
698                     struct.unpack("20s", self.io.read(20))[0])
699             bone.english_name=english_name
700         self._check_position()
701         # english skin list
702         for skin in self.morph_list:
703             if skin.name=='base':
704                 continue
705             english_name=truncate_zero(
706                     struct.unpack("20s", self.io.read(20))[0])
707             #skin=self.morph_list[index]
708             if english_name!=skin.name:
709                 skin.english_name=english_name
710         self._check_position()
711         # english bone list
712         for i in xrange(0, len(self.bone_group_list)):
713             self.bone_group_list[i].english_name=truncate_zero(
714                     struct.unpack("50s", self.io.read(50))[0])
715         self._check_position()
716         return True
717
718     def loadPhysics(self):
719         # 剛体リスト
720         count = struct.unpack("I", self.io.read(4))[0]
721         for i in xrange(count):
722             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
723             rigidbody=RigidBody(name)
724             rigidbody.boneIndex=struct.unpack("H", self.io.read(2))[0]
725             rigidbody.group=struct.unpack("B", self.io.read(1))[0]
726             rigidbody.target=struct.unpack("H", self.io.read(2))[0]
727             rigidbody.shapeType=struct.unpack("B", self.io.read(1))[0]
728             rigidbody.w=struct.unpack("f", self.io.read(4))[0]
729             rigidbody.h=struct.unpack("f", self.io.read(4))[0]
730             rigidbody.d=struct.unpack("f", self.io.read(4))[0]
731             rigidbody.position.x=struct.unpack("f", self.io.read(4))[0]
732             rigidbody.position.y=struct.unpack("f", self.io.read(4))[0]
733             rigidbody.position.z=struct.unpack("f", self.io.read(4))[0]
734             rigidbody.rotation.x=struct.unpack("f", self.io.read(4))[0]
735             rigidbody.rotation.y=struct.unpack("f", self.io.read(4))[0]
736             rigidbody.rotation.z=struct.unpack("f", self.io.read(4))[0]
737             rigidbody.weight=struct.unpack("f", self.io.read(4))[0]
738             rigidbody.linearDamping=struct.unpack("f", self.io.read(4))[0]
739             rigidbody.angularDamping=struct.unpack("f", self.io.read(4))[0]
740             rigidbody.restitution=struct.unpack("f", self.io.read(4))[0]
741             rigidbody.friction=struct.unpack("f", self.io.read(4))[0]
742             rigidbody.processType=struct.unpack("B", self.io.read(1))[0]
743             self.rigidbodies.append(rigidbody)
744         self._check_position()
745
746         # ジョイントリスト
747         count = struct.unpack("I", self.io.read(4))[0]
748         for i in xrange(count):
749             name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
750             constraint=Constraint(name)
751             constraint.rigidA=struct.unpack("I", self.io.read(4))[0]
752             constraint.rigidB=struct.unpack("I", self.io.read(4))[0]
753             constraint.pos.x=struct.unpack("f", self.io.read(4))[0]
754             constraint.pos.y=struct.unpack("f", self.io.read(4))[0]
755             constraint.pos.z=struct.unpack("f", self.io.read(4))[0]
756             constraint.rot.x=struct.unpack("f", self.io.read(4))[0]
757             constraint.rot.y=struct.unpack("f", self.io.read(4))[0]
758             constraint.rot.z=struct.unpack("f", self.io.read(4))[0]
759             constraint.constraintPosMin.x=struct.unpack("f", self.io.read(4))[0]
760             constraint.constraintPosMin.y=struct.unpack("f", self.io.read(4))[0]
761             constraint.constraintPosMin.z=struct.unpack("f", self.io.read(4))[0]
762             constraint.constraintPosMax.x=struct.unpack("f", self.io.read(4))[0]
763             constraint.constraintPosMax.y=struct.unpack("f", self.io.read(4))[0]
764             constraint.constraintPosMax.z=struct.unpack("f", self.io.read(4))[0]
765             constraint.constraintRotMin.x=struct.unpack("f", self.io.read(4))[0]
766             constraint.constraintRotMin.y=struct.unpack("f", self.io.read(4))[0]
767             constraint.constraintRotMin.z=struct.unpack("f", self.io.read(4))[0]
768             constraint.constraintRotMax.x=struct.unpack("f", self.io.read(4))[0]
769             constraint.constraintRotMax.y=struct.unpack("f", self.io.read(4))[0]
770             constraint.constraintRotMax.z=struct.unpack("f", self.io.read(4))[0]
771             constraint.springPos.x=struct.unpack("f", self.io.read(4))[0]
772             constraint.springPos.y=struct.unpack("f", self.io.read(4))[0]
773             constraint.springPos.z=struct.unpack("f", self.io.read(4))[0]
774             constraint.springRot.x=struct.unpack("f", self.io.read(4))[0]
775             constraint.springRot.y=struct.unpack("f", self.io.read(4))[0]
776             constraint.springRot.z=struct.unpack("f", self.io.read(4))[0]
777             self.constraints.append(constraint)
778         self._check_position()
779
780         return True
781