OSDN Git Service

terminate string with '\n'.
[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                         std::string english=reader_.getString(50);
297                 }
298                 return true;
299         }
300
301         bool parseEnglishMorph()
302         {
303                 int count=io_.morph_list.size()-1;
304                 for(int i=0; i<count; ++i){
305                         text::copyStringAndFillZero(
306                                         io_.morph_list[i].english_name, reader_.getString(20));
307                 }
308                 return true;
309         }
310
311         bool parseEnglishBone()
312         {
313                 for(size_t i=0; i<io_.bones.size(); ++i){
314                         text::copyStringAndFillZero(
315                                         io_.bones[i].english_name, reader_.getString(20));
316                 }
317                 return true;
318         }
319
320         bool parseEnglishName()
321         {
322                 text::copyStringAndFillZero(io_.english_model_name, 
323                                 reader_.getString(20));
324                 text::copyStringAndFillZero(io_.english_comment, 
325                                 reader_.getString(256));
326                 return true;
327         }
328
329         bool parseBoneList()
330         {
331                 unsigned int count=reader_.getUint();
332                 for(unsigned int i=0; i<count; ++i){
333                         unsigned short bone=reader_.getUshort();
334                         unsigned char disp=reader_.getUchar();
335                         io_.bone_display_list.push_back(std::make_pair(bone, disp));
336                 }
337                 return true;
338         }
339
340         bool parseBoneNameList()
341         {
342                 unsigned int count=reader_.getUchar();
343                 for(unsigned int i=0; i<count; ++i){
344                         io_.bone_display_name_list.push_back(reader_.getString(50));
345                 }
346                 return true;
347         }
348
349         bool parseFaceList()
350         {
351                 unsigned int count=reader_.getUchar();
352                 for(unsigned int i=0; i<count; ++i){
353                         io_.face_list.push_back(reader_.getUshort());
354                 }
355                 return true;
356         }
357
358         bool parseMorph()
359         {
360                 unsigned int count=reader_.getUshort();
361                 for(unsigned int i=0; i<count; ++i){
362                         io_.morph_list.push_back(Morph());
363                         read(reader_, io_.morph_list.back());
364                 }
365                 return true;
366         }
367
368         bool parseIK()
369         {
370                 unsigned int count=reader_.getUshort();
371                 for(unsigned int i=0; i<count; ++i){
372                         io_.ik_list.push_back(IK());
373                         read(reader_, io_.ik_list.back());
374                 }
375                 return true;
376         }
377
378         bool parseBones()
379         {
380                 unsigned int count=reader_.getUshort();
381                 for(unsigned int i=0; i<count; ++i){
382                         io_.bones.push_back(Bone());
383                         read(reader_, io_.bones.back());
384                 }
385                 return true;
386         }
387
388         bool parseMaterials()
389         {
390                 unsigned int count=reader_.getUint();
391                 for(unsigned int i=0; i<count; ++i){
392                         io_.materials.push_back(new Material());
393                         read(reader_, *io_.materials.back());
394                 }
395                 return true;
396         }
397
398         bool parseIndices()
399         {
400                 unsigned int count=reader_.getUint();
401                 for(unsigned int i=0; i<count; ++i){
402                         io_.indices.push_back(reader_.getUshort());
403                 }
404                 return true;
405         }
406
407         bool parseVertices()
408         {
409                 unsigned int count=reader_.getUint();
410                 for(unsigned int i=0; i<count; ++i){
411                         io_.vertices.push_back(Vertex());
412                         read(reader_, io_.vertices.back());
413                 }
414                 return true;
415         }
416
417         bool parseHeader()
418         {
419                 if(reader_.getString(3)!="Pmd"){
420                         //std::cout << "invalid pmd" << std::endl;
421                         return false;
422                 }
423                 reader_.get(io_.version);
424                 if(io_.version!=1.0){
425                         std::cout << "invalid vesion: " << io_.version <<std::endl;
426                         return false;
427                 }
428                 text::copyStringAndFillZero(io_.name, reader_.getString(20));
429                 text::copyStringAndFillZero(io_.comment, reader_.getString(256));
430
431                 return true;
432         }
433
434 };
435
436 ///////////////////////////////////////////////////////////////////////////////
437 // IO
438 ///////////////////////////////////////////////////////////////////////////////
439 IO::IO()
440 : version(0)
441 {}
442
443 IO::~IO()
444 {
445         for(size_t i=0; i<materials.size(); ++i){
446                 delete materials[i];
447         }
448         materials.clear();
449 }
450
451 bool IO::read(binary::IReader &input)
452 {
453         Impl impl(*this, input);
454         if(!impl.parse()){
455                 return false;
456         }
457
458         ////////////////////////////////////////////////////////////
459         // post process
460         ////////////////////////////////////////////////////////////
461         if(!morph_list.empty()){
462                 // validate morph
463                 assert(morph_list[0].type==MORPH_BASE);
464                 // check base
465                 Morph &base=morph_list[0];
466                 for(size_t i=0; i<base.vertex_count; ++i){
467                         assert(vertices[base.indices[i]].pos==base.pos_list[i]);
468                 }
469                 // check each face
470                 for(size_t i=1; i<morph_list.size(); ++i){
471                         Morph &m=morph_list[i];
472                         assert(m.type!=MORPH_BASE);
473                 }
474         }
475         ////////////////////////////////////////////////////////////
476         // setup bone
477         ////////////////////////////////////////////////////////////
478         for(size_t i=0; i<bones.size(); ++i){
479                 Bone &bone=bones[i];
480                 if(bone.parent_index!=0xFFFF){
481                         bone.parent=&bones[bone.parent_index];
482                         bone.parent->children.push_back(&bone);
483                 }
484                 if(bone.tail_index!=0xFFFF){
485                         bone.tail=bones[bone.tail_index].pos;
486                 }
487         }
488
489         return true;
490 }
491
492 /*
493 bool IO::read(const char *path)
494 {
495         std::vector<char> all;
496         binary::readAll(path, all);
497         if(all.empty()){
498                 return false;
499         }
500         binary::MemoryReader reader(&all[0], all.size());
501         return read(reader);
502 }
503 */
504
505 bool IO::read(const wchar_t *path)
506 {
507         std::vector<char> all;
508         binary::readAll(path, all);
509         std::cerr << all.size() << "bytes" << std::endl;
510         if(all.empty()){
511                 return false;
512         }
513         binary::MemoryReader reader(&all[0], all.size());
514         return read(reader);
515 }
516
517 bool IO::write(binary::IWriter &w)
518 {
519         w.write("Pmd", 3);
520         w.writeValue<float>(version);
521         w.write(name, 20);
522         w.write(comment, 256);
523
524         // vertices
525         //std::cout << "vertices" << std::endl;
526         w.writeValue<DWORD>(vertices.size());
527         for(size_t i=0; i<vertices.size(); ++i){
528                 Vertex &v=vertices[i];
529                 w.writeValue<float>(v.pos.x);
530                 w.writeValue<float>(v.pos.y);
531                 w.writeValue<float>(v.pos.z);
532                 w.writeValue<float>(v.normal.x);
533                 w.writeValue<float>(v.normal.y);
534                 w.writeValue<float>(v.normal.z);
535                 w.writeValue<float>(v.uv.x);
536                 w.writeValue<float>(v.uv.y);
537                 w.writeValue<WORD>(v.bone0);
538                 w.writeValue<WORD>(v.bone1);
539                 w.writeValue<BYTE>(v.weight0);
540                 w.writeValue<BYTE>(v.edge_flag);
541         }
542
543         // faces
544         //std::cout << "faces" << std::endl;
545         w.writeValue<DWORD>(indices.size());
546         if(indices.size()>0){
547                 w.writeArray<WORD>(&indices[0], indices.size());
548         }
549
550         // materials
551         //std::cout << "materials" << std::endl;
552         w.writeValue<DWORD>(materials.size());
553         for(size_t i=0; i<materials.size(); ++i){
554                 Material &m=*materials[i];
555                 w.writeValue<float>(m.diffuse.r);
556                 w.writeValue<float>(m.diffuse.g);
557                 w.writeValue<float>(m.diffuse.b);
558                 w.writeValue<float>(m.diffuse.a);
559                 w.writeValue<float>(m.shinness);
560                 w.writeValue<float>(m.specular.r);
561                 w.writeValue<float>(m.specular.g);
562                 w.writeValue<float>(m.specular.b);
563                 w.writeValue<float>(m.ambient.r);
564                 w.writeValue<float>(m.ambient.g);
565                 w.writeValue<float>(m.ambient.b);
566                 w.writeValue<BYTE>(m.toon_index);
567                 w.writeValue<BYTE>(m.flag);
568                 w.writeValue<DWORD>(m.vertex_count);
569                 w.writeArray<char>(m.texture, 20);
570         }
571
572         // bones
573         //std::cout << "bones" << std::endl;
574         w.writeValue<WORD>(bones.size());
575         for(size_t i=0; i<bones.size(); ++i){
576                 Bone &b=bones[i];
577                 w.writeArray<char>(b.name, 20);
578                 w.writeValue<WORD>(b.parent_index);
579                 w.writeValue<WORD>(b.tail_index);
580                 w.writeValue<BYTE>(b.type);
581                 w.writeValue<WORD>(b.ik_index);
582                 w.writeValue<float>(b.pos.x);
583                 w.writeValue<float>(b.pos.y);
584                 w.writeValue<float>(b.pos.z);
585         }
586
587         // ik
588         //std::cout << "ik" << std::endl;
589         w.writeValue<WORD>(ik_list.size());
590         for(size_t i=0; i<ik_list.size(); ++i){
591                 IK &ik=ik_list[i];
592                 w.writeValue<WORD>(ik.index);
593                 w.writeValue<WORD>(ik.target);
594                 w.writeValue<BYTE>(ik.length);
595                 w.writeValue<WORD>(ik.iterations);
596                 w.writeValue<float>(ik.weight);
597                 WORD parent_index=bones[ik.target].parent_index;
598                 for(size_t j=0; j<ik.length; 
599                                 ++j, parent_index=bones[parent_index].parent_index){
600                         w.writeValue<WORD>(parent_index);
601                 }
602         }
603
604         // morph
605         //std::cout << "morph" << std::endl;
606         w.writeValue<WORD>(morph_list.size());
607         for(size_t i=0; i<morph_list.size(); ++i){
608                 Morph &m=morph_list[i];
609                 w.writeArray<char>(m.name, 20);
610                 w.writeValue<DWORD>(m.indices.size());
611                 w.writeValue<BYTE>(m.type);
612                 for(size_t j=0; j<m.indices.size(); ++j){
613                         w.writeValue<DWORD>(m.indices[j]);
614                         Vector3 &pos=m.pos_list[j];
615                         w.writeValue<float>(pos.x);
616                         w.writeValue<float>(pos.y);
617                         w.writeValue<float>(pos.z);
618                 }
619         }
620
621         // face list
622         //std::cout << "face list" << std::endl;
623         w.writeValue<BYTE>(face_list.size());
624         if(face_list.size()>0){
625                 w.writeArray<WORD>(&face_list[0], face_list.size());
626         }
627
628         // bone naem list
629         //std::cout << "bone name list" << std::endl;
630         w.writeValue<BYTE>(bone_display_name_list.size());
631         for(size_t i=0; i<bone_display_name_list.size(); ++i){
632                 // 50bytes
633                 char buf[]={
634                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
635                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
636                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
637                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
638                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
639                 };
640                 sprintf(buf, "%s", bone_display_name_list[i].c_str());
641                 w.writeArray<char>(buf, 50);
642         }
643
644         // bone list
645         //std::cout << "bone list" << std::endl;
646         w.writeValue<DWORD>(bone_display_list.size());
647         for(size_t i=0; i<bone_display_list.size(); ++i){
648                 w.writeValue<WORD>(bone_display_list[i].first);
649                 w.writeValue<BYTE>(bone_display_list[i].second);
650         }
651
652         // extend
653
654         return true;
655 }
656
657 bool IO::write(const char *path)
658 {
659         binary::FileWriter w(path);
660         return write(w);
661 }
662
663 const Vector2* IO::getUV(int index)const
664 {
665         return &vertices[index].uv;
666 }
667
668 } // namespace
669 } // namespace
670