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, &section_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