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