OSDN Git Service

refactoring pmd.writer
[meshio/pymeshio.git] / pymeshio / pmd / writer.py
diff --git a/pymeshio/pmd/writer.py b/pymeshio/pmd/writer.py
new file mode 100644 (file)
index 0000000..b1340c4
--- /dev/null
@@ -0,0 +1,152 @@
+# coding: utf-8\r
+import io\r
+import struct\r
+import pymeshio.common\r
+import pymeshio.pmd\r
+\r
+\r
+class Writer(pymeshio.common.BinaryWriter):\r
+    def write_veritices(self, vertices):\r
+        self.write_uint(len(vertices), 4)\r
+        for v in vertices:\r
+            self.write_vector3(v.pos)\r
+            self.write_vector3(v.normal)\r
+            self.write_vector2(v.uv)\r
+            self.write_uint(v.bone0, 2)\r
+            self.write_uint(v.bone1, 2)\r
+            self.write_uint(v.weight0, 1)\r
+            self.write_uint(v.edge_flag, 1)\r
+\r
+    def write_indices(self, indices):\r
+        self.write_uint(len(indices), 4)\r
+        self.ios.write(struct.pack("=%dH" % len(indices), *indices))\r
+\r
+    def write_materials(self, materials):\r
+        self.write_uint(len(materials), 4)\r
+        for m in materials:\r
+            self.write_rgb(m.diffuse_color)\r
+            self.write_float(m.alpha)\r
+            self.write_float(m.specular_factor)\r
+            self.write_rgb(m.specular_color)\r
+            self.write_rgb(m.ambient_color)\r
+            self.write_uint(m.toon_index, 1)\r
+            self.write_uint(m.edge_flag, 1)\r
+            self.write_uint(m.vertex_count, 4)\r
+            self.write_text(m.texture_file, 20)\r
+\r
+    def write_bones(self, bones):\r
+        self.write_uint(len(bones), 2)\r
+        sBone=struct.Struct("=20sHHBH3f")\r
+        assert(sBone.size==39)\r
+        for b in bones:\r
+            self.write_text(b.name, 20)\r
+            self.write_uint(b.parent_index, 2)\r
+            self.write_uint(b.tail_index, 2)\r
+            self.write_uint(b.type, 1)\r
+            self.write_uint(b.ik_index, 2)\r
+            self.write_vector3(b.pos)\r
+\r
+    def write_ik_list(self, ik_list):\r
+        self.write_uint(len(ik_list), 2)\r
+        for ik in ik_list:\r
+            self.write_uint(ik.index, 2)\r
+            self.write_uint(ik.target, 2)\r
+            self.write_uint(len(ik.children), 1)\r
+            self.write_uint(ik.iterations, 2)\r
+            self.write_float(ik.weight)\r
+            self.ios.write(struct.pack("=%dH" % len(ik.children), *ik.children))\r
+\r
+    def write_morphs(self, morphs):\r
+        self.write_uint(len(morphs), 2)\r
+        for morph in morphs:\r
+            self.write_text(morph.name, 20)\r
+            self.write_uint(len(morph.indices), 4)\r
+            self.write_uint(morph.type, 1)\r
+            for i, v in zip(morph.indices, morph.pos_list):\r
+                self.write_uint(i, 4)\r
+                self.write_vector3(v)\r
+\r
+    def write_morph_indices(self, morph_indices):\r
+        self.write_uint(len(morph_indices), 1)\r
+        self.ios.write(struct.pack("=%dH" % len(morph_indices), *morph_indices))\r
+\r
+    def write_bone_group_list(self, bone_group_list):\r
+        self.write_uint(len(bone_group_list), 1)\r
+        for g in bone_group_list:\r
+            self.write_text(g, 50)\r
+\r
+    def write_bone_display_list(self, bone_display_list):\r
+        self.write_uint(len(bone_display_list), 4)\r
+        for l in bone_display_list:\r
+            self.write_uint(l[0], 2)\r
+            self.write_uint(l[1], 1)\r
+\r
+    def write_rigidbodies(self, rigidbodies):\r
+        self.write_uint(len(rigidbodies), 4)\r
+        for r in rigidbodies:\r
+            self.write_text(r.name, 20)\r
+            self.write_uint(r.bone_index, 2)\r
+            self.write_uint(r.collision_group, 1)\r
+            self.write_uint(r.no_collision_group, 2)\r
+            self.write_uint(r.shape_type, 1)\r
+            self.write_vector3(r.shape_size)\r
+            self.write_vector3(r.shape_position)\r
+            self.write_vector3(r.shape_rotation)\r
+            self.write_float(r.mass)\r
+            self.write_float(r.linear_damping)\r
+            self.write_float(r.angular_damping)\r
+            self.write_float(r.restitution)\r
+            self.write_float(r.friction)\r
+            self.write_uint(r.mode, 1)\r
+\r
+    def write_joints(self, joints):\r
+        self.write_uint(len(joints), 4)\r
+        for j in joints:\r
+            self.write_text(j.name, 20)\r
+            self.write_uint(j.rigidbody_index_a, 4)\r
+            self.write_uint(j.rigidbody_index_b, 4)\r
+            self.write_vector3(j.position)\r
+            self.write_vector3(j.rotation)\r
+            self.write_vector3(j.translation_limit_min)\r
+            self.write_vector3(j.translation_limit_max)\r
+            self.write_vector3(j.rotation_limit_min)\r
+            self.write_vector3(j.rotation_limit_max)\r
+            self.write_vector3(j.spring_constant_translation)\r
+            self.write_vector3(j.spring_constant_rotation)\r
+\r
+\r
+def write(ios, model):\r
+    assert(isinstance(ios, io.IOBase))\r
+    assert(isinstance(model, pymeshio.pmd.Model))\r
+    writer=Writer(ios)\r
+    writer.write_text(b"Pmd")\r
+    writer.write_float(model.version)\r
+    writer.write_text(model.name, 20)\r
+    writer.write_text(model.comment, 256)\r
+    writer.write_veritices(model.vertices)\r
+    writer.write_indices(model.indices)\r
+    writer.write_materials(model.materials)\r
+    writer.write_bones(model.bones)\r
+    writer.write_ik_list(model.ik_list)\r
+    writer.write_morphs(model.morphs)\r
+    writer.write_morph_indices(model.morph_indices)\r
+    writer.write_bone_group_list(model.bone_group_list)\r
+    writer.write_bone_display_list(model.bone_display_list)\r
+    # extend data\r
+    writer.write_uint(1, 1)\r
+    writer.write_text(model.english_name, 20)\r
+    writer.write_text(model.english_comment, 256)\r
+    for bone in model.bones:\r
+        writer.write_text(bone.english_name, 20)\r
+    for skin in model.morphs:\r
+        if skin.name==b'base':\r
+            continue\r
+        writer.write_text(skin.english_name, 20)\r
+    for english in model.bone_group_english_list:\r
+        writer.write_text(english, 50)\r
+    for toon_texture in model.toon_textures:\r
+        writer.write_text(toon_texture, 100)\r
+    writer.write_rigidbodies(model.rigidbodies)\r
+    writer.write_joints(model.joints)\r
+    return True\r
+\r