6 from .. import common
\r
10 class Reader(common.BinaryReader):
\r
13 def __init__(self, ios,
\r
18 material_index_size,
\r
21 rigidbody_index_size
\r
23 super(Reader, self).__init__(ios)
\r
24 self.read_text=self.get_read_text(text_encoding)
\r
26 raise common.ParseException(
\r
27 "extended uv is not supported", extended_uv)
\r
28 self.read_vertex_index=lambda : self.read_int(vertex_index_size)
\r
29 self.read_texture_index=lambda : self.read_int(texture_index_size)
\r
30 self.read_material_index=lambda : self.read_int(material_index_size)
\r
31 self.read_bone_index=lambda : self.read_int(bone_index_size)
\r
32 self.read_morph_index=lambda : self.read_int(morph_index_size)
\r
33 self.read_rigidbody_index=lambda : self.read_int(rigidbody_index_size)
\r
36 return '<pmx.Reader>'
\r
38 def get_read_text(self, text_encoding):
\r
39 if text_encoding==0:
\r
41 size=self.read_int(4)
\r
42 return self.unpack("{0}s".format(size), size).decode("UTF16")
\r
44 elif text_encoding==1:
\r
46 size=self.read_int(4)
\r
47 return self.unpack("{0}s".format(size), size).decode("UTF8")
\r
50 print("unknown text encoding", text_encoding)
\r
52 def read_vertex(self):
\r
54 self.read_vector3(), # pos
\r
55 self.read_vector3(), # normal
\r
56 self.read_vector2(), # uv
\r
57 self.read_deform(), # deform(bone weight)
\r
58 self.read_float() # edge factor
\r
61 def read_deform(self):
\r
62 deform_type=self.read_int(1)
\r
64 return pmx.Bdef1(self.read_bone_index())
\r
65 elif deform_type==1:
\r
67 self.read_bone_index(),
\r
68 self.read_bone_index(),
\r
71 elif deform_type==2:
\r
73 raise common.ParseException(
\r
74 "not implemented Bdef4")
\r
76 raise common.ParseException(
\r
77 "unknown deform type: {0}".format(deform_type))
\r
79 def read_material(self):
\r
80 material=pmx.Material(
\r
81 name=self.read_text(),
\r
82 english_name=self.read_text(),
\r
83 diffuse_color=self.read_rgb(),
\r
84 alpha=self.read_float(),
\r
85 specular_color=self.read_rgb(),
\r
86 specular_factor=self.read_float(),
\r
87 ambient_color=self.read_rgb(),
\r
88 flag=self.read_int(1),
\r
89 edge_color=self.read_rgba(),
\r
90 edge_size=self.read_float(),
\r
91 texture_index=self.read_texture_index(),
\r
92 sphere_texture_index=self.read_texture_index(),
\r
93 sphere_mode=self.read_int(1),
\r
94 toon_sharing_flag=self.read_int(1),
\r
96 if material.toon_sharing_flag==0:
\r
97 material.toon_texture_index=self.read_texture_index()
\r
98 elif material.toon_sharing_flag==1:
\r
99 material.toon_texture_index=self.read_int(1)
\r
101 raise common.ParseException(
\r
102 "unknown toon_sharing_flag {0}".format(
\r
103 material.toon_sharing_flag))
\r
104 material.comment=self.read_text()
\r
105 material.vertex_count=self.read_int(4)
\r
108 def read_bone(self):
\r
110 name=self.read_text(),
\r
111 english_name=self.read_text(),
\r
112 position=self.read_vector3(),
\r
113 parent_index=self.read_bone_index(),
\r
114 layer=self.read_int(4),
\r
115 flag=self.read_int(2)
\r
117 if bone.getConnectionFlag()==0:
\r
118 bone.tail_position=self.read_vector3()
\r
119 elif bone.getConnectionFlag()==1:
\r
120 bone.tail_index=self.read_bone_index()
\r
122 raise common.ParseException(
\r
123 "unknown bone conenction flag: {0}".format(
\r
124 bone.getConnectionFlag()))
\r
126 if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1:
\r
127 bone.effect_index=self.read_bone_index()
\r
128 bone.effect_factor=self.read_float()
\r
130 if bone.getFixedAxisFlag()==1:
\r
131 bone.fixed_axis=self.read_vector3()
\r
133 if bone.getLocalCoordinateFlag()==1:
\r
134 bone.local_x_vector=self.read_vector3()
\r
135 bone.local_z_vector=self.read_vector3()
\r
137 if bone.getExternalParentDeformFlag()==1:
\r
138 bone.external_key=self.read_int(4)
\r
140 if bone.getIkFlag()==1:
\r
141 bone.ik=self.read_ik()
\r
147 target_index=self.read_bone_index(),
\r
148 loop=self.read_int(4),
\r
149 limit_radian=self.read_float())
\r
150 link_size=self.read_int(4)
\r
151 ik.link=[self.read_ik_link()
\r
152 for _ in range(link_size)]
\r
155 def read_ik_link(self):
\r
157 self.read_bone_index(),
\r
159 if link.limit_angle==0:
\r
161 elif link.limit_angle==1:
\r
162 link.limit_min=self.read_vector3()
\r
163 link.limit_max=self.read_vector3()
\r
165 raise common.ParseException(
\r
166 "invalid ik link limit_angle: {0}".format(
\r
170 def read_morgh(self):
\r
171 name=self.read_text()
\r
172 english_name=self.read_text()
\r
173 panel=self.read_int(1)
\r
174 morph_type=self.read_int(1)
\r
175 offset_size=self.read_int(4)
\r
178 raise common.ParseException(
\r
179 "not implemented GroupMorph")
\r
180 elif morph_type==1:
\r
181 morph=pmx.Morph(name, english_name,
\r
183 morph.offsets=[self.read_vertex_morph_offset()
\r
184 for _ in range(offset_size)]
\r
186 elif morph_type==2:
\r
188 raise common.ParseException(
\r
189 "not implemented BoneMorph")
\r
190 elif morph_type==3:
\r
192 raise common.ParseException(
\r
193 "not implemented UvMorph")
\r
194 elif morph_type==4:
\r
196 raise common.ParseException(
\r
197 "not implemented extended UvMorph1")
\r
198 elif morph_type==5:
\r
200 raise common.ParseException(
\r
201 "not implemented extended UvMorph2")
\r
202 elif morph_type==6:
\r
204 raise common.ParseException(
\r
205 "not implemented extended UvMorph3")
\r
206 elif morph_type==7:
\r
208 raise common.ParseException(
\r
209 "not implemented extended UvMorph4")
\r
210 elif morph_type==8:
\r
212 raise common.ParseException(
\r
213 "not implemented extended MaterialMorph")
\r
215 raise common.ParseException(
\r
216 "unknown morph type: {0}".format(morph_type))
\r
218 def read_vertex_morph_offset(self):
\r
219 return pmx.VerexMorphOffset(
\r
220 self.read_vertex_index(), self.read_vector3())
\r
222 def read_display_slot(self):
\r
223 display_slot=pmx.DisplaySlot(self.read_text(), self.read_text(),
\r
225 display_count=self.read_int(4)
\r
226 for _ in range(display_count):
\r
227 display_type=self.read_int(1)
\r
228 if display_type==0:
\r
229 display_slot.refrences.append(
\r
230 (display_type, self.read_bone_index()))
\r
231 elif display_type==1:
\r
232 display_slot.refrences.append(
\r
233 (display_type, self.read_morph_index()))
\r
235 raise common.ParseException(
\r
236 "unknown display_type: {0}".format(display_type))
\r
237 return display_slot
\r
239 def read_rigidbody(self):
\r
240 return pmx.RigidBody(
\r
241 name=self.read_text(),
\r
242 english_name=self.read_text(),
\r
243 bone_index=self.read_bone_index(),
\r
244 collision_group=self.read_int(1),
\r
245 no_collision_group=self.read_int(2),
\r
246 shape_type=self.read_int(1),
\r
247 shape_size=self.read_vector3(),
\r
248 shape_position=self.read_vector3(),
\r
249 shape_rotation=self.read_vector3(),
\r
250 mass=self.read_float(),
\r
251 linear_damping=self.read_float(),
\r
252 angular_damping=self.read_float(),
\r
253 restitution=self.read_float(),
\r
254 friction=self.read_float(),
\r
255 mode=self.read_int(1)
\r
258 def read_joint(self):
\r
260 name=self.read_text(),
\r
261 english_name=self.read_text(),
\r
262 joint_type=self.read_int(1),
\r
263 rigidbody_index_a=self.read_rigidbody_index(),
\r
264 rigidbody_index_b=self.read_rigidbody_index(),
\r
265 position=self.read_vector3(),
\r
266 rotation=self.read_vector3(),
\r
267 translation_limit_min=self.read_vector3(),
\r
268 translation_limit_max=self.read_vector3(),
\r
269 rotation_limit_min=self.read_vector3(),
\r
270 rotation_limit_max=self.read_vector3(),
\r
271 spring_constant_translation=self.read_vector3(),
\r
272 spring_constant_rotation=self.read_vector3())
\r
275 def read_from_file(path):
\r
277 read from file path, then return the pmx.Model.
\r
283 >>> import pmx.reader
\r
284 >>> m=pmx.reader.read_from_file('resources/初音ミクVer2.pmx')
\r
286 <pmx-2.0 "Miku Hatsune" 12354vertices>
\r
289 pmx=read(io.BytesIO(common.readall(path)))
\r
296 read from ios, then return the pmx pmx.Model.
\r
300 input stream (in io.IOBase)
\r
302 >>> import pmx.reader
\r
303 >>> m=pmx.reader.read(io.open('resources/初音ミクVer2.pmx', 'rb'))
\r
305 <pmx-2.0 "Miku Hatsune" 12354vertices>
\r
308 assert(isinstance(ios, io.IOBase))
\r
309 reader=common.BinaryReader(ios)
\r
312 signature=reader.unpack("4s", 4)
\r
313 if signature!=b"PMX ":
\r
314 raise common.ParseException(
\r
315 "invalid signature", signature)
\r
317 version=reader.read_float()
\r
319 print("unknown version", version)
\r
320 model=pmx.Model(version)
\r
323 flag_bytes=reader.read_int(1)
\r
325 raise common.ParseException(
\r
326 "invalid flag length", reader.flag_bytes)
\r
327 text_encoding=reader.read_int(1)
\r
328 extended_uv=reader.read_int(1)
\r
329 vertex_index_size=reader.read_int(1)
\r
330 texture_index_size=reader.read_int(1)
\r
331 material_index_size=reader.read_int(1)
\r
332 bone_index_size=reader.read_int(1)
\r
333 morph_index_size=reader.read_int(1)
\r
334 rigidbody_index_size=reader.read_int(1)
\r
336 # pmx custom reader
\r
337 reader=Reader(reader.ios,
\r
341 texture_index_size,
\r
342 material_index_size,
\r
345 rigidbody_index_size
\r
349 model.name = reader.read_text()
\r
350 model.english_name = reader.read_text()
\r
351 model.comment = reader.read_text()
\r
352 model.english_comment = reader.read_text()
\r
355 model.vertices=[reader.read_vertex()
\r
356 for _ in range(reader.read_int(4))]
\r
357 model.indices=[reader.read_vertex_index()
\r
358 for _ in range(reader.read_int(4))]
\r
359 model.textures=[reader.read_text()
\r
360 for _ in range(reader.read_int(4))]
\r
361 model.materials=[reader.read_material()
\r
362 for _ in range(reader.read_int(4))]
\r
363 model.bones=[reader.read_bone()
\r
364 for _ in range(reader.read_int(4))]
\r
365 model.morphs=[reader.read_morgh()
\r
366 for _ in range(reader.read_int(4))]
\r
367 model.display_slots=[reader.read_display_slot()
\r
368 for _ in range(reader.read_int(4))]
\r
369 model.rigidbodies=[reader.read_rigidbody()
\r
370 for _ in range(reader.read_int(4))]
\r
371 model.joints=[reader.read_joint()
\r
372 for _ in range(reader.read_int(4))]
\r