OSDN Git Service

implement pmd_import.py.
[meshio/meshio.git] / src / pmd.cpp
1 #include "pmd.h"
2 #include <iostream>
3
4 namespace meshio {
5 namespace pmd {
6
7 // 38bytes
8 template<class READER>
9         void
10         read(READER &reader, Vertex &v)
11         {
12                 unsigned int pos=reader.getPos();
13                 reader.get(v.pos);
14                 reader.get(v.normal);
15                 reader.get(v.uv);
16                 reader.get(v.bone0);
17                 reader.get(v.bone1);
18                 reader.get(v.weight0);
19                 reader.get(v.edge_flag);
20                 assert(reader.getPos()-pos==38);
21         }
22
23
24 // 70bytes
25 template<class READER>
26         void
27         read(READER &reader, Material &m)
28         {
29                 unsigned int pos=reader.getPos();
30                 reader.get(m.diffuse);
31                 reader.get(m.shinness);
32                 reader.get(m.specular);
33                 reader.get(m.ambient);
34                 reader.get(m.toon_index);
35                 reader.get(m.flag);
36                 reader.get(m.vertex_count);
37                 text::copyStringAndFillZero(m.texture, reader.getString(20));
38                 assert(reader.getPos()-pos==70);
39         }
40
41 // 39bytes
42 template<class READER>
43         void
44         read(READER &reader, Bone &b)
45         {
46                 unsigned int pos=reader.getPos();
47                 text::copyStringAndFillZero(b.name, reader.getString(20));
48                 reader.get(b.parent_index);
49                 reader.get(b.tail_index);
50                 b.type=static_cast<BONE_TYPE>(reader.getUchar());
51                 reader.get(b.ik_index);
52                 reader.get(b.pos);
53                 assert(reader.getPos()-pos==39);
54         }
55
56 // 11+2xIK_COUNT bytes
57 template<class READER>
58         void
59         read(READER &reader, IK &ik)
60         {
61                 // 11bytes
62                 reader.get(ik.index);
63                 reader.get(ik.target);
64                 reader.get(ik.length);
65                 reader.get(ik.iterations);
66                 reader.get(ik.weight);
67                 // 2 x length bytes
68                 for(unsigned short j=0; j<ik.length; ++j){
69                         ik.children.push_back(reader.getUshort());
70                 }
71         }
72
73 // 25+12xMORPH_COUNT bytes
74 template<class READER>
75         void
76         read(READER &reader, Morph &m)
77         {
78                 // 25bytes
79                 text::copyStringAndFillZero(m.name, reader.getString(20));
80                 reader.get(m.vertex_count);
81                 m.type=static_cast<MORPH_TYPE>(reader.getUchar());
82                 // 12 x vertex_count bytes
83                 for(unsigned short i=0; i<m.vertex_count; ++i){
84                         m.indices.push_back(reader.getUint());
85                         m.pos_list.push_back(Vector3());
86                         reader.get(m.pos_list.back());
87                 }
88         }
89
90 // 83bytes
91 template<class READER>
92         void
93         read(READER &reader, RigidBody &r)
94         {
95                 unsigned int pos=reader.getPos();
96                 text::copyStringAndFillZero(r.name, reader.getString(20));
97                 reader.get(r.boneIndex);
98                 reader.get(r.group);
99                 reader.get(r.target);
100                 r.shapeType=static_cast<SHAPE_TYPE>(reader.getUchar());
101                 reader.get(r.w);
102                 reader.get(r.h);
103                 reader.get(r.d);
104                 reader.get(r.position);
105                 reader.get(r.rotation);
106                 reader.get(r.weight);
107                 reader.get(r.linearDamping);
108                 reader.get(r.angularDamping);
109                 reader.get(r.restitution);
110                 reader.get<float>(r.friction);
111                 r.processType=static_cast<PROCESS_TYPE>(reader.getUchar());
112                 assert(reader.getPos()-pos==83);
113         }
114
115 // 124bytes
116 template<class READER>
117         void
118         read(READER &reader, Constraint &c)
119         {
120                 unsigned int base_pos=reader.getPos();
121                 text::copyStringAndFillZero(c.name, reader.getString(20));
122                 reader.get(c.rigidA);
123                 reader.get(c.rigidB);
124                 reader.get(c.pos);
125                 reader.get(c.rot);
126                 reader.get(c.constraintPosMin);
127                 reader.get(c.constraintPosMax);
128                 reader.get(c.constraintRotMin);
129                 reader.get(c.constraintRotMax);
130                 reader.get(c.springPos);
131                 reader.get(c.springRot);
132                 assert(reader.getPos()-base_pos==124);
133         }
134
135 class Impl
136 {
137         IO &io_;
138         binary::IReader &reader_;
139
140 public:
141         Impl(IO &io, binary::IReader &reader)
142                 : io_(io), reader_(reader)
143                 {}
144
145         bool parse()
146         {
147                 if(!parseHeader()){
148                         return false;
149                 }
150                 if(!parseVertices()){
151                         return false;
152                 }
153                 if(!parseIndices()){
154                         return false;
155                 }
156                 if(!parseMaterials()){
157                         return false;
158                 }
159                 if(!parseBones()){
160                         return false;
161                 }
162                 if(!parseIK()){
163                         return false;
164                 }
165                 if(!parseMorph()){
166                         return false;
167                 }
168                 if(!parseFaceList()){
169                         return false;
170                 }
171                 if(!parseBoneNameList()){
172                         return false;
173                 }
174                 if(!parseBoneList()){
175                         return false;
176                 }
177                 if(reader_.isEnd()){
178                         return true;
179                 }
180
181                 ////////////////////////////////////////////////////////////
182                 // extended data
183                 ////////////////////////////////////////////////////////////
184                 // english
185                 ////////////////////////////////////////////////////////////
186                 if(reader_.getChar()){
187                         if(!parseEnglishName()){
188                                 return false;
189                         }
190                         if(!parseEnglishBone()){
191                                 return false;
192                         }
193                         if(!parseEnglishMorph()){
194                                 return false;
195                         }
196                         if(!parseEnglishBoneList()){
197                                 return false;
198                         }
199                 }
200                 if(reader_.isEnd()){
201                         return true;
202                 }
203
204                 // toone texture
205                 ////////////////////////////////////////////////////////////
206                 if(!parseToonTextures()){
207                         return false;
208                 }
209                 if(reader_.isEnd()){
210                         return true;
211                 }
212
213                 // physics
214                 ////////////////////////////////////////////////////////////
215                 if(!parseRigid()){
216                         return false;
217                 }
218                 if(!parseConstraint()){
219                         return false;
220                 }
221
222                 // end
223                 assert(reader_.isEnd());
224
225                 return true;
226         }
227
228 private:
229         bool parseConstraint()
230         {
231                 unsigned int count=reader_.getUint();
232                 for(unsigned int i=0; i<count; ++i){
233                         io_.constraints.push_back(Constraint());
234                         read(reader_, io_.constraints.back());
235                 }
236                 return true;
237         }
238
239         bool parseRigid()
240         {
241                 unsigned int count=reader_.getUint();
242                 for(unsigned int i=0; i<count; ++i){
243                         io_.rigidbodies.push_back(RigidBody());
244                         read(reader_, io_.rigidbodies.back());
245                 }
246                 return true;
247         }
248
249         bool parseToonTextures()
250         {
251                 for(size_t i=0; i<10; ++i){
252                         reader_.getString(100);
253                 }
254                 return true;
255         }
256
257         bool parseEnglishBoneList()
258         {
259                 for(size_t i=0; i<io_.bone_name_list.size(); ++i){
260                         std::string english=reader_.getString(50);
261                 }
262                 return true;
263         }
264
265         bool parseEnglishMorph()
266         {
267                 int count=io_.morph_list.size()-1;
268                 for(int i=0; i<count; ++i){
269                         text::copyStringAndFillZero(
270                                         io_.morph_list[i].english_name, reader_.getString(20));
271                 }
272                 return true;
273         }
274
275         bool parseEnglishBone()
276         {
277                 for(size_t i=0; i<io_.bones.size(); ++i){
278                         text::copyStringAndFillZero(
279                                         io_.bones[i].english_name, reader_.getString(20));
280                 }
281                 return true;
282         }
283
284         bool parseEnglishName()
285         {
286                 text::copyStringAndFillZero(io_.english_model_name, 
287                                 reader_.getString(20));
288                 text::copyStringAndFillZero(io_.english_comment, 
289                                 reader_.getString(256));
290                 return true;
291         }
292
293         bool parseBoneList()
294         {
295                 unsigned int count=reader_.getUint();
296                 for(unsigned int i=0; i<count; ++i){
297                         unsigned short bone=reader_.getUshort();
298                         unsigned char disp=reader_.getUchar();
299                         io_.bone_list.push_back(std::make_pair(bone, disp));
300                 }
301                 return true;
302         }
303
304         bool parseBoneNameList()
305         {
306                 unsigned int count=reader_.getUchar();
307                 for(unsigned int i=0; i<count; ++i){
308                         io_.bone_name_list.push_back(reader_.getString(50));
309                 }
310                 return true;
311         }
312
313         bool parseFaceList()
314         {
315                 unsigned int count=reader_.getUchar();
316                 for(unsigned int i=0; i<count; ++i){
317                         reader_.getUshort();
318                 }
319                 return true;
320         }
321
322         bool parseMorph()
323         {
324                 unsigned int count=reader_.getUshort();
325                 for(unsigned int i=0; i<count; ++i){
326                         io_.morph_list.push_back(Morph());
327                         read(reader_, io_.morph_list.back());
328                 }
329                 return true;
330         }
331
332         bool parseIK()
333         {
334                 unsigned int count=reader_.getUshort();
335                 for(unsigned int i=0; i<count; ++i){
336                         io_.ik_list.push_back(IK());
337                         read(reader_, io_.ik_list.back());
338                 }
339                 return true;
340         }
341
342         bool parseBones()
343         {
344                 unsigned int count=reader_.getUshort();
345                 for(unsigned int i=0; i<count; ++i){
346                         io_.bones.push_back(Bone());
347                         read(reader_, io_.bones.back());
348                 }
349                 return true;
350         }
351
352         bool parseMaterials()
353         {
354                 unsigned int count=reader_.getUint();
355                 for(unsigned int i=0; i<count; ++i){
356                         io_.materials.push_back(new Material());
357                         read(reader_, *io_.materials.back());
358                 }
359                 return true;
360         }
361
362         bool parseIndices()
363         {
364                 unsigned int count=reader_.getUint();
365                 for(unsigned int i=0; i<count; ++i){
366                         io_.indices.push_back(reader_.getUshort());
367                 }
368                 return true;
369         }
370
371         bool parseVertices()
372         {
373                 unsigned int count=reader_.getUint();
374                 for(unsigned int i=0; i<count; ++i){
375                         io_.vertices.push_back(Vertex());
376                         read(reader_, io_.vertices.back());
377                 }
378                 return true;
379         }
380
381         bool parseHeader()
382         {
383                 if(reader_.getString(3)!="Pmd"){
384                         //std::cout << "invalid pmd" << std::endl;
385                         return false;
386                 }
387                 reader_.get(io_.version);
388                 if(io_.version!=1.0){
389                         std::cout << "invalid vesion: " << io_.version <<std::endl;
390                         return false;
391                 }
392                 text::copyStringAndFillZero(io_.name, reader_.getString(20));
393                 text::copyStringAndFillZero(io_.comment, reader_.getString(256));
394
395                 return true;
396         }
397
398 };
399
400 ///////////////////////////////////////////////////////////////////////////////
401 // IO
402 ///////////////////////////////////////////////////////////////////////////////
403 IO::IO()
404 : version(0)
405 {}
406
407 IO::~IO()
408 {
409         for(size_t i=0; i<materials.size(); ++i){
410                 delete materials[i];
411         }
412         materials.clear();
413 }
414
415 bool IO::read(binary::IReader &input)
416 {
417         Impl impl(*this, input);
418         if(!impl.parse()){
419                 return false;
420         }
421
422         ////////////////////////////////////////////////////////////
423         // post process
424         ////////////////////////////////////////////////////////////
425         if(!morph_list.empty()){
426                 // validate morph
427                 assert(morph_list[0].type==MORPH_BASE);
428                 // check base
429                 Morph &base=morph_list[0];
430                 for(size_t i=0; i<base.vertex_count; ++i){
431                         assert(vertices[base.indices[i]].pos==base.pos_list[i]);
432                 }
433                 // check each face
434                 for(size_t i=1; i<morph_list.size(); ++i){
435                         Morph &m=morph_list[i];
436                         assert(m.type!=MORPH_BASE);
437                 }
438         }
439         ////////////////////////////////////////////////////////////
440         // setup bone
441         ////////////////////////////////////////////////////////////
442         for(size_t i=0; i<bones.size(); ++i){
443                 Bone &bone=bones[i];
444                 if(bone.parent_index!=0xFFFF){
445                         bone.parent=&bones[bone.parent_index];
446                         bone.parent->children.push_back(&bone);
447                 }
448                 if(bone.tail_index!=0xFFFF){
449                         bone.tail=bones[bone.tail_index].pos;
450                 }
451         }
452
453         return true;
454 }
455
456 bool IO::read(const char *path)
457 {
458         //std::locale::global(std::locale("japanese"));
459         std::vector<char> all;
460         binary::readAll(path, all);
461         if(all.empty()){
462                 return false;
463         }
464         binary::MemoryReader reader(&all[0], all.size());
465         return read(reader);
466 }
467
468 bool IO::write(std::ostream &os)
469 {
470         return false;
471 }
472
473 } // namespace
474 } // namespace
475