OSDN Git Service

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