OSDN Git Service

187f59dc5f35adc83683ba459d24ee037699b6dd
[meshio/pymeshio.git] / pymeshio / pmd / writer.py
1 # coding: utf-8\r
2 import io\r
3 import struct\r
4 from .. import common\r
5 from .. import pmd\r
6 \r
7 \r
8 class Writer(common.BinaryWriter):\r
9     def write_veritices(self, vertices):\r
10         self.write_uint(len(vertices), 4)\r
11         for v in vertices:\r
12             self.write_vector3(v.pos)\r
13             self.write_vector3(v.normal)\r
14             self.write_vector2(v.uv)\r
15             self.write_uint(v.bone0, 2)\r
16             self.write_uint(v.bone1, 2)\r
17             self.write_uint(v.weight0, 1)\r
18             self.write_uint(v.edge_flag, 1)\r
19 \r
20     def write_indices(self, indices):\r
21         self.write_uint(len(indices), 4)\r
22         self.ios.write(struct.pack("=%dH" % len(indices), *indices))\r
23 \r
24     def write_materials(self, materials):\r
25         self.write_uint(len(materials), 4)\r
26         for m in materials:\r
27             self.write_rgb(m.diffuse_color)\r
28             self.write_float(m.alpha)\r
29             self.write_float(m.specular_factor)\r
30             self.write_rgb(m.specular_color)\r
31             self.write_rgb(m.ambient_color)\r
32             self.write_uint(m.toon_index, 1)\r
33             self.write_uint(m.edge_flag, 1)\r
34             self.write_uint(m.vertex_count, 4)\r
35             self.write_text(m.texture_file, 20)\r
36 \r
37     def write_bones(self, bones):\r
38         self.write_uint(len(bones), 2)\r
39         sBone=struct.Struct("=20sHHBH3f")\r
40         assert(sBone.size==39)\r
41         for b in bones:\r
42             self.write_text(b.name, 20)\r
43             self.write_uint(b.parent_index, 2)\r
44             self.write_uint(b.tail_index, 2)\r
45             self.write_uint(b.type, 1)\r
46             self.write_uint(b.ik_index, 2)\r
47             self.write_vector3(b.pos)\r
48 \r
49     def write_ik_list(self, ik_list):\r
50         self.write_uint(len(ik_list), 2)\r
51         for ik in ik_list:\r
52             self.write_uint(ik.index, 2)\r
53             self.write_uint(ik.target, 2)\r
54             self.write_uint(len(ik.children), 1)\r
55             self.write_uint(ik.iterations, 2)\r
56             self.write_float(ik.weight)\r
57             self.ios.write(struct.pack("=%dH" % len(ik.children), *ik.children))\r
58 \r
59     def write_morphs(self, morphs):\r
60         self.write_uint(len(morphs), 2)\r
61         for morph in morphs:\r
62             self.write_text(morph.name, 20)\r
63             self.write_uint(len(morph.indices), 4)\r
64             self.write_uint(morph.type, 1)\r
65             for i, v in zip(morph.indices, morph.pos_list):\r
66                 self.write_uint(i, 4)\r
67                 self.write_vector3(v)\r
68 \r
69     def write_morph_indices(self, morph_indices):\r
70         self.write_uint(len(morph_indices), 1)\r
71         self.ios.write(struct.pack("=%dH" % len(morph_indices), *morph_indices))\r
72 \r
73     def write_bone_group_list(self, bone_group_list):\r
74         self.write_uint(len(bone_group_list), 1)\r
75         for g in bone_group_list:\r
76             self.write_text(g.name, 50)\r
77 \r
78     def write_bone_display_list(self, bone_display_list):\r
79         self.write_uint(len(bone_display_list), 4)\r
80         for l in bone_display_list:\r
81             self.write_uint(l[0], 2)\r
82             self.write_uint(l[1], 1)\r
83 \r
84     def write_rigidbodies(self, rigidbodies):\r
85         self.write_uint(len(rigidbodies), 4)\r
86         for r in rigidbodies:\r
87             self.write_text(r.name, 20)\r
88             self.write_uint(r.bone_index, 2)\r
89             self.write_uint(r.collision_group, 1)\r
90             self.write_uint(r.no_collision_group, 2)\r
91             self.write_uint(r.shape_type, 1)\r
92             self.write_vector3(r.shape_size)\r
93             self.write_vector3(r.shape_position)\r
94             self.write_vector3(r.shape_rotation)\r
95             self.write_float(r.mass)\r
96             self.write_float(r.linear_damping)\r
97             self.write_float(r.angular_damping)\r
98             self.write_float(r.restitution)\r
99             self.write_float(r.friction)\r
100             self.write_uint(r.mode, 1)\r
101 \r
102     def write_joints(self, joints):\r
103         self.write_uint(len(joints), 4)\r
104         for j in joints:\r
105             self.write_text(j.name, 20)\r
106             self.write_uint(j.rigidbody_index_a, 4)\r
107             self.write_uint(j.rigidbody_index_b, 4)\r
108             self.write_vector3(j.position)\r
109             self.write_vector3(j.rotation)\r
110             self.write_vector3(j.translation_limit_min)\r
111             self.write_vector3(j.translation_limit_max)\r
112             self.write_vector3(j.rotation_limit_min)\r
113             self.write_vector3(j.rotation_limit_max)\r
114             self.write_vector3(j.spring_constant_translation)\r
115             self.write_vector3(j.spring_constant_rotation)\r
116 \r
117 \r
118 def write(ios, model):\r
119     assert(isinstance(ios, io.IOBase))\r
120     assert(isinstance(model, pmd.Model))\r
121     writer=Writer(ios)\r
122     writer.write_text(b"Pmd")\r
123     writer.write_float(model.version)\r
124     writer.write_text(model.name, 20)\r
125     writer.write_text(model.comment, 256)\r
126     writer.write_veritices(model.vertices)\r
127     writer.write_indices(model.indices)\r
128     writer.write_materials(model.materials)\r
129     writer.write_bones(model.bones)\r
130     writer.write_ik_list(model.ik_list)\r
131     writer.write_morphs(model.morphs)\r
132     writer.write_morph_indices(model.morph_indices)\r
133     writer.write_bone_group_list(model.bone_group_list)\r
134     writer.write_bone_display_list(model.bone_display_list)\r
135     # extend data\r
136     writer.write_uint(1, 1)\r
137     writer.write_text(model.english_name, 20)\r
138     writer.write_text(model.english_comment, 256)\r
139     for bone in model.bones:\r
140         writer.write_text(bone.english_name, 20)\r
141     for skin in model.morphs:\r
142         if skin.name==b'base':\r
143             continue\r
144         writer.write_text(skin.english_name, 20)\r
145     for g in model.bone_group_list:\r
146         writer.write_text(g.english_name, 50)\r
147     for toon_texture in model.toon_textures:\r
148         writer.write_text(toon_texture, 100)\r
149     writer.write_rigidbodies(model.rigidbodies)\r
150     writer.write_joints(model.joints)\r
151     return True\r
152 \r