X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=src%2Fpmd.cpp;h=6df70d5888dda01097e8ceb8110b20dd7a7d1ba3;hb=HEAD;hp=9a88bd3bc79e18651e97b7c31e0d7f518c2ecec5;hpb=bc4f1e0f7da2f5447e0612569153971284d1155e;p=meshio%2Fmeshio.git diff --git a/src/pmd.cpp b/src/pmd.cpp index 9a88bd3..6df70d5 100644 --- a/src/pmd.cpp +++ b/src/pmd.cpp @@ -1,696 +1,701 @@ #include "pmd.h" -#include #include "text.h" +#ifndef _WIN32 +#include "win32.h" +#endif +#include + namespace meshio { -namespace pmd { - -std::wstring - Material::getTexture()const - { - return text::trim(text::to_WideChar(CP_OEMCP, - std::string(texture, texture+20))); - } - -std::wstring - Bone::getName()const - { - return text::trim(text::to_WideChar(CP_OEMCP, - std::string(name, name+20))); - } - -std::wstring - Morph::getName()const - { - return text::trim(text::to_WideChar(CP_OEMCP, - std::string(name, name+20))); - } - -void - Morph::append(int index, float x, float y, float z) - { - indices.push_back(index); - pos_list.push_back(Vector3(x, y, z)); - } - -std::wstring - IO::getName()const - { - return text::trim(text::to_WideChar(CP_OEMCP, - std::string(name, name+20))); - } - -// 38bytes -template - void - read(READER &reader, Vertex &v) - { - unsigned int pos=reader.getPos(); - reader.get(v.pos); - reader.get(v.normal); - reader.get(v.uv); - reader.get(v.bone0); - reader.get(v.bone1); - reader.get(v.weight0); - reader.get(v.edge_flag); - assert(reader.getPos()-pos==38); - } - - -// 70bytes -template - void - read(READER &reader, Material &m) - { - unsigned int pos=reader.getPos(); - reader.get(m.diffuse); - reader.get(m.shinness); - reader.get(m.specular); - reader.get(m.ambient); - reader.get(m.toon_index); - reader.get(m.flag); - reader.get(m.vertex_count); - text::copyStringAndFillZero(m.texture, reader.getString(20)); - assert(reader.getPos()-pos==70); - } - -// 39bytes -template - void - read(READER &reader, Bone &b) - { - unsigned int pos=reader.getPos(); - text::copyStringAndFillZero(b.name, reader.getString(20)); - reader.get(b.parent_index); - reader.get(b.tail_index); - b.type=static_cast(reader.getUchar()); - reader.get(b.ik_index); - reader.get(b.pos); - assert(reader.getPos()-pos==39); - } - -// 11+2xIK_COUNT bytes -template - void - read(READER &reader, IK &ik) - { - // 11bytes - reader.get(ik.index); - reader.get(ik.target); - reader.get(ik.length); - reader.get(ik.iterations); - reader.get(ik.weight); - // 2 x length bytes - for(unsigned short j=0; j - void - read(READER &reader, Morph &m) - { - // 25bytes - text::copyStringAndFillZero(m.name, reader.getString(20)); - reader.get(m.vertex_count); - m.type=static_cast(reader.getUchar()); - // 12 x vertex_count bytes - for(unsigned short i=0; i - void - read(READER &reader, RigidBody &r) - { - unsigned int pos=reader.getPos(); - text::copyStringAndFillZero(r.name, reader.getString(20)); - reader.get(r.boneIndex); - reader.get(r.group); - reader.get(r.target); - r.shapeType=static_cast(reader.getUchar()); - reader.get(r.w); - reader.get(r.h); - reader.get(r.d); - reader.get(r.position); - reader.get(r.rotation); - reader.get(r.weight); - reader.get(r.linearDamping); - reader.get(r.angularDamping); - reader.get(r.restitution); - reader.get(r.friction); - r.processType=static_cast(reader.getUchar()); - assert(reader.getPos()-pos==83); - } - -// 124bytes -template - void - read(READER &reader, Constraint &c) - { - unsigned int base_pos=reader.getPos(); - text::copyStringAndFillZero(c.name, reader.getString(20)); - reader.get(c.rigidA); - reader.get(c.rigidB); - reader.get(c.pos); - reader.get(c.rot); - reader.get(c.constraintPosMin); - reader.get(c.constraintPosMax); - reader.get(c.constraintRotMin); - reader.get(c.constraintRotMax); - reader.get(c.springPos); - reader.get(c.springRot); - assert(reader.getPos()-base_pos==124); - } - -class Impl -{ - IO &io_; - binary::IReader &reader_; - -public: - Impl(IO &io, binary::IReader &reader) - : io_(io), reader_(reader) - {} - - bool parse() - { - if(!parseHeader()){ - return false; - } - if(!parseVertices()){ - return false; - } - if(!parseIndices()){ - return false; - } - if(!parseMaterials()){ - return false; - } - if(!parseBones()){ - return false; - } - if(!parseIK()){ - return false; - } - if(!parseMorph()){ - return false; - } - if(!parseFaceList()){ - return false; - } - if(!parseBoneNameList()){ - return false; - } - if(!parseBoneList()){ - return false; - } - if(reader_.isEnd()){ - return true; - } - - //////////////////////////////////////////////////////////// - // extended data - //////////////////////////////////////////////////////////// - // english - //////////////////////////////////////////////////////////// - if(reader_.getChar()){ - if(!parseEnglishName()){ - return false; - } - if(!parseEnglishBone()){ - return false; - } - if(!parseEnglishMorph()){ - return false; - } - if(!parseEnglishBoneList()){ - return false; - } - } - if(reader_.isEnd()){ - return true; - } - - // toone texture - //////////////////////////////////////////////////////////// - if(!parseToonTextures()){ - return false; - } - if(reader_.isEnd()){ - return true; - } - - // physics - //////////////////////////////////////////////////////////// - if(!parseRigid()){ - return false; - } - if(!parseConstraint()){ - return false; - } - - // end - assert(reader_.isEnd()); - - return true; - } - -private: - bool parseConstraint() - { - unsigned int count=reader_.getUint(); - for(unsigned int i=0; ichildren.push_back(&bone); - } - if(bone.tail_index!=0){ - bone.tail=bones[bone.tail_index].pos; - } - } - - return true; -} - -/* -bool IO::read(const char *path) -{ - std::vector all; - binary::readAll(path, all); - if(all.empty()){ - return false; - } - binary::MemoryReader reader(&all[0], all.size()); - return read(reader); -} -*/ - -bool IO::read(const wchar_t *path) -{ - std::vector all; - binary::readAll(path, all); - std::cerr << all.size() << "bytes" << std::endl; - if(all.empty()){ - return false; - } - binary::MemoryReader reader(&all[0], all.size()); - return read(reader); -} - -bool IO::write(binary::IWriter &w) -{ - w.write("Pmd", 3); - w.writeValue(version); - w.write(name, 20); - w.write(comment, 256); - - // vertices - //std::cout << "vertices" << std::endl; - w.writeValue(vertices.size()); - for(size_t i=0; i(v.pos.x); - w.writeValue(v.pos.y); - w.writeValue(v.pos.z); - w.writeValue(v.normal.x); - w.writeValue(v.normal.y); - w.writeValue(v.normal.z); - w.writeValue(v.uv.x); - w.writeValue(v.uv.y); - w.writeValue(v.bone0); - w.writeValue(v.bone1); - w.writeValue(v.weight0); - w.writeValue(v.edge_flag); - } - - // faces - //std::cout << "faces" << std::endl; - w.writeValue(indices.size()); - if(indices.size()>0){ - w.writeArray(&indices[0], indices.size()); - } - - // materials - //std::cout << "materials" << std::endl; - w.writeValue(materials.size()); - for(size_t i=0; i(m.diffuse.r); - w.writeValue(m.diffuse.g); - w.writeValue(m.diffuse.b); - w.writeValue(m.diffuse.a); - w.writeValue(m.shinness); - w.writeValue(m.specular.r); - w.writeValue(m.specular.g); - w.writeValue(m.specular.b); - w.writeValue(m.ambient.r); - w.writeValue(m.ambient.g); - w.writeValue(m.ambient.b); - w.writeValue(m.toon_index); - w.writeValue(m.flag); - w.writeValue(m.vertex_count); - w.writeArray(m.texture, 20); - } - - // bones - //std::cout << "bones" << std::endl; - w.writeValue(bones.size()); - for(size_t i=0; i(b.name, 20); - w.writeValue(b.parent_index); - w.writeValue(b.tail_index); - w.writeValue(b.type); - w.writeValue(b.ik_index); - w.writeValue(b.pos.x); - w.writeValue(b.pos.y); - w.writeValue(b.pos.z); - } - - // ik - //std::cout << "ik" << std::endl; - w.writeValue(ik_list.size()); - for(size_t i=0; i(ik.index); - w.writeValue(ik.target); - w.writeValue(ik.length); - w.writeValue(ik.iterations); - w.writeValue(ik.weight); - WORD parent_index=bones[ik.target].parent_index; - for(size_t j=0; j(parent_index); - } - } - - // morph - //std::cout << "morph" << std::endl; - w.writeValue(morph_list.size()); - for(size_t i=0; i(m.name, 20); - w.writeValue(m.indices.size()); - w.writeValue(m.type); - for(size_t j=0; j(m.indices[j]); - Vector3 &pos=m.pos_list[j]; - w.writeValue(pos.x); - w.writeValue(pos.y); - w.writeValue(pos.z); - } - } - - // face list - //std::cout << "face list" << std::endl; - w.writeValue(face_list.size()); - if(face_list.size()>0){ - w.writeArray(&face_list[0], face_list.size()); - } - - // bone naem list - //std::cout << "bone name list" << std::endl; - w.writeValue(bone_display_name_list.size()); - for(size_t i=0; i(bone_display_name_list[i].name, 50); - } - - // bone list - //std::cout << "bone list" << std::endl; - w.writeValue(bone_display_list.size()); - for(size_t i=0; i(bone_display_list[i].first); - w.writeValue(bone_display_list[i].second); - } - - //////////////////////////////////////////////////////////// - // extend - //////////////////////////////////////////////////////////// - w.writeValue(0x01); - - //////////////////////////////////////////////////////////// - // english names - //////////////////////////////////////////////////////////// - w.writeArray(english_name, 20); - w.writeArray(english_comment, 256); - - for(size_t i=0; i(bones[i].english_name, 20); - } - - for(size_t i=1; i(morph_list[i].english_name, 20); - } - - for(size_t i=0; i(bone_display_name_list[i].english_name, 50); - } - - //////////////////////////////////////////////////////////// - // toon textures - //////////////////////////////////////////////////////////// - for(size_t i=0; i<10; ++i){ - w.writeArray(toon_textures[i].name, 100); - } - - return true; -} - -bool IO::write(const char *path) -{ - binary::FileWriter w(path); - return write(w); -} - -const Vector2* IO::getUV(int index)const -{ - return &vertices[index].uv; -} - -} // namespace -} // namespace + namespace pmd { + + // IO + bool IO::write(const char *path) + { + binary::FileWriter w(path); + return write(w); + } + + // 38bytes + template + void + read(READER &reader, Vertex &v) + { + unsigned int pos=reader.getPos(); + reader.get(v.pos); + reader.get(v.normal); + reader.get(v.uv); + reader.get(v.bone0); + reader.get(v.bone1); + reader.get(v.weight0); + reader.get(v.edge_flag); + assert(reader.getPos()-pos==38); + } + + // 70bytes + template + void + read(READER &reader, Material &m) + { + unsigned int pos=reader.getPos(); + reader.get(m.diffuse); + reader.get(m.shinness); + reader.get(m.specular); + reader.get(m.ambient); + reader.get(m.toon_index); + reader.get(m.flag); + reader.get(m.vertex_count); + reader.get(m.texture); + assert(reader.getPos()-pos==70); + } + + // 39bytes + template + void + read(READER &reader, Bone &b) + { + unsigned int pos=reader.getPos(); + reader.get(b.name); + reader.get(b.parent_index); + reader.get(b.tail_index); + b.type=static_cast(reader.getUchar()); + reader.get(b.ik_index); + reader.get(b.pos); + assert(reader.getPos()-pos==39); + } + + // 11+2xIK_COUNT bytes + template + void + read(READER &reader, IK &ik) + { + // 11bytes + reader.get(ik.index); + reader.get(ik.target); + reader.get(ik.length); + reader.get(ik.iterations); + reader.get(ik.weight); + // 2 x length bytes + for(unsigned short j=0; j + void + read(READER &reader, Morph &m) + { + // 25bytes + reader.get(m.name); + reader.get(m.vertex_count); + m.type=static_cast(reader.getUchar()); + // 12 x vertex_count bytes + for(unsigned short i=0; i + void + read(READER &reader, RigidBody &r) + { + unsigned int pos=reader.getPos(); + reader.get(r.name); + reader.get(r.boneIndex); + reader.get(r.group); + reader.get(r.target); + r.shapeType=static_cast(reader.getUchar()); + reader.get(r.w); + reader.get(r.h); + reader.get(r.d); + reader.get(r.position); + reader.get(r.rotation); + reader.get(r.weight); + reader.get(r.linearDamping); + reader.get(r.angularDamping); + reader.get(r.restitution); + reader.template get(r.friction); + r.processType=static_cast(reader.getUchar()); + assert(reader.getPos()-pos==83); + } + + // 124bytes + template + void + read(READER &reader, Constraint &c) + { + unsigned int base_pos=reader.getPos(); + reader.get(c.name); + reader.get(c.rigidA); + reader.get(c.rigidB); + reader.get(c.pos); + reader.get(c.rot); + reader.get(c.constraintPosMin); + reader.get(c.constraintPosMax); + reader.get(c.constraintRotMin); + reader.get(c.constraintRotMax); + reader.get(c.springPos); + reader.get(c.springRot); + assert(reader.getPos()-base_pos==124); + } + + class Impl + { + IO &io_; + binary::IReader &reader_; + + public: + Impl(IO &io, binary::IReader &reader) + : io_(io), reader_(reader) + {} + + bool parse() + { + if(!parseHeader()){ + return false; + } + if(!parseVertices()){ + return false; + } + if(!parseIndices()){ + return false; + } + if(!parseMaterials()){ + return false; + } + if(!parseBones()){ + return false; + } + if(!parseIK()){ + return false; + } + if(!parseMorph()){ + return false; + } + if(!parseFaceList()){ + return false; + } + if(!parseBoneGroupList()){ + return false; + } + if(!parseBoneList()){ + return false; + } + if(reader_.isEnd()){ + return true; + } + + //////////////////////////////////////////////////////////// + // extended data + //////////////////////////////////////////////////////////// + // english + //////////////////////////////////////////////////////////// + if(reader_.getChar()){ + if(!parseEnglishName()){ + return false; + } + if(!parseEnglishBone()){ + return false; + } + if(!parseEnglishMorph()){ + return false; + } + if(!parseEnglishBoneList()){ + return false; + } + } + if(reader_.isEnd()){ + return true; + } + + // toone texture + //////////////////////////////////////////////////////////// + if(!parseToonTextures()){ + return false; + } + if(reader_.isEnd()){ + return true; + } + + // physics + //////////////////////////////////////////////////////////// + if(!parseRigid()){ + return false; + } + if(!parseConstraint()){ + return false; + } + + // end + assert(reader_.isEnd()); + + return true; + } + + private: + bool parseConstraint() + { + unsigned int count=reader_.getUint(); + for(unsigned int i=0; i(std::string(toon));; + } + } + + bool IO::read(binary::IReader &input) + { + Impl impl(*this, input); + if(!impl.parse()){ + return false; + } + + //////////////////////////////////////////////////////////// + // post process + //////////////////////////////////////////////////////////// + if(!morph_list.empty()){ + // validate morph + assert(morph_list[0].type==MORPH_BASE); + // check base + Morph &base=morph_list[0]; + for(size_t i=0; ichildren.push_back(&bone); + } + if(bone.tail_index==0){ + bone.tail=Vector3(0, 0, 0); + } + else{ + bone.tail=bones[bone.tail_index].pos; + } + } + + return true; + } + + bool IO::read(const char *path) + { + std::vector all; + binary::readAll(path, all); + if(all.empty()){ + return false; + } + binary::MemoryReader reader(&all[0], all.size()); + return read(reader); + } + + bool IO::write(binary::IWriter &w) + { + w.write("Pmd", 3); + w.writeValue(version); + w.write(name); + w.write(comment); + + // vertices + //std::cout << "vertices" << std::endl; + w.writeValue(vertices.size()); + for(size_t i=0; i(v.pos.x); + w.writeValue(v.pos.y); + w.writeValue(v.pos.z); + w.writeValue(v.normal.x); + w.writeValue(v.normal.y); + w.writeValue(v.normal.z); + w.writeValue(v.uv.x); + w.writeValue(v.uv.y); + w.writeValue(v.bone0); + w.writeValue(v.bone1); + w.writeValue(v.weight0); + w.writeValue(v.edge_flag); + } + + // faces + //std::cout << "faces" << std::endl; + w.writeValue(indices.size()); + if(indices.size()>0){ + w.writeArray(&indices[0], indices.size()); + } + + // materials + //std::cout << "materials" << std::endl; + w.writeValue(materials.size()); + for(size_t i=0; i(m.diffuse.r); + w.writeValue(m.diffuse.g); + w.writeValue(m.diffuse.b); + w.writeValue(m.diffuse.a); + w.writeValue(m.shinness); + w.writeValue(m.specular.r); + w.writeValue(m.specular.g); + w.writeValue(m.specular.b); + w.writeValue(m.ambient.r); + w.writeValue(m.ambient.g); + w.writeValue(m.ambient.b); + w.writeValue(m.toon_index); + w.writeValue(m.flag); + w.writeValue(m.vertex_count); + w.write(m.texture); + } + + // bones + //std::cout << "bones" << std::endl; + w.writeValue(bones.size()); + for(size_t i=0; i(b.parent_index); + w.writeValue(b.tail_index); + w.writeValue(b.type); + w.writeValue(b.ik_index); + w.writeValue(b.pos.x); + w.writeValue(b.pos.y); + w.writeValue(b.pos.z); + } + + // ik + //std::cout << "ik" << std::endl; + w.writeValue(ik_list.size()); + for(size_t i=0; i(ik.index); + w.writeValue(ik.target); + w.writeValue(ik.length); + w.writeValue(ik.iterations); + w.writeValue(ik.weight); + WORD parent_index=bones[ik.target].parent_index; + for(size_t j=0; j(parent_index); + } + } + + // morph + //std::cout << "morph" << std::endl; + w.writeValue(morph_list.size()); + for(size_t i=0; i(m.indices.size()); + w.writeValue(m.type); + for(size_t j=0; j(m.indices[j]); + Vector3 &pos=m.pos_list[j]; + w.writeValue(pos.x); + w.writeValue(pos.y); + w.writeValue(pos.z); + } + } + + // face list + //std::cout << "face list" << std::endl; + w.writeValue(face_list.size()); + if(face_list.size()>0){ + w.writeArray(&face_list[0], face_list.size()); + } + + // bone name list + //std::cout << "bone name list" << std::endl; + w.writeValue(bone_group_list.size()); + for(size_t i=0; i(bone_display_list.size()); + for(size_t i=0; i(bone_display_list[i].first); + w.writeValue(bone_display_list[i].second); + } + + //////////////////////////////////////////////////////////// + // extend + //////////////////////////////////////////////////////////// + w.writeValue(0x01); + + //////////////////////////////////////////////////////////// + // english names + //////////////////////////////////////////////////////////// + w.write(english_name); + w.write(english_comment); + + for(size_t i=0; i(rigidbodies.size()); + for(size_t i=0; i(rb.boneIndex); + w.writeValue(rb.group); + w.writeValue(rb.target); + w.writeValue(rb.shapeType); + w.writeValue(rb.w); + w.writeValue(rb.h); + w.writeValue(rb.d); + w.writeValue(rb.position.x); + w.writeValue(rb.position.y); + w.writeValue(rb.position.z); + w.writeValue(rb.rotation.x); + w.writeValue(rb.rotation.y); + w.writeValue(rb.rotation.z); + w.writeValue(rb.weight); + w.writeValue(rb.linearDamping); + w.writeValue(rb.angularDamping); + w.writeValue(rb.restitution); + w.writeValue(rb.friction); + w.writeValue(rb.processType); + } + + //////////////////////////////////////////////////////////// + // constraints + //////////////////////////////////////////////////////////// + w.writeValue(constraints.size()); + for(size_t i=0; i(c.rigidA); + w.writeValue(c.rigidB); + w.writeValue(c.pos.x); + w.writeValue(c.pos.y); + w.writeValue(c.pos.z); + w.writeValue(c.rot.x); + w.writeValue(c.rot.y); + w.writeValue(c.rot.z); + w.writeValue(c.constraintPosMin.x); + w.writeValue(c.constraintPosMin.y); + w.writeValue(c.constraintPosMin.z); + w.writeValue(c.constraintPosMax.x); + w.writeValue(c.constraintPosMax.y); + w.writeValue(c.constraintPosMax.z); + w.writeValue(c.constraintRotMin.x); + w.writeValue(c.constraintRotMin.y); + w.writeValue(c.constraintRotMin.z); + w.writeValue(c.constraintRotMax.x); + w.writeValue(c.constraintRotMax.y); + w.writeValue(c.constraintRotMax.z); + w.writeValue(c.springPos.x); + w.writeValue(c.springPos.y); + w.writeValue(c.springPos.z); + w.writeValue(c.springRot.x); + w.writeValue(c.springRot.y); + w.writeValue(c.springRot.z); + } + + return true; + } + + + } // namespace pmd +} // namespace meshio