1 // detail_object.part (EDetailManager, EDetail)
2 #include "xr_scene_details.h"
3 #include "xr_reader.h"
4 #include "xr_writer.h"
5 #include "xr_utils.h"
6 
7 using namespace xray_re;
8 
detail_object()9 detail_object::detail_object():
10 	min_scale(0.5f), max_scale(2.f), density(1.f), flags(0) {}
11 
xr_scene_details(xr_scene & scene)12 xr_scene_details::xr_scene_details(xr_scene& scene):
13 	xr_scene_part(scene, "detail_object.part", SCENE_CHUNK_DETAIL_OBJECTS),
14 	m_flags(DETMGR_FLAG_DRAW_OBJECTS), m_num_slots(0), m_slots(0),
15 	m_density(0.2f)
16 {
17 	m_header.version = DETMGR_VERSION;
18 	m_header.object_count = 0;
19 	m_header.offs_x = 0;
20 	m_header.offs_z = 0;
21 	m_header.size_x = 0;
22 	m_header.size_z = 0;
23 }
24 
~xr_scene_details()25 xr_scene_details::~xr_scene_details()
26 {
27 	delete[] m_slots;
28 	delete_elements(m_objects);
29 	delete_elements(m_indices);
30 }
31 
operator ()read_detail32 struct read_detail { void operator()(detail_object*& _detail, xr_reader& r) const {
33 	detail_object* detail = new detail_object;
34 	_detail = detail;
35 	uint32_t version;
36 	if (!r.r_chunk(DETOBJ_CHUNK_VERSION, version))
37 		xr_not_expected();
38 	xr_assert(version == DETOBJ_VERSION);
39 
40 	if (!r.r_chunk(DETOBJ_CHUNK_REFERENCE, detail->reference))
41 		xr_not_expected();
42 
43 	if (!r.find_chunk(DETOBJ_CHUNK_SCALE_LIMITS))
44 		xr_not_expected();
45 	detail->min_scale = r.r_float();
46 	detail->max_scale = r.r_float();
47 	r.debug_find_chunk();
48 
49 	r.r_chunk<float>(DETOBJ_CHUNK_DENSITY, detail->density);
50 	r.r_chunk<uint32_t>(DETOBJ_CHUNK_FLAGS, detail->flags);
51 }};
52 
operator ()read_color_index53 struct read_color_index { void operator()(color_index*& _ci, xr_reader& r) {
54 	color_index* ci = new color_index;
55 	_ci = ci;
56 	ci->color = r.r_u32();
57 	r.r_seq(r.r_u8(), ci->references, xr_reader::f_r_sz());
58 }};
59 
load(xr_reader & r)60 void xr_scene_details::load(xr_reader& r)
61 {
62 	revision().load(r);
63 
64 	uint32_t version;
65 	if (!r.r_chunk<uint32_t>(DETMGR_CHUNK_VERSION, version))
66 		xr_not_expected();
67 	xr_assert(version == DETMGR_VERSION);
68 
69 	r.r_chunk<uint32_t>(DETMGR_CHUNK_FLAGS, m_flags);
70 	if (!r.find_chunk(DETMGR_CHUNK_HEADER))
71 		xr_not_expected();
72 	m_header.load(r);
73 	r.debug_find_chunk();
74 
75 	if (!r.find_chunk(DETMGR_CHUNK_SLOTS))
76 		xr_not_expected();
77 	if ((m_num_slots = r.r_u32())) {
78 		xr_assert(m_num_slots == m_header.size_x*m_header.size_z);
79 		m_slots = new detail_slot_v3[m_num_slots];
80 		r.r_cseq(m_num_slots, m_slots);
81 	}
82 	r.debug_find_chunk();
83 
84 	xr_reader* s = r.open_chunk(DETMGR_CHUNK_OBJECTS);
85 	if (s) {
86 		s->r_chunks(m_objects, read_detail());
87 		r.close_chunk(s);
88 	}
89 
90 	if (!r.find_chunk(DETMGR_CHUNK_COLOR_INDEX))
91 		xr_not_expected();
92 	r.r_seq(r.r_u8(), m_indices, read_color_index());
93 	r.debug_find_chunk();
94 
95 	if (!r.r_chunk(DETMGR_CHUNK_BBOX, m_bbox))
96 		xr_not_expected();
97 
98 	if (r.find_chunk(DETMGR_CHUNK_SNAP_OBJECTS))
99 		r.r_seq(r.r_u32(), m_snap_objects, xr_reader::f_r_sz());
100 
101 	r.r_chunk(DETMGR_CHUNK_DENSITY, m_density);
102 
103 	if (r.find_chunk(DETMGR_CHUNK_TEXTURE)) {
104 		r.r_sz(m_texture);
105 		r.debug_find_chunk();
106 	}
107 }
108 
operator ()write_detail109 struct write_detail {void operator()(const detail_object* detail, xr_writer& w) const {
110 	w.w_chunk(DETOBJ_CHUNK_VERSION, DETOBJ_VERSION);
111 	w.w_chunk(DETOBJ_CHUNK_REFERENCE, detail->reference);
112 	w.open_chunk(DETOBJ_CHUNK_SCALE_LIMITS);
113 	w.w_float(detail->min_scale);
114 	w.w_float(detail->max_scale);
115 	w.close_chunk();
116 	w.w_chunk(DETOBJ_CHUNK_DENSITY, detail->density);
117 	w.w_chunk(DETOBJ_CHUNK_FLAGS, detail->flags);
118 }};
119 
operator ()write_color_index120 struct write_color_index { void operator()(const color_index* ci, xr_writer& w) const {
121 	w.w_u32(ci->color);
122 	w.w_size_u8(ci->references.size());
123 	w.w_seq(ci->references, xr_writer::f_w_sz());
124 }};
125 
save(xr_writer & w) const126 void xr_scene_details::save(xr_writer& w) const
127 {
128 	revision().save(w);
129 	w.w_chunk<uint32_t>(DETMGR_CHUNK_VERSION, DETMGR_VERSION);
130 	w.w_chunk<uint32_t>(DETMGR_CHUNK_FLAGS, m_flags);
131 
132 // this is ignored in LE
133 //	m_header.object_count = uint32_t(m_objects.size() & UINT32_MAX);
134 	w.open_chunk(DETMGR_CHUNK_HEADER);
135 	m_header.save(w);
136 	w.close_chunk();
137 
138 	w.open_chunk(DETMGR_CHUNK_OBJECTS);
139 	w.w_chunks(m_objects, write_detail());
140 	w.close_chunk();
141 
142 	w.open_chunk(DETMGR_CHUNK_COLOR_INDEX);
143 	w.w_size_u8(m_indices.size());
144 	w.w_seq(m_indices, write_color_index());
145 	w.close_chunk();
146 
147 	w.open_chunk(DETMGR_CHUNK_SLOTS);
148 	w.w_u32(m_num_slots);
149 	w.w_cseq(m_num_slots, m_slots);
150 	w.close_chunk();
151 
152 	w.w_chunk(DETMGR_CHUNK_BBOX, m_bbox);
153 
154 	if (!m_texture.empty())
155 		w.w_chunk(DETMGR_CHUNK_TEXTURE, m_texture);
156 
157 	w.w_chunk(DETMGR_CHUNK_DENSITY, m_density);
158 
159 	w.open_chunk(DETMGR_CHUNK_SNAP_OBJECTS);
160 	w.w_size_u32(m_snap_objects.size());
161 	w.w_seq(m_snap_objects, xr_writer::f_w_sz());
162 	w.close_chunk();
163 }
164 
save_v12(xr_ini_writer * w) const165 void xr_scene_details::save_v12(xr_ini_writer* w) const
166 {
167 }
168