/src/assimp/code/AssetLib/MMD/MMDPmxParser.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Open Asset Import Library (assimp) |
3 | | ---------------------------------------------------------------------- |
4 | | |
5 | | Copyright (c) 2006-2024, assimp team |
6 | | |
7 | | |
8 | | All rights reserved. |
9 | | |
10 | | Redistribution and use of this software in source and binary forms, |
11 | | with or without modification, are permitted provided that the |
12 | | following conditions are met: |
13 | | |
14 | | * Redistributions of source code must retain the above |
15 | | copyright notice, this list of conditions and the |
16 | | following disclaimer. |
17 | | |
18 | | * Redistributions in binary form must reproduce the above |
19 | | copyright notice, this list of conditions and the |
20 | | following disclaimer in the documentation and/or other |
21 | | materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the assimp team, nor the names of its |
24 | | contributors may be used to endorse or promote products |
25 | | derived from this software without specific prior |
26 | | written permission of the assimp team. |
27 | | |
28 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
29 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
31 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
32 | | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
33 | | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
34 | | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
35 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
36 | | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
37 | | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
38 | | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | ---------------------------------------------------------------------- |
41 | | */ |
42 | | #include <utility> |
43 | | #include "MMDPmxParser.h" |
44 | | #include <assimp/StringUtils.h> |
45 | | #include "utf8.h" |
46 | | #include <assimp/Exceptional.h> |
47 | | |
48 | | namespace pmx |
49 | | { |
50 | | int ReadIndex(std::istream *stream, int size) |
51 | 0 | { |
52 | 0 | switch (size) |
53 | 0 | { |
54 | 0 | case 1: |
55 | 0 | uint8_t tmp8; |
56 | 0 | stream->read((char*) &tmp8, sizeof(uint8_t)); |
57 | 0 | if (255 == tmp8) |
58 | 0 | { |
59 | 0 | return -1; |
60 | 0 | } |
61 | 0 | else { |
62 | 0 | return (int) tmp8; |
63 | 0 | } |
64 | 0 | case 2: |
65 | 0 | uint16_t tmp16; |
66 | 0 | stream->read((char*) &tmp16, sizeof(uint16_t)); |
67 | 0 | if (65535 == tmp16) |
68 | 0 | { |
69 | 0 | return -1; |
70 | 0 | } |
71 | 0 | else { |
72 | 0 | return (int) tmp16; |
73 | 0 | } |
74 | 0 | case 4: |
75 | 0 | int tmp32; |
76 | 0 | stream->read((char*) &tmp32, sizeof(int)); |
77 | 0 | return tmp32; |
78 | 0 | default: |
79 | 0 | return -1; |
80 | 0 | } |
81 | 0 | } |
82 | | |
83 | | std::string ReadString(std::istream *stream, uint8_t encoding) |
84 | 0 | { |
85 | 0 | int size; |
86 | 0 | stream->read((char*) &size, sizeof(int)); |
87 | 0 | std::vector<char> buffer; |
88 | 0 | if (size == 0) |
89 | 0 | { |
90 | 0 | return std::string(); |
91 | 0 | } |
92 | 0 | buffer.resize(size); |
93 | 0 | stream->read((char*) buffer.data(), size); |
94 | 0 | if (encoding == 0) |
95 | 0 | { |
96 | | // UTF16 to UTF8 |
97 | 0 | const uint16_t* sourceStart = (uint16_t*)buffer.data(); |
98 | 0 | const unsigned int targetSize = size * 3; // enough to encode |
99 | 0 | char *targetStart = new char[targetSize]; |
100 | 0 | std::memset(targetStart, 0, targetSize * sizeof(char)); |
101 | |
|
102 | 0 | utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart ); |
103 | |
|
104 | 0 | std::string result(targetStart); |
105 | 0 | delete [] targetStart; |
106 | 0 | return result; |
107 | 0 | } |
108 | 0 | else |
109 | 0 | { |
110 | | // the name is already UTF8 |
111 | 0 | return std::string((const char*)buffer.data(), size); |
112 | 0 | } |
113 | 0 | } |
114 | | |
115 | | void PmxSetting::Read(std::istream *stream) |
116 | 0 | { |
117 | 0 | uint8_t count; |
118 | 0 | stream->read((char*) &count, sizeof(uint8_t)); |
119 | 0 | if (count < 8) |
120 | 0 | { |
121 | 0 | throw DeadlyImportError("MMD: invalid size"); |
122 | 0 | } |
123 | 0 | stream->read((char*) &encoding, sizeof(uint8_t)); |
124 | 0 | stream->read((char*) &uv, sizeof(uint8_t)); |
125 | 0 | stream->read((char*) &vertex_index_size, sizeof(uint8_t)); |
126 | 0 | stream->read((char*) &texture_index_size, sizeof(uint8_t)); |
127 | 0 | stream->read((char*) &material_index_size, sizeof(uint8_t)); |
128 | 0 | stream->read((char*) &bone_index_size, sizeof(uint8_t)); |
129 | 0 | stream->read((char*) &morph_index_size, sizeof(uint8_t)); |
130 | 0 | stream->read((char*) &rigidbody_index_size, sizeof(uint8_t)); |
131 | 0 | uint8_t temp; |
132 | 0 | for (int i = 8; i < count; i++) |
133 | 0 | { |
134 | 0 | stream->read((char*)&temp, sizeof(uint8_t)); |
135 | 0 | } |
136 | 0 | } |
137 | | |
138 | | void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting) |
139 | 0 | { |
140 | 0 | this->bone_index = ReadIndex(stream, setting->bone_index_size); |
141 | 0 | } |
142 | | |
143 | | void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting) |
144 | 0 | { |
145 | 0 | this->bone_index1 = ReadIndex(stream, setting->bone_index_size); |
146 | 0 | this->bone_index2 = ReadIndex(stream, setting->bone_index_size); |
147 | 0 | stream->read((char*) &this->bone_weight, sizeof(float)); |
148 | 0 | } |
149 | | |
150 | | void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting) |
151 | 0 | { |
152 | 0 | this->bone_index1 = ReadIndex(stream, setting->bone_index_size); |
153 | 0 | this->bone_index2 = ReadIndex(stream, setting->bone_index_size); |
154 | 0 | this->bone_index3 = ReadIndex(stream, setting->bone_index_size); |
155 | 0 | this->bone_index4 = ReadIndex(stream, setting->bone_index_size); |
156 | 0 | stream->read((char*) &this->bone_weight1, sizeof(float)); |
157 | 0 | stream->read((char*) &this->bone_weight2, sizeof(float)); |
158 | 0 | stream->read((char*) &this->bone_weight3, sizeof(float)); |
159 | 0 | stream->read((char*) &this->bone_weight4, sizeof(float)); |
160 | 0 | } |
161 | | |
162 | | void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting) |
163 | 0 | { |
164 | 0 | this->bone_index1 = ReadIndex(stream, setting->bone_index_size); |
165 | 0 | this->bone_index2 = ReadIndex(stream, setting->bone_index_size); |
166 | 0 | stream->read((char*) &this->bone_weight, sizeof(float)); |
167 | 0 | stream->read((char*) this->sdef_c, sizeof(float) * 3); |
168 | 0 | stream->read((char*) this->sdef_r0, sizeof(float) * 3); |
169 | 0 | stream->read((char*) this->sdef_r1, sizeof(float) * 3); |
170 | 0 | } |
171 | | |
172 | | void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting) |
173 | 0 | { |
174 | 0 | this->bone_index1 = ReadIndex(stream, setting->bone_index_size); |
175 | 0 | this->bone_index2 = ReadIndex(stream, setting->bone_index_size); |
176 | 0 | this->bone_index3 = ReadIndex(stream, setting->bone_index_size); |
177 | 0 | this->bone_index4 = ReadIndex(stream, setting->bone_index_size); |
178 | 0 | stream->read((char*) &this->bone_weight1, sizeof(float)); |
179 | 0 | stream->read((char*) &this->bone_weight2, sizeof(float)); |
180 | 0 | stream->read((char*) &this->bone_weight3, sizeof(float)); |
181 | 0 | stream->read((char*) &this->bone_weight4, sizeof(float)); |
182 | 0 | } |
183 | | |
184 | | void PmxVertex::Read(std::istream *stream, PmxSetting *setting) |
185 | 0 | { |
186 | 0 | stream->read((char*) this->position, sizeof(float) * 3); |
187 | 0 | stream->read((char*) this->normal, sizeof(float) * 3); |
188 | 0 | stream->read((char*) this->uv, sizeof(float) * 2); |
189 | 0 | for (int i = 0; i < setting->uv; ++i) |
190 | 0 | { |
191 | 0 | stream->read((char*) this->uva[i], sizeof(float) * 4); |
192 | 0 | } |
193 | 0 | stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType)); |
194 | 0 | switch (this->skinning_type) |
195 | 0 | { |
196 | 0 | case PmxVertexSkinningType::BDEF1: |
197 | 0 | this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>(); |
198 | 0 | break; |
199 | 0 | case PmxVertexSkinningType::BDEF2: |
200 | 0 | this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>(); |
201 | 0 | break; |
202 | 0 | case PmxVertexSkinningType::BDEF4: |
203 | 0 | this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>(); |
204 | 0 | break; |
205 | 0 | case PmxVertexSkinningType::SDEF: |
206 | 0 | this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>(); |
207 | 0 | break; |
208 | 0 | case PmxVertexSkinningType::QDEF: |
209 | 0 | this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>(); |
210 | 0 | break; |
211 | 0 | default: |
212 | 0 | throw "invalid skinning type"; |
213 | 0 | } |
214 | 0 | this->skinning->Read(stream, setting); |
215 | 0 | stream->read((char*) &this->edge, sizeof(float)); |
216 | 0 | } |
217 | | |
218 | | void PmxMaterial::Read(std::istream *stream, PmxSetting *setting) |
219 | 0 | { |
220 | 0 | this->material_name = ReadString(stream, setting->encoding); |
221 | 0 | this->material_english_name = ReadString(stream, setting->encoding); |
222 | 0 | stream->read((char*) this->diffuse, sizeof(float) * 4); |
223 | 0 | stream->read((char*) this->specular, sizeof(float) * 3); |
224 | 0 | stream->read((char*) &this->specularlity, sizeof(float)); |
225 | 0 | stream->read((char*) this->ambient, sizeof(float) * 3); |
226 | 0 | stream->read((char*) &this->flag, sizeof(uint8_t)); |
227 | 0 | stream->read((char*) this->edge_color, sizeof(float) * 4); |
228 | 0 | stream->read((char*) &this->edge_size, sizeof(float)); |
229 | 0 | this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size); |
230 | 0 | this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size); |
231 | 0 | stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t)); |
232 | 0 | stream->read((char*) &this->common_toon_flag, sizeof(uint8_t)); |
233 | 0 | if (this->common_toon_flag) |
234 | 0 | { |
235 | 0 | stream->read((char*) &this->toon_texture_index, sizeof(uint8_t)); |
236 | 0 | } |
237 | 0 | else { |
238 | 0 | this->toon_texture_index = ReadIndex(stream, setting->texture_index_size); |
239 | 0 | } |
240 | 0 | this->memo = ReadString(stream, setting->encoding); |
241 | 0 | stream->read((char*) &this->index_count, sizeof(int)); |
242 | 0 | } |
243 | | |
244 | | void PmxIkLink::Read(std::istream *stream, PmxSetting *setting) |
245 | 0 | { |
246 | 0 | this->link_target = ReadIndex(stream, setting->bone_index_size); |
247 | 0 | stream->read((char*) &this->angle_lock, sizeof(uint8_t)); |
248 | 0 | if (angle_lock == 1) |
249 | 0 | { |
250 | 0 | stream->read((char*) this->max_radian, sizeof(float) * 3); |
251 | 0 | stream->read((char*) this->min_radian, sizeof(float) * 3); |
252 | 0 | } |
253 | 0 | } |
254 | | |
255 | | void PmxBone::Read(std::istream *stream, PmxSetting *setting) |
256 | 0 | { |
257 | 0 | this->bone_name = ReadString(stream, setting->encoding); |
258 | 0 | this->bone_english_name = ReadString(stream, setting->encoding); |
259 | 0 | stream->read((char*) this->position, sizeof(float) * 3); |
260 | 0 | this->parent_index = ReadIndex(stream, setting->bone_index_size); |
261 | 0 | stream->read((char*) &this->level, sizeof(int)); |
262 | 0 | stream->read((char*) &this->bone_flag, sizeof(uint16_t)); |
263 | 0 | if (this->bone_flag & 0x0001) { |
264 | 0 | this->target_index = ReadIndex(stream, setting->bone_index_size); |
265 | 0 | } |
266 | 0 | else { |
267 | 0 | stream->read((char*)this->offset, sizeof(float) * 3); |
268 | 0 | } |
269 | 0 | if (this->bone_flag & (0x0100 | 0x0200)) { |
270 | 0 | this->grant_parent_index = ReadIndex(stream, setting->bone_index_size); |
271 | 0 | stream->read((char*) &this->grant_weight, sizeof(float)); |
272 | 0 | } |
273 | 0 | if (this->bone_flag & 0x0400) { |
274 | 0 | stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3); |
275 | 0 | } |
276 | 0 | if (this->bone_flag & 0x0800) { |
277 | 0 | stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3); |
278 | 0 | stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3); |
279 | 0 | } |
280 | 0 | if (this->bone_flag & 0x2000) { |
281 | 0 | stream->read((char*) &this->key, sizeof(int)); |
282 | 0 | } |
283 | 0 | if (this->bone_flag & 0x0020) { |
284 | 0 | this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size); |
285 | 0 | stream->read((char*) &ik_loop, sizeof(int)); |
286 | 0 | stream->read((char*) &ik_loop_angle_limit, sizeof(float)); |
287 | 0 | stream->read((char*) &ik_link_count, sizeof(int)); |
288 | 0 | this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count); |
289 | 0 | for (int i = 0; i < ik_link_count; i++) { |
290 | 0 | ik_links[i].Read(stream, setting); |
291 | 0 | } |
292 | 0 | } |
293 | 0 | } |
294 | | |
295 | | void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting) |
296 | 0 | { |
297 | 0 | this->vertex_index = ReadIndex(stream, setting->vertex_index_size); |
298 | 0 | stream->read((char*)this->position_offset, sizeof(float) * 3); |
299 | 0 | } |
300 | | |
301 | | void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting) |
302 | 0 | { |
303 | 0 | this->vertex_index = ReadIndex(stream, setting->vertex_index_size); |
304 | 0 | stream->read((char*)this->uv_offset, sizeof(float) * 4); |
305 | 0 | } |
306 | | |
307 | | void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting) |
308 | 0 | { |
309 | 0 | this->bone_index = ReadIndex(stream, setting->bone_index_size); |
310 | 0 | stream->read((char*)this->translation, sizeof(float) * 3); |
311 | 0 | stream->read((char*)this->rotation, sizeof(float) * 4); |
312 | 0 | } |
313 | | |
314 | | void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting) |
315 | 0 | { |
316 | 0 | this->material_index = ReadIndex(stream, setting->material_index_size); |
317 | 0 | stream->read((char*) &this->offset_operation, sizeof(uint8_t)); |
318 | 0 | stream->read((char*)this->diffuse, sizeof(float) * 4); |
319 | 0 | stream->read((char*)this->specular, sizeof(float) * 3); |
320 | 0 | stream->read((char*) &this->specularity, sizeof(float)); |
321 | 0 | stream->read((char*)this->ambient, sizeof(float) * 3); |
322 | 0 | stream->read((char*)this->edge_color, sizeof(float) * 4); |
323 | 0 | stream->read((char*) &this->edge_size, sizeof(float)); |
324 | 0 | stream->read((char*)this->texture_argb, sizeof(float) * 4); |
325 | 0 | stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4); |
326 | 0 | stream->read((char*)this->toon_texture_argb, sizeof(float) * 4); |
327 | 0 | } |
328 | | |
329 | | void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting) |
330 | 0 | { |
331 | 0 | this->morph_index = ReadIndex(stream, setting->morph_index_size); |
332 | 0 | stream->read((char*) &this->morph_weight, sizeof(float)); |
333 | 0 | } |
334 | | |
335 | | void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting) |
336 | 0 | { |
337 | 0 | this->morph_index = ReadIndex(stream, setting->morph_index_size); |
338 | 0 | stream->read((char*) &this->morph_value, sizeof(float)); |
339 | 0 | } |
340 | | |
341 | | void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting) |
342 | 0 | { |
343 | 0 | this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size); |
344 | 0 | stream->read((char*) &this->is_local, sizeof(uint8_t)); |
345 | 0 | stream->read((char*)this->velocity, sizeof(float) * 3); |
346 | 0 | stream->read((char*)this->angular_torque, sizeof(float) * 3); |
347 | 0 | } |
348 | | |
349 | | void PmxMorph::Read(std::istream *stream, PmxSetting *setting) |
350 | 0 | { |
351 | 0 | this->morph_name = ReadString(stream, setting->encoding); |
352 | 0 | this->morph_english_name = ReadString(stream, setting->encoding); |
353 | 0 | stream->read((char*) &category, sizeof(MorphCategory)); |
354 | 0 | stream->read((char*) &morph_type, sizeof(MorphType)); |
355 | 0 | stream->read((char*) &this->offset_count, sizeof(int)); |
356 | 0 | switch (this->morph_type) |
357 | 0 | { |
358 | 0 | case MorphType::Group: |
359 | 0 | group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count); |
360 | 0 | for (int i = 0; i < offset_count; i++) |
361 | 0 | { |
362 | 0 | group_offsets[i].Read(stream, setting); |
363 | 0 | } |
364 | 0 | break; |
365 | 0 | case MorphType::Vertex: |
366 | 0 | vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count); |
367 | 0 | for (int i = 0; i < offset_count; i++) |
368 | 0 | { |
369 | 0 | vertex_offsets[i].Read(stream, setting); |
370 | 0 | } |
371 | 0 | break; |
372 | 0 | case MorphType::Bone: |
373 | 0 | bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count); |
374 | 0 | for (int i = 0; i < offset_count; i++) |
375 | 0 | { |
376 | 0 | bone_offsets[i].Read(stream, setting); |
377 | 0 | } |
378 | 0 | break; |
379 | 0 | case MorphType::Matrial: |
380 | 0 | material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count); |
381 | 0 | for (int i = 0; i < offset_count; i++) |
382 | 0 | { |
383 | 0 | material_offsets[i].Read(stream, setting); |
384 | 0 | } |
385 | 0 | break; |
386 | 0 | case MorphType::UV: |
387 | 0 | case MorphType::AdditionalUV1: |
388 | 0 | case MorphType::AdditionalUV2: |
389 | 0 | case MorphType::AdditionalUV3: |
390 | 0 | case MorphType::AdditionalUV4: |
391 | 0 | uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count); |
392 | 0 | for (int i = 0; i < offset_count; i++) |
393 | 0 | { |
394 | 0 | uv_offsets[i].Read(stream, setting); |
395 | 0 | } |
396 | 0 | break; |
397 | 0 | default: |
398 | 0 | throw DeadlyImportError("MMD: unknown morth type"); |
399 | 0 | } |
400 | 0 | } |
401 | | |
402 | | void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting) |
403 | 0 | { |
404 | 0 | stream->read((char*) &this->element_target, sizeof(uint8_t)); |
405 | 0 | if (this->element_target == 0x00) |
406 | 0 | { |
407 | 0 | this->index = ReadIndex(stream, setting->bone_index_size); |
408 | 0 | } |
409 | 0 | else { |
410 | 0 | this->index = ReadIndex(stream, setting->morph_index_size); |
411 | 0 | } |
412 | 0 | } |
413 | | |
414 | | void PmxFrame::Read(std::istream *stream, PmxSetting *setting) |
415 | 0 | { |
416 | 0 | this->frame_name = ReadString(stream, setting->encoding); |
417 | 0 | this->frame_english_name = ReadString(stream, setting->encoding); |
418 | 0 | stream->read((char*) &this->frame_flag, sizeof(uint8_t)); |
419 | 0 | stream->read((char*) &this->element_count, sizeof(int)); |
420 | 0 | this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count); |
421 | 0 | for (int i = 0; i < this->element_count; i++) |
422 | 0 | { |
423 | 0 | this->elements[i].Read(stream, setting); |
424 | 0 | } |
425 | 0 | } |
426 | | |
427 | | void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting) |
428 | 0 | { |
429 | 0 | this->girid_body_name = ReadString(stream, setting->encoding); |
430 | 0 | this->girid_body_english_name = ReadString(stream, setting->encoding); |
431 | 0 | this->target_bone = ReadIndex(stream, setting->bone_index_size); |
432 | 0 | stream->read((char*) &this->group, sizeof(uint8_t)); |
433 | 0 | stream->read((char*) &this->mask, sizeof(uint16_t)); |
434 | 0 | stream->read((char*) &this->shape, sizeof(uint8_t)); |
435 | 0 | stream->read((char*) this->size, sizeof(float) * 3); |
436 | 0 | stream->read((char*) this->position, sizeof(float) * 3); |
437 | 0 | stream->read((char*) this->orientation, sizeof(float) * 3); |
438 | 0 | stream->read((char*) &this->mass, sizeof(float)); |
439 | 0 | stream->read((char*) &this->move_attenuation, sizeof(float)); |
440 | 0 | stream->read((char*) &this->rotation_attenuation, sizeof(float)); |
441 | 0 | stream->read((char*) &this->repulsion, sizeof(float)); |
442 | 0 | stream->read((char*) &this->friction, sizeof(float)); |
443 | 0 | stream->read((char*) &this->physics_calc_type, sizeof(uint8_t)); |
444 | 0 | } |
445 | | |
446 | | void PmxJointParam::Read(std::istream *stream, PmxSetting *setting) |
447 | 0 | { |
448 | 0 | this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size); |
449 | 0 | this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size); |
450 | 0 | stream->read((char*) this->position, sizeof(float) * 3); |
451 | 0 | stream->read((char*) this->orientaiton, sizeof(float) * 3); |
452 | 0 | stream->read((char*) this->move_limitation_min, sizeof(float) * 3); |
453 | 0 | stream->read((char*) this->move_limitation_max, sizeof(float) * 3); |
454 | 0 | stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3); |
455 | 0 | stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3); |
456 | 0 | stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3); |
457 | 0 | stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3); |
458 | 0 | } |
459 | | |
460 | | void PmxJoint::Read(std::istream *stream, PmxSetting *setting) |
461 | 0 | { |
462 | 0 | this->joint_name = ReadString(stream, setting->encoding); |
463 | 0 | this->joint_english_name = ReadString(stream, setting->encoding); |
464 | 0 | stream->read((char*) &this->joint_type, sizeof(uint8_t)); |
465 | 0 | this->param.Read(stream, setting); |
466 | 0 | } |
467 | | |
468 | | void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting) |
469 | 0 | { |
470 | 0 | this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size); |
471 | 0 | this->related_vertex = ReadIndex(stream, setting->vertex_index_size); |
472 | 0 | stream->read((char*) &this->is_near, sizeof(uint8_t)); |
473 | 0 | } |
474 | | |
475 | | void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) |
476 | 0 | { |
477 | 0 | throw DeadlyImportError("MMD: Soft Body support is not implemented."); |
478 | 0 | } |
479 | | |
480 | | void PmxModel::Init() |
481 | 0 | { |
482 | 0 | this->version = 0.0f; |
483 | 0 | this->model_name.clear(); |
484 | 0 | this->model_english_name.clear(); |
485 | 0 | this->model_comment.clear(); |
486 | 0 | this->model_english_comment.clear(); |
487 | 0 | this->vertex_count = 0; |
488 | 0 | this->vertices = nullptr; |
489 | 0 | this->index_count = 0; |
490 | 0 | this->indices = nullptr; |
491 | 0 | this->texture_count = 0; |
492 | 0 | this->textures = nullptr; |
493 | 0 | this->material_count = 0; |
494 | 0 | this->materials = nullptr; |
495 | 0 | this->bone_count = 0; |
496 | 0 | this->bones = nullptr; |
497 | 0 | this->morph_count = 0; |
498 | 0 | this->morphs = nullptr; |
499 | 0 | this->frame_count = 0; |
500 | 0 | this->frames = nullptr; |
501 | 0 | this->rigid_body_count = 0; |
502 | 0 | this->rigid_bodies = nullptr; |
503 | 0 | this->joint_count = 0; |
504 | 0 | this->joints = nullptr; |
505 | 0 | this->soft_body_count = 0; |
506 | 0 | this->soft_bodies = nullptr; |
507 | 0 | } |
508 | | |
509 | | void PmxModel::Read(std::istream *stream) |
510 | 0 | { |
511 | 0 | char magic[4]; |
512 | 0 | stream->read((char*) magic, sizeof(char) * 4); |
513 | 0 | if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) |
514 | 0 | { |
515 | 0 | throw DeadlyImportError("MMD: Invalid magic number."); |
516 | 0 | } |
517 | 0 | stream->read((char*) &version, sizeof(float)); |
518 | 0 | if (version != 2.0f && version != 2.1f) |
519 | 0 | { |
520 | 0 | throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version)); |
521 | 0 | } |
522 | 0 | this->setting.Read(stream); |
523 | |
|
524 | 0 | this->model_name = ReadString(stream, setting.encoding); |
525 | 0 | this->model_english_name = ReadString(stream, setting.encoding); |
526 | 0 | this->model_comment = ReadString(stream, setting.encoding); |
527 | 0 | this->model_english_comment = ReadString(stream, setting.encoding); |
528 | | |
529 | | // read vertices |
530 | 0 | stream->read((char*) &vertex_count, sizeof(int)); |
531 | 0 | this->vertices = mmd::make_unique<PmxVertex []>(vertex_count); |
532 | 0 | for (int i = 0; i < vertex_count; i++) |
533 | 0 | { |
534 | 0 | vertices[i].Read(stream, &setting); |
535 | 0 | } |
536 | | |
537 | | // read indices |
538 | 0 | stream->read((char*) &index_count, sizeof(int)); |
539 | 0 | this->indices = mmd::make_unique<int []>(index_count); |
540 | 0 | for (int i = 0; i < index_count; i++) |
541 | 0 | { |
542 | 0 | this->indices[i] = ReadIndex(stream, setting.vertex_index_size); |
543 | 0 | } |
544 | | |
545 | | // read texture names |
546 | 0 | stream->read((char*) &texture_count, sizeof(int)); |
547 | 0 | this->textures = mmd::make_unique<std::string []>(texture_count); |
548 | 0 | for (int i = 0; i < texture_count; i++) |
549 | 0 | { |
550 | 0 | this->textures[i] = ReadString(stream, setting.encoding); |
551 | 0 | } |
552 | | |
553 | | // read materials |
554 | 0 | stream->read((char*) &material_count, sizeof(int)); |
555 | 0 | this->materials = mmd::make_unique<PmxMaterial []>(material_count); |
556 | 0 | for (int i = 0; i < material_count; i++) |
557 | 0 | { |
558 | 0 | this->materials[i].Read(stream, &setting); |
559 | 0 | } |
560 | | |
561 | | // read bones |
562 | 0 | stream->read((char*) &this->bone_count, sizeof(int)); |
563 | 0 | this->bones = mmd::make_unique<PmxBone []>(this->bone_count); |
564 | 0 | for (int i = 0; i < this->bone_count; i++) |
565 | 0 | { |
566 | 0 | this->bones[i].Read(stream, &setting); |
567 | 0 | } |
568 | | |
569 | | // read morphs |
570 | 0 | stream->read((char*) &this->morph_count, sizeof(int)); |
571 | 0 | this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count); |
572 | 0 | for (int i = 0; i < this->morph_count; i++) |
573 | 0 | { |
574 | 0 | this->morphs[i].Read(stream, &setting); |
575 | 0 | } |
576 | | |
577 | | // read display frames |
578 | 0 | stream->read((char*) &this->frame_count, sizeof(int)); |
579 | 0 | this->frames = mmd::make_unique<PmxFrame []>(this->frame_count); |
580 | 0 | for (int i = 0; i < this->frame_count; i++) |
581 | 0 | { |
582 | 0 | this->frames[i].Read(stream, &setting); |
583 | 0 | } |
584 | | |
585 | | // read rigid bodies |
586 | 0 | stream->read((char*) &this->rigid_body_count, sizeof(int)); |
587 | 0 | this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count); |
588 | 0 | for (int i = 0; i < this->rigid_body_count; i++) |
589 | 0 | { |
590 | 0 | this->rigid_bodies[i].Read(stream, &setting); |
591 | 0 | } |
592 | | |
593 | | // read joints |
594 | 0 | stream->read((char*) &this->joint_count, sizeof(int)); |
595 | 0 | this->joints = mmd::make_unique<PmxJoint []>(this->joint_count); |
596 | 0 | for (int i = 0; i < this->joint_count; i++) |
597 | 0 | { |
598 | 0 | this->joints[i].Read(stream, &setting); |
599 | 0 | } |
600 | 0 | } |
601 | | } |