1 #include <algorithm>
2 #include "xr_ogf_v3.h"
3 #include "xr_file_system.h"
4 #include "xr_ini_file.h"
5 #include "xr_string_utils.h"
6
7 using namespace xray_re;
8
9 struct xr_ogf_v3::bone_io: public xr_bone {
10 void import(xr_reader& r);
11 void import_ikdata_0(xr_reader& r);
12 void import_ikdata(xr_reader& r);
13 void import_ikdata_2(xr_reader& r);
14 void define(uint16_t id, const std::string& name);
15 };
16
17 struct xr_ogf_v3::partition_io: public xr_partition {
18 void import(xr_reader& r, xr_bone_vec& all_bones, int version);
19 void import(const xr_ini_file& ini, const char* part_name, xr_ogf_v3& ogf);
20 };
21
22 struct xr_ogf_v3::bone_motion_io: public xr_ogf::bone_motion_io {
23 void import(xr_reader& r, uint_fast32_t num_keys);
24 void import_new(xr_reader& r, uint_fast32_t num_keys);
25 };
26
27 struct xr_ogf_v3::motion_io: public xr_skl_motion {
28 motion_io();
29 void import_bone_motions(xr_reader& r, xr_bone_vec& all_bones);
30 uint16_t import_params(xr_reader& r);
31 uint16_t import_params_new(xr_reader& r, unsigned version);
32 void import_params(const xr_ini_file& ini, ogf3_motion_type motion_type,
33 const char* section, const char* name, xr_ogf_v3& ogf);
34 void import_bone_motions_new(xr_reader& r, xr_bone_vec& all_bones);
35 };
36
motion_io()37 inline xr_ogf_v3::motion_io::motion_io() { m_fps = OGF3_MOTION_FPS; }
38
39 ////////////////////////////////////////////////////////////////////////////////
40
xr_ogf_v3()41 xr_ogf_v3::xr_ogf_v3(): xr_ogf(OGF3_VERSION),
42 m_vsplits(0), m_fix_faces(0),
43 m_ext_vb_index(0), m_ext_vb_offset(0), m_ext_vb_size(0) {}
44
~xr_ogf_v3()45 xr_ogf_v3::~xr_ogf_v3()
46 {
47 delete[] m_vsplits;
48 delete[] m_fix_faces;
49 }
50
clear()51 void xr_ogf_v3::clear()
52 {
53 xr_ogf::clear();
54 delete[] m_vsplits; m_vsplits = 0;
55 delete[] m_fix_faces; m_fix_faces = 0;
56 m_ib.clear();
57 }
58
hierarchical() const59 bool xr_ogf_v3::hierarchical() const
60 {
61 switch (m_model_type) {
62 case MT3_HIERRARHY:
63 case MT3_SKELETON_ANIM:
64 case MT3_SKELETON_RIGID:
65 case MT3_LOD:
66 return true;
67 default:
68 return false;
69 }
70 }
71
skeletal() const72 bool xr_ogf_v3::skeletal() const { return m_model_type == MT3_SKELETON_ANIM; }
73
animated() const74 bool xr_ogf_v3::animated() const { return m_model_type == MT3_SKELETON_ANIM; }
75
progressive() const76 bool xr_ogf_v3::progressive() const
77 {
78 switch (m_model_type) {
79 case MT3_PROGRESSIVE:
80 case MT3_SKELETON_GEOMDEF_PM:
81 return true;
82 default:
83 return false;
84 }
85 }
86
versioned() const87 bool xr_ogf_v3::versioned() const { return false; }
88
setup_ib0()89 void xr_ogf_v3::setup_ib0()
90 {
91 m_ib0 = m_ib;
92 size_t fix_idx = 0;
93 uint16_t active_vb_size = uint16_t(m_min_vertices & UINT16_MAX);
94 for (ogf3_vsplit *p = m_vsplits, *end = p + m_vb.size() - m_min_vertices; p != end; ++p) {
95 for (uint_fast32_t end_idx = fix_idx + p->fix_faces; fix_idx < end_idx; ++fix_idx)
96 m_ib0[m_fix_faces[fix_idx]] = active_vb_size;
97 ++active_vb_size;
98 }
99 assert(active_vb_size == m_vb.size());
100 }
101
set_ext_geom(const xr_vbuf_vec & ext_vbufs)102 void xr_ogf_v3::set_ext_geom(const xr_vbuf_vec& ext_vbufs)
103 {
104 if (is_chunk_loaded(OGF3_VCONTAINER))
105 m_vb.proxy(ext_vbufs.at(m_ext_vb_index), m_ext_vb_offset, m_ext_vb_size);
106 }
107
set_ext_geom(const xr_vbuf_vec & ext_vbufs,const xr_ibuf_vec & ext_ibufs)108 void xr_ogf_v3::set_ext_geom(const xr_vbuf_vec& ext_vbufs, const xr_ibuf_vec& ext_ibufs)
109 {
110 if (is_chunk_loaded(OGF3_VCONTAINER))
111 m_vb.proxy(ext_vbufs.at(m_ext_vb_index), m_ext_vb_offset, m_ext_vb_size);
112 if (is_chunk_loaded(OGF3_ICONTAINER))
113 m_ib.proxy(ext_ibufs.at(m_ext_ib_index), m_ext_ib_offset, m_ext_ib_size);
114 }
115
116 ////////////////////////////////////////////////////////////////////////////////
117
load_header(xr_reader & r)118 void xr_ogf_v3::load_header(xr_reader& r)
119 {
120 m_version = static_cast<ogf_version>(r.r_u8());
121 m_model_type = static_cast<ogf_model_type>(r.r_u8());
122 uint16_t unused = r.r_u16();
123 m_texture_l = unused;
124 m_shader_l = unused;
125 set_chunk_loaded(OGF_HEADER);
126 }
127
load_texture(xr_reader & r)128 inline void xr_ogf_v3::load_texture(xr_reader& r)
129 {
130 xr_ogf::load_texture(r);
131 set_chunk_loaded(OGF3_TEXTURE);
132 }
133
load_texture_l(xr_reader & r)134 inline void xr_ogf_v3::load_texture_l(xr_reader& r)
135 {
136 m_texture_l = r.r_u32();
137 m_shader_l = r.r_u32();
138 set_chunk_loaded(OGF3_TEXTURE_L);
139 }
140
load_child_refs(xr_reader & r)141 void xr_ogf_v3::load_child_refs(xr_reader& r)
142 {
143 assert(m_children.empty());
144 std::string folder, name;
145 xr_file_system::split_path(m_path, &folder);
146 xr_file_system& fs = xr_file_system::instance();
147 for (uint_fast32_t n = r.r_u32(); n; --n) {
148 r.r_sz(name);
149 xr_reader* s = fs.r_open(folder + name);
150 if (!s)
151 continue;
152 xr_ogf_v3* ogf = new xr_ogf_v3;
153 ogf->load_ogf(*s);
154 m_children.push_back(ogf);
155 fs.r_close(s);
156 }
157 set_chunk_loaded(OGF3_CHILD_REFS);
158 }
159
load_bbox(xr_reader & r)160 inline void xr_ogf_v3::load_bbox(xr_reader& r)
161 {
162 r.r(m_bbox);
163 set_chunk_loaded(OGF3_BBOX);
164 }
165
load_vertices(xr_reader & r)166 void xr_ogf_v3::load_vertices(xr_reader& r)
167 {
168 ogf_vertex_format fmt = static_cast<ogf_vertex_format>(r.r_u32());
169 size_t n = r.r_u32();
170 m_vb.load_ogf3(r, n, fmt);
171 r.debug_find_chunk();
172 set_chunk_loaded(OGF3_VERTICES);
173 }
174
load_indices(xr_reader & r)175 void xr_ogf_v3::load_indices(xr_reader& r)
176 {
177 size_t n = r.r_u32();
178 m_ib.load(r, n);
179 r.debug_find_chunk();
180 set_chunk_loaded(OGF3_INDICES);
181 }
182
load_loddata(xr_reader & r)183 inline void xr_ogf_v3::load_loddata(xr_reader& r)
184 {
185 if (!r.find_chunk(OGF3_HOPPE_HEADER))
186 xr_not_expected();
187 m_min_vertices = r.r_u32();
188 m_min_indices = r.r_u32();
189 r.debug_find_chunk();
190
191 if (!r.find_chunk(OGF3_HOPPE_VERT_SPLITS))
192 xr_not_expected();
193 xr_assert(is_chunk_loaded(OGF3_VERTICES));
194 size_t num_vsplits = m_vb.size() - m_min_vertices;
195 m_vsplits = new ogf3_vsplit[num_vsplits];
196 r.r_cseq(num_vsplits, m_vsplits);
197 r.debug_find_chunk();
198
199 if (!r.find_chunk(OGF3_HOPPE_FIX_FACES))
200 xr_not_expected();
201 m_num_fix_faces = r.r_u32();
202 m_fix_faces = new uint16_t[m_num_fix_faces];
203 r.r_cseq(m_num_fix_faces, m_fix_faces);
204 r.debug_find_chunk();
205
206 setup_ib0();
207
208 set_chunk_loaded(OGF3_LODDATA);
209 }
210
load_vcontainer(xr_reader & r)211 inline void xr_ogf_v3::load_vcontainer(xr_reader& r)
212 {
213 m_ext_vb_index = r.r_u32();
214 m_ext_vb_offset = r.r_u32();
215 m_ext_vb_size = r.r_u32();
216 set_chunk_loaded(OGF3_VCONTAINER);
217 }
218
load_icontainer(xr_reader & r)219 inline void xr_ogf_v3::load_icontainer(xr_reader& r)
220 {
221 m_ext_ib_index = r.r_u32();
222 m_ext_ib_offset = r.r_u32();
223 m_ext_ib_size = r.r_u32();
224 set_chunk_loaded(OGF3_ICONTAINER);
225 }
226
load_bsphere(xr_reader & r)227 inline void xr_ogf_v3::load_bsphere(xr_reader& r)
228 {
229 r.r(m_bsphere);
230 set_chunk_loaded(OGF3_BSPHERE);
231 }
232
load_children_l(xr_reader & r)233 void xr_ogf_v3::load_children_l(xr_reader& r)
234 {
235 r.r_seq(r.r_u32(), m_children_l);
236 set_chunk_loaded(OGF3_CHILDREN_L);
237 }
238
load_dpatch(xr_reader & r)239 void xr_ogf_v3::load_dpatch(xr_reader& r)
240 {
241 xr_not_implemented();
242 set_chunk_loaded(OGF3_DPATCH);
243 }
244
load_lods(xr_reader & r)245 void xr_ogf_v3::load_lods(xr_reader& r)
246 {
247 assert(m_lods.empty());
248 xr_reader* s;
249 for (uint32_t id = 0; (s = r.open_chunk(id)); ++id) {
250 xr_ogf_v3* ogf = new xr_ogf_v3;
251 ogf->load_ogf(*s);
252 m_lods.push_back(ogf);
253 r.close_chunk(s);
254 }
255 set_chunk_loaded(OGF3_LODS);
256 }
257
load_children(xr_reader & r)258 void xr_ogf_v3::load_children(xr_reader& r)
259 {
260 assert(m_children.empty());
261 xr_reader* s;
262 for (uint32_t id = 0; (s = r.open_chunk(id)); ++id) {
263 xr_ogf_v3* ogf = new xr_ogf_v3;
264 ogf->load_ogf(*s);
265 m_children.push_back(ogf);
266 r.close_chunk(s);
267 }
268 set_chunk_loaded(OGF3_CHILDREN);
269 }
270
import(xr_reader & r,uint_fast32_t num_keys)271 inline void xr_ogf_v3::bone_motion_io::import(xr_reader& r, uint_fast32_t num_keys)
272 {
273 create_envelopes();
274 for (uint_fast32_t i = 0; i != num_keys; ++i) {
275 float time = float(i)/OGF3_MOTION_FPS;
276 insert_key(time, r.skip<ogf_key_qr>());
277 insert_key(time, r.skip<fvector3>());
278 }
279 }
280
import_bone_motions(xr_reader & r,xr_bone_vec & all_bones)281 inline void xr_ogf_v3::motion_io::import_bone_motions(xr_reader& r, xr_bone_vec& all_bones)
282 {
283 uint_fast32_t num_keys = r.r_u32();
284 m_frame_start = 0;
285 m_frame_end = int32_t(num_keys & INT32_MAX);
286
287 assert(m_bone_motions.empty());
288 m_bone_motions.reserve(all_bones.size());
289 for (xr_bone_vec_it it = all_bones.begin(), end = all_bones.end(); it != end; ++it) {
290 xr_ogf_v3::bone_motion_io* bm = new xr_ogf_v3::bone_motion_io;
291 bm->name() = (*it)->name();
292 bm->import(r, num_keys);
293 m_bone_motions.push_back(bm);
294 }
295 }
296
load_s_motions(xr_reader & r)297 void xr_ogf_v3::load_s_motions(xr_reader& r)
298 {
299 if (!r.find_chunk(0))
300 xr_not_expected();
301 size_t num_motions = r.r_u32();
302 xr_assert(m_motions.size() == num_motions);
303 for (uint32_t id = 1; id <= num_motions; ++id) {
304 if (!r.find_chunk(id))
305 xr_not_expected();
306
307 const char* name = r.skip_sz();
308 motion_io* smotion = static_cast<motion_io*>(find_motion(name));
309 if (smotion == 0) {
310 msg("unknown motion %s", name);
311 throw xr_error();
312 }
313 smotion->import_bone_motions(r, m_bones);
314
315 r.debug_find_chunk();
316 }
317 set_chunk_loaded(OGF3_S_MOTIONS);
318 }
319
import(xr_reader & r,xr_bone_vec & all_bones,int version)320 inline void xr_ogf_v3::partition_io::import(xr_reader& r, xr_bone_vec& all_bones, int version)
321 {
322 r.r_sz(m_name);
323 for (uint_fast32_t n = r.r_u16(); n; --n)
324 {
325 std::string name;
326 switch (version)
327 {
328 case 1:
329 name = all_bones.at(r.r_u32())->name();
330 break;
331 case 2:
332 r.r_sz(name);
333 break;
334 case 3:
335 r.r_sz(name);
336 xr_assert(all_bones.at(r.r_u32())->name() == name);
337 }
338 m_bones.push_back(name);
339 }
340 }
341
import_params(xr_reader & r)342 inline uint16_t xr_ogf_v3::motion_io::import_params(xr_reader& r)
343 {
344 r.r_sz(m_name);
345 m_flags = (r.r_u8() == SMT_FX) ? SMF_FX : 0;
346 m_bone_or_part = r.r_u16();
347 uint16_t motion_id = r.r_u16();
348 m_speed = r.r_float();
349 m_power = r.r_float();
350 m_accrue = r.r_float();
351 m_falloff = r.r_float();
352 if (r.r_bool())
353 m_flags |= SMF_STOP_AT_END;
354 return motion_id;
355 }
356
357 struct read_partition_v3 {
358 xr_bone_vec& all_bones;
359 int version;
read_partition_v3read_partition_v3360 read_partition_v3(xr_bone_vec& _all_bones, int _version): all_bones(_all_bones), version(_version) {}
operator ()read_partition_v3361 void operator()(xr_partition*& _part, xr_reader& r) {
362 xr_ogf_v3::partition_io* part = new xr_ogf_v3::partition_io;
363 _part = part;
364 part->import(r, all_bones, version);
365 }
366 };
367
load_s_smparams(xr_reader & r)368 void xr_ogf_v3::load_s_smparams(xr_reader& r)
369 {
370 assert(m_partitions.empty());
371 r.r_seq(r.r_u16(), m_partitions, read_partition_v3(m_bones, 1));
372 setup_partitions();
373
374 assert(m_motions.empty());
375 size_t num_motions = r.r_u16();
376 m_motions.resize(num_motions);
377 for (; num_motions; --num_motions) {
378 motion_io* smotion = new xr_ogf_v3::motion_io;
379 m_motions.at(smotion->import_params(r)) = smotion;
380 }
381 assert(std::find(m_motions.begin(), m_motions.end(), static_cast<xr_skl_motion*>(0)) == m_motions.end());
382
383 set_chunk_loaded(OGF3_S_SMPARAMS);
384 }
385
import(const xr_ini_file & ini,const char * part_name,xr_ogf_v3 & ogf)386 inline void xr_ogf_v3::partition_io::import(const xr_ini_file& ini, const char* part_name, xr_ogf_v3& ogf)
387 {
388 size_t num_bones = ini.line_count(part_name);
389 if (num_bones == 0) {
390 msg("empty partition section %s", part_name);
391 throw xr_error();
392 }
393
394 m_name = part_name;
395 m_bones.reserve(num_bones);
396 for (size_t i = 0; i != num_bones; ++i) {
397 const char* bone_name;
398 ini.r_line(part_name, i, &bone_name, 0);
399 if (ogf.find_bone(bone_name) == 0) {
400 msg("unknown bone %s in partition %s", bone_name, part_name);
401 throw xr_error();
402 }
403 m_bones.push_back(bone_name);
404 }
405 }
406
import_params(const xr_ini_file & ini,ogf3_motion_type motion_type,const char * section,const char * name,xr_ogf_v3 & ogf)407 inline void xr_ogf_v3::motion_io::import_params(const xr_ini_file& ini, ogf3_motion_type motion_type,
408 const char* section, const char* name, xr_ogf_v3& ogf)
409 {
410 if (motion_type == SMT_CYCLE) {
411 const char* part_name = ini.r_string(section, "part");
412 if (strstr(part_name, "--none--") == 0) {
413 xr_partition* part = ogf.find_partition(part_name);
414 if (part == 0) {
415 msg("unknown partition %s in motion %s", part_name, name);
416 throw xr_error();
417 }
418 m_bone_or_part = part->id();
419 } else {
420 m_bone_or_part = ALL_PARTITIONS;
421 }
422 m_flags = 0;
423 } else {
424 const char* bone_name = ini.r_string(section, "bone");
425 xr_bone* bone = ogf.find_bone(bone_name);
426 if (bone == 0) {
427 msg("unknown bone %s in motion %s", bone_name, name);
428 throw xr_error();
429 }
430 m_bone_or_part = bone->id();
431 m_flags = SMF_FX;
432 }
433 m_speed = ini.r_float(section, "speed");
434 m_power = ini.r_float(section, "power");
435 m_accrue = ini.r_float(section, "accrue");
436 m_falloff = ini.r_float(section, "falloff");
437 if (ini.r_bool(section, "stop@end"))
438 m_flags |= SMF_STOP_AT_END;
439 // else
440 // m_flags &= ~SMF_STOP_AT_END;
441 m_name = name;
442 }
443
load_motion_defs(xr_ini_file & ini,ogf3_motion_type motion_type,const char * motion_type_name)444 void xr_ogf_v3::load_motion_defs(xr_ini_file& ini,
445 ogf3_motion_type motion_type, const char* motion_type_name)
446 {
447 if (!ini.section_exist(motion_type_name)) {
448 msg("empty motion defs section %s", motion_type_name);
449 throw xr_error();
450 }
451 size_t num_motions = ini.line_count(motion_type_name);
452 m_motions.reserve(num_motions + m_motions.size());
453 for (size_t i = 0; i != num_motions; ++i) {
454 const char* name;
455 const char* section_name;
456 ini.r_line(motion_type_name, i, &name, §ion_name);
457 // sometimes there is no right side
458 if (section_name && section_name[0] == '\0')
459 section_name = name;
460 xr_assert(xr_stricmp(ini.r_string(section_name, "motion"), name) == 0);
461 motion_io* smotion = new xr_ogf_v3::motion_io;
462 smotion->import_params(ini, motion_type, section_name, name, *this);
463 m_motions.push_back(smotion);
464 }
465 }
466
load_s_smparams()467 void xr_ogf_v3::load_s_smparams()
468 {
469 assert(!m_path.empty());
470 std::string folder, name, ltx_name;
471 xr_file_system::split_path(m_path, &folder, &name);
472
473 xr_ini_file ini;
474 if (!ini.load(ltx_name.append(folder).append(name).append(".ltx"))) {
475 msg("cannot open %s", ltx_name.c_str());
476 throw xr_error();
477 }
478
479 size_t num_parts = ini.line_count("partition");
480 if (num_parts == 0) {
481 msg("empty partition section");
482 throw xr_error();
483 }
484
485 assert(m_partitions.empty());
486 m_partitions.reserve(num_parts);
487 for (size_t i = 0; i != num_parts; ++i) {
488 const char* part_name;
489 ini.r_line("partition", i, &part_name, 0);
490 xr_ogf_v3::partition_io* part = new xr_ogf_v3::partition_io;
491 part->import(ini, part_name, *this);
492 m_partitions.push_back(part);
493 }
494 setup_partitions();
495
496 assert(m_motions.empty());
497 load_motion_defs(ini, SMT_CYCLE, "cycle");
498 load_motion_defs(ini, SMT_FX, "fx");
499 }
500
import(xr_reader & r)501 inline void xr_ogf_v3::bone_io::import(xr_reader& r)
502 {
503 r.r_sz(m_name);
504 r.r_sz(m_parent_name);
505 m_vmap_name = m_name;
506
507 m_shape.type = ST_BOX;
508 m_shape.flags = 0;
509 r.r(m_shape.box);
510
511 // FIXME: reconstruct bind pose here
512 m_bind_offset.set();
513 m_bind_rotate.set();
514 m_bind_length = 0.5f;
515 }
516
517 struct read_bone_v3 {
518 xr_ogf_v3& ogf;
read_bone_v3read_bone_v3519 read_bone_v3(xr_ogf_v3& _ogf): ogf(_ogf) {}
operator ()read_bone_v3520 void operator()(xr_bone*& _bone, xr_reader& r) {
521 xr_ogf_v3::bone_io* bone = new xr_ogf_v3::bone_io;
522 _bone = bone;
523 bone->import(r);
524 }
525 };
526
load_s_bone_names(xr_reader & r)527 void xr_ogf_v3::load_s_bone_names(xr_reader& r)
528 {
529 assert(m_bones.empty());
530 r.r_seq(r.r_u32(), m_bones, read_bone_v3(*this));
531 setup_bones();
532 set_chunk_loaded(OGF3_S_BONE_NAMES);
533 }
534
load_loddef2(xr_reader & r)535 inline void xr_ogf_v3::load_loddef2(xr_reader& r)
536 {
537 r.r_cseq<ogf4_lod_face>(8, m_lod_faces);
538 set_chunk_loaded(OGF3_LODDEF2);
539 }
540
load_treedef2(xr_reader & r)541 inline void xr_ogf_v3::load_treedef2(xr_reader& r)
542 {
543 r.r(m_tree_xform);
544 r.r(m_c_scale);
545 r.r(m_c_bias);
546 set_chunk_loaded(OGF3_TREEDEF2);
547 }
548
import_params_new(xr_reader & r,unsigned version)549 inline uint16_t xr_ogf_v3::motion_io::import_params_new(xr_reader& r, unsigned version)
550 {
551 r.r_sz(m_name);
552 m_flags = r.r_u32();
553 m_bone_or_part = r.r_u16();
554 uint16_t motion_id = r.r_u16();
555 m_speed = r.r_float();
556 m_power = r.r_float();
557 m_accrue = r.r_float();
558 m_falloff = r.r_float();
559
560 return motion_id;
561 }
562
define(uint16_t id,const std::string & name)563 void xr_ogf_v3::bone_io::define(uint16_t id, const std::string& name)
564 {
565 m_id = id;
566 m_name = name;
567 }
568
load_s_smparams_new(xr_reader & r)569 void xr_ogf_v3::load_s_smparams_new(xr_reader& r)
570 {
571 uint16_t version = r.r_u16();
572 xr_assert(version >= OGF3_S_SMPARAMS_VERSION_1 && version <= OGF3_S_SMPARAMS_VERSION_3);
573
574 assert(m_partitions.empty());
575 r.r_seq(r.r_u16(), m_partitions, read_partition_v3(m_bones, version));
576 setup_partitions();
577
578 assert(m_motions.empty());
579 size_t num_motions = r.r_u16();
580 m_motions.resize(num_motions);
581 for (; num_motions; --num_motions) {
582 motion_io* smotion = new xr_ogf_v3::motion_io;
583 m_motions.at(smotion->import_params_new(r, version)) = smotion;
584 }
585 assert(std::find(m_motions.begin(), m_motions.end(), static_cast<xr_skl_motion*>(0)) == m_motions.end());
586
587 set_chunk_loaded(OGF3_S_SMPARAMS_NEW);
588 }
589
load_s_desc(xr_reader & r)590 inline void xr_ogf_v3::load_s_desc(xr_reader& r)
591 {
592 r.r_sz(m_source);
593 r.r_sz(m_export_tool);
594 m_export_time = r.r_u32();
595 r.r_sz(m_owner_name);
596 m_creation_time = r.r_u32();
597 r.r_sz(m_modif_name);
598 m_modified_time = r.r_u32();
599 set_chunk_loaded(OGF3_S_DESC);
600 }
601
import_new(xr_reader & r,uint_fast32_t num_keys)602 void xr_ogf_v3::bone_motion_io::import_new(xr_reader& r, uint_fast32_t num_keys)
603 {
604 create_envelopes();
605
606 unsigned flags = r.r_u8();
607
608 r.r_u32();
609 for (size_t i = 0; i != num_keys; ++i)
610 insert_key(i/OGF3_MOTION_FPS, r.skip<ogf_key_qr>());
611
612 fvector3 t_init;
613 if (flags != 0) { // & KPF_T_PRESENT
614 r.r_u32();
615 fvector3 t_size, value;
616
617 const ogf4_key_qt* keys_qt = r.skip<ogf4_key_qt>(num_keys);
618 r.r_fvector3(t_size);
619 r.r_fvector3(t_init);
620 for (uint_fast32_t i = 0; i != num_keys; ++i) {
621 keys_qt[i].dequantize(value, t_size);
622 value.add(t_init);
623 insert_key(float(i)/OGF3_MOTION_FPS, &value);
624 }
625
626 } else {
627 r.r_fvector3(t_init);
628 for (uint_fast32_t i = 0; i != num_keys; ++i) {
629 insert_key(float(i)/OGF3_MOTION_FPS, &t_init);
630 }
631 }
632 }
633
import_bone_motions_new(xr_reader & r,xr_bone_vec & all_bones)634 inline void xr_ogf_v3::motion_io::import_bone_motions_new(xr_reader& r, xr_bone_vec& all_bones)
635 {
636 uint_fast32_t num_keys = r.r_u32();
637 m_frame_start = 0;
638 m_frame_end = int32_t(num_keys & INT32_MAX);
639
640 assert(m_bone_motions.empty());
641 m_bone_motions.reserve(all_bones.size());
642 for (xr_bone_vec_it it = all_bones.begin(), end = all_bones.end(); it != end; ++it) {
643 xr_ogf_v3::bone_motion_io* bm = new xr_ogf_v3::bone_motion_io;
644 bm->name() = (*it)->name();
645 bm->import_new(r, num_keys);
646 m_bone_motions.push_back(bm);
647 }
648 }
649
load_s_motions_new(xr_reader & r)650 void xr_ogf_v3::load_s_motions_new(xr_reader& r)
651 {
652 if (!r.find_chunk(0))
653 xr_not_expected();
654 size_t num_motions = r.r_u32();
655 xr_assert(m_motions.size() == num_motions);
656 for (uint32_t id = 1; id <= num_motions; ++id) {
657 if (!r.find_chunk(id))
658 xr_not_expected();
659
660 const char* name = r.skip_sz();
661 motion_io* smotion = static_cast<motion_io*>(find_motion(name));
662 if (smotion == 0) {
663 msg("unknown motion %s", name);
664 throw xr_error();
665 }
666 smotion->import_bone_motions_new(r, m_bones);
667 r.debug_find_chunk();
668 }
669 set_chunk_loaded(OGF3_S_MOTIONS_NEW);
670 }
671
import_ikdata(xr_reader & r)672 inline void xr_ogf_v3::bone_io::import_ikdata(xr_reader& r)
673 {
674 r.r_sz(m_gamemtl);
675 r.r(m_shape);
676 r.r(m_joint_ik_data);
677
678 //friction �� �������� - ������������� ��� � 0 � ������� ��������� ������ �� 4 �����
679 m_joint_ik_data.friction = 0.0f;
680 r.advance(-4);
681
682 r.r_fvector3(m_bind_rotate);
683 r.r_fvector3(m_bind_offset);
684 m_bind_length = 0.5f;
685 m_mass = r.r_float();
686 r.r_fvector3(m_center_of_mass);
687 }
688
load_s_ikdata(xr_reader & r)689 void xr_ogf_v3::load_s_ikdata(xr_reader& r)
690 {
691 for (xr_bone_vec_it it = m_bones.begin(), end = m_bones.end(); it != end; ++it)
692 static_cast<bone_io*>(*it)->import_ikdata(r);
693 set_chunk_loaded(OGF3_S_IKDATA);
694 }
695
import_ikdata_0(xr_reader & r)696 void xr_ogf_v3::bone_io::import_ikdata_0(xr_reader& r)
697 {
698 r.r_sz(m_gamemtl);
699 r.r(m_shape);
700 r.r(m_joint_ik_data);
701
702 m_joint_ik_data.friction = 0.0f;
703 m_joint_ik_data.ik_flags = 0;
704 m_joint_ik_data.break_force = 0.0f;
705 m_joint_ik_data.break_torque = 0.0f;
706 r.advance(-16);
707
708 r.r_fvector3(m_bind_rotate);
709 r.r_fvector3(m_bind_offset);
710
711 //std::swap(m_bind_offset.x, m_bind_offset.y);
712 //std::swap(m_bind_rotate.x, m_bind_rotate.y);
713
714 m_bind_length = 0.5f;
715 m_mass = r.r_float();
716 r.r_fvector3(m_center_of_mass);
717 }
718
fix_bind(xr_bone * bone)719 void fix_bind(xr_bone * bone)
720 {
721 for (xr_bone_vec_it it = bone->children().begin(), end = bone->children().end(); it != end; ++it)
722 fix_bind(*it);
723
724 if (!bone->is_root())
725 {
726 fmatrix total, parent, local, parent_i, total_i, local_i;
727 total.set_xyz_i(bone->bind_rotate());
728 total.c.set(bone->bind_offset());
729 parent.set_xyz_i(bone->parent()->bind_rotate());
730 parent.c.set(bone->parent()->bind_offset());
731 parent_i.invert_43(parent);
732 total_i.invert_43(total);
733 local.mul_43(total_i, parent);
734 local_i.invert_43(local);
735
736 bone->bind_offset() = local_i.c;
737 local_i.get_xyz_i(bone->bind_rotate());
738 }
739 }
740
load_s_ikdata_0(xr_reader & r)741 void xr_ogf_v3::load_s_ikdata_0(xr_reader& r)
742 {
743 for (xr_bone_vec_it it = m_bones.begin(), end = m_bones.end(); it != end; ++it)
744 static_cast<bone_io*>(*it)->import_ikdata_0(r);
745 set_chunk_loaded(OGF3_S_IKDATA_0);
746
747 //� ������ ������� �� ����� OGF3_S_IKDATA_0 bind pose ������ �������� ������������ ������
748 //��� ������������� ���� ����������� ������������ ������������ �����
749 for (xr_bone_vec_it it = m_bones.begin(), end = m_bones.end(); it != end; ++it)
750 {
751 if ((*it)->is_root())
752 {
753 fix_bind(*it);
754 break;
755 }
756 }
757 }
758
import_ikdata_2(xr_reader & r)759 inline void xr_ogf_v3::bone_io::import_ikdata_2(xr_reader& r)
760 {
761 uint32_t version = r.r_u32();
762 xr_assert(version == OGF3_S_JOINT_IK_DATA_VERSION);
763
764 r.r_sz(m_gamemtl);
765 r.r(m_shape);
766 r.r(m_joint_ik_data);
767 r.r_fvector3(m_bind_rotate);
768 r.r_fvector3(m_bind_offset);
769 m_bind_length = 0.5f;
770 m_mass = r.r_float();
771 r.r_fvector3(m_center_of_mass);
772 }
773
load_s_ikdata_2(xr_reader & r)774 void xr_ogf_v3::load_s_ikdata_2(xr_reader& r)
775 {
776 for (xr_bone_vec_it it = m_bones.begin(), end = m_bones.end(); it != end; ++it)
777 static_cast<bone_io*>(*it)->import_ikdata_2(r);
778 set_chunk_loaded(OGF3_S_IKDATA_2);
779 }
780
load_s_userdata(xr_reader & r)781 void xr_ogf_v3::load_s_userdata(xr_reader& r)
782 {
783 r.r_sz(m_userdata);
784 set_chunk_loaded(OGF3_S_USERDATA);
785 }
786
load_s_motion_refs(xr_reader & r)787 void xr_ogf_v3::load_s_motion_refs(xr_reader& r)
788 {
789 r.r_sz(m_motion_refs);
790 set_chunk_loaded(OGF3_S_MOTION_REFS);
791 }
792 ////////////////////////////////////////////////////////////////////////////////
793
load_render_visual(xr_reader & r)794 void xr_ogf_v3::load_render_visual(xr_reader& r)
795 {
796 // header is already loaded
797
798 if (!r.find_chunk(OGF3_BBOX))
799 xr_not_expected();
800 load_bbox(r);
801 r.debug_find_chunk();
802
803 if (r.find_chunk(OGF3_BSPHERE)) {
804 load_bsphere(r);
805 r.debug_find_chunk();
806 }
807
808 if (r.find_chunk(OGF3_TEXTURE_L)) {
809 load_texture_l(r);
810 r.debug_find_chunk();
811 } else if (r.find_chunk(OGF3_TEXTURE)) {
812 load_texture(r);
813 r.debug_find_chunk();
814 }
815
816 if (r.find_chunk(OGF3_S_DESC)) {
817 load_s_desc(r);
818 r.debug_find_chunk();
819 }
820 }
821
load_visual(xr_reader & r)822 void xr_ogf_v3::load_visual(xr_reader& r)
823 {
824 load_render_visual(r);
825 if (r.find_chunk(OGF3_VCONTAINER)) {
826 load_vcontainer(r);
827 r.debug_find_chunk();
828 } else {
829 if (!r.find_chunk(OGF3_VERTICES))
830 xr_not_expected();
831 load_vertices(r);
832 r.debug_find_chunk();
833 }
834 if (r.find_chunk(OGF3_ICONTAINER)) {
835 load_icontainer(r);
836 r.debug_find_chunk();
837 } else {
838 if (!r.find_chunk(OGF3_INDICES))
839 xr_not_expected();
840 load_indices(r);
841 r.debug_find_chunk();
842 }
843 }
844
load_hierrarhy_visual(xr_reader & r)845 void xr_ogf_v3::load_hierrarhy_visual(xr_reader& r)
846 {
847 load_render_visual(r);
848 if (r.find_chunk(OGF3_CHILDREN_L)) {
849 load_children_l(r);
850 r.debug_find_chunk();
851 } else {
852 xr_reader* s = r.open_chunk(OGF3_CHILDREN);
853 if (s) {
854 load_children(*s);
855 r.close_chunk(s);
856 } else {
857 if (!r.find_chunk(OGF3_CHILD_REFS))
858 xr_not_expected();
859 load_child_refs(r);
860 r.debug_find_chunk();
861 }
862 }
863 }
864
load_progressive_fixed_visual(xr_reader & r)865 void xr_ogf_v3::load_progressive_fixed_visual(xr_reader& r)
866 {
867 load_visual(r);
868
869 xr_reader* s = r.open_chunk(OGF3_LODDATA);
870 assert(s);
871 load_loddata(*s);
872 r.close_chunk(s);
873 }
874
load_kinematics(xr_reader & r)875 void xr_ogf_v3::load_kinematics(xr_reader& r)
876 {
877 load_hierrarhy_visual(r);
878
879 xr_reader* s = r.open_chunk(OGF3_S_USERDATA);
880 if (s) {
881 load_s_userdata(*s);
882 assert(s->eof());
883 r.close_chunk(s);
884 }
885
886 if (!r.find_chunk(OGF3_S_BONE_NAMES))
887 xr_not_expected();
888 load_s_bone_names(r);
889 r.debug_find_chunk();
890
891 s = r.open_chunk(OGF3_S_IKDATA_2);
892 if (s) {
893 load_s_ikdata_2(*s);
894 xr_assert(s->eof());
895 r.close_chunk(s);
896 } else {
897 s = r.open_chunk(OGF3_S_IKDATA);
898 if (s) {
899 load_s_ikdata(*s);
900 xr_assert(s->eof());
901 r.close_chunk(s);
902 } else {
903 s = r.open_chunk(OGF3_S_IKDATA_0);
904 if (s) {
905 load_s_ikdata_0(*s);
906 xr_assert(s->eof());
907 r.close_chunk(s);
908 }
909 }
910 }
911
912 //��������� ���������� ������ �� ������� ������������ ����� � ������� ������������ ������
913 //������ ������� ������ ��� ��������
914 calculate_bind();
915 for(size_t j = 0; j!= children().size(); ++j)
916 {
917 const xr_vbuf & vb = children()[j]->vb();
918 for (size_t i = 0; i != vb.size(); ++i)
919 {
920 const finfluence * weights = vb.w() + i;
921 int bone = weights->array[0].bone;
922 fvector3 * pv = const_cast<fvector3 *>(vb.p() + i);
923 const fmatrix& xform = bones()[bone]->bind_xform();
924 fvector3 temp;
925 temp.transform(*pv, xform);
926 *pv = temp;
927 }
928 }
929 }
load_kinematics_animated(xr_reader & r)930 void xr_ogf_v3::load_kinematics_animated(xr_reader& r) {
931 load_kinematics(r);
932 xr_reader* s = r.open_chunk(OGF3_S_MOTION_REFS);
933 if (s) {
934 load_s_motion_refs(*s);
935 r.close_chunk(s);
936 } else {
937 s = r.open_chunk(OGF3_S_SMPARAMS_NEW);
938 if (s) {
939 load_s_smparams_new(*s);
940 xr_assert(s->eof());
941 r.close_chunk(s);
942 } else {
943 s = r.open_chunk(OGF3_S_SMPARAMS);
944 if (s) {
945 load_s_smparams(*s);
946 xr_assert(s->eof());
947 r.close_chunk(s);
948 } else {
949 load_s_smparams();
950 }
951 }
952
953 s = r.open_chunk(OGF3_S_MOTIONS_NEW);
954 if (s) {
955 load_s_motions_new(*s);
956 xr_assert(s->eof());
957 r.close_chunk(s);
958 } else {
959 s = r.open_chunk(OGF3_S_MOTIONS);
960 xr_assert(s != 0);
961 load_s_motions(*s);
962 assert(s->eof());
963 r.close_chunk(s);
964 }
965 }
966 }
967
load_skeletonx(xr_reader & r)968 inline void xr_ogf_v3::load_skeletonx(xr_reader& r)
969 {
970 xr_assert(r.find_chunk(OGF3_VERTICES));
971 uint32_t format = r.r_u32();
972 xr_assert(format == OGF3_VERTEXFORMAT_FVF_1L || format == OGF3_VERTEXFORMAT_FVF_2L);
973 //OGF3_VERTEXFORMAT_FVF_2L in build 1844
974 }
975
load_skeletonx_pm(xr_reader & r)976 void xr_ogf_v3::load_skeletonx_pm(xr_reader& r)
977 {
978 load_skeletonx(r);
979 load_progressive_fixed_visual(r);
980 }
981
load_skeletonx_st(xr_reader & r)982 void xr_ogf_v3::load_skeletonx_st(xr_reader& r)
983 {
984 load_skeletonx(r);
985 load_visual(r);
986 }
987
load_detail_patch(xr_reader & r)988 void xr_ogf_v3::load_detail_patch(xr_reader& r)
989 {
990 load_render_visual(r);
991 if (!r.find_chunk(OGF3_DPATCH))
992 xr_not_expected();
993 load_dpatch(r);
994 r.debug_find_chunk();
995 }
996
load_cached(xr_reader & r)997 void xr_ogf_v3::load_cached(xr_reader& r)
998 {
999 load_render_visual(r);
1000 if (!r.find_chunk(OGF3_VERTICES))
1001 xr_not_expected();
1002 load_vertices(r);
1003 r.debug_find_chunk();
1004
1005 if (!r.find_chunk(OGF3_INDICES))
1006 xr_not_expected();
1007 load_indices(r);
1008 r.debug_find_chunk();
1009 }
1010
load_particle(xr_reader & r)1011 inline void xr_ogf_v3::load_particle(xr_reader& r)
1012 {
1013 load_render_visual(r);
1014 }
1015
load_progressive(xr_reader & r)1016 void xr_ogf_v3::load_progressive(xr_reader& r)
1017 {
1018 load_render_visual(r);
1019 xr_reader* s = r.open_chunk(OGF3_LODS);
1020 assert(s);
1021 load_lods(*s);
1022 r.close_chunk(s);
1023 }
1024
load_lod(xr_reader & r)1025 void xr_ogf_v3::load_lod(xr_reader& r)
1026 {
1027 load_hierrarhy_visual(r);
1028 if (!r.find_chunk(OGF3_LODDEF2))
1029 xr_not_expected();
1030 load_loddef2(r);
1031 r.debug_find_chunk();
1032 }
1033
load_tree_visual(xr_reader & r)1034 void xr_ogf_v3::load_tree_visual(xr_reader& r)
1035 {
1036 load_render_visual(r);
1037
1038 if (!r.find_chunk(OGF3_VCONTAINER))
1039 xr_not_expected();
1040 load_vcontainer(r);
1041 r.debug_find_chunk();
1042
1043 if (!r.find_chunk(OGF3_ICONTAINER))
1044 xr_not_expected();
1045 load_icontainer(r);
1046 r.debug_find_chunk();
1047
1048 if (!r.find_chunk(OGF3_TREEDEF2))
1049 xr_not_expected();
1050 load_treedef2(r);
1051 r.debug_find_chunk();
1052 }
1053
1054 ////////////////////////////////////////////////////////////////////////////////
1055
load_ogf(xr_reader & r)1056 void xr_ogf_v3::load_ogf(xr_reader& r)
1057 {
1058 if (!r.find_chunk(OGF_HEADER))
1059 xr_not_expected();
1060 load_header(r);
1061 r.debug_find_chunk();
1062
1063 switch (m_model_type) {
1064 case MT3_NORMAL:
1065 load_visual(r);
1066 break;
1067 case MT3_HIERRARHY:
1068 load_hierrarhy_visual(r);
1069 break;
1070 case MT3_PROGRESSIVE:
1071 load_progressive_fixed_visual(r);
1072 m_flags = EOF_PROGRESSIVE;
1073 break;
1074 case MT3_SKELETON_ANIM:
1075 load_kinematics_animated(r);
1076 m_flags = EOF_DYNAMIC;
1077 break;
1078 case MT3_SKELETON_GEOMDEF_PM:
1079 load_skeletonx_pm(r);
1080 m_flags = EOF_PROGRESSIVE;
1081 break;
1082 case MT3_DETAIL_PATCH:
1083 load_detail_patch(r);
1084 break;
1085 case MT3_SKELETON_GEOMDEF_ST:
1086 load_skeletonx_st(r);
1087 break;
1088 case MT3_CACHED:
1089 load_cached(r);
1090 break;
1091 case MT3_PARTICLE:
1092 load_particle(r);
1093 break;
1094 case MT3_PROGRESSIVE2:
1095 load_progressive(r);
1096 m_flags = EOF_PROGRESSIVE;
1097 break;
1098 case MT3_LOD:
1099 load_lod(r);
1100 m_flags = EOF_MULTIPLE_USAGE;
1101 break;
1102 case MT3_TREE:
1103 load_tree_visual(r);
1104 m_flags = EOF_STATIC;
1105 break;
1106 case MT3_SKELETON_RIGID:
1107 load_kinematics(r);
1108 m_flags = EOF_DYNAMIC;
1109 break;
1110 default:
1111 xr_not_expected();
1112 break;
1113 }
1114 check_unhandled_chunks(r);
1115 }
1116