3 from .. import common
\r
7 class Reader(common.BinaryReader):
\r
10 def __init__(self, ios, version):
\r
11 super(Reader, self).__init__(ios)
\r
12 self.version=version
\r
14 def read_text(self, size):
\r
17 src=self.unpack("%ds" % size, size)
\r
18 assert(type(src)==bytes)
\r
19 pos = src.find(b"\x00")
\r
25 def read_vertex(self):
\r
27 self.read_vector3(),
\r
28 self.read_vector3(),
\r
29 self.read_vector2(),
\r
35 def read_material(self):
\r
36 return pmd.Material(
\r
37 diffuse_color=self.read_rgb(),
\r
38 alpha=self.read_float(),
\r
39 specular_factor=self.read_float(),
\r
40 specular_color=self.read_rgb(),
\r
41 ambient_color=self.read_rgb(),
\r
42 toon_index=self.read_uint(1),
\r
43 edge_flag=self.read_uint(1),
\r
44 vertex_count=self.read_uint(4),
\r
45 texture_file=self.read_text(20)
\r
48 def read_bone(self):
\r
49 name=self.read_text(20)
\r
50 parent_index=self.read_uint(2)
\r
51 tail_index=self.read_uint(2)
\r
52 bone=pmd.createBone(name, self.read_uint(1))
\r
53 bone.parent_index=parent_index
\r
54 bone.tail_index=tail_index
\r
55 bone.ik_index = self.read_uint(2)
\r
56 bone.pos = self.read_vector3()
\r
60 ik=pmd.IK(self.read_uint(2), self.read_uint(2))
\r
61 ik.length = self.read_uint(1)
\r
62 ik.iterations = self.read_uint(2)
\r
63 ik.weight = self.read_float()
\r
64 ik.children=[self.read_uint(2) for _ in range(ik.length)]
\r
67 def read_morph(self):
\r
68 morph=pmd.Morph(self.read_text(20))
\r
69 morph_size = self.read_uint(4)
\r
70 morph.type = self.read_uint(1)
\r
71 for j in range(morph_size):
\r
72 morph.indices.append(self.read_uint(4))
\r
73 morph.pos_list.append(self.read_vector3())
\r
76 def read_rigidbody(self):
\r
77 return pmd.RigidBody(
\r
78 name=self.read_text(20),
\r
79 bone_index=self.read_uint(2),
\r
80 collision_group=self.read_uint(1),
\r
81 no_collision_group=self.read_uint(2),
\r
82 shape_type=self.read_uint(1),
\r
83 shape_size=self.read_vector3(),
\r
84 shape_position=self.read_vector3(),
\r
85 shape_rotation=self.read_vector3(),
\r
86 mass=self.read_float(),
\r
87 linear_damping=self.read_float(),
\r
88 angular_damping=self.read_float(),
\r
89 restitution=self.read_float(),
\r
90 friction=self.read_float(),
\r
91 mode=self.read_uint(1)
\r
94 def read_joint(self):
\r
96 name=self.read_text(20),
\r
97 rigidbody_index_a=self.read_uint(4),
\r
98 rigidbody_index_b=self.read_uint(4),
\r
99 position=self.read_vector3(),
\r
100 rotation=self.read_vector3(),
\r
101 translation_limit_min=self.read_vector3(),
\r
102 translation_limit_max=self.read_vector3(),
\r
103 rotation_limit_min=self.read_vector3(),
\r
104 rotation_limit_max=self.read_vector3(),
\r
105 spring_constant_translation=self.read_vector3(),
\r
106 spring_constant_rotation=self.read_vector3())
\r
110 def __read(reader, model):
\r
112 model.name=reader.read_text(20)
\r
113 model.comment=reader.read_text(256)
\r
116 model.vertices=[reader.read_vertex()
\r
117 for _ in range(reader.read_uint(4))]
\r
118 model.indices=[reader.read_uint(2)
\r
119 for _ in range(reader.read_uint(4))]
\r
120 model.materials=[reader.read_material()
\r
121 for _ in range(reader.read_uint(4))]
\r
122 model.bones=[reader.read_bone()
\r
123 for _ in range(reader.read_uint(2))]
\r
124 model.ik_list=[reader.read_ik()
\r
125 for _ in range(reader.read_uint(2))]
\r
126 model.morphs=[reader.read_morph()
\r
127 for _ in range(reader.read_uint(2))]
\r
128 model.morph_indices=[reader.read_uint(2)
\r
129 for _ in range(reader.read_uint(1))]
\r
130 model.bone_group_list=[pmd.BoneGroup(reader.read_text(50))
\r
131 for _ in range(reader.read_uint(1))]
\r
132 model.bone_display_list=[(reader.read_uint(2), reader.read_uint(1))
\r
133 for _i in range(reader.read_uint(4))]
\r
135 if reader.is_end():
\r
139 ############################################################
\r
140 # extend1: english name
\r
141 ############################################################
\r
142 if reader.read_uint(1)==0:
\r
143 print("no extend flag")
\r
145 model.english_name=reader.read_text(20)
\r
146 model.english_comment=reader.read_text(256)
\r
147 for bone in model.bones:
\r
148 bone.english_name=reader.read_text(20)
\r
149 for morph in model.morphs:
\r
150 if morph.name==b'base':
\r
152 morph.english_name=reader.read_text(20)
\r
153 for g in model.bone_group_list:
\r
154 g.english_name=reader.read_text(50)
\r
157 ############################################################
\r
158 # extend2: toon_textures
\r
159 ############################################################
\r
160 if reader.is_end():
\r
163 model.toon_textures=[reader.read_text(100)
\r
164 for _ in range(10)]
\r
166 ############################################################
\r
167 # extend2: rigidbodies and joints
\r
168 ############################################################
\r
169 if reader.is_end():
\r
172 model.rigidbodies=[reader.read_rigidbody()
\r
173 for _ in range(reader.read_uint(4))]
\r
174 model.joints=[reader.read_joint()
\r
175 for _ in range(reader.read_uint(4))]
\r
180 def read_from_file(path):
\r
181 return read(io.BytesIO(common.readall(path)))
\r
185 assert(isinstance(ios, io.IOBase))
\r
186 reader=common.BinaryReader(ios)
\r
189 signature=reader.unpack("3s", 3)
\r
190 if signature!=b"Pmd":
\r
191 raise common.ParseException(
\r
192 "invalid signature: {0}".format(signature))
\r
193 version=reader.read_float()
\r
195 model=pmd.Model(version)
\r
196 reader=Reader(reader.ios, version)
\r
197 if(__read(reader, model)):
\r
199 if not reader.is_end():
\r
200 #print("can not reach eof.")
\r
204 for i, child in enumerate(model.bones):
\r
205 if child.parent_index==0xFFFF:
\r
207 model.no_parent_bones.append(child)
\r
211 parent=model.bones[child.parent_index]
\r
212 child.parent=parent
\r
213 parent.children.append(child)
\r
215 if child.hasChild():
\r
216 child.tail=model.bones[child.tail_index].pos
\r