1 #include <algorithm>
2 #include "xr_math.h"
3 #include "xr_ogf.h"
4 #include "xr_ogf_v3.h"
5 #include "xr_ogf_v4.h"
6 #include "xr_mesh_builder.h"
7 #include "xr_utils.h"
8 #include "xr_envelope.h"
9 #include "xr_file_system.h"
10 
11 using namespace xray_re;
12 
insert_key(float time,const ogf_key_qr * value)13 void xr_ogf::bone_motion_io::insert_key(float time, const ogf_key_qr* value)
14 {
15 	dquaternion q;
16 	value->dequantize(q);
17 	dmatrix xform;
18 	xform.rotation(q);
19 	dvector3 r;
20 	xform.get_xyz_i(r);
21 	m_envelopes[4]->insert_key(time, float(r.x));
22 	m_envelopes[3]->insert_key(time, float(r.y));
23 	m_envelopes[5]->insert_key(time, float(r.z));
24 }
25 
insert_key(float time,const fvector3 * value)26 void xr_ogf::bone_motion_io::insert_key(float time, const fvector3* value)
27 {
28 	m_envelopes[0]->insert_key(time, value->x);
29 	m_envelopes[1]->insert_key(time, value->y);
30 	m_envelopes[2]->insert_key(time, value->z);
31 }
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 
xr_ogf(ogf_version version)35 xr_ogf::xr_ogf(ogf_version version): m_loaded(0), m_version(version) {}
36 
~xr_ogf()37 xr_ogf::~xr_ogf()
38 {
39 	delete_elements(m_children);
40 	delete_elements(m_lods);
41 }
42 
clear()43 void xr_ogf::clear()
44 {
45 	xr_object::clear();
46 	m_loaded = 0;
47 	m_path.clear();
48 	m_bbox.null();
49 	m_bsphere.reset();
50 	m_texture.clear();
51 	m_shader.clear();
52 	m_vb.clear();
53 	m_ib.clear();
54 	trim_container(m_children);
55 	trim_container(m_lods);
56 	m_children_l.clear();
57 }
58 
load_ogf(const std::string & path)59 xr_ogf* xr_ogf::load_ogf(const std::string& path)
60 {
61 	xr_file_system& fs = xr_file_system::instance();
62 	xr_reader* r = fs.r_open(path);
63 	if (r == 0)
64 		return 0;
65 
66 	xr_ogf* ogf = 0;
67 	if (!r->find_chunk(OGF_HEADER))
68 		xr_not_expected();
69 
70 	unsigned version = r->r_u8();
71 	if (version == OGF3_VERSION) {
72 		ogf = new xr_ogf_v3();
73 	} else if (version == OGF4_VERSION) {
74 		ogf = new xr_ogf_v4();
75 	} else {
76 		msg("load_ogf: unknown version %u", version);
77 	}
78 	if (ogf) {
79 		try {
80 			ogf->m_path = path;
81 			ogf->load_ogf(*r);
82 		} catch (xr_error) {
83 			delete ogf;
84 			ogf = 0;
85 		}
86 	}
87 	fs.r_close(r);
88 	return ogf;
89 }
90 
load_ogf(const char * path,const std::string & name)91 bool xr_ogf::load_ogf(const char* path, const std::string& name)
92 {
93 	xr_file_system& fs = xr_file_system::instance();
94 	xr_reader* r = fs.r_open(path, name);
95 	if (r == 0)
96 		return false;
97 	load_ogf(*r);
98 	fs.r_close(r);
99 	return true;
100 }
101 
check_unhandled_chunks(xr_reader & r) const102 void xr_ogf::check_unhandled_chunks(xr_reader& r) const
103 {
104 	// FIXME: there is no need to "open" chunks
105 	uint32_t id;
106 	for (xr_reader* s = 0; (s = r.open_chunk_next(id, s)) != 0;) {
107 		if (!is_chunk_loaded(id))
108 			msg("unhandled chunk %u", id);
109 	}
110 }
111 
load_texture(xr_reader & r)112 void xr_ogf::load_texture(xr_reader& r)
113 {
114 	r.r_sz(m_texture);
115 	r.r_sz(m_shader);
116 }
117 
create_surface(const xr_raw_surface & raw_surface) const118 xr_surface* xr_ogf::create_surface(const xr_raw_surface& raw_surface) const
119 {
120 	xr_surface* surface = new xr_surface(true);
121 	if (hierarchical()) {
122 		surface->texture() = m_children.at(raw_surface.texture)->texture();
123 		surface->eshader() = m_children.at(raw_surface.eshader)->shader();
124 	} else {
125 		surface->texture() = texture();
126 		surface->eshader() = shader();
127 	}
128 	if (raw_surface.two_sided())
129 		surface->set_two_sided();
130 	return surface;
131 }
132 
to_object()133 void xr_ogf::to_object()
134 {
135 	xr_mesh_builder* mesh = new xr_mesh_builder;
136 	if (hierarchical()) {
137 		size_t vb_reserve = 0, ib_reserve = 0;
138 		unsigned vb_signature = 0;
139 		for (xr_ogf_vec_it it = m_children.begin(), end = m_children.end(); it != end; ++it) {
140 			xr_ogf* ogf = *it;
141 			vb_signature |= ogf->vb().signature();
142 			vb_reserve += ogf->vb().size();
143 			ib_reserve += ogf->ib().size();
144 			if (ogf->progressive())
145 				m_flags |= EOF_PROGRESSIVE;
146 		}
147 		mesh->prepare(vb_signature, vb_reserve, ib_reserve);
148 		uint16_t shader_id = 0;
149 		for (xr_ogf_vec_it it = m_children.begin(), end = m_children.end(); it != end; ++it) {
150 			xr_ogf* ogf = *it;
151 			mesh->push(ogf->vb(), ogf->ib(), shader_id, shader_id);
152 			++shader_id;
153 		}
154 	} else {
155 		mesh->prepare(vb().signature());
156 		mesh->push(vb(), ib(), 0, 0);
157 	}
158 	mesh->compact_geometry();
159 	mesh->remove_duplicate_faces();
160 	mesh->remove_back_faces();
161 	mesh->commit(*this);
162 	if (m_path.empty()) {
163 		mesh->name() = "ogfShape";
164 	} else {
165 		xr_file_system::split_path(m_path, 0, &mesh->name());
166 		mesh->name() += "Shape";
167 	}
168 	denominate_surfaces();
169 	trim_container(m_children);
170 	trim_container(m_lods);
171 }
172