7 ###############################################################################
9 ###############################################################################
10 if sys.version_info[0]<3:
11 def encode_string(src):
14 return src.encode('cp932')
18 raise "INVALID str: %s" % t
21 def encode_string(src):
26 return src.decode('cp932')
28 raise "INVALID str: %s" % t
32 __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag']
33 def __init__(self, x=0, y=0, z=0, nx=0, ny=0, nz=0, u=0, v=0,
34 bone0=0, bone1=0, weight0=0, edge_flag=0):
35 self.pos=Vector3(x, y, z)
36 self.normal=Vector3(nx, ny, nz)
41 self.edge_flag=edge_flag
44 return "<%s %s %s, (%d, %d, %d)>" % (str(self.pos), str(self.normal), str(self.uv), self.bone0, self.bone1, self.weight0)
46 def __getitem__(self, key):
57 class Material(object):
59 'diffuse', 'shinness', 'specular',
60 'ambient', 'vertex_count', '_texture', 'toon_index', 'flag',
62 def getTexture(self): return self._texture
63 def setTexture(self, texture): self._texture=encode_string(texture)
64 texture=property(getTexture, setTexture)
66 def __init__(self, dr=0, dg=0, db=0, alpha=1,
67 specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0):
68 self.diffuse=RGBA(dr, dg, db, alpha)
69 self.specular=RGBA(sr, sg, sb)
70 self.shinness=specular
71 self.ambient=RGBA(ar, ag, ab)
78 return "<Material [%f, %f, %f, %f]>" % (
79 self.diffuse[0], self.diffuse[1],
80 self.diffuse[2], self.diffuse[3],
84 # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ
86 def material_per_face(materials):
88 for x in range(int(m.vertex_count/3)):
104 __slots__=['_name', 'index', 'type', 'parent', 'ik', 'pos',
105 'children', '_english_name', 'ik_index',
106 'parent_index', 'tail_index', 'tail',
108 def getName(self): return self._name
109 def setName(self, name): self._name=encode_string(name)
110 name=property(getName, setName)
111 def getEnglishName(self): return self._english_name
112 def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
113 english_name=property(getEnglishName, setEnglishName)
115 def __init__(self, name='bone', type=0):
119 self.parent_index=0xFFFF
121 self.tail=Vector3(0, 0, 0)
124 self.pos=Vector3(0, 0, 0)
129 return self.parent_index!=0xFFFF
132 return self.tail_index!=0
134 def display(self, indent=[]):
137 for i, is_end in enumerate(indent):
141 prefix+=' ' if is_end else ' |'
142 uni='%s +%s(%s)' % (prefix, unicode(self), self.english_name)
143 print(uni.encode(ENCODING))
145 uni='%s(%s)' % (unicode(self), self.english_name)
146 print(uni.encode(ENCODING))
148 child_count=len(self.children)
149 for i in range(child_count):
150 child=self.children[i]
152 child.display(indent+[False])
155 child.display(indent+[True])
158 class Bone_Rotate(Bone):
160 def __init__(self, name):
161 super(Bone_Rotate, self).__init__(name, 0)
163 return '<ROTATE %s>' % (self.name)
165 class Bone_RotateMove(Bone):
167 def __init__(self, name):
168 super(Bone_RotateMove, self).__init__(name, 1)
170 return '<ROTATE_MOVE %s>' % (self.name)
174 def __init__(self, name):
175 super(Bone_IK, self).__init__(name, 2)
177 return '<IK %s>' % (self.name)
179 class Bone_IKRotateInfl(Bone):
181 def __init__(self, name):
182 super(Bone_IKRotateInfl, self).__init__(name, 4)
184 return '<IK_ROTATE_INFL %s>' % (self.name)
186 class Bone_RotateInfl(Bone):
188 def __init__(self, name):
189 super(Bone_RotateInfl, self).__init__(name, 5)
191 return '<ROTATE_INFL %s>' % (self.name)
193 class Bone_IKTarget(Bone):
195 def __init__(self, name):
196 super(Bone_IKTarget, self).__init__(name, 6)
198 return '<IK_TARGET %s>' % (self.name)
200 class Bone_Unvisible(Bone):
202 def __init__(self, name):
203 super(Bone_Unvisible, self).__init__(name, 7)
205 return '<UNVISIBLE %s>' % (self.name)
207 class Bone_Rolling(Bone):
209 def __init__(self, name):
210 super(Bone_Rolling, self).__init__(name, 8)
212 return '<ROLLING %s>' % (self.name)
214 class Bone_Tweak(Bone):
216 def __init__(self, name):
217 super(Bone_Tweak, self).__init__(name, 9)
219 return '<TWEAK %s>' % (self.name)
222 def createBone(name, type):
224 return Bone_Rotate(name)
226 return Bone_RotateMove(name)
230 raise Exception("no used bone type: 3(%s)" % name)
232 return Bone_IKRotateInfl(name)
234 return Bone_RotateInfl(name)
236 return Bone_IKTarget(name)
238 return Bone_Unvisible(name)
240 return Bone_Rolling(name)
242 return Bone_Tweak(name)
244 raise Exception("unknown bone type: %d(%s)", type, name)
248 __slots__=['index', 'target', 'iterations', 'weight', 'length', 'children']
249 def __init__(self, index=0, target=0):
257 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))
261 __slots__=['_name', 'type', 'indices', 'pos_list', '_english_name',
263 def getName(self): return self._name
264 def setName(self, name): self._name=encode_string(name)
265 name=property(getName, setName)
266 def getEnglishName(self): return self._english_name
267 def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
268 english_name=property(getEnglishName, setEnglishName)
270 def __init__(self, name='skin'):
278 def append(self, index, x, y, z):
279 self.indices.append(index)
280 self.pos_list.append(Vector3(x, y, z))
283 return '<Skin name: "%s", type: %d, vertex: %d>' % (
284 self.name, self.type, len(self.indices))
287 class BoneGroup(object):
288 __slots__=['_name', '_english_name']
289 def getName(self): return self._name
290 def setName(self, name): self._name=encode_string(name)
291 name=property(getName, setName)
292 def getEnglishName(self): return self._english_name
293 def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
294 english_name=property(getEnglishName, setEnglishName)
296 def __init__(self, name='group'): self._name=name; self._english_name='center'
303 RIGIDBODY_KINEMATICS=0
305 RIGIDBODY_PHYSICS_WITH_BONE=2
308 class RigidBody(object):
309 __slots__=['_name', 'boneIndex', 'group', 'target', 'shapeType',
310 'w', 'h', 'd', 'position', 'rotation', 'weight',
311 'linearDamping', 'angularDamping', 'restitution', 'friction', 'processType'
313 def getName(self): return self._name
314 def setName(self, name): self._name=encode_string(name)
315 name=property(getName, setName)
317 def __init__(self, name):
319 self.position=Vector3()
320 self.rotation=Vector3()
323 class Constraint(object):
324 __slots__=[ '_name', 'rigidA', 'rigidB', 'pos', 'rot',
325 'constraintPosMin', 'constraintPosMax',
326 'constraintRotMin', 'constraintRotMax',
327 'springPos', 'springRot',
329 def getName(self): return self._name
330 def setName(self, name): self._name=encode_string(name)
331 name=property(getName, setName)
333 def __init__(self, name):
337 self.constraintPosMin=Vector3()
338 self.constraintPosMax=Vector3()
339 self.constraintRotMin=Vector3()
340 self.constraintRotMax=Vector3()
341 self.springPos=Vector3()
342 self.springRot=Vector3()
345 class ToonTextures(object):
346 __slots__=['_toon_textures']
348 self._toon_textures=[]
350 self._toon_textures.append('toon%02d.bmp' % (i+1))
352 def __getitem__(self, key):
353 return self._toon_textures[key]
355 def __setitem__(self, key, value):
356 self._toon_textures[key]=encode_string(value)
362 for toon_texture in self._toon_textures:
367 __slots__=['io', 'end', 'pos',
368 'version', '_name', '_comment',
369 '_english_name', '_english_comment',
370 'vertices', 'indices', 'materials', 'bones',
371 'ik_list', 'morph_list',
372 'face_list', 'bone_group_list', 'bone_display_list',
375 'rigidbodies', 'constraints',
377 def getName(self): return self._name
378 def setName(self, name): self._name=encode_string(name)
379 name=property(getName, setName)
380 def getEnglishName(self): return self._english_name
381 def setEnglishName(self, english_name): self._english_name=encode_string(english_name)
382 english_name=property(getEnglishName, setEnglishName)
383 def getComment(self): return self._comment
384 def setComment(self, comment): self._comment=encode_string(comment)
385 comment=property(getComment, setComment)
386 def getEnglishComment(self): return self._english_comment
387 def setEnglishComment(self, english_comment): self._english_comment=encode_string(english_comment)
388 english_comment=property(getEnglishComment, setEnglishComment)
393 self.comment='default'
394 self.english_name='default'
395 self.english_comment='default'
403 self.bone_group_list=[]
404 self.bone_display_list=[]
406 self.toon_textures=ToonTextures()
410 self.no_parent_bones=[]
412 def each_vertex(self): return self.vertices
413 def getUV(self, i): return self.vertices[i].uv
416 self.vertices.append(v)
418 def addMaterial(self):
420 self.materials.append(m)
428 self.ik_list.append(ik)
432 self.morph_list.append(s)
434 def addBoneGroup(self):
436 self.bone_group_list.append(g)
438 def addBoneDisplay(self, b, g):
439 self.bone_display_list.append((b, g))
442 return '<PMDLoader version: %g, model: "%s", vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
443 self.version, self.name, len(self.vertices), len(self.indices),
444 len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
446 def _check_position(self):
447 self.pos=self.io.tell()
449 def read(self, path):
450 size=os.path.getsize(path)
451 with open(path, "rb") as f:
452 return self.load(path, f, size)
454 def load(self, path, io, end):
456 self.pos=self.io.tell()
458 self._check_position()
460 if not self._loadHeader():
462 self._check_position()
464 if not self._loadVertex():
466 self._check_position()
468 if not self._loadFace():
470 self._check_position()
472 if not self._loadMaterial():
474 self._check_position()
476 if not self._loadBone():
478 self._check_position()
480 if not self._loadIK():
482 self._check_position()
484 if not self._loadSkin():
486 self._check_position()
488 if not self._loadSkinIndex():
490 self._check_position()
492 if not self._loadBoneName():
494 self._check_position()
496 if not self._loadBoneIndex():
498 self._check_position()
500 if not self._loadExtend():
501 print('fail to loadExtend')
505 if self.io.tell()!=self.end:
506 print("can not reach eof.")
507 print("current: %d, end: %d, remain: %d" % (
508 self.io.tell(), self.end, self.end-self.io.tell()))
511 for i, child in enumerate(self.bones):
512 if child.parent_index==0xFFFF:
514 self.no_parent_bones.append(child)
518 parent=self.bones[child.parent_index]
520 parent.children.append(child)
523 child.tail=self.bones[child.tail_index].pos
527 def write(self, path):
533 io.write(struct.pack("f", self.version))
534 io.write(struct.pack("20s", self.name))
535 io.write(struct.pack("256s", self.comment))
538 io.write(struct.pack("I", len(self.vertices)))
539 sVertex=struct.Struct("=8f2H2B") # 38byte
540 assert(sVertex.size==38)
541 for v in self.vertices:
543 v.pos[0], v.pos[1], v.pos[2],
544 v.normal[0], v.normal[1], v.normal[2],
546 v.bone0, v.bone1, v.weight0, v.edge_flag)
550 io.write(struct.pack("I", len(self.indices)))
551 io.write(struct.pack("=%dH" % len(self.indices), *self.indices))
554 io.write(struct.pack("I", len(self.materials)))
555 sMaterial=struct.Struct("=3fff3f3fBBI20s") # 70byte
556 assert(sMaterial.size==70)
557 for m in self.materials:
558 io.write(sMaterial.pack(
559 m.diffuse[0], m.diffuse[1], m.diffuse[2], m.diffuse[3],
561 m.specular[0], m.specular[1], m.specular[2],
562 m.ambient[0], m.ambient[1], m.ambient[2],
563 m.toon_index, m.flag,
569 io.write(struct.pack("H", len(self.bones)))
570 sBone=struct.Struct("=20sHHBH3f")
571 assert(sBone.size==39)
575 b.parent_index, b.tail_index, b.type, b.ik_index,
576 b.pos[0], b.pos[1], b.pos[2]))
579 io.write(struct.pack("H", len(self.ik_list)))
580 for ik in self.ik_list:
581 io.write(struct.pack("=2HBHf",
582 ik.index, ik.target, ik.length, ik.iterations, ik.weight
584 for c in ik.children:
585 io.write(struct.pack("H", c))
588 io.write(struct.pack("H", len(self.morph_list)))
589 for s in self.morph_list:
590 io.write(struct.pack("20sIB",
591 s.name, len(s.indices), s.type))
592 for i, v in zip(s.indices, s.pos_list):
593 io.write(struct.pack("I3f", i, v[0], v[1], v[2]))
596 io.write(struct.pack("B", len(self.face_list)))
597 for i in self.face_list:
598 io.write(struct.pack("H", i))
601 io.write(struct.pack("B", len(self.bone_group_list)))
602 for g in self.bone_group_list:
603 io.write(struct.pack("50s", g.name))
605 io.write(struct.pack("I", len(self.bone_display_list)))
606 for l in self.bone_display_list:
607 io.write(struct.pack("=HB", *l))
609 ############################################################
611 ############################################################
612 io.write(struct.pack("B", 1))
614 io.write(struct.pack("=20s", self.english_name))
615 io.write(struct.pack("=256s", self.english_comment))
617 for bone in self.bones:
618 io.write(struct.pack("=20s", bone.english_name))
620 for skin in self.morph_list:
622 if skin.name==b'base':
624 io.write(struct.pack("=20s", skin.english_name))
626 for bone_group in self.bone_group_list:
627 io.write(struct.pack("50s", bone_group.english_name))
629 for toon_texture in self.toon_textures:
630 io.write(struct.pack("=100s", toon_texture))
632 io.write(struct.pack("I", len(self.rigidbodies)))
633 for r in self.rigidbodies:
634 io.write(struct.pack("=20sHBHB14fB",
635 r.name, r.boneIndex, r.group, r.target, r.shapeType,
637 r.position.x, r.position.y, r.position.z,
638 r.rotation.x, r.rotation.y, r.rotation.z,
640 r.linearDamping, r.angularDamping, r.restitution,
641 r.friction, r.processType))
644 io.write(struct.pack("I", len(self.constraints)))
645 for c in self.constraints:
646 io.write(struct.pack("=20sII24f",
647 c.name, c.rigidA, c.rigidB,
648 c.pos.x, c.pos.y, c.pos.z,
649 c.rot.x, c.rot.y, c.rot.z,
650 c.constraintPosMin.x, c.constraintPosMin.y, c.constraintPosMin.z,
651 c.constraintPosMax.x, c.constraintPosMax.y, c.constraintPosMax.z,
652 c.constraintRotMin.x, c.constraintRotMin.y, c.constraintRotMin.z,
653 c.constraintRotMax.x, c.constraintRotMax.y, c.constraintRotMax.z,
654 c.springPos.x, c.springPos.y, c.springPos.z,
655 c.springRot.x, c.springRot.y, c.springRot.z
661 def _loadExtend(self):
662 ############################################################
663 # extend1: english name
664 ############################################################
665 if self.io.tell()>=self.end:
667 if struct.unpack("B", self.io.read(1))[0]==1:
668 if not self.loadEnglishName():
670 self._check_position()
672 ############################################################
673 # extend2: toon texture list
674 ############################################################
675 if self.io.tell()>=self.end:
677 if not self.loadToonTexture():
679 self._check_position()
681 ############################################################
683 ############################################################
684 if self.io.tell()>=self.end:
686 if not self.loadPhysics():
688 self._check_position()
692 def _loadHeader(self):
693 signature=struct.unpack("3s", self.io.read(3))[0]
694 if signature!=b"Pmd":
695 print("invalid signature", signature)
697 self.version=struct.unpack("f", self.io.read(4))[0]
698 self.name = truncate_zero(struct.unpack("20s", self.io.read(20))[0])
699 self.comment = truncate_zero(
700 struct.unpack("256s", self.io.read(256))[0])
703 def _loadVertex(self):
704 count = struct.unpack("I", self.io.read(4))[0]
705 for i in range(count):
706 self.vertices.append(Vertex(*struct.unpack("8f2H2B", self.io.read(38))))
710 count = struct.unpack("I", self.io.read(4))[0]
711 for i in range(0, count, 3):
712 self.indices+=struct.unpack("HHH", self.io.read(6))
715 def _loadMaterial(self):
716 count = struct.unpack("I", self.io.read(4))[0]
717 for i in range(count):
718 material=Material(*struct.unpack("4ff3f3f", self.io.read(44)))
719 material.toon_index=struct.unpack("B", self.io.read(1))[0]
720 material.flag=struct.unpack("B", self.io.read(1))[0]
721 material.vertex_count=struct.unpack("I", self.io.read(4))[0]
722 texture=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
724 #material.texture=texture.split('*')[0]
725 material.texture=texture
726 self.materials.append(material)
730 size = struct.unpack("H", self.io.read(2))[0]
731 for i in range(size):
732 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
733 parent_index, tail_index = struct.unpack("HH", self.io.read(4))
734 type = struct.unpack("B", self.io.read(1))[0]
735 bone=createBone(name, type)
736 bone.parent_index=parent_index
737 bone.tail_index=tail_index
738 bone.ik_index = struct.unpack("H", self.io.read(2))[0]
739 bone.pos = Vector3(*struct.unpack("3f", self.io.read(12)))
740 bone.english_name="bone%03d" % len(self.bones)
741 self.bones.append(bone)
745 size = struct.unpack("H", self.io.read(2))[0]
746 for i in range(size):
747 ik=IK(*struct.unpack("2H", self.io.read(4)))
748 ik.length = struct.unpack("B", self.io.read(1))[0]
749 ik.iterations = struct.unpack("H", self.io.read(2))[0]
750 ik.weight = struct.unpack("f", self.io.read(4))[0]
751 for j in range(ik.length):
752 ik.children.append(struct.unpack("H", self.io.read(2))[0])
753 self.ik_list.append(ik)
757 size = struct.unpack("H", self.io.read(2))[0]
758 for i in range(size):
759 skin=Skin(truncate_zero(struct.unpack("20s", self.io.read(20))[0]))
760 skin_size = struct.unpack("I", self.io.read(4))[0]
761 skin.type = struct.unpack("B", self.io.read(1))[0]
762 for j in range(skin_size):
763 skin.indices.append(struct.unpack("I", self.io.read(4))[0])
764 skin.pos_list.append(
765 Vector3(*struct.unpack("3f", self.io.read(12))))
766 skin.english_name="skin%03d" % len(self.morph_list)
767 self.morph_list.append(skin)
770 def _loadSkinIndex(self):
771 size = struct.unpack("B", self.io.read(1))[0]
772 for i in range(size):
773 self.face_list.append(struct.unpack("H", self.io.read(2))[0])
776 def _loadBoneName(self):
777 size = struct.unpack("B", self.io.read(1))[0]
778 for i in range(size):
779 self.bone_group_list.append(BoneGroup(
780 truncate_zero(struct.unpack("50s", self.io.read(50))[0])))
783 def _loadBoneIndex(self):
784 size = struct.unpack("I", self.io.read(4))[0]
785 for i in range(size):
786 first=struct.unpack("H", self.io.read(2))[0]
787 second=struct.unpack("B", self.io.read(1))[0]
788 self.bone_display_list.append((first, second))
791 def loadToonTexture(self):
796 self.toon_textures[i]=truncate_zero(struct.unpack("100s", self.io.read(100))[0])
799 def loadEnglishName(self):
801 self.english_name=truncate_zero(
802 struct.unpack("20s", self.io.read(20))[0])
803 self.english_comment=truncate_zero(
804 struct.unpack("256s", self.io.read(256))[0])
805 self._check_position()
807 for bone in self.bones:
808 english_name=truncate_zero(
809 struct.unpack("20s", self.io.read(20))[0])
810 bone.english_name=english_name
811 self._check_position()
813 for skin in self.morph_list:
814 if skin.name=='base':
816 english_name=truncate_zero(
817 struct.unpack("20s", self.io.read(20))[0])
818 #skin=self.morph_list[index]
819 if english_name!=skin.name:
820 skin.english_name=english_name
821 self._check_position()
823 for i in range(0, len(self.bone_group_list)):
824 self.bone_group_list[i].english_name=truncate_zero(
825 struct.unpack("50s", self.io.read(50))[0])
826 self._check_position()
829 def loadPhysics(self):
831 count = struct.unpack("I", self.io.read(4))[0]
832 for i in range(count):
833 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
834 rigidbody=RigidBody(name)
835 rigidbody.boneIndex=struct.unpack("H", self.io.read(2))[0]
836 rigidbody.group=struct.unpack("B", self.io.read(1))[0]
837 rigidbody.target=struct.unpack("H", self.io.read(2))[0]
838 rigidbody.shapeType=struct.unpack("B", self.io.read(1))[0]
839 rigidbody.w=struct.unpack("f", self.io.read(4))[0]
840 rigidbody.h=struct.unpack("f", self.io.read(4))[0]
841 rigidbody.d=struct.unpack("f", self.io.read(4))[0]
842 rigidbody.position.x=struct.unpack("f", self.io.read(4))[0]
843 rigidbody.position.y=struct.unpack("f", self.io.read(4))[0]
844 rigidbody.position.z=struct.unpack("f", self.io.read(4))[0]
845 rigidbody.rotation.x=struct.unpack("f", self.io.read(4))[0]
846 rigidbody.rotation.y=struct.unpack("f", self.io.read(4))[0]
847 rigidbody.rotation.z=struct.unpack("f", self.io.read(4))[0]
848 rigidbody.weight=struct.unpack("f", self.io.read(4))[0]
849 rigidbody.linearDamping=struct.unpack("f", self.io.read(4))[0]
850 rigidbody.angularDamping=struct.unpack("f", self.io.read(4))[0]
851 rigidbody.restitution=struct.unpack("f", self.io.read(4))[0]
852 rigidbody.friction=struct.unpack("f", self.io.read(4))[0]
853 rigidbody.processType=struct.unpack("B", self.io.read(1))[0]
854 self.rigidbodies.append(rigidbody)
855 self._check_position()
858 count = struct.unpack("I", self.io.read(4))[0]
859 for i in range(count):
860 name=truncate_zero(struct.unpack("20s", self.io.read(20))[0])
861 constraint=Constraint(name)
862 constraint.rigidA=struct.unpack("I", self.io.read(4))[0]
863 constraint.rigidB=struct.unpack("I", self.io.read(4))[0]
864 constraint.pos.x=struct.unpack("f", self.io.read(4))[0]
865 constraint.pos.y=struct.unpack("f", self.io.read(4))[0]
866 constraint.pos.z=struct.unpack("f", self.io.read(4))[0]
867 constraint.rot.x=struct.unpack("f", self.io.read(4))[0]
868 constraint.rot.y=struct.unpack("f", self.io.read(4))[0]
869 constraint.rot.z=struct.unpack("f", self.io.read(4))[0]
870 constraint.constraintPosMin.x=struct.unpack("f", self.io.read(4))[0]
871 constraint.constraintPosMin.y=struct.unpack("f", self.io.read(4))[0]
872 constraint.constraintPosMin.z=struct.unpack("f", self.io.read(4))[0]
873 constraint.constraintPosMax.x=struct.unpack("f", self.io.read(4))[0]
874 constraint.constraintPosMax.y=struct.unpack("f", self.io.read(4))[0]
875 constraint.constraintPosMax.z=struct.unpack("f", self.io.read(4))[0]
876 constraint.constraintRotMin.x=struct.unpack("f", self.io.read(4))[0]
877 constraint.constraintRotMin.y=struct.unpack("f", self.io.read(4))[0]
878 constraint.constraintRotMin.z=struct.unpack("f", self.io.read(4))[0]
879 constraint.constraintRotMax.x=struct.unpack("f", self.io.read(4))[0]
880 constraint.constraintRotMax.y=struct.unpack("f", self.io.read(4))[0]
881 constraint.constraintRotMax.z=struct.unpack("f", self.io.read(4))[0]
882 constraint.springPos.x=struct.unpack("f", self.io.read(4))[0]
883 constraint.springPos.y=struct.unpack("f", self.io.read(4))[0]
884 constraint.springPos.z=struct.unpack("f", self.io.read(4))[0]
885 constraint.springRot.x=struct.unpack("f", self.io.read(4))[0]
886 constraint.springRot.y=struct.unpack("f", self.io.read(4))[0]
887 constraint.springRot.z=struct.unpack("f", self.io.read(4))[0]
888 self.constraints.append(constraint)
889 self._check_position()