3 import pymeshio.common
\r
7 class Loader(pymeshio.common.BinaryLoader):
\r
10 def __init__(self, ios, version):
\r
11 super(Loader, 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
26 return pymeshio.pmd.Vertex(
\r
27 self.read_vector3(),
\r
28 self.read_vector3(),
\r
29 self.read_vector2(),
\r
35 def read_material(self):
\r
36 return pymeshio.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=pymeshio.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=pymeshio.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=pymeshio.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 pymeshio.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
95 return pymeshio.pmd.Joint(
\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 __load(loader, model):
\r
112 model.name=loader.read_text(20)
\r
113 model.comment=loader.read_text(256)
\r
116 model.vertices=[loader.read_vertex()
\r
117 for _ in range(loader.read_uint(4))]
\r
118 model.indices=[loader.read_uint(2)
\r
119 for _ in range(loader.read_uint(4))]
\r
120 model.materials=[loader.read_material()
\r
121 for _ in range(loader.read_uint(4))]
\r
122 model.bones=[loader.read_bone()
\r
123 for _ in range(loader.read_uint(2))]
\r
124 model.ik_list=[loader.read_ik()
\r
125 for _ in range(loader.read_uint(2))]
\r
126 model.morphs=[loader.read_morph()
\r
127 for _ in range(loader.read_uint(2))]
\r
128 model.morph_indices=[loader.read_uint(2)
\r
129 for _ in range(loader.read_uint(1))]
\r
130 model.bone_group_list=[loader.read_text(50)
\r
131 for _ in range(loader.read_uint(1))]
\r
132 model.bone_display_list=[(loader.read_uint(2), loader.read_uint(1))
\r
133 for _i in range(loader.read_uint(4))]
\r
135 if loader.is_end():
\r
139 ############################################################
\r
140 # extend1: english name
\r
141 ############################################################
\r
142 if loader.read_uint(1)==0:
\r
143 print("no extend flag")
\r
145 model.english_name=loader.read_text(20)
\r
146 model.english_comment=loader.read_text(256)
\r
147 for bone in model.bones:
\r
148 bone.english_name=loader.read_text(20)
\r
149 for morph in model.morphs:
\r
150 if morph.name==b'base':
\r
152 morph.english_name=loader.read_text(20)
\r
153 model.bone_group_english_list=[loader.read_text(50)
\r
154 for _ in model.bone_group_list]
\r
156 ############################################################
\r
157 # extend2: toon_textures
\r
158 ############################################################
\r
159 if loader.is_end():
\r
162 model.toon_textures=[loader.read_text(100)
\r
163 for _ in range(10)]
\r
165 ############################################################
\r
166 # extend2: rigidbodies and joints
\r
167 ############################################################
\r
168 if loader.is_end():
\r
171 model.rigidbodies=[loader.read_rigidbody()
\r
172 for _ in range(loader.read_uint(4))]
\r
173 model.joints=[loader.read_joint()
\r
174 for _ in range(loader.read_uint(4))]
\r
179 def load_from_file(path):
\r
180 return load(io.BytesIO(pymeshio.common.readall(path)))
\r
184 assert(isinstance(ios, io.IOBase))
\r
185 loader=pymeshio.common.BinaryLoader(ios)
\r
188 signature=loader.unpack("3s", 3)
\r
189 if signature!=b"Pmd":
\r
190 raise pymeshio.common.ParseException(
\r
191 "invalid signature: {0}".format(signature))
\r
192 version=loader.read_float()
\r
194 model=pymeshio.pmd.Model(version)
\r
195 loader=Loader(loader.ios, version)
\r
196 if(__load(loader, model)):
\r
198 if not loader.is_end():
\r
199 #print("can not reach eof.")
\r
203 for i, child in enumerate(model.bones):
\r
204 if child.parent_index==0xFFFF:
\r
206 model.no_parent_bones.append(child)
\r
210 parent=model.bones[child.parent_index]
\r
211 child.parent=parent
\r
212 parent.children.append(child)
\r
214 if child.hasChild():
\r
215 child.tail=model.bones[child.tail_index].pos
\r