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#include <utility>
42#include "MMDPmxParser.h"
43#include "../contrib/utf8cpp/source/utf8.h"
44#include "Exceptional.h"
45
46namespace pmx
47{
48 int ReadIndex(std::istream *stream, int size)
49 {
50 switch (size)
51 {
52 case 1:
53 uint8_t tmp8;
54 stream->read((char*) &tmp8, sizeof(uint8_t));
55 if (255 == tmp8)
56 {
57 return -1;
58 }
59 else {
60 return (int) tmp8;
61 }
62 case 2:
63 uint16_t tmp16;
64 stream->read((char*) &tmp16, sizeof(uint16_t));
65 if (65535 == tmp16)
66 {
67 return -1;
68 }
69 else {
70 return (int) tmp16;
71 }
72 case 4:
73 int tmp32;
74 stream->read((char*) &tmp32, sizeof(int));
75 return tmp32;
76 default:
77 return -1;
78 }
79 }
80
81 std::string ReadString(std::istream *stream, uint8_t encoding)
82 {
83 int size;
84 stream->read((char*) &size, sizeof(int));
85 std::vector<char> buffer;
86 if (size == 0)
87 {
88 return std::string("");
89 }
90 buffer.reserve(size);
91 stream->read((char*) buffer.data(), size);
92 if (encoding == 0)
93 {
94 // UTF16 to UTF8
95 std::string result;
96
97 const char* sourceStart = buffer.data();
98 const unsigned int targetSize = size * 3; // enough to encode
99 char* targetStart = new char[targetSize]();
100 const char* targetReserved = targetStart;
101 utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
102
103 result.assign(targetReserved, targetStart - targetReserved);
104 delete[] targetReserved;
105 return result;
106 }
107 else
108 {
109 // the name is already UTF8
110 return std::string((const char*)buffer.data(), size);
111 }
112 }
113
114 void PmxSetting::Read(std::istream *stream)
115 {
116 uint8_t count;
117 stream->read((char*) &count, sizeof(uint8_t));
118 if (count < 8)
119 {
120 throw;
121 }
122 stream->read((char*) &encoding, sizeof(uint8_t));
123 stream->read((char*) &uv, sizeof(uint8_t));
124 stream->read((char*) &vertex_index_size, sizeof(uint8_t));
125 stream->read((char*) &texture_index_size, sizeof(uint8_t));
126 stream->read((char*) &material_index_size, sizeof(uint8_t));
127 stream->read((char*) &bone_index_size, sizeof(uint8_t));
128 stream->read((char*) &morph_index_size, sizeof(uint8_t));
129 stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
130 uint8_t temp;
131 for (int i = 8; i < count; i++)
132 {
133 stream->read((char*)&temp, sizeof(uint8_t));
134 }
135 }
136
137 void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
138 {
139 this->bone_index = ReadIndex(stream, setting->bone_index_size);
140 }
141
142 void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
143 {
144 this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
145 this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
146 stream->read((char*) &this->bone_weight, sizeof(float));
147 }
148
149 void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
150 {
151 this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
152 this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
153 this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
154 this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
155 stream->read((char*) &this->bone_weight1, sizeof(float));
156 stream->read((char*) &this->bone_weight2, sizeof(float));
157 stream->read((char*) &this->bone_weight3, sizeof(float));
158 stream->read((char*) &this->bone_weight4, sizeof(float));
159 }
160
161 void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
162 {
163 this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
164 this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
165 stream->read((char*) &this->bone_weight, sizeof(float));
166 stream->read((char*) this->sdef_c, sizeof(float) * 3);
167 stream->read((char*) this->sdef_r0, sizeof(float) * 3);
168 stream->read((char*) this->sdef_r1, sizeof(float) * 3);
169 }
170
171 void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
172 {
173 this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
174 this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
175 this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
176 this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
177 stream->read((char*) &this->bone_weight1, sizeof(float));
178 stream->read((char*) &this->bone_weight2, sizeof(float));
179 stream->read((char*) &this->bone_weight3, sizeof(float));
180 stream->read((char*) &this->bone_weight4, sizeof(float));
181 }
182
183 void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
184 {
185 stream->read((char*) this->position, sizeof(float) * 3);
186 stream->read((char*) this->normal, sizeof(float) * 3);
187 stream->read((char*) this->uv, sizeof(float) * 2);
188 for (int i = 0; i < setting->uv; ++i)
189 {
190 stream->read((char*) this->uva[i], sizeof(float) * 4);
191 }
192 stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
193 switch (this->skinning_type)
194 {
195 case PmxVertexSkinningType::BDEF1:
196 this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>();
197 break;
198 case PmxVertexSkinningType::BDEF2:
199 this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>();
200 break;
201 case PmxVertexSkinningType::BDEF4:
202 this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>();
203 break;
204 case PmxVertexSkinningType::SDEF:
205 this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>();
206 break;
207 case PmxVertexSkinningType::QDEF:
208 this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>();
209 break;
210 default:
211 throw "invalid skinning type";
212 }
213 this->skinning->Read(stream, setting);
214 stream->read((char*) &this->edge, sizeof(float));
215 }
216
217 void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
218 {
219 this->material_name = ReadString(stream, setting->encoding);
220 this->material_english_name = ReadString(stream, setting->encoding);
221 stream->read((char*) this->diffuse, sizeof(float) * 4);
222 stream->read((char*) this->specular, sizeof(float) * 3);
223 stream->read((char*) &this->specularlity, sizeof(float));
224 stream->read((char*) this->ambient, sizeof(float) * 3);
225 stream->read((char*) &this->flag, sizeof(uint8_t));
226 stream->read((char*) this->edge_color, sizeof(float) * 4);
227 stream->read((char*) &this->edge_size, sizeof(float));
228 this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
229 this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
230 stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
231 stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
232 if (this->common_toon_flag)
233 {
234 stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
235 }
236 else {
237 this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
238 }
239 this->memo = ReadString(stream, setting->encoding);
240 stream->read((char*) &this->index_count, sizeof(int));
241 }
242
243 void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
244 {
245 this->link_target = ReadIndex(stream, setting->bone_index_size);
246 stream->read((char*) &this->angle_lock, sizeof(uint8_t));
247 if (angle_lock == 1)
248 {
249 stream->read((char*) this->max_radian, sizeof(float) * 3);
250 stream->read((char*) this->min_radian, sizeof(float) * 3);
251 }
252 }
253
254 void PmxBone::Read(std::istream *stream, PmxSetting *setting)
255 {
256 this->bone_name = ReadString(stream, setting->encoding);
257 this->bone_english_name = ReadString(stream, setting->encoding);
258 stream->read((char*) this->position, sizeof(float) * 3);
259 this->parent_index = ReadIndex(stream, setting->bone_index_size);
260 stream->read((char*) &this->level, sizeof(int));
261 stream->read((char*) &this->bone_flag, sizeof(uint16_t));
262 if (this->bone_flag & 0x0001) {
263 this->target_index = ReadIndex(stream, setting->bone_index_size);
264 }
265 else {
266 stream->read((char*)this->offset, sizeof(float) * 3);
267 }
268 if (this->bone_flag & (0x0100 | 0x0200)) {
269 this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
270 stream->read((char*) &this->grant_weight, sizeof(float));
271 }
272 if (this->bone_flag & 0x0400) {
273 stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
274 }
275 if (this->bone_flag & 0x0800) {
276 stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
277 stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
278 }
279 if (this->bone_flag & 0x2000) {
280 stream->read((char*) &this->key, sizeof(int));
281 }
282 if (this->bone_flag & 0x0020) {
283 this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
284 stream->read((char*) &ik_loop, sizeof(int));
285 stream->read((char*) &ik_loop_angle_limit, sizeof(float));
286 stream->read((char*) &ik_link_count, sizeof(int));
287 this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count);
288 for (int i = 0; i < ik_link_count; i++) {
289 ik_links[i].Read(stream, setting);
290 }
291 }
292 }
293
294 void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
295 {
296 this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
297 stream->read((char*)this->position_offset, sizeof(float) * 3);
298 }
299
300 void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
301 {
302 this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
303 stream->read((char*)this->uv_offset, sizeof(float) * 4);
304 }
305
306 void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
307 {
308 this->bone_index = ReadIndex(stream, setting->bone_index_size);
309 stream->read((char*)this->translation, sizeof(float) * 3);
310 stream->read((char*)this->rotation, sizeof(float) * 4);
311 }
312
313 void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
314 {
315 this->material_index = ReadIndex(stream, setting->material_index_size);
316 stream->read((char*) &this->offset_operation, sizeof(uint8_t));
317 stream->read((char*)this->diffuse, sizeof(float) * 4);
318 stream->read((char*)this->specular, sizeof(float) * 3);
319 stream->read((char*) &this->specularity, sizeof(float));
320 stream->read((char*)this->ambient, sizeof(float) * 3);
321 stream->read((char*)this->edge_color, sizeof(float) * 4);
322 stream->read((char*) &this->edge_size, sizeof(float));
323 stream->read((char*)this->texture_argb, sizeof(float) * 4);
324 stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
325 stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
326 }
327
328 void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
329 {
330 this->morph_index = ReadIndex(stream, setting->morph_index_size);
331 stream->read((char*) &this->morph_weight, sizeof(float));
332 }
333
334 void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
335 {
336 this->morph_index = ReadIndex(stream, setting->morph_index_size);
337 stream->read((char*) &this->morph_value, sizeof(float));
338 }
339
340 void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
341 {
342 this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
343 stream->read((char*) &this->is_local, sizeof(uint8_t));
344 stream->read((char*)this->velocity, sizeof(float) * 3);
345 stream->read((char*)this->angular_torque, sizeof(float) * 3);
346 }
347
348 void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
349 {
350 this->morph_name = ReadString(stream, setting->encoding);
351 this->morph_english_name = ReadString(stream, setting->encoding);
352 stream->read((char*) &category, sizeof(MorphCategory));
353 stream->read((char*) &morph_type, sizeof(MorphType));
354 stream->read((char*) &this->offset_count, sizeof(int));
355 switch (this->morph_type)
356 {
357 case MorphType::Group:
358 group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count);
359 for (int i = 0; i < offset_count; i++)
360 {
361 group_offsets[i].Read(stream, setting);
362 }
363 break;
364 case MorphType::Vertex:
365 vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count);
366 for (int i = 0; i < offset_count; i++)
367 {
368 vertex_offsets[i].Read(stream, setting);
369 }
370 break;
371 case MorphType::Bone:
372 bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count);
373 for (int i = 0; i < offset_count; i++)
374 {
375 bone_offsets[i].Read(stream, setting);
376 }
377 break;
378 case MorphType::Matrial:
379 material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
380 for (int i = 0; i < offset_count; i++)
381 {
382 material_offsets[i].Read(stream, setting);
383 }
384 break;
385 case MorphType::UV:
386 case MorphType::AdditionalUV1:
387 case MorphType::AdditionalUV2:
388 case MorphType::AdditionalUV3:
389 case MorphType::AdditionalUV4:
390 uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count);
391 for (int i = 0; i < offset_count; i++)
392 {
393 uv_offsets[i].Read(stream, setting);
394 }
395 break;
396 default:
397 throw;
398 }
399 }
400
401 void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
402 {
403 stream->read((char*) &this->element_target, sizeof(uint8_t));
404 if (this->element_target == 0x00)
405 {
406 this->index = ReadIndex(stream, setting->bone_index_size);
407 }
408 else {
409 this->index = ReadIndex(stream, setting->morph_index_size);
410 }
411 }
412
413 void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
414 {
415 this->frame_name = ReadString(stream, setting->encoding);
416 this->frame_english_name = ReadString(stream, setting->encoding);
417 stream->read((char*) &this->frame_flag, sizeof(uint8_t));
418 stream->read((char*) &this->element_count, sizeof(int));
419 this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count);
420 for (int i = 0; i < this->element_count; i++)
421 {
422 this->elements[i].Read(stream, setting);
423 }
424 }
425
426 void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
427 {
428 this->girid_body_name = ReadString(stream, setting->encoding);
429 this->girid_body_english_name = ReadString(stream, setting->encoding);
430 this->target_bone = ReadIndex(stream, setting->bone_index_size);
431 stream->read((char*) &this->group, sizeof(uint8_t));
432 stream->read((char*) &this->mask, sizeof(uint16_t));
433 stream->read((char*) &this->shape, sizeof(uint8_t));
434 stream->read((char*) this->size, sizeof(float) * 3);
435 stream->read((char*) this->position, sizeof(float) * 3);
436 stream->read((char*) this->orientation, sizeof(float) * 3);
437 stream->read((char*) &this->mass, sizeof(float));
438 stream->read((char*) &this->move_attenuation, sizeof(float));
439 stream->read((char*) &this->rotation_attenuation, sizeof(float));
440 stream->read((char*) &this->repulsion, sizeof(float));
441 stream->read((char*) &this->friction, sizeof(float));
442 stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
443 }
444
445 void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
446 {
447 this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
448 this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
449 stream->read((char*) this->position, sizeof(float) * 3);
450 stream->read((char*) this->orientaiton, sizeof(float) * 3);
451 stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
452 stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
453 stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
454 stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
455 stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
456 stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
457 }
458
459 void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
460 {
461 this->joint_name = ReadString(stream, setting->encoding);
462 this->joint_english_name = ReadString(stream, setting->encoding);
463 stream->read((char*) &this->joint_type, sizeof(uint8_t));
464 this->param.Read(stream, setting);
465 }
466
467 void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
468 {
469 this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
470 this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
471 stream->read((char*) &this->is_near, sizeof(uint8_t));
472 }
473
474 void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
475 {
476 // 未実装
477 std::cerr << "Not Implemented Exception" << std::endl;
478 throw;
479 }
480
481 void PmxModel::Init()
482 {
483 this->version = 0.0f;
484 this->model_name.clear();
485 this->model_english_name.clear();
486 this->model_comment.clear();
487 this->model_english_comment.clear();
488 this->vertex_count = 0;
489 this->vertices = nullptr;
490 this->index_count = 0;
491 this->indices = nullptr;
492 this->texture_count = 0;
493 this->textures = nullptr;
494 this->material_count = 0;
495 this->materials = nullptr;
496 this->bone_count = 0;
497 this->bones = nullptr;
498 this->morph_count = 0;
499 this->morphs = nullptr;
500 this->frame_count = 0;
501 this->frames = nullptr;
502 this->rigid_body_count = 0;
503 this->rigid_bodies = nullptr;
504 this->joint_count = 0;
505 this->joints = nullptr;
506 this->soft_body_count = 0;
507 this->soft_bodies = nullptr;
508 }
509
510 void PmxModel::Read(std::istream *stream)
511 {
512 // マジック
513 char magic[4];
514 stream->read((char*) magic, sizeof(char) * 4);
515 if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
516 {
517 std::cerr << "invalid magic number." << std::endl;
518 throw;
519 }
520 // バージョン
521 stream->read((char*) &version, sizeof(float));
522 if (version != 2.0f && version != 2.1f)
523 {
524 std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
525 throw;
526 }
527 // ファイル設定
528 this->setting.Read(stream);
529
530 // モデル情報
531 this->model_name = ReadString(stream, setting.encoding);
532 this->model_english_name = ReadString(stream, setting.encoding);
533 this->model_comment = ReadString(stream, setting.encoding);
534 this->model_english_comment = ReadString(stream, setting.encoding);
535
536 // 頂点
537 stream->read((char*) &vertex_count, sizeof(int));
538 this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
539 for (int i = 0; i < vertex_count; i++)
540 {
541 vertices[i].Read(stream, &setting);
542 }
543
544 // 面
545 stream->read((char*) &index_count, sizeof(int));
546 this->indices = mmd::make_unique<int []>(index_count);
547 for (int i = 0; i < index_count; i++)
548 {
549 this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
550 }
551
552 // テクスチャ
553 stream->read((char*) &texture_count, sizeof(int));
554 this->textures = mmd::make_unique<std::string []>(texture_count);
555 for (int i = 0; i < texture_count; i++)
556 {
557 this->textures[i] = ReadString(stream, setting.encoding);
558 }
559
560 // マテリアル
561 stream->read((char*) &material_count, sizeof(int));
562 this->materials = mmd::make_unique<PmxMaterial []>(material_count);
563 for (int i = 0; i < material_count; i++)
564 {
565 this->materials[i].Read(stream, &setting);
566 }
567
568 // ボーン
569 stream->read((char*) &this->bone_count, sizeof(int));
570 this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
571 for (int i = 0; i < this->bone_count; i++)
572 {
573 this->bones[i].Read(stream, &setting);
574 }
575
576 // モーフ
577 stream->read((char*) &this->morph_count, sizeof(int));
578 this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
579 for (int i = 0; i < this->morph_count; i++)
580 {
581 this->morphs[i].Read(stream, &setting);
582 }
583
584 // 表示枠
585 stream->read((char*) &this->frame_count, sizeof(int));
586 this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
587 for (int i = 0; i < this->frame_count; i++)
588 {
589 this->frames[i].Read(stream, &setting);
590 }
591
592 // 剛体
593 stream->read((char*) &this->rigid_body_count, sizeof(int));
594 this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
595 for (int i = 0; i < this->rigid_body_count; i++)
596 {
597 this->rigid_bodies[i].Read(stream, &setting);
598 }
599
600 // ジョイント
601 stream->read((char*) &this->joint_count, sizeof(int));
602 this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
603 for (int i = 0; i < this->joint_count; i++)
604 {
605 this->joints[i].Read(stream, &setting);
606 }
607
608 //if (this->version == 2.1f)
609 //{
610 // stream->read((char*) &this->soft_body_count, sizeof(int));
611 // this->soft_bodies = mmd::make_unique<PmxSoftBody []>(this->soft_body_count);
612 // for (int i = 0; i < this->soft_body_count; i++)
613 // {
614 // this->soft_bodies[i].Read(stream, &setting);
615 // }
616 //}
617 }
618
619 //std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
620 //{
621 // auto stream = std::ifstream(filename, std::ios_base::binary);
622 // auto pmx = PmxModel::ReadFromStream(&stream);
623 // if (!stream.eof())
624 // {
625 // std::cerr << "don't reach the end of file." << std::endl;
626 // }
627 // stream.close();
628 // return pmx;
629 //}
630
631 //std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
632 //{
633 // auto pmx = mmd::make_unique<PmxModel>();
634 // pmx->Read(stream);
635 // return pmx;
636 //}
637}
638