1
2 """
3 convert model
4 """
5
6 import math
7 from . import common
8 from .common import unicode as u
9 from . import pmx
10 from . import pmd
11
13 """
14 Exception in writer
15 """
16 pass
17
18
43 dst.vertices=[
44 pmx.Vertex(
45 v.pos,
46 v.normal,
47 v.uv,
48 createDeform(v.bone0, v.bone1, v.weight0),
49 1.0 if v.edge_flag==0 else 0.0
50 )
51 for v in src.vertices]
52
53 dst.indices=src.indices[:]
54
55 texture_map={}
56 def get_flag(m):
57 return (
58 (1 if False else 0)+
59 (2 if (m.edge_flag & 1!=0) else 0)+
60 (4 if True else 0)+
61 (8 if True else 0)+
62 (16 if (m.edge_flag & 1!=0) else 0)
63 )
64 def get_texture_file(path):
65 if len(path)==0:
66 return None
67 elif path.find(b'*')==-1:
68 return path
69 else:
70 return b'*'.split(path)[0]
71 def get_sphere_texture_file(path):
72 if len(path)==0:
73 return None
74 elif path.find(b'*')==-1:
75 return None
76 else:
77 return b'*'.split(path)[1]
78 def get_texture_index(path):
79 try:
80 return texture_map[get_texture_file(path)]
81 except KeyError:
82 return -1
83 def get_sphere_texture_index(path):
84 try:
85 return texture_map[get_sphere_texture_file(path)]
86 except KeyError:
87 return -1
88 def get_sphere_texture_flag(path):
89 sphere_texture=get_sphere_texture_file(path)
90 if sphere_texture:
91 if sphere_texture.endswith('.sph'):
92 return 1
93 elif sphere_texture.endswith('.spa'):
94 return 2
95 else:
96 raise ConvertException(
97 "invalid sphere texture: {0}".format(sphere_texture))
98 return 0
99 def get_toon_shared_flag(m):
100 return 1
101 def get_toon_index(m):
102 return m.toon_index
103 for m in src.materials:
104 texture=get_texture_file(m.texture_file)
105 if texture and not texture in texture_map:
106 texture_map[texture]=len(texture_map)
107 dst.textures.append(texture.decode("cp932"))
108 sphere_texture=get_sphere_texture_file(m.texture_file)
109 if sphere_texture and not sphere_texture in texture_map:
110 texture_map[sphere_texture]=len(texture_map)
111 dst.textures.append(sphere_texture.decode("cp932"))
112 dst.materials=[
113 pmx.Material(
114 name=common.unicode(""),
115 english_name=common.unicode(""),
116 diffuse_color=m.diffuse_color,
117 alpha=m.alpha,
118 specular_factor=m.specular_factor,
119 specular_color=m.specular_color,
120 ambient_color=m.ambient_color,
121 flag=get_flag(m),
122 edge_color=common.RGBA(0.0, 0.0, 0.0, 1.0),
123 edge_size=1.0,
124 texture_index=get_texture_index(m.texture_file),
125 sphere_texture_index=get_sphere_texture_index(m.texture_file),
126 sphere_mode=get_sphere_texture_flag(m.texture_file),
127 toon_sharing_flag=get_toon_shared_flag(m),
128 toon_texture_index=get_toon_index(m),
129 comment=common.unicode(""),
130 vertex_count=m.vertex_count
131 )
132 for i, m in enumerate(src.materials)]
133
134 ik_map={}
135 for ik in src.ik_list:
136 ik_map[ik.index]=ik
137 def is_connected(b):
138 if isinstance(b, pmd.Bone_Rolling):
139 return False
140 if isinstance(b, pmd.Bone_Tweak):
141 return False
142 return True
143 def is_rotatable(b):
144 if isinstance(b, pmd.Bone_Rotate):
145 return True
146 if isinstance(b, pmd.Bone_RotateMove):
147 return True
148 if isinstance(b, pmd.Bone_RotateInfl):
149 return True
150 if isinstance(b, pmd.Bone_IKRotateInfl):
151 return True
152 if isinstance(b, pmd.Bone_Rolling):
153 return True
154 if isinstance(b, pmd.Bone_IKTarget):
155 return True
156 if isinstance(b, pmd.Bone_IK):
157 return True
158 if isinstance(b, pmd.Bone_Unvisible):
159 return True
160 if isinstance(b, pmd.Bone_Tweak):
161 return True
162 def is_movable(b):
163 if isinstance(b, pmd.Bone_RotateMove):
164 return True
165 if isinstance(b, pmd.Bone_IK):
166 return True
167 def is_visible(b):
168 if isinstance(b, pmd.Bone_Unvisible):
169 return False
170 if isinstance(b, pmd.Bone_IKTarget):
171 return False
172 if isinstance(b, pmd.Bone_Tweak):
173 return False
174 return True
175 def is_manupilatable(b):
176 return True
177 def has_ik(b):
178 if isinstance(b, pmd.Bone_IK):
179 return True
180 def is_external_rotation(b):
181 if isinstance(b, pmd.Bone_RotateInfl):
182 return True
183 if isinstance(b, pmd.Bone_Tweak):
184 return True
185 def is_fixed_axis(b):
186 if isinstance(b, pmd.Bone_Rolling):
187 return True
188 def is_local_axis(b):
189 pass
190 def after_physics(b):
191 pass
192 def external_parent(b):
193 pass
194 def get_bone_flag(b):
195 return (
196 (1 if is_connected(b) else 0)+
197 (2 if is_rotatable(b) else 0)+
198 (4 if is_movable(b) else 0)+
199 (8 if is_visible(b) else 0)+
200
201 (16 if is_manupilatable(b) else 0)+
202 (32 if has_ik(b) else 0)+
203 0+
204 0+
205
206 (256 if is_external_rotation(b) else 0)+
207 0+
208 (1024 if is_fixed_axis(b) else 0)+
209 (2048 if is_local_axis(b) else 0)+
210
211 (4096 if after_physics(b) else 0)+
212 (8192 if external_parent(b) else 0)
213 )
214 def get_tail_position(b):
215 return common.Vector3()
216 def get_tail_index(b):
217 if isinstance(b, pmd.Bone_Rolling):
218 return -1
219 if isinstance(b, pmd.Bone_IKTarget):
220 return -1
221 if isinstance(b, pmd.Bone_Unvisible):
222 return -1
223 if isinstance(b, pmd.Bone_Tweak):
224 return -1
225 return b.tail_index
226 def get_ik_link(bone_index):
227 b=src.bones[bone_index]
228 if b.english_name.find(b'knee')==-1:
229 return pmx.IkLink(
230 bone_index, 0,
231 common.Vector3(),
232 common.Vector3())
233 else:
234 return pmx.IkLink(
235 bone_index, 1,
236 common.Vector3(-3.1415927410125732, 0.0, 0.0),
237 common.Vector3(-0.00872664619237184524536132812500, 0.0, 0.0))
238 def get_ik(b):
239 if isinstance(b, pmd.Bone_IK):
240 ik=ik_map[b.index]
241 return pmx.Ik(
242 ik.target, ik.iterations, ik.weight * 4, [
243 get_ik_link(child) for child in ik.children ])
244 return None
245 def get_layer(b):
246 return 0
247 dst.bones=[
248 pmx.Bone(
249 name=b.name.decode('cp932'),
250 english_name=b.english_name.decode('cp932'),
251 position=b.pos,
252 parent_index=b.parent_index if b.parent_index!=65535 else -1,
253 layer=get_layer(b),
254 flag=get_bone_flag(b),
255 tail_position=get_tail_position(b),
256 tail_index=get_tail_index(b),
257 effect_index=-1,
258 effect_factor=0.0,
259 fixed_axis=common.Vector3(),
260 local_x_vector=common.Vector3(),
261 local_z_vector=common.Vector3(),
262 external_key=-1,
263 ik=get_ik(b),
264 )
265 for i, b in enumerate(src.bones)]
266
267 def get_panel(m):
268 return 1
269 if len(src.morphs)>0:
270 base=src.morphs[0]
271 assert(base.name==b"base")
272 dst.morphs=[
273 pmx.Morph(
274 name=m.name.decode('cp932'),
275 english_name=m.english_name.decode('cp932'),
276 panel=get_panel(m),
277 morph_type=1,
278 offsets=[pmx.VertexMorphOffset(base.indices[i], pos)
279 for i, pos in zip(m.indices, m.pos_list)]
280 )
281 for i, m in enumerate(src.morphs) if m.name!=b"base"]
282
283 dst.display_slots=[
284 pmx.DisplaySlot(u('Root'), u('Root'), 1),
285 pmx.DisplaySlot(u('表情'), u('Exp'), 1)]+[
286 pmx.DisplaySlot(
287 name=g.name.strip().decode('cp932'),
288 english_name=g.english_name.strip().decode('cp932'),
289 special_flag=0)
290 for i, g in enumerate(src.bone_group_list)]
291
292 dst.rigidbodies=[
293 pmx.RigidBody(
294 name=r.name.decode("cp932"),
295 english_name=u(""),
296 bone_index=r.bone_index,
297 collision_group=r.collision_group,
298 no_collision_group=r.no_collision_group,
299 shape_type=r.shape_type,
300 shape_size=r.shape_size,
301 shape_position=(r.shape_position+src.bones[0].pos if r.bone_index==-1
302 else r.shape_position+src.bones[r.bone_index].pos),
303 shape_rotation=r.shape_rotation,
304 mass=r.mass,
305 linear_damping=r.linear_damping,
306 angular_damping=r.angular_damping,
307 restitution=r.restitution,
308 friction=r.friction,
309 mode=r.mode
310 )
311 for i, r in enumerate(src.rigidbodies)]
312
313 dst.joints=[
314 pmx.Joint(
315 j.name.decode('cp932'),
316 u(""),
317 0,
318 j.rigidbody_index_a,
319 j.rigidbody_index_b,
320 j.position,
321 j.rotation,
322 j.translation_limit_min,
323 j.translation_limit_max,
324 j.rotation_limit_min,
325 j.rotation_limit_max,
326 j.spring_constant_translation,
327 j.spring_constant_rotation
328 )
329 for i, j in enumerate(src.joints)]
330 return dst
331