OSDN Git Service

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