52generate_block(
unsigned short mx,
54 unsigned short level) {
56 nassertr(mx < (_xsize - 1) / _block_size,
nullptr);
57 nassertr(my < (_ysize - 1) / _block_size,
nullptr);
59 unsigned short center = _block_size / 2;
60 unsigned int vcounter = 0;
65 array->add_column(InternalName::get_color(), 4,
66 Geom::NT_stdfloat, Geom::C_color);
68 array->add_column(InternalName::get_vertex(), 3,
69 Geom::NT_stdfloat, Geom::C_point);
70 array->add_column(InternalName::get_texcoord(), 2,
71 Geom::NT_stdfloat, Geom::C_texcoord);
72 array->add_column(InternalName::get_normal(), 3,
73 Geom::NT_stdfloat, Geom::C_normal);
76 format->add_array(array);
80 GeomVertexFormat::register_format(format), Geom::UH_stream);
81 vdata->unclean_set_num_rows((_block_size + 1) * (_block_size + 1));
98 level = min(max(_min_level, level), _max_level);
99 unsigned short reallevel = level;
100 level = int(pow(2.0,
int(level)));
103 unsigned short lnlevel = get_neighbor_level(mx, my, -1, 0);
104 unsigned short rnlevel = get_neighbor_level(mx, my, 1, 0);
105 unsigned short bnlevel = get_neighbor_level(mx, my, 0, -1);
106 unsigned short tnlevel = get_neighbor_level(mx, my, 0, 1);
107 bool ljunction = (lnlevel != reallevel);
108 bool rjunction = (rnlevel != reallevel);
109 bool bjunction = (bnlevel != reallevel);
110 bool tjunction = (tnlevel != reallevel);
117 unsigned short lowblocksize = _block_size / level + 1;
119 PN_stdfloat cmap_xratio = _color_map.
get_x_size() / (PN_stdfloat)_xsize;
120 PN_stdfloat cmap_yratio = _color_map.
get_y_size() / (PN_stdfloat)_ysize;
122 PN_stdfloat tc_xscale = 1.0f / PN_stdfloat(_xsize - 1);
123 PN_stdfloat tc_yscale = 1.0f / PN_stdfloat(_ysize - 1);
125 for (
int x = 0; x <= _block_size; x++) {
126 for (
int y = 0; y <= _block_size; y++) {
127 if ((x % level) == 0 && (y % level) == 0) {
128 if (_has_color_map) {
130 int((mx * _block_size + x) * cmap_xratio),
131 int((my * _block_size + y) * cmap_yratio));
134 vwriter.
set_data3(x - 0.5 * _block_size, y - 0.5 * _block_size, get_pixel_value(mx, my, x, y));
135 twriter.
set_data2((mx * _block_size + x) * tc_xscale,
136 (my * _block_size + y) * tc_yscale);
139 if (x > 0 && y > 0) {
141 if (x == level && ljunction) {
142 if (y > level && y < _block_size) {
143 prim->add_vertex(min(max(sfav(y / level, lnlevel, reallevel), 0), lowblocksize - 1));
144 prim->add_vertex(vcounter - 1);
145 prim->add_vertex(vcounter);
146 prim->close_primitive();
148 if (f_part((y / level) / PN_stdfloat(pow(2.0,
int(lnlevel - reallevel)))) == 0.5) {
149 prim->add_vertex(min(max(sfav(y / level + 1, lnlevel, reallevel), 0), lowblocksize - 1));
150 prim->add_vertex(min(max(sfav(y / level - 1, lnlevel, reallevel), 0), lowblocksize - 1));
151 prim->add_vertex(vcounter);
152 prim->close_primitive();
155 (!(bjunction && y == level && x > level && x < _block_size) &&
156 !(rjunction && x == _block_size) &&
157 !(tjunction && y == _block_size && x > level && x < _block_size))) {
158 if ((x <= center && y <= center) || (x > center && y > center)) {
160 prim->add_vertex(vcounter - lowblocksize - 1);
161 prim->add_vertex(vcounter - 1);
162 prim->add_vertex(vcounter);
164 prim->add_vertex(vcounter);
165 prim->add_vertex(vcounter - lowblocksize);
166 prim->add_vertex(vcounter - lowblocksize - 1);
170 prim->add_vertex(vcounter);
171 prim->add_vertex(vcounter - lowblocksize);
172 prim->add_vertex(vcounter - 1);
174 prim->add_vertex(vcounter - 1);
175 prim->add_vertex(vcounter - lowblocksize);
176 prim->add_vertex(vcounter - lowblocksize - 1);
179 prim->close_primitive();
182 if (x == _block_size - level && rjunction) {
183 if (y > level && y < _block_size) {
184 prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level, rnlevel, reallevel), 0), lowblocksize - 1));
185 prim->add_vertex(vcounter);
186 prim->add_vertex(vcounter - 1);
187 prim->close_primitive();
189 if (f_part((y / level) / PN_stdfloat(pow(2.0,
int(rnlevel - reallevel)))) == 0.5) {
190 prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level - 1, rnlevel, reallevel), 0), lowblocksize - 1));
191 prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level + 1, rnlevel, reallevel), 0), lowblocksize - 1));
192 prim->add_vertex(vcounter);
193 prim->close_primitive();
197 if (y == level && bjunction) {
198 if (x > level && x < _block_size) {
199 prim->add_vertex(vcounter);
200 prim->add_vertex(vcounter - lowblocksize);
201 prim->add_vertex(min(max(sfav(x / level, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
202 prim->close_primitive();
204 if (f_part((x / level) / PN_stdfloat(pow(2.0,
int(bnlevel - reallevel)))) == 0.5) {
205 prim->add_vertex(min(max(sfav(x / level - 1, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
206 prim->add_vertex(min(max(sfav(x / level + 1, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
207 prim->add_vertex(vcounter);
208 prim->close_primitive();
211 (!(ljunction && x == level && y > level && y < _block_size) &&
212 !(tjunction && y == _block_size) &&
213 !(rjunction && x == _block_size && y > level && y < _block_size))) {
214 if ((x <= center && y <= center) || (x > center && y > center)) {
216 prim->add_vertex(vcounter);
217 prim->add_vertex(vcounter - lowblocksize);
218 prim->add_vertex(vcounter - lowblocksize - 1);
220 prim->add_vertex(vcounter - lowblocksize - 1);
221 prim->add_vertex(vcounter - 1);
222 prim->add_vertex(vcounter);
226 prim->add_vertex(vcounter);
227 prim->add_vertex(vcounter - lowblocksize);
228 prim->add_vertex(vcounter - 1);
230 prim->add_vertex(vcounter - 1);
231 prim->add_vertex(vcounter - lowblocksize);
232 prim->add_vertex(vcounter - lowblocksize - 1);
235 prim->close_primitive();
238 if (y == _block_size - level && tjunction) {
239 if (x > level && x < _block_size) {
240 prim->add_vertex(min(max(sfav(x / level, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
241 prim->add_vertex(vcounter - lowblocksize);
242 prim->add_vertex(vcounter);
243 prim->close_primitive();
245 if (f_part((x / level) / PN_stdfloat(pow(2.0,
int(tnlevel - reallevel)))) == 0.5) {
246 prim->add_vertex(min(max(sfav(x / level + 1, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
247 prim->add_vertex(min(max(sfav(x / level - 1, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
248 prim->add_vertex(vcounter);
249 prim->close_primitive();
259 geom->add_primitive(prim);
260 geom->set_bounds_type(BoundingVolume::BT_box);
262 std::ostringstream sname;
263 sname <<
"gmm" << mx <<
"x" << my;
265 node->add_geom(geom);
266 node->set_bounds_type(BoundingVolume::BT_box);
267 _old_levels.at(mx).at(my) = reallevel;