OSDN Git Service

fix for gcc-4.5 on cygwin
[meshio/meshio.git] / src / pmd.h
index e1e25f9..d0deb7b 100644 (file)
--- a/src/pmd.h
+++ b/src/pmd.h
 #ifndef MESH_IO_PMD_H_INCLUDED
 #define MESH_IO_PMD_H_INCLUDED 
 
-#include <ostream>
-#include <vector>
 #include "la.h"
 #include "text.h"
+#include "binary.h"
+#include <ostream>
+#include <vector>
+#include <array>
 
 namespace meshio {
-namespace pmd {
-
-typedef ::meshio::la::Vector2 Vector2;
-typedef ::meshio::la::Vector3 Vector3;
-typedef ::meshio::la::Vector4 Vector4;
-typedef ::meshio::color::fRGBA fRGBA;
-typedef ::meshio::color::fRGB fRGB;
-
-////////////////////////////////////////////////////////////
-//! \92¸\93_
-////////////////////////////////////////////////////////////
-struct Vertex
-{
-       //! \8dÀ\95W
-       Vector3 pos;
-       //! \96@\90ü\83x\83N\83g\83\8b
-       Vector3 normal;
-       //! \83e\83N\83X\83`\83\83UV
-       Vector2 uv;
-       //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\931
-       unsigned short bone0;
-       //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\932
-       unsigned short bone1;
-       //! \83E\83F\83C\83g[0 - 100]
-       unsigned char weight0;
-       //! \94ñ\83G\83b\83W
-       unsigned char edge_flag;
-};
-inline std::ostream &operator<<(std::ostream &os, const Vertex &rhs)
-{
-       os
-               << "[Vertex"
-               << " pos:" << rhs.pos
-               << " normal:" << rhs.normal
-               << " uv:" << rhs.uv
-               << " bone0:" << rhs.bone0
-               << " bone1:" << rhs.bone1
-               << " weight0:" << (int)rhs.weight0
-               << " edge_flag:" << (int)rhs.edge_flag
-               << "]"
-               ;
-       return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \8dÞ\8e¿
-////////////////////////////////////////////////////////////
-struct Material
-{
-       //! Diffuse
-       fRGBA diffuse;
-       //! Shinness
-       float shinness;
-       //! Specular
-       fRGB specular;
-       //! Ambient
-       fRGB ambient;
-       //! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
-       unsigned char toon_index;
-       //! \97Ö\8as/\89e
-       unsigned char flag;
-       //! \96Ê\92¸\93_\90\94
-       unsigned int vertex_count;
-       //! \83e\83N\83X\83`\83\83
-       char texture[20];
-
-       std::wstring getTexture()const;
-       void setTexture(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os,
-               const Material &rhs)
-{
-       os
-               << "[Material"
-               << " diffuse:" << rhs.diffuse
-               << " toon_index:" << (int)rhs.toon_index
-               << " flag:" << (int)rhs.flag
-               << " vertex_count:" << rhs.vertex_count
-               << " texture:" << rhs.texture
-               << "]"
-               ;
-       return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93 
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93\82Ì\8eí\97Þ
-enum BONE_TYPE
-{
-       // \89ñ\93]
-       BONE_ROTATE=0,
-       // \89ñ\93]\82Æ\88Ú\93®
-       BONE_ROTATE_MOVE,
-       // IK
-       BONE_IK,
-       // \95s\96¾
-       BONE_UNKNOWN,
-       // IK\89e\8b¿\89º
-       BONE_IK_INFLUENCED,
-       // \89ñ\93]\89e\8b¿\89º
-       BONE_ROTATE_INFLUENCED,
-       // IK\90Ú\91±\90æ
-       BONE_IK_CONNECT,
-       // \94ñ\95\\8e¦
-       BONE_INVISIBLE,
-       // \94P\82è
-       BONE_TWIST,
-       // \89ñ\93]\98A\93®
-       BONE_REVOLVE,
-};
-struct Bone
-{
-       //! \96¼\91O
-       char name[20];
-       //! \90e\83{\81[\83\93
-       unsigned short parent_index;
-       //! \8eq\83{\81[\83\93
-       unsigned short tail_index;
-       //! \83{\81[\83\93\8eí\97Þ
-       BONE_TYPE type;
-       //! \89e\8b¿IK\83{\81[\83\93
-       unsigned short ik_index;
-       // \83{\81[\83\93\8dÀ\95W
-       Vector3 pos;
-       //! \89p\8cê\96¼
-       char english_name[20];
-       //! \83{\81[\83\93\8aK\91w\8d\\92z\97p
-       Bone* parent;
-       Vector3 tail;
-       std::vector<Bone*> children;
-       unsigned short index;
-
-       Bone()
-               : parent(0)
-               {}
-       std::wstring getName()const;
-       void setName(const char *src);
-       void setEnglishName(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os,
-               const Bone &rhs)
-{
-       os
-               << "[Bone "
-               << '"' << rhs.name << '"'
-               << "]"
-               ;
-       return os;
-}
-
-////////////////////////////////////////////////////////////
-//! IK
-////////////////////////////////////////////////////////////
-struct IK
-{
-       //! IK(IK\83^\81[\83Q\83b\83g)
-       unsigned short index;
-       //! Target(\83G\83t\83F\83N\83^\81[)
-       unsigned short target;
-       //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93\90\94
-       unsigned char length;
-       //! IK\92l1\81BCCD-IK\8e\8e\8ds\89ñ\90\94
-       unsigned short iterations;
-       //! IK\92l2\81BCCD-IK\8e\8e\8ds\88ê\89ñ\95Ó\82è\82Ì\89e\8b¿\93x
-       float weight;
-       //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93(\8aî\96{\93I\82É\90e\83{\81[\83\93\82É\91k\82é)
-       std::vector<unsigned short> children;
-};
-inline std::ostream &operator<<(std::ostream &os, const IK &rhs)
-{
-       os
-               << "[IK "
-               << "]"
-               ;
-       return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \95\\8fî
-////////////////////////////////////////////////////////////
-//! \95\\8fî\82Ì\8eí\97Þ
-enum MORPH_TYPE
-{
-       //! \83x\81[\83X\95\\8fî
-       MORPH_BASE=0,
-       //! \82Ü\82ä
-       MORPH_MAYU,
-       //! \96Ú
-       MORPH_ME,
-       //! \83\8a\83b\83v
-       MORPH_LIP,
-       //! \82»\82Ì\91¼
-       MORPH_OTHER,
-};
-struct Morph
-{
-       //! \95\\8fî\96¼
-       char name[20];
-       //! \8eg\97p\82·\82é\92¸\93_\90\94
-       unsigned int vertex_count;
-       //! \95ª\97Þ
-       unsigned char type;
-       //! \92¸\93_Index
-       std::vector<unsigned int> indices;
-       //! \88Ú\93®\97Ê
-       std::vector<Vector3> pos_list;
-       //! \89p\8cê\96¼
-       char english_name[20];
-
-       void append(int index, float x, float y, float z);
-       std::wstring getName()const;
-       void setName(const char *src);
-       void setEnglishName(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os, const Morph &rhs)
-{
-       os
-               << "[Morph "
-               << '"' << rhs.name << '"'
-               << "]"
-               ;
-       return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93\95\\8e¦\98g
-////////////////////////////////////////////////////////////
-struct BoneGroup
-{
-       char name[50];
-       char english_name[50];
-
-       void setName(const char *src);
-       void setEnglishName(const char *src);
-       std::wstring getName()const;
-};
-
-////////////////////////////////////////////////////////////
-//! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
-////////////////////////////////////////////////////////////
-struct ToonTexture
-{
-       char name[100];
-       std::wstring getName()const;
-       void setName(const char *src);
-};
-
-////////////////////////////////////////////////////////////
-//! \8d\84\91Ì
-////////////////////////////////////////////////////////////
-//! \8c`\8fó
-enum SHAPE_TYPE
-{
-       //! \8b\85
-       SHAPE_SPHERE=0,
-       //! \94 
-       SHAPE_BOX,
-       //! \83J\83v\83Z\83\8b
-       SHAPE_CAPSULE,
-};
-//! \8d\84\91Ì\83^\83C\83v
-enum PROCESS_TYPE
-{
-       //! \83{\81[\83\93\82Æ\93¯\82\93®\82«
-       RIGIDBODY_KINEMATICS=0,
-       //! \95¨\97\9d\89\89\8eZ
-       RIGIDBODY_PHYSICS,
-       //! \95¨\97\9d\89\89\8eZ\8c\8b\89Ê\82ð\83{\81[\83\93\82É\94½\89f\82·\82é
-       RIGIDBODY_PHYSICS_WITH_BONE,
-};
-
-struct RigidBody
-{
-       //! \8d\84\91Ì\96¼
-       char name[20];
-       //! \8aÖ\98A\83{\81[\83\93(\83{\81[\83\93\92Ç\8f]\82Æ\83{\81[\83\93\88Ê\92u\8d\87\82í\82¹\82Å\95K\97v)
-       unsigned short boneIndex;
-       //! \83O\83\8b\81[\83v
-       unsigned char group;
-       //! \94ñ\8fÕ\93Ë\83O\83\8b\81[\83v
-       unsigned short target;
-       //! \8c`\8fó
-       SHAPE_TYPE shapeType;
-       //! \83T\83C\83Y
-       float w;
-       float h;
-       float d;
-       //! \8ep\90¨
-       Vector3 position;
-       Vector3 rotation;
-       //! \8e¿\97Ê
-       float weight;
-       //! \95¨\97\9d\89\89\8eZ\83p\83\89\83\81\81[\83^(bullet)
-       float linearDamping;
-       float angularDamping;
-       float restitution;
-       float friction;
-       //! \8d\84\91Ì\83^\83C\83v
-       PROCESS_TYPE processType;
-
-       std::wstring getName()const;
-       void setName(const char *src);
-};
-
-//! Joint(\95¨\97\9d\89\89\8eZ\82Å\82ÌJoint\82ÆConstraint\82Í\93¯\82\88Ó\96¡)
-struct Constraint
-{
-       //! Joint\96¼
-       char name[20];
-       //! \90Ú\91±\8d\84\91ÌA
-       unsigned int rigidA;
-       //! \90Ú\91±\8d\84\91ÌB
-       unsigned int rigidB;
-       //! \88Ê\92u
-       Vector3 pos;
-       //! \89ñ\93]
-       Vector3 rot;
-       //! \88Ú\93®\90§\8cÀ
-       Vector3 constraintPosMin;
-       Vector3 constraintPosMax;
-       //! \89ñ\93]\90§\8cÀ
-       Vector3 constraintRotMin;
-       Vector3 constraintRotMax;
-       //! \82Î\82Ë
-       Vector3 springPos;
-       Vector3 springRot;
-
-       std::wstring getName()const;
-       void setName(const char *src);
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// IO
-///////////////////////////////////////////////////////////////////////////////
-struct IO
-{
-       float version;
-       char name[20];
-       char comment[256];
-       std::vector<Vertex> vertices;
-       std::vector<unsigned short> indices;
-       std::vector<Material*> materials;
-       std::vector<Bone> bones;
-       std::vector<IK> ik_list;
-       std::vector<Morph> morph_list;
-       std::vector<unsigned short> face_list;
-       std::vector<BoneGroup> bone_group_list;
-       std::vector<std::pair<unsigned short, unsigned char> > bone_display_list;
-       ToonTexture toon_textures[10];
-       std::vector<RigidBody> rigidbodies;
-       std::vector<Constraint> constraints;
-
-       char english_name[20];
-       char english_comment[256];
-
-       IO();
-       ~IO();
-       bool read(const char *path);
-       bool write(const char *path);
-       bool read(binary::IReader &reader);
-       bool write(binary::IWriter &writer);
-#ifdef _WIN32
-       bool read(const wchar_t *path);
-       bool write(const wchar_t *path);
+  namespace pmd {
+
+    ////////////////////////////////////////////////////////////
+    //! \92¸\93_
+    ////////////////////////////////////////////////////////////
+    struct Vertex
+    {
+      //! \8dÀ\95W
+      meshio::Vector3 pos;
+      //! \96@\90ü\83x\83N\83g\83\8b
+      meshio::Vector3 normal;
+      //! \83e\83N\83X\83`\83\83UV
+      meshio::Vector2 uv;
+      //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\931
+      unsigned short bone0;
+      //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\932
+      unsigned short bone1;
+      //! \83E\83F\83C\83g[0 - 100]
+      unsigned char weight0;
+      //! \94ñ\83G\83b\83W
+      unsigned char edge_flag;
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os, const Vertex &rhs)
+    {
+      os
+        << "[Vertex"
+        << " pos:" << rhs.pos
+        << " normal:" << rhs.normal
+        << " uv:" << rhs.uv
+        << " bone0:" << rhs.bone0
+        << " bone1:" << rhs.bone1
+        << " weight0:" << (int)rhs.weight0
+        << " edge_flag:" << (int)rhs.edge_flag
+        << "]"
+        ;
+      return os;
+    }
 #endif
 
-       const Vector2* getUV(int index)const;
-       std::wstring getName()const;
-       std::wstring getComment()const;
-       std::wstring getEnglishName()const;
-       std::wstring getEnglishComment()const;
-       void setName(const char *src);
-       void setComment(const char *src);
-       void setEnglishName(const char *src);
-       void setEnglishComment(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os, const IO &rhs)
-{
-       os
-               << "<PMD " << rhs.name << std::endl
-               << rhs.comment << std::endl
-               << "[vertices] " << rhs.vertices.size() << std::endl
-               << "[indices] " << rhs.indices.size() << std::endl
-               << "[materials] " << rhs.materials.size() << std::endl
-               ;
-       /*
-       std::copy(rhs.materials.begin(), rhs.materials.end(), 
-                       std::ostream_iterator<Material>(os, ""));
+    ////////////////////////////////////////////////////////////
+    //! \8dÞ\8e¿
+    ////////////////////////////////////////////////////////////
+    struct Material
+    {
+      //! Diffuse
+      meshio::fRGBA diffuse;
+      //! Shinness
+      float shinness;
+      //! Specular
+      meshio::fRGB specular;
+      //! Ambient
+      meshio::fRGB ambient;
+      //! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
+      unsigned char toon_index;
+      //! \97Ö\8as/\89e
+      unsigned char flag;
+      //! \96Ê\92¸\93_\90\94
+      unsigned int vertex_count;
+      //! \83e\83N\83X\83`\83\83
+      meshio::fixed_string<20> texture;
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os,
+        const Material &rhs)
+    {
+      os
+        << "[Material"
+        << " diffuse:" << rhs.diffuse
+        << " toon_index:" << (int)rhs.toon_index
+        << " flag:" << (int)rhs.flag
+        << " vertex_count:" << rhs.vertex_count
+        << " texture:" << rhs.texture
+        << "]"
+        ;
+      return os;
+    }
+#endif
 
-       os
-               << "[bones] " << rhs.bones.size() << std::endl
-               ;
-       std::copy(rhs.bones.begin(), rhs.bones.end(), 
-                       std::ostream_iterator<Bone>(os, ""));
+    ////////////////////////////////////////////////////////////
+    //! \83{\81[\83\93 
+    ////////////////////////////////////////////////////////////
+    //! \83{\81[\83\93\82Ì\8eí\97Þ
+    enum BONE_TYPE
+    {
+      // \89ñ\93]
+      BONE_ROTATE=0,
+      // \89ñ\93]\82Æ\88Ú\93®
+      BONE_ROTATE_MOVE,
+      // IK
+      BONE_IK,
+      // \95s\96¾
+      BONE_UNKNOWN,
+      // IK\89e\8b¿\89º
+      BONE_IK_INFLUENCED,
+      // \89ñ\93]\89e\8b¿\89º
+      BONE_ROTATE_INFLUENCED,
+      // IK\90Ú\91±\90æ
+      BONE_IK_CONNECT,
+      // \94ñ\95\\8e¦
+      BONE_INVISIBLE,
+      // \94P\82è
+      BONE_TWIST,
+      // \89ñ\93]\98A\93®
+      BONE_REVOLVE,
+    };
+    struct Bone
+    {
+      //! \96¼\91O
+      meshio::fixed_string<20> name;
+      //! \90e\83{\81[\83\93
+      unsigned short parent_index;
+      //! \8eq\83{\81[\83\93
+      unsigned short tail_index;
+      //! \83{\81[\83\93\8eí\97Þ
+      BONE_TYPE type;
+      //! \89e\8b¿IK\83{\81[\83\93
+      unsigned short ik_index;
+      // \83{\81[\83\93\8dÀ\95W
+      meshio::Vector3 pos;
+      //! \89p\8cê\96¼
+      meshio::fixed_string<20> english_name;
+      //! \83{\81[\83\93\8aK\91w\8d\\92z\97p
+      Bone* parent;
+      meshio::Vector3 tail;
+      std::vector<Bone*> children;
+      unsigned short index;
+
+      Bone()
+        : parent_index(-1), tail_index(-1), type(BONE_UNKNOWN), ik_index(-1), parent(0), index(-1)
+      {}
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os,
+        const Bone &rhs)
+    {
+      os
+        << "[Bone "
+        << '"' << rhs.name << '"'
+        << "]"
+        ;
+      return os;
+    }
+#endif
 
-       os
-               << "[ik] " << rhs.ik_list.size() << std::endl
-               ;
-       std::copy(rhs.ik_list.begin(), rhs.ik_list.end(), 
-                       std::ostream_iterator<IK>(os, ""));
+    ////////////////////////////////////////////////////////////
+    //! IK
+    ////////////////////////////////////////////////////////////
+    struct IK
+    {
+      //! IK(IK\83^\81[\83Q\83b\83g)
+      unsigned short index;
+      //! Target(\83G\83t\83F\83N\83^\81[)
+      unsigned short target;
+      //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93\90\94
+      unsigned char length;
+      //! IK\92l1\81BCCD-IK\8e\8e\8ds\89ñ\90\94
+      unsigned short iterations;
+      //! IK\92l2\81BCCD-IK\8e\8e\8ds\88ê\89ñ\95Ó\82è\82Ì\89e\8b¿\93x
+      float weight;
+      //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93(\8aî\96{\93I\82É\90e\83{\81[\83\93\82É\91k\82é)
+      std::vector<unsigned short> children;
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os, const IK &rhs)
+    {
+      os
+        << "[IK "
+        << "]"
+        ;
+      return os;
+    }
+#endif
 
-       os
-               << "[morph] " << rhs.morph_list.size() << std::endl
-               ;
-       std::copy(rhs.morph_list.begin(), rhs.morph_list.end(), 
-                       std::ostream_iterator<Morph>(os, ""));
-                       */
+    ////////////////////////////////////////////////////////////
+    //! \95\\8fî
+    ////////////////////////////////////////////////////////////
+    //! \95\\8fî\82Ì\8eí\97Þ
+    enum MORPH_TYPE
+    {
+      //! \83x\81[\83X\95\\8fî
+      MORPH_BASE=0,
+      //! \82Ü\82ä
+      MORPH_MAYU,
+      //! \96Ú
+      MORPH_ME,
+      //! \83\8a\83b\83v
+      MORPH_LIP,
+      //! \82»\82Ì\91¼
+      MORPH_OTHER,
+    };
+    struct Morph
+    {
+      //! \95\\8fî\96¼
+      meshio::fixed_string<20> name;
+      //! \8eg\97p\82·\82é\92¸\93_\90\94
+      unsigned int vertex_count;
+      //! \95ª\97Þ
+      unsigned char type;
+      //! \92¸\93_Index
+      std::vector<unsigned int> indices;
+      //! \88Ú\93®\97Ê
+      std::vector<meshio::Vector3> pos_list;
+      //! \89p\8cê\96¼
+      meshio::fixed_string<20> english_name;
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os, const Morph &rhs)
+    {
+      os
+        << "[Morph "
+        << '"' << rhs.name << '"'
+        << "]"
+        ;
+      return os;
+    }
+#endif
 
-       os
-               << ">" << std::endl
-               ;
-       return os;
-}
+    ////////////////////////////////////////////////////////////
+    //! \83{\81[\83\93\95\\8e¦\98g
+    ////////////////////////////////////////////////////////////
+    struct BoneGroup
+    {
+      meshio::fixed_string<50> name;
+      meshio::fixed_string<50> english_name;
+    };
+
+    ////////////////////////////////////////////////////////////
+    //! \8d\84\91Ì
+    ////////////////////////////////////////////////////////////
+    //! \8c`\8fó
+    enum SHAPE_TYPE
+    {
+      //! \8b\85
+      SHAPE_SPHERE=0,
+      //! \94 
+      SHAPE_BOX,
+      //! \83J\83v\83Z\83\8b
+      SHAPE_CAPSULE,
+    };
+    //! \8d\84\91Ì\83^\83C\83v
+    enum PROCESS_TYPE
+    {
+      //! \83{\81[\83\93\82Æ\93¯\82\93®\82«
+      RIGIDBODY_KINEMATICS=0,
+      //! \95¨\97\9d\89\89\8eZ
+      RIGIDBODY_PHYSICS,
+      //! \95¨\97\9d\89\89\8eZ\8c\8b\89Ê\82ð\83{\81[\83\93\82É\94½\89f\82·\82é
+      RIGIDBODY_PHYSICS_WITH_BONE,
+    };
+
+    struct RigidBody
+    {
+      //! \8d\84\91Ì\96¼
+      meshio::fixed_string<20> name;
+      //! \8aÖ\98A\83{\81[\83\93(\83{\81[\83\93\92Ç\8f]\82Æ\83{\81[\83\93\88Ê\92u\8d\87\82í\82¹\82Å\95K\97v)
+      unsigned short boneIndex;
+      //! \83O\83\8b\81[\83v
+      unsigned char group;
+      //! \94ñ\8fÕ\93Ë\83O\83\8b\81[\83v
+      unsigned short target;
+      //! \8c`\8fó
+      SHAPE_TYPE shapeType;
+      //! \83T\83C\83Y
+      float w;
+      float h;
+      float d;
+      //! \8ep\90¨
+      meshio::Vector3 position;
+      meshio::Vector3 rotation;
+      //! \8e¿\97Ê
+      float weight;
+      //! \95¨\97\9d\89\89\8eZ\83p\83\89\83\81\81[\83^(bullet)
+      float linearDamping;
+      float angularDamping;
+      float restitution;
+      float friction;
+      //! \8d\84\91Ì\83^\83C\83v
+      PROCESS_TYPE processType;
+    };
+
+    //! Joint(\95¨\97\9d\89\89\8eZ\82Å\82ÌJoint\82ÆConstraint\82Í\93¯\82\88Ó\96¡)
+    struct Constraint
+    {
+      //! Joint\96¼
+      meshio::fixed_string<20> name;
+      //! \90Ú\91±\8d\84\91ÌA
+      unsigned int rigidA;
+      //! \90Ú\91±\8d\84\91ÌB
+      unsigned int rigidB;
+      //! \88Ê\92u
+      meshio::Vector3 pos;
+      //! \89ñ\93]
+      meshio::Vector3 rot;
+      //! \88Ú\93®\90§\8cÀ
+      meshio::Vector3 constraintPosMin;
+      meshio::Vector3 constraintPosMax;
+      //! \89ñ\93]\90§\8cÀ
+      meshio::Vector3 constraintRotMin;
+      meshio::Vector3 constraintRotMax;
+      //! \82Î\82Ë
+      meshio::Vector3 springPos;
+      meshio::Vector3 springRot;
+    };
+
+
+    // IO
+    struct IO
+    {
+      float version;
+      meshio::fixed_string<20> name;
+      meshio::fixed_string<256> comment;
+      std::vector<Vertex> vertices;
+      std::vector<unsigned short> indices;
+      std::vector<Material> materials;
+      std::vector<Bone> bones;
+      std::vector<IK> ik_list;
+      std::vector<Morph> morph_list;
+      std::vector<unsigned short> face_list;
+      std::vector<BoneGroup> bone_group_list;
+      std::vector<std::pair<unsigned short, unsigned char> > bone_display_list;
+      std::array<meshio::fixed_string<100>, 10> toon_textures;
+      std::vector<RigidBody> rigidbodies;
+      std::vector<Constraint> constraints;
+
+      meshio::fixed_string<20> english_name;
+      meshio::fixed_string<256> english_comment;
+
+      IO();
+      bool read(const char *path);
+      bool write(const char *path);
+      bool read(meshio::binary::IReader &reader);
+      bool write(meshio::binary::IWriter &writer);
+    };
+#ifndef SWIG
+    inline std::ostream &operator<<(std::ostream &os, const IO &rhs)
+    {
+      os
+        << "<PMD " << rhs.name << std::endl
+        << rhs.comment << std::endl
+        << "[vertices] " << rhs.vertices.size() << std::endl
+        << "[indices] " << rhs.indices.size() << std::endl
+        << "[materials] " << rhs.materials.size() << std::endl
+        ;
+      /*
+         std::copy(rhs.materials.begin(), rhs.materials.end(), 
+         std::ostream_iterator<Material>(os, ""));
+
+         os
+         << "[bones] " << rhs.bones.size() << std::endl
+         ;
+         std::copy(rhs.bones.begin(), rhs.bones.end(), 
+         std::ostream_iterator<Bone>(os, ""));
+
+         os
+         << "[ik] " << rhs.ik_list.size() << std::endl
+         ;
+         std::copy(rhs.ik_list.begin(), rhs.ik_list.end(), 
+         std::ostream_iterator<IK>(os, ""));
+
+         os
+         << "[morph] " << rhs.morph_list.size() << std::endl
+         ;
+         std::copy(rhs.morph_list.begin(), rhs.morph_list.end(), 
+         std::ostream_iterator<Morph>(os, ""));
+       */
+
+      os
+        << ">" << std::endl
+        ;
+      return os;
+    }
+#endif
 
 
-} // namespace pmd
+  } // namespace pmd
 } // namespace meshio
 
 #endif // MESH_IO_PMD_H_INCLUDED