OSDN Git Service

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