OSDN Git Service

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