OSDN Git Service

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