OSDN Git Service

fixed by @santarh
[meshio/meshio.git] / src / pmd.cpp
1 #include "pmd.h"
2 #include "text.h"
3 #ifndef _WIN32
4 #include "win32.h"
5 #endif
6 #include <iostream>
7
8
9 namespace meshio {
10   namespace pmd {
11
12     // IO
13     bool IO::write(const char *path)
14     {
15       binary::FileWriter w(path);
16       return write(w);
17     }
18
19     // 38bytes
20     template<class READER>
21       void
22       read(READER &reader, Vertex &v)
23       {
24         unsigned int pos=reader.getPos();
25         reader.get(v.pos);
26         reader.get(v.normal);
27         reader.get(v.uv);
28         reader.get(v.bone0);
29         reader.get(v.bone1);
30         reader.get(v.weight0);
31         reader.get(v.edge_flag);
32         assert(reader.getPos()-pos==38);
33       }
34
35     // 70bytes
36     template<class READER>
37       void
38       read(READER &reader, Material &m)
39       {
40         unsigned int pos=reader.getPos();
41         reader.get(m.diffuse);
42         reader.get(m.shinness);
43         reader.get(m.specular);
44         reader.get(m.ambient);
45         reader.get(m.toon_index);
46         reader.get(m.flag);
47         reader.get(m.vertex_count);
48         reader.get(m.texture);
49         assert(reader.getPos()-pos==70);
50       }
51
52     // 39bytes
53     template<class READER>
54       void
55       read(READER &reader, Bone &b)
56       {
57         unsigned int pos=reader.getPos();
58         reader.get(b.name);
59         reader.get(b.parent_index);
60         reader.get(b.tail_index);
61         b.type=static_cast<BONE_TYPE>(reader.getUchar());
62         reader.get(b.ik_index);
63         reader.get(b.pos);
64         assert(reader.getPos()-pos==39);
65       }
66
67     // 11+2xIK_COUNT bytes
68     template<class READER>
69       void
70       read(READER &reader, IK &ik)
71       {
72         // 11bytes
73         reader.get(ik.index);
74         reader.get(ik.target);
75         reader.get(ik.length);
76         reader.get(ik.iterations);
77         reader.get(ik.weight);
78         // 2 x length bytes
79         for(unsigned short j=0; j<ik.length; ++j){
80           ik.children.push_back(reader.getUshort());
81         }
82       }
83
84     // 25+12xMORPH_COUNT bytes
85     template<class READER>
86       void
87       read(READER &reader, Morph &m)
88       {
89         // 25bytes
90         reader.get(m.name);
91         reader.get(m.vertex_count);
92         m.type=static_cast<MORPH_TYPE>(reader.getUchar());
93         // 12 x vertex_count bytes
94         for(unsigned short i=0; i<m.vertex_count; ++i){
95           m.indices.push_back(reader.getUint());
96           m.pos_list.push_back(Vector3());
97           reader.get(m.pos_list.back());
98         }
99       }
100
101     // 83bytes
102     template<class READER>
103       void
104       read(READER &reader, RigidBody &r)
105       {
106         unsigned int pos=reader.getPos();
107         reader.get(r.name);
108         reader.get(r.boneIndex);
109         reader.get(r.group);
110         reader.get(r.target);
111         r.shapeType=static_cast<SHAPE_TYPE>(reader.getUchar());
112         reader.get(r.w);
113         reader.get(r.h);
114         reader.get(r.d);
115         reader.get(r.position);
116         reader.get(r.rotation);
117         reader.get(r.weight);
118         reader.get(r.linearDamping);
119         reader.get(r.angularDamping);
120         reader.get(r.restitution);
121         reader.template get<float>(r.friction);
122         r.processType=static_cast<PROCESS_TYPE>(reader.getUchar());
123         assert(reader.getPos()-pos==83);
124       }
125
126     // 124bytes
127     template<class READER>
128       void
129       read(READER &reader, Constraint &c)
130       {
131         unsigned int base_pos=reader.getPos();
132         reader.get(c.name);
133         reader.get(c.rigidA);
134         reader.get(c.rigidB);
135         reader.get(c.pos);
136         reader.get(c.rot);
137         reader.get(c.constraintPosMin);
138         reader.get(c.constraintPosMax);
139         reader.get(c.constraintRotMin);
140         reader.get(c.constraintRotMax);
141         reader.get(c.springPos);
142         reader.get(c.springRot);
143         assert(reader.getPos()-base_pos==124);
144       }
145
146     class Impl
147     {
148       IO &io_;
149       binary::IReader &reader_;
150
151     public:
152       Impl(IO &io, binary::IReader &reader)
153         : io_(io), reader_(reader)
154       {}
155
156       bool parse()
157       {
158         if(!parseHeader()){
159           return false;
160         }
161         if(!parseVertices()){
162           return false;
163         }
164         if(!parseIndices()){
165           return false;
166         }
167         if(!parseMaterials()){
168           return false;
169         }
170         if(!parseBones()){
171           return false;
172         }
173         if(!parseIK()){
174           return false;
175         }
176         if(!parseMorph()){
177           return false;
178         }
179         if(!parseFaceList()){
180           return false;
181         }
182         if(!parseBoneGroupList()){
183           return false;
184         }
185         if(!parseBoneList()){
186           return false;
187         }
188         if(reader_.isEnd()){
189           return true;
190         }
191
192         ////////////////////////////////////////////////////////////
193         // extended data
194         ////////////////////////////////////////////////////////////
195         // english
196         ////////////////////////////////////////////////////////////
197         if(reader_.getChar()){
198           if(!parseEnglishName()){
199             return false;
200           }
201           if(!parseEnglishBone()){
202             return false;
203           }
204           if(!parseEnglishMorph()){
205             return false;
206           }
207           if(!parseEnglishBoneList()){
208             return false;
209           }
210         }
211         if(reader_.isEnd()){
212           return true;
213         }
214
215         // toone texture
216         ////////////////////////////////////////////////////////////
217         if(!parseToonTextures()){
218           return false;
219         }
220         if(reader_.isEnd()){
221           return true;
222         }
223
224         // physics
225         ////////////////////////////////////////////////////////////
226         if(!parseRigid()){
227           return false;
228         }
229         if(!parseConstraint()){
230           return false;
231         }
232
233         // end
234         assert(reader_.isEnd());
235
236         return true;
237       }
238
239     private:
240       bool parseConstraint()
241       {
242         unsigned int count=reader_.getUint();
243         for(unsigned int i=0; i<count; ++i){
244           io_.constraints.push_back(Constraint());
245           read(reader_, io_.constraints.back());
246         }
247         return true;
248       }
249
250       bool parseRigid()
251       {
252         unsigned int count=reader_.getUint();
253         for(unsigned int i=0; i<count; ++i){
254           io_.rigidbodies.push_back(RigidBody());
255           read(reader_, io_.rigidbodies.back());
256         }
257         return true;
258       }
259
260       bool parseToonTextures()
261       {
262         for(size_t i=0; i<10; ++i){
263           reader_.get(io_.toon_textures[i]);
264         }
265         return true;
266       }
267
268       bool parseEnglishBoneList()
269       {
270         for(size_t i=0; i<io_.bone_group_list.size(); ++i){
271             reader_.get(io_.bone_group_list[i].english_name);
272         }
273         return true;
274       }
275
276       bool parseEnglishMorph()
277       {
278         int count=io_.morph_list.size()-1;
279         for(int i=0; i<count; ++i){
280           reader_.get(io_.morph_list[i].english_name);
281         }
282         return true;
283       }
284
285       bool parseEnglishBone()
286       {
287         for(size_t i=0; i<io_.bones.size(); ++i){
288           reader_.get(io_.bones[i].english_name);
289         }
290         return true;
291       }
292
293       bool parseEnglishName()
294       {
295         reader_.get(io_.english_name);
296         reader_.get(io_.english_comment);
297         return true;
298       }
299
300       bool parseBoneList()
301       {
302         unsigned int count=reader_.getUint();
303         for(unsigned int i=0; i<count; ++i){
304           unsigned short bone=reader_.getUshort();
305           unsigned char disp=reader_.getUchar();
306           io_.bone_display_list.push_back(std::make_pair(bone, disp));
307         }
308         return true;
309       }
310
311       bool parseBoneGroupList()
312       {
313         unsigned int count=reader_.getUchar();
314         for(unsigned int i=0; i<count; ++i){
315           io_.bone_group_list.push_back(BoneGroup());
316           reader_.get(io_.bone_group_list.back().name);
317         }
318         return true;
319       }
320
321       bool parseFaceList()
322       {
323         unsigned int count=reader_.getUchar();
324         for(unsigned int i=0; i<count; ++i){
325           io_.face_list.push_back(reader_.getUshort());
326         }
327         return true;
328       }
329
330       bool parseMorph()
331       {
332         unsigned int count=reader_.getUshort();
333         for(unsigned int i=0; i<count; ++i){
334           io_.morph_list.push_back(Morph());
335           read(reader_, io_.morph_list.back());
336         }
337         return true;
338       }
339
340       bool parseIK()
341       {
342         unsigned int count=reader_.getUshort();
343         for(unsigned int i=0; i<count; ++i){
344           io_.ik_list.push_back(IK());
345           read(reader_, io_.ik_list.back());
346         }
347         return true;
348       }
349
350       bool parseBones()
351       {
352         unsigned int count=reader_.getUshort();
353         for(unsigned int i=0; i<count; ++i){
354           io_.bones.push_back(Bone());
355           read(reader_, io_.bones.back());
356         }
357         return true;
358       }
359
360       bool parseMaterials()
361       {
362         unsigned int count=reader_.getUint();
363         for(unsigned int i=0; i<count; ++i){
364           io_.materials.push_back(Material());
365           read(reader_, io_.materials.back());
366         }
367         return true;
368       }
369
370       bool parseIndices()
371       {
372         unsigned int count=reader_.getUint();
373         for(unsigned int i=0; i<count; ++i){
374           io_.indices.push_back(reader_.getUshort());
375         }
376         return true;
377       }
378
379       bool parseVertices()
380       {
381         unsigned int count=reader_.getUint();
382         for(unsigned int i=0; i<count; ++i){
383           io_.vertices.push_back(Vertex());
384           read(reader_, io_.vertices.back());
385         }
386         return true;
387       }
388
389       bool parseHeader()
390       {
391         if(reader_.getString(3)!="Pmd"){
392           //std::cout << "invalid pmd" << std::endl;
393           return false;
394         }
395         reader_.get(io_.version);
396         if(io_.version!=1.0){
397           std::cout << "invalid vesion: " << io_.version <<std::endl;
398           return false;
399         }
400         reader_.get(io_.name);
401         reader_.get(io_.comment);
402         return true;
403       }
404
405     };
406
407     // IO
408     IO::IO()
409       : version(0)
410     {
411       for(int i=0; i<10; ++i){
412         char toon[100];
413         sprintf(toon, "toon%02d.bmp", i+1);
414         toon_textures[i]=fixed_string<100>(std::string(toon));;
415       }
416     }
417
418     bool IO::read(binary::IReader &input)
419     {
420       Impl impl(*this, input);
421       if(!impl.parse()){
422         return false;
423       }
424
425       ////////////////////////////////////////////////////////////
426       // post process
427       ////////////////////////////////////////////////////////////
428       if(!morph_list.empty()){
429         // validate morph
430         assert(morph_list[0].type==MORPH_BASE);
431         // check base
432         Morph &base=morph_list[0];
433         for(size_t i=0; i<base.vertex_count; ++i){
434           assert(vertices[base.indices[i]].pos==base.pos_list[i]);
435         }
436         // check each face
437         for(size_t i=1; i<morph_list.size(); ++i){
438           Morph &m=morph_list[i];
439           assert(m.type!=MORPH_BASE);
440         }
441       }
442       ////////////////////////////////////////////////////////////
443       // setup bone
444       ////////////////////////////////////////////////////////////
445       for(size_t i=0; i<bones.size(); ++i){
446         Bone &bone=bones[i];
447         bone.index=i;
448         if(bone.parent_index!=0xFFFF){
449           bone.parent=&bones[bone.parent_index];
450           bone.parent->children.push_back(&bone);
451         }
452         if(bone.tail_index==0){
453           bone.tail=Vector3(0, 0, 0);
454         }
455         else{
456           bone.tail=bones[bone.tail_index].pos;
457         }
458       }
459
460       return true;
461     }
462
463     bool IO::read(const char *path)
464     {
465       std::vector<char> all;
466       binary::readAll(path, all);
467       if(all.empty()){
468         return false;
469       }
470       binary::MemoryReader reader(&all[0], all.size());
471       return read(reader);
472     }
473
474     bool IO::write(binary::IWriter &w)
475     {
476       w.write("Pmd", 3);
477       w.writeValue<float>(version);
478       w.write(name);
479       w.write(comment);
480
481       // vertices
482       //std::cout << "vertices" << std::endl;
483       w.writeValue<DWORD>(vertices.size());
484       for(size_t i=0; i<vertices.size(); ++i){
485         Vertex &v=vertices[i];
486         w.writeValue<float>(v.pos.x);
487         w.writeValue<float>(v.pos.y);
488         w.writeValue<float>(v.pos.z);
489         w.writeValue<float>(v.normal.x);
490         w.writeValue<float>(v.normal.y);
491         w.writeValue<float>(v.normal.z);
492         w.writeValue<float>(v.uv.x);
493         w.writeValue<float>(v.uv.y);
494         w.writeValue<WORD>(v.bone0);
495         w.writeValue<WORD>(v.bone1);
496         w.writeValue<BYTE>(v.weight0);
497         w.writeValue<BYTE>(v.edge_flag);
498       }
499
500       // faces
501       //std::cout << "faces" << std::endl;
502       w.writeValue<DWORD>(indices.size());
503       if(indices.size()>0){
504         w.writeArray<WORD>(&indices[0], indices.size());
505       }
506
507       // materials
508       //std::cout << "materials" << std::endl;
509       w.writeValue<DWORD>(materials.size());
510       for(size_t i=0; i<materials.size(); ++i){
511         Material &m=materials[i];
512         w.writeValue<float>(m.diffuse.r);
513         w.writeValue<float>(m.diffuse.g);
514         w.writeValue<float>(m.diffuse.b);
515         w.writeValue<float>(m.diffuse.a);
516         w.writeValue<float>(m.shinness);
517         w.writeValue<float>(m.specular.r);
518         w.writeValue<float>(m.specular.g);
519         w.writeValue<float>(m.specular.b);
520         w.writeValue<float>(m.ambient.r);
521         w.writeValue<float>(m.ambient.g);
522         w.writeValue<float>(m.ambient.b);
523         w.writeValue<BYTE>(m.toon_index);
524         w.writeValue<BYTE>(m.flag);
525         w.writeValue<DWORD>(m.vertex_count);
526         w.write(m.texture);
527       }
528
529       // bones
530       //std::cout << "bones" << std::endl;
531       w.writeValue<WORD>(bones.size());
532       for(size_t i=0; i<bones.size(); ++i){
533         Bone &b=bones[i];
534         w.write(b.name);
535         w.writeValue<WORD>(b.parent_index);
536         w.writeValue<WORD>(b.tail_index);
537         w.writeValue<BYTE>(b.type);
538         w.writeValue<WORD>(b.ik_index);
539         w.writeValue<float>(b.pos.x);
540         w.writeValue<float>(b.pos.y);
541         w.writeValue<float>(b.pos.z);
542       }
543
544       // ik
545       //std::cout << "ik" << std::endl;
546       w.writeValue<WORD>(ik_list.size());
547       for(size_t i=0; i<ik_list.size(); ++i){
548         IK &ik=ik_list[i];
549         w.writeValue<WORD>(ik.index);
550         w.writeValue<WORD>(ik.target);
551         w.writeValue<BYTE>(ik.length);
552         w.writeValue<WORD>(ik.iterations);
553         w.writeValue<float>(ik.weight);
554         WORD parent_index=bones[ik.target].parent_index;
555         for(size_t j=0; j<ik.length; 
556             ++j, parent_index=bones[parent_index].parent_index){
557           w.writeValue<WORD>(parent_index);
558         }
559       }
560
561       // morph
562       //std::cout << "morph" << std::endl;
563       w.writeValue<WORD>(morph_list.size());
564       for(size_t i=0; i<morph_list.size(); ++i){
565         Morph &m=morph_list[i];
566         w.write(m.name);
567         w.writeValue<DWORD>(m.indices.size());
568         w.writeValue<BYTE>(m.type);
569         for(size_t j=0; j<m.indices.size(); ++j){
570           w.writeValue<DWORD>(m.indices[j]);
571           Vector3 &pos=m.pos_list[j];
572           w.writeValue<float>(pos.x);
573           w.writeValue<float>(pos.y);
574           w.writeValue<float>(pos.z);
575         }
576       }
577
578       // face list
579       //std::cout << "face list" << std::endl;
580       w.writeValue<BYTE>(face_list.size());
581       if(face_list.size()>0){
582         w.writeArray<WORD>(&face_list[0], face_list.size());
583       }
584
585       // bone name list
586       //std::cout << "bone name list" << std::endl;
587       w.writeValue<BYTE>(bone_group_list.size());
588       for(size_t i=0; i<bone_group_list.size(); ++i){
589         // 50bytes
590         w.write(bone_group_list[i].name);
591       }
592
593       // bone list
594       //std::cout << "bone list" << std::endl;
595       w.writeValue<DWORD>(bone_display_list.size());
596       for(size_t i=0; i<bone_display_list.size(); ++i){
597         w.writeValue<WORD>(bone_display_list[i].first);
598         w.writeValue<BYTE>(bone_display_list[i].second);
599       }
600
601       ////////////////////////////////////////////////////////////
602       // extend
603       ////////////////////////////////////////////////////////////
604       w.writeValue<char>(0x01);
605
606       ////////////////////////////////////////////////////////////
607       // english names
608       ////////////////////////////////////////////////////////////
609       w.write(english_name);
610       w.write(english_comment);
611
612       for(size_t i=0; i<bones.size(); ++i){
613         w.write(bones[i].english_name);
614       }
615
616       // skip base
617       for(size_t i=1; i<morph_list.size(); ++i){
618         w.write(morph_list[i].english_name);
619       }
620
621       for(size_t i=0; i<bone_group_list.size(); ++i){
622         w.write(bone_group_list[i].english_name);
623       }
624
625       ////////////////////////////////////////////////////////////
626       // toon textures
627       ////////////////////////////////////////////////////////////
628       for(size_t i=0; i<10; ++i){
629         w.write(toon_textures[i]);
630       }
631
632       ////////////////////////////////////////////////////////////
633       // rigid bodies
634       ////////////////////////////////////////////////////////////
635       w.writeValue<DWORD>(rigidbodies.size());
636       for(size_t i=0; i<rigidbodies.size(); ++i){
637         RigidBody &rb=rigidbodies[i];
638         w.write(rb.name);
639         w.writeValue<WORD>(rb.boneIndex);
640         w.writeValue<BYTE>(rb.group);
641         w.writeValue<WORD>(rb.target);
642         w.writeValue<BYTE>(rb.shapeType);
643         w.writeValue<float>(rb.w);
644         w.writeValue<float>(rb.h);
645         w.writeValue<float>(rb.d);
646         w.writeValue<float>(rb.position.x);
647         w.writeValue<float>(rb.position.y);
648         w.writeValue<float>(rb.position.z);
649         w.writeValue<float>(rb.rotation.x);
650         w.writeValue<float>(rb.rotation.y);
651         w.writeValue<float>(rb.rotation.z);
652         w.writeValue<float>(rb.weight);
653         w.writeValue<float>(rb.linearDamping);
654         w.writeValue<float>(rb.angularDamping);
655         w.writeValue<float>(rb.restitution);
656         w.writeValue<float>(rb.friction);
657         w.writeValue<BYTE>(rb.processType);
658       }
659
660       ////////////////////////////////////////////////////////////
661       // constraints
662       ////////////////////////////////////////////////////////////
663       w.writeValue<DWORD>(constraints.size());
664       for(size_t i=0; i<constraints.size(); ++i){
665         Constraint &c=constraints[i];
666         w.write(c.name);
667         w.writeValue<DWORD>(c.rigidA);
668         w.writeValue<DWORD>(c.rigidB);
669         w.writeValue<float>(c.pos.x);
670         w.writeValue<float>(c.pos.y);
671         w.writeValue<float>(c.pos.z);
672         w.writeValue<float>(c.rot.x);
673         w.writeValue<float>(c.rot.y);
674         w.writeValue<float>(c.rot.z);
675         w.writeValue<float>(c.constraintPosMin.x);
676         w.writeValue<float>(c.constraintPosMin.y);
677         w.writeValue<float>(c.constraintPosMin.z);
678         w.writeValue<float>(c.constraintPosMax.x);
679         w.writeValue<float>(c.constraintPosMax.y);
680         w.writeValue<float>(c.constraintPosMax.z);
681         w.writeValue<float>(c.constraintRotMin.x);
682         w.writeValue<float>(c.constraintRotMin.y);
683         w.writeValue<float>(c.constraintRotMin.z);
684         w.writeValue<float>(c.constraintRotMax.x);
685         w.writeValue<float>(c.constraintRotMax.y);
686         w.writeValue<float>(c.constraintRotMax.z);
687         w.writeValue<float>(c.springPos.x);
688         w.writeValue<float>(c.springPos.y);
689         w.writeValue<float>(c.springPos.z);
690         w.writeValue<float>(c.springRot.x);
691         w.writeValue<float>(c.springRot.y);
692         w.writeValue<float>(c.springRot.z);
693       }
694
695       return true;
696     }
697
698
699   } // namespace pmd
700 } // namespace meshio
701