1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14copyright notice, this list of conditions and the
15following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18copyright notice, this list of conditions and the
19following disclaimer in the documentation and/or other
20materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23contributors may be used to endorse or promote products
24derived from this software without specific prior
25written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41#pragma once
42
43#include <vector>
44#include <string>
45#include <iostream>
46#include <fstream>
47#include <memory>
48#include "MMDCpp14.h"
49
50namespace pmx
51{
52 class PmxSetting
53 {
54 public:
55 PmxSetting()
56 : encoding(0)
57 , uv(0)
58 , vertex_index_size(0)
59 , texture_index_size(0)
60 , material_index_size(0)
61 , bone_index_size(0)
62 , morph_index_size(0)
63 , rigidbody_index_size(0)
64 {}
65
66 uint8_t encoding;
67 uint8_t uv;
68 uint8_t vertex_index_size;
69 uint8_t texture_index_size;
70 uint8_t material_index_size;
71 uint8_t bone_index_size;
72 uint8_t morph_index_size;
73 uint8_t rigidbody_index_size;
74 void Read(std::istream *stream);
75 };
76
77 enum class PmxVertexSkinningType : uint8_t
78 {
79 BDEF1 = 0,
80 BDEF2 = 1,
81 BDEF4 = 2,
82 SDEF = 3,
83 QDEF = 4,
84 };
85
86 class PmxVertexSkinning
87 {
88 public:
89 virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
90 };
91
92 class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
93 {
94 public:
95 PmxVertexSkinningBDEF1()
96 : bone_index(0)
97 {}
98
99 int bone_index;
100 void Read(std::istream *stresam, PmxSetting *setting);
101 };
102
103 class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
104 {
105 public:
106 PmxVertexSkinningBDEF2()
107 : bone_index1(0)
108 , bone_index2(0)
109 , bone_weight(0.0f)
110 {}
111
112 int bone_index1;
113 int bone_index2;
114 float bone_weight;
115 void Read(std::istream *stresam, PmxSetting *setting);
116 };
117
118 class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
119 {
120 public:
121 PmxVertexSkinningBDEF4()
122 : bone_index1(0)
123 , bone_index2(0)
124 , bone_index3(0)
125 , bone_index4(0)
126 , bone_weight1(0.0f)
127 , bone_weight2(0.0f)
128 , bone_weight3(0.0f)
129 , bone_weight4(0.0f)
130 {}
131
132 int bone_index1;
133 int bone_index2;
134 int bone_index3;
135 int bone_index4;
136 float bone_weight1;
137 float bone_weight2;
138 float bone_weight3;
139 float bone_weight4;
140 void Read(std::istream *stresam, PmxSetting *setting);
141 };
142
143 class PmxVertexSkinningSDEF : public PmxVertexSkinning
144 {
145 public:
146 PmxVertexSkinningSDEF()
147 : bone_index1(0)
148 , bone_index2(0)
149 , bone_weight(0.0f)
150 {
151 for (int i = 0; i < 3; ++i) {
152 sdef_c[i] = 0.0f;
153 sdef_r0[i] = 0.0f;
154 sdef_r1[i] = 0.0f;
155 }
156 }
157
158 int bone_index1;
159 int bone_index2;
160 float bone_weight;
161 float sdef_c[3];
162 float sdef_r0[3];
163 float sdef_r1[3];
164 void Read(std::istream *stresam, PmxSetting *setting);
165 };
166
167 class PmxVertexSkinningQDEF : public PmxVertexSkinning
168 {
169 public:
170 PmxVertexSkinningQDEF()
171 : bone_index1(0)
172 , bone_index2(0)
173 , bone_index3(0)
174 , bone_index4(0)
175 , bone_weight1(0.0f)
176 , bone_weight2(0.0f)
177 , bone_weight3(0.0f)
178 , bone_weight4(0.0f)
179 {}
180
181 int bone_index1;
182 int bone_index2;
183 int bone_index3;
184 int bone_index4;
185 float bone_weight1;
186 float bone_weight2;
187 float bone_weight3;
188 float bone_weight4;
189 void Read(std::istream *stresam, PmxSetting *setting);
190 };
191
192 class PmxVertex
193 {
194 public:
195 PmxVertex()
196 : edge(0.0f)
197 {
198 uv[0] = uv[1] = 0.0f;
199 for (int i = 0; i < 3; ++i) {
200 position[i] = 0.0f;
201 normal[i] = 0.0f;
202 }
203 for (int i = 0; i < 4; ++i) {
204 for (int k = 0; k < 4; ++k) {
205 uva[i][k] = 0.0f;
206 }
207 }
208 }
209
210 float position[3];
211 float normal[3];
212 float uv[2];
213 float uva[4][4];
214 PmxVertexSkinningType skinning_type;
215 std::unique_ptr<PmxVertexSkinning> skinning;
216 float edge;
217 void Read(std::istream *stream, PmxSetting *setting);
218 };
219
220 class PmxMaterial
221 {
222 public:
223 PmxMaterial()
224 : specularlity(0.0f)
225 , flag(0)
226 , edge_size(0.0f)
227 , diffuse_texture_index(0)
228 , sphere_texture_index(0)
229 , sphere_op_mode(0)
230 , common_toon_flag(0)
231 , toon_texture_index(0)
232 , index_count(0)
233 {
234 for (int i = 0; i < 3; ++i) {
235 specular[i] = 0.0f;
236 ambient[i] = 0.0f;
237 edge_color[i] = 0.0f;
238 }
239 for (int i = 0; i < 4; ++i) {
240 diffuse[i] = 0.0f;
241 }
242 }
243
244 std::string material_name;
245 std::string material_english_name;
246 float diffuse[4];
247 float specular[3];
248 float specularlity;
249 float ambient[3];
250 uint8_t flag;
251 float edge_color[4];
252 float edge_size;
253 int diffuse_texture_index;
254 int sphere_texture_index;
255 uint8_t sphere_op_mode;
256 uint8_t common_toon_flag;
257 int toon_texture_index;
258 std::string memo;
259 int index_count;
260 void Read(std::istream *stream, PmxSetting *setting);
261 };
262
263 class PmxIkLink
264 {
265 public:
266 PmxIkLink()
267 : link_target(0)
268 , angle_lock(0)
269 {
270 for (int i = 0; i < 3; ++i) {
271 max_radian[i] = 0.0f;
272 min_radian[i] = 0.0f;
273 }
274 }
275
276 int link_target;
277 uint8_t angle_lock;
278 float max_radian[3];
279 float min_radian[3];
280 void Read(std::istream *stream, PmxSetting *settingn);
281 };
282
283 class PmxBone
284 {
285 public:
286 PmxBone()
287 : parent_index(0)
288 , level(0)
289 , bone_flag(0)
290 , target_index(0)
291 , grant_parent_index(0)
292 , grant_weight(0.0f)
293 , key(0)
294 , ik_target_bone_index(0)
295 , ik_loop(0)
296 , ik_loop_angle_limit(0.0f)
297 , ik_link_count(0)
298 {
299 for (int i = 0; i < 3; ++i) {
300 position[i] = 0.0f;
301 offset[i] = 0.0f;
302 lock_axis_orientation[i] = 0.0f;
303 local_axis_x_orientation[i] = 0.0f;
304 local_axis_y_orientation[i] = 0.0f;
305 }
306 }
307
308 std::string bone_name;
309 std::string bone_english_name;
310 float position[3];
311 int parent_index;
312 int level;
313 uint16_t bone_flag;
314 float offset[3];
315 int target_index;
316 int grant_parent_index;
317 float grant_weight;
318 float lock_axis_orientation[3];
319 float local_axis_x_orientation[3];
320 float local_axis_y_orientation[3];
321 int key;
322 int ik_target_bone_index;
323 int ik_loop;
324 float ik_loop_angle_limit;
325 int ik_link_count;
326 std::unique_ptr<PmxIkLink []> ik_links;
327 void Read(std::istream *stream, PmxSetting *setting);
328 };
329
330 enum class MorphType : uint8_t
331 {
332 Group = 0,
333 Vertex = 1,
334 Bone = 2,
335 UV = 3,
336 AdditionalUV1 = 4,
337 AdditionalUV2 = 5,
338 AdditionalUV3 = 6,
339 AdditionalUV4 = 7,
340 Matrial = 8,
341 Flip = 9,
342 Implus = 10,
343 };
344
345 enum class MorphCategory : uint8_t
346 {
347 ReservedCategory = 0,
348 Eyebrow = 1,
349 Eye = 2,
350 Mouth = 3,
351 Other = 4,
352 };
353
354 class PmxMorphOffset
355 {
356 public:
357 void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
358 };
359
360 class PmxMorphVertexOffset : public PmxMorphOffset
361 {
362 public:
363 PmxMorphVertexOffset()
364 : vertex_index(0)
365 {
366 for (int i = 0; i < 3; ++i) {
367 position_offset[i] = 0.0f;
368 }
369 }
370 int vertex_index;
371 float position_offset[3];
372 void Read(std::istream *stream, PmxSetting *setting); //override;
373 };
374
375 class PmxMorphUVOffset : public PmxMorphOffset
376 {
377 public:
378 PmxMorphUVOffset()
379 : vertex_index(0)
380 {
381 for (int i = 0; i < 4; ++i) {
382 uv_offset[i] = 0.0f;
383 }
384 }
385 int vertex_index;
386 float uv_offset[4];
387 void Read(std::istream *stream, PmxSetting *setting); //override;
388 };
389
390 class PmxMorphBoneOffset : public PmxMorphOffset
391 {
392 public:
393 PmxMorphBoneOffset()
394 : bone_index(0)
395 {
396 for (int i = 0; i < 3; ++i) {
397 translation[i] = 0.0f;
398 }
399 for (int i = 0; i < 4; ++i) {
400 rotation[i] = 0.0f;
401 }
402 }
403 int bone_index;
404 float translation[3];
405 float rotation[4];
406 void Read(std::istream *stream, PmxSetting *setting); //override;
407 };
408
409 class PmxMorphMaterialOffset : public PmxMorphOffset
410 {
411 public:
412 PmxMorphMaterialOffset()
413 : specularity(0.0f)
414 , edge_size(0.0f)
415 {
416 for (int i = 0; i < 3; ++i) {
417 specular[i] = 0.0f;
418 ambient[i] = 0.0f;
419 }
420 for (int i = 0; i < 4; ++i) {
421 diffuse[i] = 0.0f;
422 edge_color[i] = 0.0f;
423 texture_argb[i] = 0.0f;
424 sphere_texture_argb[i] = 0.0f;
425 toon_texture_argb[i] = 0.0f;
426 }
427 }
428 int material_index;
429 uint8_t offset_operation;
430 float diffuse[4];
431 float specular[3];
432 float specularity;
433 float ambient[3];
434 float edge_color[4];
435 float edge_size;
436 float texture_argb[4];
437 float sphere_texture_argb[4];
438 float toon_texture_argb[4];
439 void Read(std::istream *stream, PmxSetting *setting); //override;
440 };
441
442 class PmxMorphGroupOffset : public PmxMorphOffset
443 {
444 public:
445 PmxMorphGroupOffset()
446 : morph_index(0)
447 , morph_weight(0.0f)
448 {}
449 int morph_index;
450 float morph_weight;
451 void Read(std::istream *stream, PmxSetting *setting); //override;
452 };
453
454 class PmxMorphFlipOffset : public PmxMorphOffset
455 {
456 public:
457 PmxMorphFlipOffset()
458 : morph_index(0)
459 , morph_value(0.0f)
460 {}
461 int morph_index;
462 float morph_value;
463 void Read(std::istream *stream, PmxSetting *setting); //override;
464 };
465
466 class PmxMorphImplusOffset : public PmxMorphOffset
467 {
468 public:
469 PmxMorphImplusOffset()
470 : rigid_body_index(0)
471 , is_local(0)
472 {
473 for (int i = 0; i < 3; ++i) {
474 velocity[i] = 0.0f;
475 angular_torque[i] = 0.0f;
476 }
477 }
478 int rigid_body_index;
479 uint8_t is_local;
480 float velocity[3];
481 float angular_torque[3];
482 void Read(std::istream *stream, PmxSetting *setting); //override;
483 };
484
485 class PmxMorph
486 {
487 public:
488 PmxMorph()
489 : offset_count(0)
490 {
491 }
492 std::string morph_name;
493 std::string morph_english_name;
494 MorphCategory category;
495 MorphType morph_type;
496 int offset_count;
497 std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
498 std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
499 std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
500 std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
501 std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
502 std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
503 std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
504 void Read(std::istream *stream, PmxSetting *setting);
505 };
506
507 class PmxFrameElement
508 {
509 public:
510 PmxFrameElement()
511 : element_target(0)
512 , index(0)
513 {
514 }
515 uint8_t element_target;
516 int index;
517 void Read(std::istream *stream, PmxSetting *setting);
518 };
519
520 class PmxFrame
521 {
522 public:
523 PmxFrame()
524 : frame_flag(0)
525 , element_count(0)
526 {
527 }
528 std::string frame_name;
529 std::string frame_english_name;
530 uint8_t frame_flag;
531 int element_count;
532 std::unique_ptr<PmxFrameElement []> elements;
533 void Read(std::istream *stream, PmxSetting *setting);
534 };
535
536 class PmxRigidBody
537 {
538 public:
539 PmxRigidBody()
540 : target_bone(0)
541 , group(0)
542 , mask(0)
543 , shape(0)
544 , mass(0.0f)
545 , move_attenuation(0.0f)
546 , rotation_attenuation(0.0f)
547 , repulsion(0.0f)
548 , friction(0.0f)
549 , physics_calc_type(0)
550 {
551 for (int i = 0; i < 3; ++i) {
552 size[i] = 0.0f;
553 position[i] = 0.0f;
554 orientation[i] = 0.0f;
555 }
556 }
557 std::string girid_body_name;
558 std::string girid_body_english_name;
559 int target_bone;
560 uint8_t group;
561 uint16_t mask;
562 uint8_t shape;
563 float size[3];
564 float position[3];
565 float orientation[3];
566 float mass;
567 float move_attenuation;
568 float rotation_attenuation;
569 float repulsion;
570 float friction;
571 uint8_t physics_calc_type;
572 void Read(std::istream *stream, PmxSetting *setting);
573 };
574
575 enum class PmxJointType : uint8_t
576 {
577 Generic6DofSpring = 0,
578 Generic6Dof = 1,
579 Point2Point = 2,
580 ConeTwist = 3,
581 Slider = 5,
582 Hinge = 6
583 };
584
585 class PmxJointParam
586 {
587 public:
588 PmxJointParam()
589 : rigid_body1(0)
590 , rigid_body2(0)
591 {
592 for (int i = 0; i < 3; ++i) {
593 position[i] = 0.0f;
594 orientaiton[i] = 0.0f;
595 move_limitation_min[i] = 0.0f;
596 move_limitation_max[i] = 0.0f;
597 rotation_limitation_min[i] = 0.0f;
598 rotation_limitation_max[i] = 0.0f;
599 spring_move_coefficient[i] = 0.0f;
600 spring_rotation_coefficient[i] = 0.0f;
601 }
602 }
603 int rigid_body1;
604 int rigid_body2;
605 float position[3];
606 float orientaiton[3];
607 float move_limitation_min[3];
608 float move_limitation_max[3];
609 float rotation_limitation_min[3];
610 float rotation_limitation_max[3];
611 float spring_move_coefficient[3];
612 float spring_rotation_coefficient[3];
613 void Read(std::istream *stream, PmxSetting *setting);
614 };
615
616 class PmxJoint
617 {
618 public:
619 std::string joint_name;
620 std::string joint_english_name;
621 PmxJointType joint_type;
622 PmxJointParam param;
623 void Read(std::istream *stream, PmxSetting *setting);
624 };
625
626 enum PmxSoftBodyFlag : uint8_t
627 {
628 BLink = 0x01,
629 Cluster = 0x02,
630 Link = 0x04
631 };
632
633 class PmxAncherRigidBody
634 {
635 public:
636 PmxAncherRigidBody()
637 : related_rigid_body(0)
638 , related_vertex(0)
639 , is_near(false)
640 {}
641 int related_rigid_body;
642 int related_vertex;
643 bool is_near;
644 void Read(std::istream *stream, PmxSetting *setting);
645 };
646
647 class PmxSoftBody
648 {
649 public:
650 PmxSoftBody()
651 : shape(0)
652 , target_material(0)
653 , group(0)
654 , mask(0)
655 , blink_distance(0)
656 , cluster_count(0)
657 , mass(0.0)
658 , collisioni_margin(0.0)
659 , aero_model(0)
660 , VCF(0.0f)
661 , DP(0.0f)
662 , DG(0.0f)
663 , LF(0.0f)
664 , PR(0.0f)
665 , VC(0.0f)
666 , DF(0.0f)
667 , MT(0.0f)
668 , CHR(0.0f)
669 , KHR(0.0f)
670 , SHR(0.0f)
671 , AHR(0.0f)
672 , SRHR_CL(0.0f)
673 , SKHR_CL(0.0f)
674 , SSHR_CL(0.0f)
675 , SR_SPLT_CL(0.0f)
676 , SK_SPLT_CL(0.0f)
677 , SS_SPLT_CL(0.0f)
678 , V_IT(0)
679 , P_IT(0)
680 , D_IT(0)
681 , C_IT(0)
682 , LST(0.0f)
683 , AST(0.0f)
684 , VST(0.0f)
685 , anchor_count(0)
686 , pin_vertex_count(0)
687 {}
688 std::string soft_body_name;
689 std::string soft_body_english_name;
690 uint8_t shape;
691 int target_material;
692 uint8_t group;
693 uint16_t mask;
694 PmxSoftBodyFlag flag;
695 int blink_distance;
696 int cluster_count;
697 float mass;
698 float collisioni_margin;
699 int aero_model;
700 float VCF;
701 float DP;
702 float DG;
703 float LF;
704 float PR;
705 float VC;
706 float DF;
707 float MT;
708 float CHR;
709 float KHR;
710 float SHR;
711 float AHR;
712 float SRHR_CL;
713 float SKHR_CL;
714 float SSHR_CL;
715 float SR_SPLT_CL;
716 float SK_SPLT_CL;
717 float SS_SPLT_CL;
718 int V_IT;
719 int P_IT;
720 int D_IT;
721 int C_IT;
722 float LST;
723 float AST;
724 float VST;
725 int anchor_count;
726 std::unique_ptr<PmxAncherRigidBody []> anchers;
727 int pin_vertex_count;
728 std::unique_ptr<int []> pin_vertices;
729 void Read(std::istream *stream, PmxSetting *setting);
730 };
731
732 class PmxModel
733 {
734 public:
735 PmxModel()
736 : version(0.0f)
737 , vertex_count(0)
738 , index_count(0)
739 , texture_count(0)
740 , material_count(0)
741 , bone_count(0)
742 , morph_count(0)
743 , frame_count(0)
744 , rigid_body_count(0)
745 , joint_count(0)
746 , soft_body_count(0)
747 {}
748
749 float version;
750 PmxSetting setting;
751 std::string model_name;
752 std::string model_english_name;
753 std::string model_comment;
754 std::string model_english_comment;
755 int vertex_count;
756 std::unique_ptr<PmxVertex []> vertices;
757 int index_count;
758 std::unique_ptr<int []> indices;
759 int texture_count;
760 std::unique_ptr< std::string []> textures;
761 int material_count;
762 std::unique_ptr<PmxMaterial []> materials;
763 int bone_count;
764 std::unique_ptr<PmxBone []> bones;
765 int morph_count;
766 std::unique_ptr<PmxMorph []> morphs;
767 int frame_count;
768 std::unique_ptr<PmxFrame [] > frames;
769 int rigid_body_count;
770 std::unique_ptr<PmxRigidBody []> rigid_bodies;
771 int joint_count;
772 std::unique_ptr<PmxJoint []> joints;
773 int soft_body_count;
774 std::unique_ptr<PmxSoftBody []> soft_bodies;
775 void Init();
776 void Read(std::istream *stream);
777 //static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
778 //static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
779 };
780}
781