OSDN Git Service

chmod
[meshio/meshio.git] / src / vmd.cpp
1 #include "vmd.h"
2 #include "text.h"
3 #include <algorithm>
4 #include <string>
5
6 namespace meshio {
7   namespace vmd {
8
9     template<typename T>
10       struct SortKeyFrameList
11       {
12         typedef T MAP;
13         void operator()(typename MAP::value_type &channel)
14         {
15           channel.second->sort();
16         }
17       };
18
19     template<class READER>
20       void
21       readBoneMap(READER &reader, IO &io)
22       {
23         std::wstring name=
24           trim(cp932_to_unicode(reader.getString(15, true)));
25         unsigned int frame=reader.getUint();
26         IO::BoneMap::iterator found=io.boneMap.find(name);
27         if(found==io.boneMap.end()){
28           // not found
29           found=io.boneMap.insert(
30               std::make_pair(name, 
31                 new KeyFrameList<KeyFrame<BoneKey> >())).first;
32           io.boneKeys.push_back(name);
33         }
34         BoneKey &key=found->second->push(frame).key;
35
36         reader.get(key.pos);
37         reader.get(key.q);
38         reader.get(key.interpolationX);
39         reader.get(key.interpolationY);
40         reader.get(key.interpolationZ);
41         reader.get(key.interpolationRot);
42       }
43
44     template<class READER>
45       void
46       readMorphMap(READER &reader, IO &io)
47       {
48         std::wstring name=
49           trim(cp932_to_unicode(reader.getString(15, true)));
50         unsigned int frame=reader.getUint();
51         IO::MorphMap::iterator found=io.morphMap.find(name);
52         if(found==io.morphMap.end()){
53           // not found
54           found=io.morphMap.insert(
55               std::make_pair(name, 
56                 new KeyFrameList<KeyFrame<MorphKey> >())).first;
57           io.morphKeys.push_back(name);
58         }
59         MorphKey &key=found->second->push(frame).key;
60
61         reader.get(key.weight);
62       }
63
64     class Implementation
65     {
66       IO &io_;
67       binary::IReader &reader_;
68
69     public:
70       Implementation(IO &io, binary::IReader &reader)
71         : io_(io), reader_(reader)
72       {}
73
74       bool parse()
75       {
76         // check header
77         std::string line=reader_.getString(30, true);
78         if(line=="Vocaloid Motion Data file"){
79           io_.version="1";
80           reader_.get(io_.name);
81           return parseBody();
82         }
83         else if(line=="Vocaloid Motion Data 0002"){
84           io_.version="2";
85           reader_.get(io_.name);
86           return parseBody();
87         }
88         else{
89           //std::cout << "unknown header:" << line << std::endl;
90           return false;
91         }
92       }
93
94
95     private:
96       bool parseBody()
97       {
98         if(!parseFrame()){
99           return false;
100         }
101         if(!parseMorph()){
102           return false;
103         }
104         if(!parseCamera()){
105           return false;
106         }
107         if(!parseLight()){
108           return false;
109         }
110         // sort
111         std::for_each(io_.boneMap.begin(), io_.boneMap.end(), 
112             SortKeyFrameList<IO::BoneMap>());
113         std::for_each(io_.morphMap.begin(), io_.morphMap.end(), 
114             SortKeyFrameList<IO::MorphMap>());
115         return true;
116       }
117
118       bool parseMorph()
119       {
120         unsigned int count=reader_.getUint();
121         for(unsigned int i=0; i<count; ++i){
122           readMorphMap(reader_, io_);
123         }
124         return true;
125       }
126
127       bool parseFrame()
128       {
129         unsigned int count=reader_.getUint();
130         for(unsigned int i=0; i<count; ++i){
131           readBoneMap(reader_, io_);
132         }
133         return true;
134       }
135
136       bool parseCamera()
137       {
138         return true;
139       }
140
141       bool parseLight()
142       {
143         return true;
144       }
145     };
146
147
148     ///////////////////////////////////////////////////////////////////////////////
149     //! IO
150     ///////////////////////////////////////////////////////////////////////////////
151     IO::IO()
152     {
153     }
154
155     IO::~IO()
156     {
157       for(BoneMap::iterator it=boneMap.begin(); it!=boneMap.end(); ++it){
158         delete it->second;
159       }
160       boneMap.clear();
161
162       for(MorphMap::iterator it=morphMap.begin(); it!=morphMap.end(); ++it){
163         delete it->second;
164       }
165       morphMap.clear();
166
167     }
168
169     bool IO::read(binary::IReader &reader)
170     {
171       return Implementation(*this, reader).parse();
172     }
173
174     bool IO::read(const char *path)
175     {
176       std::vector<char> all;
177       binary::readAll(path, all);
178       if(all.empty()){
179         return false;
180       }
181       binary::MemoryReader reader(&all[0], all.size());
182       return read(reader);
183     }
184
185     bool IO::write(std::ostream &os)
186     {
187       // not implemented
188       return false;
189     }
190
191   } // namespace vmd
192 } // namespace meshio