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