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