OSDN Git Service

refactoring pmd.writer
[meshio/pymeshio.git] / pymeshio / pmx / __init__.py
1 #!/usr/bin/env python\r
2 # coding: utf-8\r
3 """\r
4 pmx file io library.\r
5 \r
6 pmx file format:\r
7     PMDEditor's Lib/PMX仕様/PMX仕様.txt\r
8 """\r
9 __author__="ousttrue"\r
10 __license__="zlib"\r
11 __versioon__="1.0.0"\r
12 \r
13 \r
14 import io\r
15 import os\r
16 import struct\r
17 from pymeshio import common\r
18 \r
19 \r
20 \r
21 class Ik(object):\r
22     """ik info\r
23     """\r
24     __slots__=[\r
25             'target_index',\r
26             'loop',\r
27             'limit_radian',\r
28             'link',\r
29             ]\r
30     def __init__(self, target_index, loop, limit_radian):\r
31         self.target_index=target_index\r
32         self.loop=loop\r
33         self.limit_radian=limit_radian\r
34         self.link=[]\r
35 \r
36 \r
37 class IkLink(object):\r
38     """ik link info\r
39     """\r
40     __slots__=[\r
41             'bone_index',\r
42             'limit_angle',\r
43             'limit_min',\r
44             'limit_max',\r
45             ]\r
46     def __init__(self, bone_index, limit_angle):\r
47         self.bone_index=bone_index\r
48         self.limit_angle=limit_angle\r
49         self.limit_min=None\r
50         self.limit_max=None\r
51 \r
52 \r
53 class Bone(object):\r
54     """material\r
55 \r
56     Bone: see __init__\r
57     """\r
58     __slots__=[\r
59             'name',\r
60             'english_name',\r
61             'position',\r
62             'parent_index',\r
63             'layer',\r
64             'flag',\r
65 \r
66             'tail_positoin',\r
67             'tail_index',\r
68             'effect_index',\r
69             'effect_factor',\r
70             'fixed_axis',\r
71             'local_x_vector',\r
72             'local_z_vector',\r
73             'external_key',\r
74             'ik',\r
75             ]\r
76     def __init__(self,\r
77             name,\r
78             english_name,\r
79             position,\r
80             parent_index,\r
81             layer,\r
82             flag\r
83             ):\r
84         self.name=name,\r
85         self.english_name=english_name\r
86         self.position=position\r
87         self.parent_index=parent_index\r
88         self.layer=layer\r
89         self.flag=flag\r
90 \r
91     def getConnectionFlag(self):\r
92         return self.flag & 0x0001\r
93 \r
94     def getIkFlag(self):\r
95         return (self.flag & 0x0020) >> 5\r
96 \r
97     def getRotationFlag(self):\r
98         return (self.flag & 0x0100) >> 8\r
99 \r
100     def getTranslationFlag(self):\r
101         return (self.flag & 0x0200) >> 9\r
102 \r
103     def getFixedAxisFlag(self):\r
104         return (self.flag & 0x0400) >> 10\r
105 \r
106     def getLocalCoordinateFlag(self):\r
107         return (self.flag &  0x0800) >> 11\r
108     \r
109     def getExternalParentDeformFlag(self):\r
110         return (self.flag &  0x2000) >> 13\r
111 \r
112  \r
113 class Material(object):\r
114     """material\r
115 \r
116     Attributes: see __init__\r
117     """\r
118     __slots__=[\r
119             'name',\r
120             'english_name',\r
121             'diffuse_color',\r
122             'diffuse_alpha',\r
123             'specular_color',\r
124             'specular_factor',\r
125             'ambient_color',\r
126             'flag',\r
127             'edge_color',\r
128             'edge_size',\r
129             'texture_index',\r
130             'sphia_texture_index',\r
131             'sphia_mode',\r
132             'toon_sharing_flag',\r
133             'toon_texture_index',\r
134             'comment',\r
135             'vertex_count',\r
136             ]\r
137     def __init__(self,\r
138             name,\r
139             english_name,\r
140             diffuse_color,\r
141             diffuse_alpha,\r
142             specular_color,\r
143             specular_factor,\r
144             ambient_color,\r
145             flag,\r
146             edge_color,\r
147             edge_size,\r
148             texture_index,\r
149             sphia_texture_index,\r
150             sphia_mode,\r
151             toon_sharing_flag\r
152             ):\r
153         self.name=name\r
154         self.english_name=english_name\r
155         self.diffuse_color=diffuse_color\r
156         self.diffuse_alpha=diffuse_alpha\r
157         self.specular_color=specular_color\r
158         self.specular_factor=specular_factor\r
159         self.ambient_color=ambient_color\r
160         self.flag=flag\r
161         self.edge_color=edge_color\r
162         self.edge_size=edge_size\r
163         self.texture_index=texture_index\r
164         self.sphia_texture_index=sphia_texture_index\r
165         self.sphia_mode=sphia_mode\r
166         self.toon_sharing_flag=toon_sharing_flag\r
167         #\r
168         self.toon_texture_index=None\r
169         self.comment=''\r
170         self.vertex_count=0\r
171 \r
172     def __str__(self):\r
173         return ("<pmx.Material {name}>".format(\r
174             name=self.english_name\r
175             ))\r
176 \r
177 \r
178 class Deform(object):\r
179     pass\r
180 \r
181 \r
182 class Bdef1(object):\r
183     """bone deform. use a weight\r
184 \r
185     Attributes: see __init__\r
186     """\r
187     __slots__=[ 'index0']\r
188     def __init__(self, index0):\r
189         self.index0=index0\r
190 \r
191 \r
192 class Bdef2(object):\r
193     """bone deform. use two weights\r
194 \r
195     Attributes: see __init__\r
196     """\r
197     __slots__=[ 'index0', 'index1', 'weight0']\r
198     def __init__(self, \r
199             index0,\r
200             index1,\r
201             weight0):\r
202         self.index0=index0\r
203         self.index1=index1\r
204         self.weight0=weight0\r
205 \r
206 \r
207 class Vertex(object):\r
208     """pmx vertex\r
209 \r
210     Attributes: see __init__\r
211     """\r
212     __slots__=[ 'position', 'normal', 'uv', 'deform', 'edge_factor' ]\r
213     def __init__(self, \r
214             position, \r
215             normal, \r
216             uv, \r
217             deform, \r
218             edge_factor):\r
219         self.position=position \r
220         self.normal=normal\r
221         self.uv=uv\r
222         self.deform=deform\r
223         self.edge_factor=edge_factor\r
224 \r
225 \r
226 class Morph(object):\r
227     """pmx morph\r
228 \r
229     Attributes:\r
230         name: \r
231         english_name: \r
232         panel:\r
233         morph_type:\r
234         offsets:\r
235     """\r
236     __slots__=[\r
237             'name',\r
238             'english_name',\r
239             'panel',\r
240             'morph_type',\r
241             'offsets',\r
242             ]\r
243     def __init__(self, name, english_name, panel, morph_type):\r
244         self.name=name\r
245         self.english_name=english_name\r
246         self.panel=panel\r
247         self.morph_type=morph_type\r
248         self.offsets=[]\r
249 \r
250 \r
251 class VerexMorphOffset(object):\r
252     """pmx vertex morph offset\r
253 \r
254     Attributes:\r
255         vertex_index:\r
256         position_offset: Vector3\r
257     """\r
258     __slots__=[\r
259             'vertex_index',\r
260             'position_offset',\r
261             ]\r
262     def __init__(self, vertex_index, position_offset):\r
263         self.vertex_index=vertex_index\r
264         self.position_offset=position_offset\r
265 \r
266 \r
267 class DisplaySlot(object):\r
268     """pmx display slot\r
269 \r
270     Attributes:\r
271         name: \r
272         english_name: \r
273         special_flag:\r
274         refrences: list of (ref_type, ref_index)\r
275     """\r
276     __slots__=[\r
277             'name',\r
278             'english_name',\r
279             'special_flag',\r
280             'refrences',\r
281             ]\r
282     def __init__(self, name, english_name, special_flag):\r
283         self.name=name\r
284         self.english_name=english_name\r
285         self.special_flag=special_flag\r
286         self.refrences=[]\r
287 \r
288 \r
289 class Shape(object):\r
290     pass\r
291 \r
292 \r
293 class SphereShape(Shape):\r
294     __slots__=['radius']\r
295     def __init__(self, radius):\r
296         self.radius=radius\r
297 \r
298 \r
299 class CapsuleShape(Shape):\r
300     __slots__=['short_radius', 'long_radius']\r
301     def __init__(self, short_radius, long_radius): \r
302         self.short_radius=short_radius\r
303         self.long_radius=long_radius\r
304 \r
305 \r
306 class BoxShape(Shape):\r
307     __slots__=['x', 'y', 'z']\r
308     def __init__(self, x, y, z):\r
309         self.x=x\r
310         self.y=y\r
311         self.z=z\r
312 \r
313 \r
314 class RigidBodyParam(object):\r
315     """pmx rigidbody param(for bullet)\r
316 \r
317     Attributes:\r
318         mass:\r
319         linear_damping:\r
320         angular_damping:\r
321         restitution:\r
322         friction:\r
323     """\r
324     __slots__=[\r
325             'mass',\r
326             'linear_damping',\r
327             'angular_damping',\r
328             'restitution',\r
329             'friction',\r
330             ]\r
331     def __init__(self, mass, \r
332             linear_damping, angular_damping, restitution, friction):\r
333         self.mass=mass\r
334         self.linear_damping=linear_damping\r
335         self.angular_damping=angular_damping\r
336         self.restitution=restitution\r
337         self.friction=friction\r
338 \r
339 \r
340 class RigidBody(object):\r
341     """pmx rigidbody\r
342 \r
343     Attributes:\r
344         name: \r
345         english_name: \r
346         bone_index:\r
347         collision_group:\r
348         no_collision_group:\r
349         shape:\r
350         param:\r
351         mode:\r
352     """\r
353     __slots__=[\r
354             'name',\r
355             'english_name',\r
356             'bone_index',\r
357             'collision_group',\r
358             'no_collision_group',\r
359             'shape',\r
360             'param',\r
361             'mode',\r
362             ]\r
363     def __init__(self,\r
364             name,\r
365             english_name,\r
366             bone_index,\r
367             collision_group,\r
368             no_collision_group,\r
369             shape_type,\r
370             shape_size,\r
371             shape_position,\r
372             shape_rotation,\r
373             mass,\r
374             linear_damping,\r
375             angular_damping,\r
376             restitution,\r
377             friction,\r
378             mode\r
379             ):\r
380         self.name=name\r
381         self.english_name=english_name\r
382         self.bone_index=bone_index\r
383         self.collision_group=collision_group\r
384         self.no_collision_group=no_collision_group\r
385         if shape_type==0:\r
386             self.shape=SphereShape(shape_size.x)\r
387         elif shape_type==1:\r
388             self.shape=BoxShape(shape_size.x, shape_size.y, shape_size.z)\r
389         elif shape_type==2:\r
390             self.shape=CapsuleShape(shape_size.x, shape_size.y)\r
391         else:\r
392             raise pymeshio.common.ParseException(\r
393                     "unknown shape_type: {0}".format(shape_type))\r
394         self.param=RigidBodyParam(mass,\r
395                 linear_damping, angular_damping,\r
396                 restitution, friction)\r
397         self.mode=mode\r
398 \r
399 \r
400 class Joint(object):\r
401     """pmx joint\r
402 \r
403     Attributes:\r
404         name: \r
405         english_name: \r
406         joint_type:\r
407         rigidbody_index_a:\r
408         rigidbody_index_b:\r
409         position: Vector3\r
410         rotation: Vector3\r
411         translation_limit_min: Vector3\r
412         translation_limit_max: Vector3\r
413         rotation_limit_min: Vector3\r
414         rotation_limit_max: Vector3\r
415         spring_constant_translation: Vector3\r
416         spring_constant_rotation: Vector3\r
417     """\r
418     __slots__=[\r
419             'name',\r
420             'english_name',\r
421             'joint_type',\r
422             'rigidbody_index_a',\r
423             'rigidbody_index_b',\r
424             'position',\r
425             'rotation',\r
426             'translation_limit_min',\r
427             'translation_limit_max',\r
428             'rotation_limit_min',\r
429             'rotation_limit_max',\r
430             'spring_constant_translation',\r
431             'spring_constant_rotation',\r
432             ]\r
433     def __init__(self, name, english_name,\r
434             joint_type,\r
435             rigidbody_index_a,\r
436             rigidbody_index_b,\r
437             position,\r
438             rotation,\r
439             translation_limit_min,\r
440             translation_limit_max,\r
441             rotation_limit_min,\r
442             rotation_limit_max,\r
443             spring_constant_translation,\r
444             spring_constant_rotation\r
445             ):\r
446         self.name=name\r
447         self.english_name=english_name\r
448         self.joint_type=joint_type\r
449         self.rigidbody_index_a=rigidbody_index_a\r
450         self.rigidbody_index_b=rigidbody_index_b\r
451         self.position=position\r
452         self.rotation=rotation\r
453         self.translation_limit_min=translation_limit_min\r
454         self.translation_limit_max=translation_limit_max\r
455         self.rotation_limit_min=rotation_limit_min\r
456         self.rotation_limit_max=rotation_limit_max\r
457         self.spring_constant_translation=spring_constant_translation\r
458         self.spring_constant_rotation=spring_constant_rotation\r
459 \r
460 \r
461 class Model(object):\r
462     """pmx data representation\r
463 \r
464     Attributes:\r
465         version: pmx version(expected 2.0)\r
466         name: \r
467         english_name: \r
468         comment: \r
469         english_comment: \r
470         vertices:\r
471         textures:\r
472         materials:\r
473         bones:\r
474         morph:\r
475         display_slots:\r
476         rigidbodies:\r
477         joints:\r
478     """\r
479     __slots__=[\r
480             'version', # pmx version\r
481             'name', # model name\r
482             'english_name', # model name in english\r
483             'comment', # model comment\r
484             'english_comment', # model comment in english\r
485             'vertices',\r
486             'indices',\r
487             'textures',\r
488             'materials',\r
489             'bones',\r
490             'morphs',\r
491             'display_slots',\r
492             'rigidbodies',\r
493             'joints',\r
494             ]\r
495     def __init__(self, version):\r
496         self.version=version\r
497         self.name=''\r
498         self.english_name=''\r
499         self.comment=''\r
500         self.english_comment=''\r
501         self.vertices=[]\r
502         self.indices=[]\r
503         self.textures=[]\r
504         self.materials=[]\r
505         self.bones=[]\r
506         self.rigidbodies=[]\r
507         self.joints=[]\r
508 \r
509     def __str__(self):\r
510         return ('<pmx-{version} "{name}" {vertices}vertices>'.format(\r
511             version=self.version,\r
512             name=self.english_name,\r
513             vertices=len(self.vertices)\r
514             ))\r
515 \r