00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "space/spherical_quadtree.hpp"
00035 #include "math/vector.hpp"
00036
00037 #include "scenegraph/camera.hpp"
00038 #include "scenegraph/utils.hpp"
00039 #include "platform/texture.hpp"
00040 #include "platform/heightmap.hpp"
00041 #include "platform/lowlevel.hpp"
00042
00043 #include <cmath>
00044
00045
00046 using namespace gsgl;
00047 using namespace gsgl::data;
00048 using namespace gsgl::math;
00049 using namespace gsgl::scenegraph;
00050 using namespace gsgl::platform;
00051
00052
00053 namespace periapsis
00054 {
00055
00056 namespace space
00057 {
00058
00059 static inline vector get_vector(const simple_array<gsgl::real_t> & a, const gsgl::index_t & index)
00060 {
00061 return vector(a[index*3+0], a[index*3+1], a[index*3+2]);
00062 }
00063
00064
00065
00066 sph_qt_node::sph_qt_node(spherical_quadtree *parent_quadtree, sph_qt_node *parent_node)
00067 : parent_quadtree(parent_quadtree),
00068 level(parent_node ? parent_node->level + 1 : 0),
00069 dirty(true), parent_node(parent_node),
00070 triangle_fan_indices(32),
00071 radius_in_world_space(0), radius_in_screen_space(0),
00072 last_radius_frame(static_cast<unsigned long>(-1)),
00073 last_merge_frame(0), last_split_frame(0),
00074 pos_in_leaf_node_array(-1),
00075 pos_in_merge_node_array(-1)
00076 {
00077 for (int i = 0; i < 4; ++i)
00078 children[i] = 0;
00079
00080 for (int i = 0; i < 4; ++i)
00081 adjacent_nodes[i] = 0;
00082
00083 for (int i = 0; i < 25; ++i)
00084 vertex_indices[i] = 0;
00085
00086 for (int i = 0; i < 4; ++i)
00087 num_indices_in_quadrants[i] = 0;
00088
00089
00090 assert(parent_quadtree->buffers);
00091 buffer_pool_rec = parent_quadtree->buffers->allocate_object();
00092 }
00093
00094
00095 sph_qt_node::~sph_qt_node()
00096 {
00097
00098 parent_quadtree->buffers->free_object(buffer_pool_rec);
00099
00100
00101 for (int i = 0; i < 4; ++i)
00102 {
00103 if (children[i])
00104 {
00105 delete children[i];
00106 children[i] = 0;
00107 }
00108 }
00109
00110
00111 for (int i = 0; i < 25; ++i)
00112 parent_quadtree->free_vertex_index(vertex_indices[i]);
00113 }
00114
00115
00116
00117
00118 void sph_qt_node::draw(gsgl::scenegraph::context *c)
00119 {
00120
00121 if (true || utils::is_on_screen(parent_quadtree->parent_sg_node, c->cam->get_field_of_view(), c->screen->get_aspect_ratio(), get_vector(parent_quadtree->global_vertices, vertex_indices[12]), radius_in_world_space))
00122 {
00123
00124 if (is_a_leaf())
00125 {
00126 update_fan_indices();
00127
00128 buffer_pool_rec.parent->vertices.bind();
00129 glInterleavedArrays(GL_T2F_N3F_V3F, 0, vbuffer::VBO_OFFSET<float>(buffer_pool_rec.pos_in_vertices));
00130
00131 buffer_pool_rec.parent->indices.bind();
00132
00133 int prev_elements_drawn = 0;
00134 for (int i = 0; i < 4; ++i)
00135 {
00136 if (num_indices_in_quadrants[i])
00137 {
00138
00139
00140
00141 glDrawElements(GL_TRIANGLE_FAN, num_indices_in_quadrants[i], GL_UNSIGNED_INT, vbuffer::VBO_OFFSET<unsigned int>( buffer_pool_rec.pos_in_indices + prev_elements_drawn ));
00142
00143 prev_elements_drawn += num_indices_in_quadrants[i];
00144 }
00145 }
00146
00147 }
00148 else
00149 {
00150
00151 for (int i = 0; i < 4; ++i)
00152 {
00153 if (children[i])
00154 children[i]->draw(c);
00155 }
00156 }
00157 }
00158 }
00159
00160
00161
00162
00163 bool sph_qt_node::is_a_leaf() const
00164 {
00165 return !children[0] && !children[1] && !children[2] && !children[3];
00166 }
00167
00168
00169 void sph_qt_node::update_fan_indices()
00170 {
00171 if (dirty)
00172 {
00173 gsgl::index_t prev_total = 0;
00174
00175
00176 if (!children[0])
00177 {
00178 int & num = num_indices_in_quadrants[0]; num = 0;
00179
00180 triangle_fan_indices[prev_total + num++] = vertex_indices[6];
00181 triangle_fan_indices[prev_total + num++] = vertex_indices[10];
00182 triangle_fan_indices[prev_total + num++] = vertex_indices[12];
00183 triangle_fan_indices[prev_total + num++] = vertex_indices[2];
00184 if (adjacent_nodes[0] && !adjacent_nodes[0]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[1];
00185 triangle_fan_indices[prev_total + num++] = vertex_indices[0];
00186 if (adjacent_nodes[3] && !adjacent_nodes[3]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[5];
00187 triangle_fan_indices[prev_total + num++] = vertex_indices[10];
00188
00189 prev_total += num_indices_in_quadrants[0];
00190 }
00191 else
00192 {
00193 num_indices_in_quadrants[0] = 0;
00194 }
00195
00196
00197 if (!children[1])
00198 {
00199 int & num = num_indices_in_quadrants[1]; num = 0;
00200
00201 triangle_fan_indices[prev_total + num++] = vertex_indices[8];
00202 triangle_fan_indices[prev_total + num++] = vertex_indices[2];
00203 triangle_fan_indices[prev_total + num++] = vertex_indices[12];
00204 triangle_fan_indices[prev_total + num++] = vertex_indices[14];
00205 if (adjacent_nodes[1] && !adjacent_nodes[1]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[9];
00206 triangle_fan_indices[prev_total + num++] = vertex_indices[4];
00207 if (adjacent_nodes[0] && !adjacent_nodes[0]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[3];
00208 triangle_fan_indices[prev_total + num++] = vertex_indices[2];
00209
00210 prev_total += num_indices_in_quadrants[1];
00211 }
00212 else
00213 {
00214 num_indices_in_quadrants[1] = 0;
00215 }
00216
00217
00218 if (!children[2])
00219 {
00220 int & num = num_indices_in_quadrants[2]; num = 0;
00221
00222 triangle_fan_indices[prev_total + num++] = vertex_indices[18];
00223 triangle_fan_indices[prev_total + num++] = vertex_indices[14];
00224 triangle_fan_indices[prev_total + num++] = vertex_indices[12];
00225 triangle_fan_indices[prev_total + num++] = vertex_indices[22];
00226 if (adjacent_nodes[2] && !adjacent_nodes[2]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[23];
00227 triangle_fan_indices[prev_total + num++] = vertex_indices[24];
00228 if (adjacent_nodes[1] && !adjacent_nodes[1]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[19];
00229 triangle_fan_indices[prev_total + num++] = vertex_indices[14];
00230
00231 prev_total += num_indices_in_quadrants[2];
00232 }
00233 else
00234 {
00235 num_indices_in_quadrants[2] = 0;
00236 }
00237
00238
00239 if (!children[3])
00240 {
00241 int & num = num_indices_in_quadrants[3]; num = 0;
00242
00243 triangle_fan_indices[prev_total + num++] = vertex_indices[16];
00244 triangle_fan_indices[prev_total + num++] = vertex_indices[22];
00245 triangle_fan_indices[prev_total + num++] = vertex_indices[12];
00246 triangle_fan_indices[prev_total + num++] = vertex_indices[10];
00247 if (adjacent_nodes[3] && !adjacent_nodes[3]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[15];
00248 triangle_fan_indices[prev_total + num++] = vertex_indices[20];
00249 if (adjacent_nodes[2] && !adjacent_nodes[2]->is_a_leaf()) triangle_fan_indices[prev_total + num++] = vertex_indices[21];
00250 triangle_fan_indices[prev_total + num++] = vertex_indices[22];
00251
00252 prev_total += num_indices_in_quadrants[3];
00253 }
00254 else
00255 {
00256 num_indices_in_quadrants[3] = 0;
00257 }
00258
00259
00260 vbuffer::index_t vertex_pos = buffer_pool_rec.pos_in_vertices;
00261 vbuffer::index_t index_pos = buffer_pool_rec.pos_in_indices;
00262 int triangle_index_pos = 0;
00263 for (int i = 0; i < 4; ++i)
00264 {
00265 for (int j = 0; j < num_indices_in_quadrants[i]; ++j)
00266 {
00267 gsgl::index_t global_index = triangle_fan_indices[triangle_index_pos];
00268
00269
00270 buffer_pool_rec.parent->indices[index_pos++] = triangle_index_pos++;
00271
00272
00273 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_polar_coords[ global_index*2 + 0 ];
00274 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_polar_coords[ global_index*2 + 1 ];
00275
00276
00277 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_normals[ global_index*3 + 0 ];
00278 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_normals[ global_index*3 + 1 ];
00279 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_normals[ global_index*3 + 2 ];
00280
00281
00282 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_vertices[ global_index*3 + 0 ];
00283 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_vertices[ global_index*3 + 1 ];
00284 buffer_pool_rec.parent->vertices[ vertex_pos++ ] = parent_quadtree->global_vertices[ global_index*3 + 2 ];
00285 }
00286 }
00287 }
00288
00289 dirty = false;
00290 }
00291
00292
00293
00294
00295 spherical_quadtree::spherical_quadtree(gsgl::scenegraph::node *parent_sg_node, const gsgl::real_t & polar_radius, const gsgl::real_t & equatorial_radius)
00296 : parent_sg_node(parent_sg_node), polar_radius(polar_radius), equatorial_radius(equatorial_radius),
00297 buffers(0),
00298 num_leaf_nodes(0), last_num_leaf_nodes(0), num_merge_nodes(0), last_num_merge_nodes(0)
00299 {
00300 for (int i = 0; i < 6; ++i)
00301 root_nodes[i] = 0;
00302 }
00303
00304
00305 spherical_quadtree::~spherical_quadtree()
00306 {
00307 for (int i = 0; i < 6; ++i)
00308 delete root_nodes[i];
00309
00310 for (int i = 0; i < leaf_nodes.size(); ++i)
00311 {
00312 node_level_rec *rec = leaf_nodes[i];
00313 if (rec)
00314 {
00315 delete leaf_nodes[i]->first;
00316 delete leaf_nodes[i]->second;
00317 delete rec;
00318 }
00319 }
00320
00321
00322 delete buffers;
00323 }
00324
00325
00326
00327
00328 void spherical_quadtree::init(gsgl::scenegraph::context *c)
00329 {
00330
00331 if (!buffers)
00332 {
00333
00334
00335
00336
00337 buffers = new buffer_pool(vbuffer::DYNAMIC, 64, 32*8, 32);
00338 }
00339
00340
00341 init_root_nodes();
00342 }
00343
00344
00345
00346
00347 void spherical_quadtree::draw(gsgl::scenegraph::context *c)
00348 {
00349
00350
00351 if (c->frame == 1)
00352 {
00353 update(c, false);
00354 }
00355
00356 glPushAttrib(GL_ALL_ATTRIB_BITS); CHECK_GL_ERRORS();
00357 glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); CHECK_GL_ERRORS();
00358
00359 glEnableClientState(GL_VERTEX_ARRAY); CHECK_GL_ERRORS();
00360 glEnableClientState(GL_NORMAL_ARRAY);
00361 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00362 glEnableClientState(GL_INDEX_ARRAY); CHECK_GL_ERRORS();
00363
00364 for (int i = 0; i < 6; ++i)
00365 if (root_nodes[i])
00366 root_nodes[i]->draw(c);
00367
00368 utils::save_screen_info(last_frame_viewport, last_frame_modelview_projection);
00369
00370 glPopClientAttrib();
00371 glPopAttrib();
00372 }
00373
00374
00375
00376
00377 static config_variable<gsgl::real_t> ANGLE_CUTOFF(L"space/spherical_quadtree/angle_cutoff", -0.5f);
00378 static config_variable<gsgl::real_t> PIXEL_CUTOFF(L"space/spherical_quadtree/pixel_cutoff", 64);
00379
00380
00381 static string get_indent(int indent)
00382 {
00383 string res;
00384 for (int i = 0; i < indent; ++i)
00385 res += L" ";
00386 return res;
00387 }
00388
00389
00390 void spherical_quadtree::add_leaf_node(sph_qt_node *qtn)
00391 {
00392 assert(qtn);
00393 node_level_rec *record = leaf_nodes[qtn->level];
00394 if (!record)
00395 record = leaf_nodes[qtn->level] = new node_level_rec(new simple_array<sph_qt_node *>(), new simple_stack<gsgl::index_t>());
00396
00397 gsgl::index_t new_pos;
00398 if (record->second->size())
00399 {
00400 new_pos = record->second->top();
00401 record->second->pop();
00402 }
00403 else
00404 {
00405 new_pos = record->first->size();
00406 }
00407
00408 qtn->pos_in_leaf_node_array = new_pos;
00409 record->first->item(new_pos) = qtn;
00410 ++num_leaf_nodes;
00411 }
00412
00413
00414 void spherical_quadtree::remove_leaf_node(sph_qt_node *qtn)
00415 {
00416 assert(qtn);
00417 if (qtn->pos_in_leaf_node_array != -1)
00418 {
00419 node_level_rec *record = leaf_nodes[qtn->level];
00420 if (!record)
00421 throw internal_exception(__FILE__, __LINE__, L"Problem with leaf node array.");
00422
00423 record->second->push(qtn->pos_in_leaf_node_array);
00424 record->first->item(qtn->pos_in_leaf_node_array) = 0;
00425 qtn->pos_in_leaf_node_array = -1;
00426 --num_leaf_nodes;
00427 }
00428 else
00429 {
00430 throw internal_exception(__FILE__, __LINE__, L"Trying to remove a non-leaf node from the leaf node list.");
00431 }
00432 }
00433
00434
00435 void spherical_quadtree::add_merge_node(sph_qt_node *qtn)
00436 {
00437 assert(qtn);
00438 node_level_rec *record = merge_nodes[qtn->level];
00439 if (!record)
00440 record = merge_nodes[qtn->level] = new node_level_rec(new simple_array<sph_qt_node *>(), new simple_stack<gsgl::index_t>());
00441
00442 gsgl::index_t new_pos;
00443 if (record->second->size())
00444 {
00445 new_pos = record->second->top();
00446 record->second->pop();
00447 }
00448 else
00449 {
00450 new_pos = record->first->size();
00451 }
00452
00453 qtn->pos_in_merge_node_array = new_pos;
00454 record->first->item(new_pos) = qtn;
00455 ++num_merge_nodes;
00456 }
00457
00458
00459 void spherical_quadtree::remove_merge_node(sph_qt_node *qtn)
00460 {
00461 if (qtn && qtn->pos_in_merge_node_array != -1)
00462 {
00463 node_level_rec *record = merge_nodes[qtn->level];
00464 if (!record)
00465 throw internal_exception(__FILE__, __LINE__, L"Problem with merge node array.");
00466
00467 record->second->push(qtn->pos_in_merge_node_array);
00468 record->first->item(qtn->pos_in_merge_node_array) = 0;
00469 qtn->pos_in_merge_node_array = -1;
00470 --num_merge_nodes;
00471 }
00472 else
00473 {
00474
00475 }
00476 }
00477
00478
00479 gsgl::real_t spherical_quadtree::node_cos_angle(sph_qt_node *qtn, const transform & modelview)
00480 {
00481 gsgl::real_t result;
00482
00483 vector normal_pos_in_world_space = get_vector(global_vertices, qtn->vertex_indices[12]) + get_vector(global_normals, qtn->vertex_indices[12]) * 1000.0;
00484 vector normal_pos_in_eye_space = modelview * normal_pos_in_world_space;
00485
00486 vector center_pos_in_eye_space = modelview * get_vector(global_vertices, qtn->vertex_indices[12]);
00487 vector normal_in_eye_space = normal_pos_in_eye_space - center_pos_in_eye_space;
00488 normal_in_eye_space.normalize();
00489
00490 result = vector::Z_AXIS.dot(normal_in_eye_space);
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 return result;
00503 }
00504
00505
00506 gsgl::real_t spherical_quadtree::node_radius(sph_qt_node *qtn, const gsgl::scenegraph::context *c)
00507 {
00508 if (qtn->last_radius_frame != c->frame)
00509 {
00510 gsgl::real_t radius = (get_vector(global_vertices, qtn->vertex_indices[0]) - get_vector(global_vertices, qtn->vertex_indices[12])).mag();
00511 gsgl::real_t distance = (parent_sg_node->get_modelview() * get_vector(global_vertices, qtn->vertex_indices[12])).mag(); if (distance < 1.0f) distance = 1.0f;
00512 gsgl::real_t angle = ::atan(radius / distance);
00513
00514 gsgl::real_t pct_screen_angle = static_cast<gsgl::real_t>(angle / (c->cam->get_field_of_view() * math::DEG2RAD));
00515 gsgl::real_t pixel_radius = pct_screen_angle * c->screen->get_height();
00516
00517 qtn->radius_in_world_space = radius;
00518 qtn->radius_in_screen_space = pixel_radius;
00519 qtn->last_radius_frame = c->frame;
00520 }
00521
00522 return qtn->radius_in_screen_space;
00523 }
00524
00525
00526 #ifdef DEBUG_SPLITS_AND_MERGES
00527 static int get_ptr_num(sph_qt_node **adjacent_nodes, sph_qt_node *child)
00528 {
00529 assert(child);
00530
00531 for (int i = 0; i < 4; ++i)
00532 if (adjacent_nodes[i] == child)
00533 return i;
00534 return -1;
00535 }
00536 #endif
00537
00538
00539
00540
00541
00542 sph_qt_node *spherical_quadtree::get_adjacent(sph_qt_node *candidate, const vbuffer::index_t & index0, const vbuffer::index_t & index1, sph_qt_node ***peer_handle, vbuffer::index_t *side0, vbuffer::index_t *side1)
00543 {
00544 sph_qt_node *result = candidate;
00545 *peer_handle = 0;
00546 if (side0) *side0 = 0;
00547 if (side1) *side1 = 0;
00548
00549 if (!candidate->is_a_leaf())
00550 {
00551
00552 for (int i = 0; i < 4; ++i)
00553 {
00554 sph_qt_node *child = candidate->children[i];
00555
00556
00557 if (child)
00558 {
00559
00560 if (child->vertex_indices[0] == index0 && child->vertex_indices[4] == index1)
00561 {
00562 result = child;
00563 *peer_handle = &child->adjacent_nodes[0];
00564 if (side0) *side0 = child->vertex_indices[1];
00565 if (side1) *side1 = child->vertex_indices[3];
00566 }
00567 else if (child->vertex_indices[4] == index0 && child->vertex_indices[0] == index1)
00568 {
00569 result = child;
00570 *peer_handle = &child->adjacent_nodes[0];
00571 if (side0) *side0 = child->vertex_indices[3];
00572 if (side1) *side1 = child->vertex_indices[1];
00573 }
00574
00575
00576 else if (child->vertex_indices[4] == index0 && child->vertex_indices[24] == index1)
00577 {
00578 result = child;
00579 *peer_handle = &child->adjacent_nodes[1];
00580 if (side0) *side0 = child->vertex_indices[9];
00581 if (side1) *side1 = child->vertex_indices[19];
00582 }
00583 else if (child->vertex_indices[24] == index0 && child->vertex_indices[4] == index1)
00584 {
00585 result = child;
00586 *peer_handle = &child->adjacent_nodes[1];
00587 if (side0) *side0 = child->vertex_indices[19];
00588 if (side1) *side1 = child->vertex_indices[9];
00589 }
00590
00591
00592 else if (child->vertex_indices[24] == index0 && child->vertex_indices[20] == index1)
00593 {
00594 result = child;
00595 *peer_handle = &child->adjacent_nodes[2];
00596 if (side0) *side0 = child->vertex_indices[23];
00597 if (side1) *side1 = child->vertex_indices[21];
00598 }
00599 else if (child->vertex_indices[20] == index0 && child->vertex_indices[24] == index1)
00600 {
00601 result = child;
00602 *peer_handle = &child->adjacent_nodes[2];
00603 if (side0) *side0 = child->vertex_indices[21];
00604 if (side1) *side1 = child->vertex_indices[23];
00605 }
00606
00607
00608 else if (child->vertex_indices[20] == index0 && child->vertex_indices[0] == index1)
00609 {
00610 result = child;
00611 *peer_handle = &child->adjacent_nodes[3];
00612 if (side0) *side0 = child->vertex_indices[15];
00613 if (side1) *side1 = child->vertex_indices[5];
00614 }
00615 else if (child->vertex_indices[0] == index0 && child->vertex_indices[20] == index1)
00616 {
00617 result = child;
00618 *peer_handle = &child->adjacent_nodes[3];
00619 if (side0) *side0 = child->vertex_indices[5];
00620 if (side1) *side1 = child->vertex_indices[15];
00621 }
00622
00623 if (result == child)
00624 break;
00625 }
00626 }
00627 }
00628
00629 return result;
00630 }
00631
00632
00633 bool spherical_quadtree::neighbor_allows_merge(sph_qt_node *qtn, sph_qt_node *adj)
00634 {
00635 if (adj && adj->level >= qtn->level)
00636 {
00637 for (int i = 0; i < 4; ++i)
00638 {
00639 if (adj->children[i] && !adj->children[i]->is_a_leaf())
00640 return false;
00641 }
00642 }
00643
00644 return true;
00645 }
00646
00647
00648 void spherical_quadtree::merge_node_aux(sph_qt_node *qtn)
00649 {
00650
00651 for (int i = 0; i < 4; ++i)
00652 {
00653 sph_qt_node *child = qtn->children[i];
00654
00655 #ifdef DEBUG_SPLITS_AND_MERGES
00656 log(string::format(L" child %d: {%ls}", i, child ? child->path.w_string() : L"<null>"));
00657 #endif
00658
00659 if (child)
00660 {
00661 for (int j = 0; j < 4; ++j)
00662 {
00663 if (child->adjacent_nodes[j] && child->adjacent_nodes[j]->parent_node != qtn)
00664 {
00665 sph_qt_node *adj = child->adjacent_nodes[j];
00666
00667 for (int k = 0; k < 4; ++k)
00668 {
00669 if (adj->adjacent_nodes[k] == child)
00670 {
00671 #ifdef DEBUG_SPLITS_AND_MERGES
00672 log(string::format(L" switching {%ls}'s ptr %d to point to {%ls}", adj->path.w_string(), k, qtn->path.w_string()));
00673 #endif
00674
00675 adj->adjacent_nodes[k] = qtn;
00676 adj->dirty = true;
00677 }
00678 }
00679 }
00680 }
00681 }
00682 }
00683
00684 }
00685
00686
00687 bool spherical_quadtree::merge_node(sph_qt_node *qtn, const transform & modelview, const gsgl::scenegraph::context *c)
00688 {
00689
00690 if (qtn->last_merge_frame == c->frame)
00691 return true;
00692
00693
00694 if (qtn->last_split_frame == c->frame)
00695 return false;
00696
00697
00698 for (int i = 0; i < 4; ++i)
00699 {
00700 if (qtn->children[i] && !qtn->children[i]->is_a_leaf())
00701 throw internal_exception(__FILE__, __LINE__, L"Trying to merge a node whose children are not leaves!");
00702 }
00703
00704
00705 if (node_cos_angle(qtn, modelview) < ANGLE_CUTOFF || node_radius(qtn, c) < PIXEL_CUTOFF)
00706 {
00707
00708 bool can_merge = true;
00709 for (int i = 0; can_merge && i < 4; ++i)
00710 {
00711 if (qtn->children[i])
00712 {
00713 sph_qt_node *child = qtn->children[i];
00714
00715 for (int j = 0; can_merge && j < 4; ++j)
00716 {
00717 if (child->adjacent_nodes[j] && child->adjacent_nodes[j]->parent_node != qtn)
00718 {
00719 sph_qt_node *adj = child->adjacent_nodes[j];
00720
00721 if (adj->level > child->level)
00722 throw internal_exception(__FILE__, __LINE__, L"Trying to merge a node whose children are next to nodes of a greater level!");
00723
00724 if (adj->level == child->level && !adj->is_a_leaf())
00725 can_merge = false;
00726 }
00727 }
00728 }
00729 }
00730
00731
00732 if (can_merge)
00733 {
00734 #ifdef DEBUG_SPLITS_AND_MERGES
00735 gsgl::log(string(L"\nMERGE {") + qtn->path + L"}");
00736 #endif
00737
00738 merge_node_aux(qtn);
00739
00740
00741 for (int i = 0; i < 4; ++i)
00742 {
00743 if (qtn->children[i])
00744 remove_leaf_node(qtn->children[i]);
00745 delete qtn->children[i];
00746 qtn->children[i] = 0;
00747
00748 if (qtn->adjacent_nodes[i])
00749 qtn->adjacent_nodes[i]->dirty = true;
00750 }
00751
00752 qtn->dirty = true;
00753 qtn->last_merge_frame = c->frame;
00754 remove_merge_node(qtn);
00755 add_leaf_node(qtn);
00756
00757
00758 if (qtn->parent_node)
00759 {
00760 if (qtn->parent_node->pos_in_merge_node_array == -1
00761 && qtn->parent_node->children[0]->is_a_leaf()
00762 && qtn->parent_node->children[1]->is_a_leaf()
00763 && qtn->parent_node->children[2]->is_a_leaf()
00764 && qtn->parent_node->children[3]->is_a_leaf())
00765 {
00766 add_merge_node(qtn->parent_node);
00767 }
00768 }
00769
00770 return true;
00771 }
00772 }
00773
00774 return false;
00775 }
00776
00777
00778 static const bool NEW_NODE_VERTEX_FLAGS[] =
00779 {
00780 true, false, true, false, true,
00781 false, false, false, false, false,
00782 true, false, true, false, true,
00783 false, false, false, false, false,
00784 true, false, true, false, true
00785 };
00786
00787
00788 void spherical_quadtree::split_node_aux(sph_qt_node *qtn, int force_level)
00789 {
00790
00791 for (int i = 0; i < 4; ++i)
00792 if (qtn->adjacent_nodes[i])
00793 qtn->adjacent_nodes[i]->dirty = true;
00794
00795
00796 vector geographic_normals[25];
00797 vbuffer::index_t indices[25];
00798
00799 sph_qt_node *child0 = qtn->children[0] = create_node(qtn);
00800 sph_qt_node *child1 = qtn->children[1] = create_node(qtn);
00801 sph_qt_node *child2 = qtn->children[2] = create_node(qtn);
00802 sph_qt_node *child3 = qtn->children[3] = create_node(qtn);
00803
00804
00805 if (child0)
00806 {
00807 #ifdef DEBUG_SPLITS_AND_MERGES
00808 log(string::format(L"%ls creating child {%ls 0}", get_indent(force_level).w_string(), qtn->path.w_string()));
00809 #endif
00810
00811 add_leaf_node(child0);
00812
00813 bool node_vertex_flags[25];
00814 for (int i = 0; i < 25; ++i)
00815 node_vertex_flags[i] = NEW_NODE_VERTEX_FLAGS[i];
00816
00817
00818 geographic_normals[0] = get_vector(global_normals, qtn->vertex_indices[0]);
00819 geographic_normals[2] = get_vector(global_normals, qtn->vertex_indices[1]);
00820 geographic_normals[4] = get_vector(global_normals, qtn->vertex_indices[2]);
00821
00822 geographic_normals[10] = get_vector(global_normals, qtn->vertex_indices[5]);
00823 geographic_normals[12] = get_vector(global_normals, qtn->vertex_indices[6]);
00824 geographic_normals[14] = get_vector(global_normals, qtn->vertex_indices[7]);
00825
00826 geographic_normals[24] = get_vector(global_normals, qtn->vertex_indices[12]);
00827 geographic_normals[22] = get_vector(global_normals, qtn->vertex_indices[11]);
00828 geographic_normals[20] = get_vector(global_normals, qtn->vertex_indices[10]);
00829 fill_in_normals(geographic_normals);
00830
00831
00832 vbuffer::index_t middle_top_left, middle_top_right;
00833 sph_qt_node **adj_top_handle_to_us = 0;
00834 sph_qt_node *adj_top = get_adjacent(qtn->adjacent_nodes[0], qtn->vertex_indices[0], qtn->vertex_indices[2], &adj_top_handle_to_us, &middle_top_left, &middle_top_right);
00835
00836
00837 vbuffer::index_t middle_left_top, middle_left_bottom;
00838 sph_qt_node **adj_left_handle_to_us = 0;
00839 sph_qt_node *adj_left = get_adjacent(qtn->adjacent_nodes[3], qtn->vertex_indices[0], qtn->vertex_indices[10], &adj_left_handle_to_us, &middle_left_top, &middle_left_bottom);
00840
00841
00842 indices[0] = qtn->vertex_indices[0];
00843 indices[1] = adj_top_handle_to_us ? middle_top_left : get_new_vertex_index();
00844 indices[2] = qtn->vertex_indices[1];
00845 indices[3] = adj_top_handle_to_us ? middle_top_right : get_new_vertex_index();
00846 indices[4] = qtn->vertex_indices[2];
00847
00848 indices[5] = adj_left_handle_to_us ? middle_left_top : get_new_vertex_index();
00849 indices[6] = get_new_vertex_index();
00850 indices[7] = get_new_vertex_index();
00851 indices[8] = get_new_vertex_index();
00852 indices[9] = get_new_vertex_index();
00853
00854 indices[10] = qtn->vertex_indices[5];
00855 indices[11] = get_new_vertex_index();
00856 indices[12] = qtn->vertex_indices[6];
00857 indices[13] = get_new_vertex_index();
00858 indices[14] = qtn->vertex_indices[7];
00859
00860 indices[15] = adj_left_handle_to_us ? middle_left_bottom : get_new_vertex_index();
00861 indices[16] = get_new_vertex_index();
00862 indices[17] = get_new_vertex_index();
00863 indices[18] = get_new_vertex_index();
00864 indices[19] = get_new_vertex_index();
00865
00866 indices[20] = qtn->vertex_indices[10];
00867 indices[21] = get_new_vertex_index();
00868 indices[22] = qtn->vertex_indices[11];
00869 indices[23] = get_new_vertex_index();
00870 indices[24] = qtn->vertex_indices[12];
00871
00872
00873 if (adj_top_handle_to_us)
00874 node_vertex_flags[1] = node_vertex_flags[3] = true;
00875 if (adj_left_handle_to_us)
00876 node_vertex_flags[5] = node_vertex_flags[5] = true;
00877
00878
00879 generate_vertices(child0, geographic_normals, node_vertex_flags, indices);
00880
00881 child0->adjacent_nodes[0] = adj_top;
00882 child0->adjacent_nodes[1] = child1;
00883 child0->adjacent_nodes[2] = child3;
00884 child0->adjacent_nodes[3] = adj_left;
00885 child0->dirty = true;
00886
00887 if (adj_top_handle_to_us)
00888 {
00889 #ifdef DEBUG_SPLITS_AND_MERGES
00890 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
00891 get_indent(force_level).w_string(), adj_top->path.w_string(), get_ptr_num(adj_top->adjacent_nodes, *adj_top_handle_to_us), (*adj_top_handle_to_us)->path.w_string()));
00892 #endif
00893 *adj_top_handle_to_us = child0;
00894 adj_top->dirty = true;
00895 }
00896
00897 if (adj_left_handle_to_us)
00898 {
00899 #ifdef DEBUG_SPLITS_AND_MERGES
00900 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
00901 get_indent(force_level).w_string(), adj_left->path.w_string(), get_ptr_num(adj_left->adjacent_nodes, *adj_left_handle_to_us), (*adj_left_handle_to_us)->path.w_string()));
00902 #endif
00903 *adj_left_handle_to_us = child0;
00904 adj_left->dirty = true;
00905 }
00906 }
00907
00908
00909 if (child1)
00910 {
00911 #ifdef DEBUG_SPLITS_AND_MERGES
00912 log(string::format(L"%ls creating child {%ls 1}", get_indent(force_level).w_string(), qtn->path.w_string()));
00913 #endif
00914
00915 add_leaf_node(child1);
00916
00917 bool node_vertex_flags[25];
00918 for (int i = 0; i < 25; ++i)
00919 node_vertex_flags[i] = NEW_NODE_VERTEX_FLAGS[i];
00920
00921
00922 geographic_normals[0] = get_vector(global_normals, qtn->vertex_indices[2]);
00923 geographic_normals[2] = get_vector(global_normals, qtn->vertex_indices[3]);
00924 geographic_normals[4] = get_vector(global_normals, qtn->vertex_indices[4]);
00925
00926 geographic_normals[10] = get_vector(global_normals, qtn->vertex_indices[7]);
00927 geographic_normals[12] = get_vector(global_normals, qtn->vertex_indices[8]);
00928 geographic_normals[14] = get_vector(global_normals, qtn->vertex_indices[9]);
00929
00930 geographic_normals[24] = get_vector(global_normals, qtn->vertex_indices[14]);
00931 geographic_normals[22] = get_vector(global_normals, qtn->vertex_indices[13]);
00932 geographic_normals[20] = get_vector(global_normals, qtn->vertex_indices[12]);
00933 fill_in_normals(geographic_normals);
00934
00935
00936 vbuffer::index_t middle_top_left, middle_top_right;
00937 sph_qt_node **adj_top_handle_to_us = 0;
00938 sph_qt_node *adj_top = get_adjacent(qtn->adjacent_nodes[0], qtn->vertex_indices[2], qtn->vertex_indices[4], &adj_top_handle_to_us, &middle_top_left, &middle_top_right);
00939
00940
00941 vbuffer::index_t middle_right_top, middle_right_bottom;
00942 sph_qt_node **adj_right_handle_to_us = 0;
00943 sph_qt_node *adj_right = get_adjacent(qtn->adjacent_nodes[1], qtn->vertex_indices[4], qtn->vertex_indices[14], &adj_right_handle_to_us, &middle_right_top, &middle_right_bottom);
00944
00945
00946 indices[0] = qtn->vertex_indices[2];
00947 indices[1] = adj_top_handle_to_us ? middle_top_left : get_new_vertex_index();
00948 indices[2] = qtn->vertex_indices[3];
00949 indices[3] = adj_top_handle_to_us ? middle_top_right : get_new_vertex_index();
00950 indices[4] = qtn->vertex_indices[4];
00951
00952 indices[5] = child0 ? child0->vertex_indices[9] : get_new_vertex_index();
00953 indices[6] = get_new_vertex_index();
00954 indices[7] = get_new_vertex_index();
00955 indices[8] = get_new_vertex_index();
00956 indices[9] = adj_right_handle_to_us ? middle_right_top : get_new_vertex_index();
00957
00958 indices[10] = qtn->vertex_indices[7];
00959 indices[11] = get_new_vertex_index();
00960 indices[12] = qtn->vertex_indices[8];
00961 indices[13] = get_new_vertex_index();
00962 indices[14] = qtn->vertex_indices[9];
00963
00964 indices[15] = child0 ? child0->vertex_indices[19] : get_new_vertex_index();
00965 indices[16] = get_new_vertex_index();
00966 indices[17] = get_new_vertex_index();
00967 indices[18] = get_new_vertex_index();
00968 indices[19] = adj_right_handle_to_us ? middle_right_bottom : get_new_vertex_index();
00969
00970 indices[20] = qtn->vertex_indices[12];
00971 indices[21] = get_new_vertex_index();
00972 indices[22] = qtn->vertex_indices[13];
00973 indices[23] = get_new_vertex_index();
00974 indices[24] = qtn->vertex_indices[14];
00975
00976
00977 if (child0)
00978 node_vertex_flags[5] = node_vertex_flags[15] = true;
00979 if (adj_top_handle_to_us)
00980 node_vertex_flags[1] = node_vertex_flags[3] = true;
00981 if (adj_right_handle_to_us)
00982 node_vertex_flags[9] = node_vertex_flags[19] = true;
00983
00984 generate_vertices(child1, geographic_normals, node_vertex_flags, indices);
00985
00986
00987 child1->adjacent_nodes[0] = adj_top;
00988 child1->adjacent_nodes[1] = adj_right;
00989 child1->adjacent_nodes[2] = child2;
00990 child1->adjacent_nodes[3] = child0;
00991 child1->dirty = true;
00992
00993
00994 if (adj_top_handle_to_us)
00995 {
00996 #ifdef DEBUG_SPLITS_AND_MERGES
00997 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
00998 get_indent(force_level).w_string(), adj_top->path.w_string(), get_ptr_num(adj_top->adjacent_nodes, *adj_top_handle_to_us), (*adj_top_handle_to_us)->path.w_string()));
00999 #endif
01000 *adj_top_handle_to_us = child1;
01001 adj_top->dirty = true;
01002 }
01003
01004 if (adj_right_handle_to_us)
01005 {
01006 #ifdef DEBUG_SPLITS_AND_MERGES
01007 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
01008 get_indent(force_level).w_string(), adj_right->path.w_string(), get_ptr_num(adj_right->adjacent_nodes, *adj_right_handle_to_us), (*adj_right_handle_to_us)->path.w_string()));
01009 #endif
01010 *adj_right_handle_to_us = child1;
01011 adj_right->dirty = true;
01012 }
01013 }
01014
01015
01016 if (child2)
01017 {
01018 #ifdef DEBUG_SPLITS_AND_MERGES
01019 log(string::format(L"%ls creating child {%ls 2}", get_indent(force_level).w_string(), qtn->path.w_string()));
01020 #endif
01021
01022 add_leaf_node(child2);
01023
01024 bool node_vertex_flags[25];
01025 for (int i = 0; i < 25; ++i)
01026 node_vertex_flags[i] = NEW_NODE_VERTEX_FLAGS[i];
01027
01028
01029 geographic_normals[0] = get_vector(global_normals, qtn->vertex_indices[12]);
01030 geographic_normals[2] = get_vector(global_normals, qtn->vertex_indices[13]);
01031 geographic_normals[4] = get_vector(global_normals, qtn->vertex_indices[14]);
01032
01033 geographic_normals[10] = get_vector(global_normals, qtn->vertex_indices[17]);
01034 geographic_normals[12] = get_vector(global_normals, qtn->vertex_indices[18]);
01035 geographic_normals[14] = get_vector(global_normals, qtn->vertex_indices[19]);
01036
01037 geographic_normals[24] = get_vector(global_normals, qtn->vertex_indices[24]);
01038 geographic_normals[22] = get_vector(global_normals, qtn->vertex_indices[23]);
01039 geographic_normals[20] = get_vector(global_normals, qtn->vertex_indices[22]);
01040 fill_in_normals(geographic_normals);
01041
01042
01043 vbuffer::index_t middle_right_top, middle_right_bottom;
01044 sph_qt_node **adj_right_handle_to_us = 0;
01045 sph_qt_node *adj_right = get_adjacent(qtn->adjacent_nodes[1], qtn->vertex_indices[14], qtn->vertex_indices[24], &adj_right_handle_to_us, &middle_right_top, &middle_right_bottom);
01046
01047
01048 vbuffer::index_t middle_bottom_left, middle_bottom_right;
01049 sph_qt_node **adj_bottom_handle_to_us = 0;
01050 sph_qt_node *adj_bottom = get_adjacent(qtn->adjacent_nodes[2], qtn->vertex_indices[22], qtn->vertex_indices[24], &adj_bottom_handle_to_us, &middle_bottom_left, &middle_bottom_right);
01051
01052
01053 indices[0] = qtn->vertex_indices[12];
01054 indices[1] = child1 ? child1->vertex_indices[21] : get_new_vertex_index();
01055 indices[2] = qtn->vertex_indices[13];
01056 indices[3] = child1 ? child1->vertex_indices[23] : get_new_vertex_index();
01057 indices[4] = qtn->vertex_indices[14];
01058
01059 indices[5] = get_new_vertex_index();
01060 indices[6] = get_new_vertex_index();
01061 indices[7] = get_new_vertex_index();
01062 indices[8] = get_new_vertex_index();
01063 indices[9] = adj_right_handle_to_us ? middle_right_top : get_new_vertex_index();
01064
01065 indices[10] = qtn->vertex_indices[17];
01066 indices[11] = get_new_vertex_index();
01067 indices[12] = qtn->vertex_indices[18];
01068 indices[13] = get_new_vertex_index();
01069 indices[14] = qtn->vertex_indices[19];
01070
01071 indices[15] = get_new_vertex_index();
01072 indices[16] = get_new_vertex_index();
01073 indices[17] = get_new_vertex_index();
01074 indices[18] = get_new_vertex_index();
01075 indices[19] = adj_right_handle_to_us ? middle_right_bottom : get_new_vertex_index();
01076
01077 indices[20] = qtn->vertex_indices[22];
01078 indices[21] = adj_bottom_handle_to_us ? middle_bottom_left : get_new_vertex_index();
01079 indices[22] = qtn->vertex_indices[23];
01080 indices[23] = adj_bottom_handle_to_us ? middle_bottom_right : get_new_vertex_index();
01081 indices[24] = qtn->vertex_indices[24];
01082
01083
01084 if (child1)
01085 node_vertex_flags[1] = node_vertex_flags[3] = true;
01086 if (adj_right_handle_to_us)
01087 node_vertex_flags[9] = node_vertex_flags[19] = true;
01088 if (adj_bottom_handle_to_us)
01089 node_vertex_flags[21] = node_vertex_flags[23] = true;
01090
01091
01092 generate_vertices(child2, geographic_normals, node_vertex_flags, indices);
01093
01094
01095 child2->adjacent_nodes[0] = child1;
01096 child2->adjacent_nodes[1] = adj_right;
01097 child2->adjacent_nodes[2] = adj_bottom;
01098 child2->adjacent_nodes[3] = child3;
01099 child2->dirty = true;
01100
01101 if (adj_right_handle_to_us)
01102 {
01103 #ifdef DEBUG_SPLITS_AND_MERGES
01104 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
01105 get_indent(force_level).w_string(), adj_right->path.w_string(), get_ptr_num(adj_right->adjacent_nodes, *adj_right_handle_to_us), (*adj_right_handle_to_us)->path.w_string()));
01106 #endif
01107 *adj_right_handle_to_us = child2;
01108 adj_right->dirty = true;
01109 }
01110
01111 if (adj_bottom_handle_to_us)
01112 {
01113 #ifdef DEBUG_SPLITS_AND_MERGES
01114 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
01115 get_indent(force_level).w_string(), adj_bottom->path.w_string(), get_ptr_num(adj_bottom->adjacent_nodes, *adj_bottom_handle_to_us), (*adj_bottom_handle_to_us)->path.w_string()));
01116 #endif
01117 *adj_bottom_handle_to_us = child2;
01118 adj_bottom->dirty = true;
01119 }
01120 }
01121
01122
01123 if (child3)
01124 {
01125 #ifdef DEBUG_SPLITS_AND_MERGES
01126 log(string::format(L"%ls creating child {%ls 3}", get_indent(force_level).w_string(), qtn->path.w_string()));
01127 #endif
01128
01129 add_leaf_node(child3);
01130
01131 bool node_vertex_flags[25];
01132 for (int i = 0; i < 25; ++i)
01133 node_vertex_flags[i] = NEW_NODE_VERTEX_FLAGS[i];
01134
01135
01136 geographic_normals[0] = get_vector(global_normals, qtn->vertex_indices[10]);
01137 geographic_normals[2] = get_vector(global_normals, qtn->vertex_indices[11]);
01138 geographic_normals[4] = get_vector(global_normals, qtn->vertex_indices[12]);
01139
01140 geographic_normals[10] = get_vector(global_normals, qtn->vertex_indices[15]);
01141 geographic_normals[12] = get_vector(global_normals, qtn->vertex_indices[16]);
01142 geographic_normals[14] = get_vector(global_normals, qtn->vertex_indices[17]);
01143
01144 geographic_normals[24] = get_vector(global_normals, qtn->vertex_indices[22]);
01145 geographic_normals[22] = get_vector(global_normals, qtn->vertex_indices[21]);
01146 geographic_normals[20] = get_vector(global_normals, qtn->vertex_indices[20]);
01147 fill_in_normals(geographic_normals);
01148
01149
01150 vbuffer::index_t middle_bottom_left, middle_bottom_right;
01151 sph_qt_node **adj_bottom_handle_to_us = 0;
01152 sph_qt_node *adj_bottom = get_adjacent(qtn->adjacent_nodes[2], qtn->vertex_indices[20], qtn->vertex_indices[22], &adj_bottom_handle_to_us, &middle_bottom_left, &middle_bottom_right);
01153
01154
01155 vbuffer::index_t middle_left_top, middle_left_bottom;
01156 sph_qt_node **adj_left_handle_to_us = 0;
01157 sph_qt_node *adj_left = get_adjacent(qtn->adjacent_nodes[3], qtn->vertex_indices[10], qtn->vertex_indices[20], &adj_left_handle_to_us, &middle_left_top, &middle_left_bottom);
01158
01159
01160 indices[0] = qtn->vertex_indices[10];
01161 indices[1] = child0 ? child0->vertex_indices[21] : get_new_vertex_index();
01162 indices[2] = qtn->vertex_indices[11];
01163 indices[3] = child0 ? child0->vertex_indices[23] : get_new_vertex_index();
01164 indices[4] = qtn->vertex_indices[12];
01165
01166 indices[5] = adj_left_handle_to_us ? middle_left_top : get_new_vertex_index();
01167 indices[6] = get_new_vertex_index();
01168 indices[7] = get_new_vertex_index();
01169 indices[8] = get_new_vertex_index();
01170 indices[9] = child2 ? child2->vertex_indices[5] : get_new_vertex_index();
01171
01172 indices[10] = qtn->vertex_indices[15];
01173 indices[11] = get_new_vertex_index();
01174 indices[12] = qtn->vertex_indices[16];
01175 indices[13] = get_new_vertex_index();
01176 indices[14] = qtn->vertex_indices[17];
01177
01178 indices[15] = adj_left_handle_to_us ? middle_left_bottom : get_new_vertex_index();
01179 indices[16] = get_new_vertex_index();
01180 indices[17] = get_new_vertex_index();
01181 indices[18] = get_new_vertex_index();
01182 indices[19] = child2 ? child2->vertex_indices[15] : get_new_vertex_index();
01183
01184 indices[20] = qtn->vertex_indices[20];
01185 indices[21] = adj_bottom_handle_to_us ? middle_bottom_left : get_new_vertex_index();
01186 indices[22] = qtn->vertex_indices[21];
01187 indices[23] = adj_bottom_handle_to_us ? middle_bottom_right : get_new_vertex_index();
01188 indices[24] = qtn->vertex_indices[22];
01189
01190
01191 if (child0)
01192 node_vertex_flags[1] = node_vertex_flags[3] = true;
01193 if (child2)
01194 node_vertex_flags[9] = node_vertex_flags[19] = true;
01195 if (adj_bottom_handle_to_us)
01196 node_vertex_flags[21] = node_vertex_flags[23] = true;
01197 if (adj_left_handle_to_us)
01198 node_vertex_flags[5] = node_vertex_flags[15] = true;
01199
01200
01201 generate_vertices(child3, geographic_normals, node_vertex_flags, indices);
01202
01203
01204 child3->adjacent_nodes[0] = child0;
01205 child3->adjacent_nodes[1] = child2;
01206 child3->adjacent_nodes[2] = adj_bottom;
01207 child3->adjacent_nodes[3] = adj_left;
01208 child3->dirty = true;
01209
01210 if (adj_bottom_handle_to_us)
01211 {
01212 #ifdef DEBUG_SPLITS_AND_MERGES
01213 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
01214 get_indent(force_level).w_string(), adj_bottom->path.w_string(), get_ptr_num(adj_bottom->adjacent_nodes, *adj_bottom_handle_to_us), (*adj_bottom_handle_to_us)->path.w_string()));
01215 #endif
01216 *adj_bottom_handle_to_us = child3;
01217 adj_bottom->dirty = true;
01218 }
01219
01220 if (adj_left_handle_to_us)
01221 {
01222 #ifdef DEBUG_SPLITS_AND_MERGES
01223 log(string::format(L"%ls switching node {%s}'s pointer %d from {%ls} to us",
01224 get_indent(force_level).w_string(), adj_left->path.w_string(), get_ptr_num(adj_left->adjacent_nodes, *adj_left_handle_to_us), (*adj_left_handle_to_us)->path.w_string()));
01225 #endif
01226 *adj_left_handle_to_us = child3;
01227 adj_left->dirty = true;
01228 }
01229 }
01230
01231
01232 #ifdef DEBUG
01233 for (int i = 0; i < 4; ++i)
01234 {
01235 if (qtn->children[i])
01236 qtn->children[i]->path = qtn->path + string::format(L" %d", i);
01237 }
01238 #endif
01239
01240 #ifdef DEBUG_SPLITS_AND_MERGES
01241
01242 for (int i = 0; i < 4; ++i)
01243 {
01244 if (qtn->children[i])
01245 {
01246 gsgl::log(string::format(L"%lschild %d {%ls}: neighbors are 0:{%ls}, 1:{%ls}, 2:{%ls}, 3:{%ls}",
01247 get_indent(force_level+1).w_string(), i, qtn->children[i]->path.w_string(),
01248 (qtn->children[i]->adjacent_nodes[0] ? qtn->children[i]->adjacent_nodes[0]->path.w_string() : L"<null>"),
01249 (qtn->children[i]->adjacent_nodes[1] ? qtn->children[i]->adjacent_nodes[1]->path.w_string() : L"<null>"),
01250 (qtn->children[i]->adjacent_nodes[2] ? qtn->children[i]->adjacent_nodes[2]->path.w_string() : L"<null>"),
01251 (qtn->children[i]->adjacent_nodes[3] ? qtn->children[i]->adjacent_nodes[3]->path.w_string() : L"<null>")));
01252 }
01253 else
01254 {
01255 gsgl::log(get_indent(force_level+1) + string::format(L"child %d: <null>", i));
01256 }
01257 }
01258 #endif
01259 }
01260
01261
01262 bool spherical_quadtree::split_node(sph_qt_node *qtn, const transform & modelview, const gsgl::scenegraph::context *c, bool no_visual_check, int force_level)
01263 {
01264 assert(qtn);
01265
01266
01267 if (qtn->last_split_frame == c->frame)
01268 return true;
01269
01270
01271 if (!qtn->is_a_leaf())
01272 throw internal_exception(__FILE__, __LINE__, L"Trying to split a non-leaf node!");
01273
01274
01275 if (no_visual_check || ( (node_radius(qtn, c) > PIXEL_CUTOFF)))
01276 {
01277 #ifdef DEBUG_SPLITS_AND_MERGES
01278 gsgl::log(string(L"\n") + get_indent(force_level) + L"SPLIT {" + qtn->path.w_string() + L"}");
01279 #endif
01280
01281
01282 bool can_split = true;
01283 for (int i = 0; can_split && i < 4; ++i)
01284 {
01285 if (qtn->adjacent_nodes[i] && qtn->adjacent_nodes[i]->level < qtn->level)
01286 {
01287 can_split = split_node(qtn->adjacent_nodes[i], modelview, c, true, force_level+1);
01288 }
01289 }
01290
01291
01292 if (qtn->last_split_frame == c->frame)
01293 return true;
01294
01295
01296 if (can_split)
01297 {
01298 remove_leaf_node(qtn);
01299 split_node_aux(qtn, force_level);
01300 qtn->last_split_frame = c->frame;
01301
01302 remove_merge_node(qtn->parent_node);
01303 add_merge_node(qtn);
01304 return true;
01305 }
01306 }
01307
01308 return false;
01309 }
01310
01311
01312 static const bool allow_merge = true;
01313 static const bool allow_split = true;
01314
01315
01316 void spherical_quadtree::update(gsgl::scenegraph::context *c, const bool not_visible)
01317 {
01318
01319 vector eye_pos = parent_sg_node->get_modelview().inverse() * vector::ZERO;
01320
01321 if (c->frame < 10
01322 || num_leaf_nodes != last_num_leaf_nodes
01323 || num_merge_nodes != last_num_merge_nodes
01324 || (eye_pos.get_x() != eye_pos_in_object_space.get_x())
01325 || (eye_pos.get_y() != eye_pos_in_object_space.get_y())
01326 || (eye_pos.get_z() != eye_pos_in_object_space.get_z()))
01327 {
01328 last_num_leaf_nodes = num_leaf_nodes;
01329 last_num_merge_nodes = num_merge_nodes;
01330
01331
01332 if (allow_split && !not_visible)
01333 {
01334 int level, num_levels = leaf_nodes.size();
01335 for (level = 0; level < num_levels; ++level)
01336 {
01337 node_level_rec *rec = leaf_nodes[level];
01338 if (rec)
01339 {
01340 int i, count = 0, len = rec->first->size();
01341 for (i = 0; i < len; ++i)
01342 {
01343 sph_qt_node *leaf = rec->first->item(i);
01344 if (leaf)
01345 {
01346 if (leaf->last_merge_frame < c->frame)
01347 {
01348 split_node(leaf, parent_sg_node->get_modelview(), c, false, 0);
01349 }
01350 ++count;
01351 }
01352 }
01353
01354
01355 if (len && !count)
01356 {
01357 rec->first->clear();
01358 }
01359 }
01360 }
01361 }
01362
01363
01364 if (allow_merge)
01365 {
01366 int level, num_levels = merge_nodes.size();
01367 for (level = num_levels; level > 0; --level)
01368 {
01369 node_level_rec *rec = merge_nodes[level-1];
01370 if (rec)
01371 {
01372 int i, count = 0, len = rec->first->size();
01373 for (i = 0; i < len; ++i)
01374 {
01375 sph_qt_node *mrg = rec->first->item(i);
01376 if (mrg)
01377 {
01378 if (mrg->last_split_frame < c->frame && (c->frame - mrg->last_split_frame) > 10)
01379 {
01380 merge_node(mrg, parent_sg_node->get_modelview(), c);
01381 }
01382 ++count;
01383 }
01384 }
01385
01386
01387 if (len && !count)
01388 {
01389 rec->first->clear();
01390 }
01391 }
01392 }
01393 }
01394
01395 eye_pos_in_object_space = eye_pos;
01396 }
01397 }
01398
01399
01400 void spherical_quadtree::cleanup()
01401 {
01402
01403 for (int i = 0; i < 6; ++i)
01404 {
01405 if (root_nodes[i])
01406 {
01407 for (int j = 0; j < 4; ++j)
01408 {
01409 if (root_nodes[i]->children[j])
01410 {
01411 delete root_nodes[i]->children[j];
01412 root_nodes[i]->children[j] = 0;
01413 }
01414 }
01415 }
01416 }
01417
01418
01419 if (buffers)
01420 buffers->unload();
01421 }
01422
01423
01424
01425
01426 void spherical_quadtree::free_vertex_index(const vbuffer::index_t & index)
01427 {
01428 vbuffer::index_t & count = index_refcounts[index];
01429
01430 if (count == 0)
01431 throw internal_exception(__FILE__, __LINE__, L"Something wrong with index refcounts.");
01432
01433 if (--count == 0)
01434 {
01435 freed_vertex_indices.push(index);
01436 }
01437 }
01438
01439
01440 const vbuffer::index_t & spherical_quadtree::attach_vertex_index(const vbuffer::index_t & index)
01441 {
01442 index_refcounts[index]++;
01443 return index;
01444 }
01445
01446
01447 vbuffer::index_t spherical_quadtree::get_new_vertex_index()
01448 {
01449 vbuffer::index_t result = 0;
01450
01451 if (freed_vertex_indices.size())
01452 {
01453 result = freed_vertex_indices.top();
01454 freed_vertex_indices.pop();
01455 }
01456 else
01457 {
01458 result = global_vertices.size() / 3;
01459 }
01460
01461 global_vertices[result*3+0] = 0;
01462 global_vertices[result*3+1] = 0;
01463 global_vertices[result*3+2] = 0;
01464
01465 return result;
01466 }
01467
01468
01469
01470
01471 static vector vavg(const vector & a, const vector & b)
01472 {
01473 return (a + b) * 0.5;
01474 }
01475
01476
01477
01478 void spherical_quadtree::fill_in_normals(vector *n)
01479 {
01480
01481 n[0].normalize();
01482 n[2].normalize();
01483 n[4].normalize();
01484
01485 n[10].normalize();
01486 n[12].normalize();
01487 n[14].normalize();
01488
01489 n[20].normalize();
01490 n[22].normalize();
01491 n[24].normalize();
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 n[1] = vavg(n[0], n[2]);
01504 n[3] = vavg(n[2], n[4]);
01505
01506 n[5] = vavg(n[0], n[10]);
01507 n[6] = vavg(n[0], n[12]);
01508 n[7] = vavg(n[2], n[12]);
01509 n[8] = vavg(n[12], n[4]);
01510 n[9] = vavg(n[4], n[14]);
01511
01512 n[11] = vavg(n[10], n[12]);
01513 n[13] = vavg(n[12], n[14]);
01514
01515 n[15] = vavg(n[10], n[20]);
01516 n[16] = vavg(n[12], n[20]);
01517 n[17] = vavg(n[12], n[22]);
01518 n[18] = vavg(n[12], n[24]);
01519 n[19] = vavg(n[14], n[24]);
01520
01521 n[21] = vavg(n[20], n[22]);
01522 n[23] = vavg(n[22], n[24]);
01523
01524
01525 for (int i = 0; i < 25; ++i)
01526 n[i].normalize();
01527 }
01528
01529
01530 void spherical_quadtree::generate_vertices(sph_qt_node *quad, vector *normals, const bool *vertex_flags, vbuffer::index_t *quad_indices)
01531 {
01532 gsgl::real_t b_over_a = polar_radius / equatorial_radius;
01533
01534 for (int i = 0; i < 25; ++i)
01535 {
01536 gsgl::index_t index = quad_indices[i];
01537 attach_vertex_index(index);
01538
01539 if (!vertex_flags || !vertex_flags[i])
01540 {
01541
01542 global_normals[index*3+0] = normals[i].get_x();
01543 global_normals[index*3+1] = normals[i].get_y();
01544 global_normals[index*3+2] = normals[i].get_z();
01545
01546
01547 double normal_x = normals[i].get_x();
01548 double normal_y = normals[i].get_y();
01549 double normal_z = normals[i].get_z();
01550
01551 double geographic_longitude = ::atan2(normal_y, normal_x);
01552 double geographic_latitude = ::asin(normal_z);
01553
01554 global_polar_coords[index*2+0] = static_cast<vbuffer::real_t>(geographic_longitude / math::PI_TIMES_2);
01555 global_polar_coords[index*2+1] = static_cast<vbuffer::real_t>(0.5 + geographic_latitude / math::PI);
01556
01557
01558 double normal_base = ::sqrt(normal_x*normal_x + normal_y*normal_y);
01559 double geocentric_latitude = ::atan2(b_over_a*b_over_a*normal_z, normal_base);
01560
01561 double x = equatorial_radius * ::cos(geographic_longitude) * ::sin(math::PI_OVER_2 - geocentric_latitude);
01562 double y = equatorial_radius * ::sin(geographic_longitude) * ::sin(math::PI_OVER_2 - geocentric_latitude);
01563 double z = polar_radius * ::cos(math::PI_OVER_2 - geocentric_latitude);
01564
01565 global_vertices[index*3+0] = static_cast<vbuffer::real_t>(x);
01566 global_vertices[index*3+1] = static_cast<vbuffer::real_t>(y);
01567 global_vertices[index*3+2] = static_cast<vbuffer::real_t>(z);
01568 }
01569
01570 quad->vertex_indices[i] = index;
01571 }
01572 }
01573
01574
01575 void spherical_quadtree::init_root_nodes()
01576 {
01577
01578 vector geographic_normals[25];
01579
01580
01581 sph_qt_node *top_quad = root_nodes[0] = create_node(0);
01582
01583 geographic_normals[0] = vector(-1, 1, 1);
01584 geographic_normals[2] = vector( 0, 1, 1);
01585 geographic_normals[4] = vector( 1, 1, 1);
01586
01587 geographic_normals[10] = vector(-1, 0, 1);
01588 geographic_normals[12] = vector( 0, 0, 1);
01589 geographic_normals[14] = vector( 1, 0, 1);
01590
01591 geographic_normals[24] = vector( 1,-1, 1);
01592 geographic_normals[22] = vector( 0,-1, 1);
01593 geographic_normals[20] = vector(-1,-1, 1);
01594 fill_in_normals(geographic_normals);
01595
01596 static vbuffer::index_t top_indices[25] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
01597 generate_vertices(top_quad, geographic_normals, 0, top_indices);
01598
01599
01600 sph_qt_node *front_quad = root_nodes[1] = create_node(0);
01601
01602 geographic_normals[0] = vector(-1,-1, 1);
01603 geographic_normals[2] = vector( 0,-1, 1);
01604 geographic_normals[4] = vector( 1,-1, 1);
01605
01606 geographic_normals[10] = vector(-1,-1, 0);
01607 geographic_normals[12] = vector( 0,-1, 0);
01608 geographic_normals[14] = vector( 1,-1, 0);
01609
01610 geographic_normals[24] = vector( 1,-1,-1);
01611 geographic_normals[22] = vector( 0,-1,-1);
01612 geographic_normals[20] = vector(-1,-1,-1);
01613 fill_in_normals(geographic_normals);
01614
01615 static vbuffer::index_t front_indices[25] = { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 };
01616 generate_vertices(front_quad, geographic_normals, 0, front_indices);
01617
01618
01619 sph_qt_node *left_quad = root_nodes[2] = create_node(0);
01620
01621 geographic_normals[0] = vector(-1, 1, 1);
01622 geographic_normals[2] = vector(-1, 0, 1);
01623 geographic_normals[4] = vector(-1,-1, 1);
01624
01625 geographic_normals[10] = vector(-1, 1, 0);
01626 geographic_normals[12] = vector(-1, 0, 0);
01627 geographic_normals[14] = vector(-1,-1, 0);
01628
01629 geographic_normals[24] = vector(-1,-1,-1);
01630 geographic_normals[22] = vector(-1, 0,-1);
01631 geographic_normals[20] = vector(-1, 1,-1);
01632 fill_in_normals(geographic_normals);
01633
01634 static vbuffer::index_t left_indices[25] = { 0, 5, 10, 15, 20, 45, 46, 47, 48, 25, 49, 50, 51, 52, 30, 53, 54, 55, 56, 35, 57, 58, 59, 60, 40 };
01635 generate_vertices(left_quad, geographic_normals, 0, left_indices);
01636
01637
01638 sph_qt_node *right_quad = root_nodes[3] = create_node(0);
01639
01640 geographic_normals[0] = vector( 1,-1, 1);
01641 geographic_normals[2] = vector( 1, 0, 1);
01642 geographic_normals[4] = vector( 1, 1, 1);
01643
01644 geographic_normals[10] = vector( 1,-1, 0);
01645 geographic_normals[12] = vector( 1, 0, 0);
01646 geographic_normals[14] = vector( 1, 1, 0);
01647
01648 geographic_normals[24] = vector( 1, 1,-1);
01649 geographic_normals[22] = vector( 1, 0,-1);
01650 geographic_normals[20] = vector( 1,-1,-1);
01651 fill_in_normals(geographic_normals);
01652
01653 static vbuffer::index_t right_indices[25] = { 24, 19, 14, 9, 4, 29, 61, 62, 63, 64, 34, 65, 66, 67, 68, 39, 69, 70, 71, 72, 44, 73, 74, 75, 76 };
01654 generate_vertices(right_quad, geographic_normals, 0, right_indices);
01655
01656
01657 sph_qt_node *bottom_quad = root_nodes[4] = create_node(0);
01658
01659 geographic_normals[0] = vector(-1,-1,-1);
01660 geographic_normals[2] = vector( 0,-1,-1);
01661 geographic_normals[4] = vector( 1,-1,-1);
01662
01663 geographic_normals[10] = vector(-1, 0, -1);
01664 geographic_normals[12] = vector( 0, 0, -1);
01665 geographic_normals[14] = vector( 1, 0, -1);
01666
01667 geographic_normals[24] = vector( 1, 1,-1);
01668 geographic_normals[22] = vector( 0, 1,-1);
01669 geographic_normals[20] = vector(-1, 1,-1);
01670 fill_in_normals(geographic_normals);
01671
01672 static vbuffer::index_t bottom_indices[25] = { 40, 41, 42, 43, 44, 60, 77, 78, 79, 73, 59, 80, 81, 82, 74, 58, 83, 84, 85, 75, 57, 86, 87, 88, 76 };
01673 generate_vertices(bottom_quad, geographic_normals, 0, bottom_indices);
01674
01675
01676 sph_qt_node *back_quad = root_nodes[5] = create_node(0);
01677
01678 geographic_normals[0] = vector(-1, 1,-1);
01679 geographic_normals[2] = vector( 0, 1,-1);
01680 geographic_normals[4] = vector( 1, 1,-1);
01681
01682 geographic_normals[10] = vector(-1, 1, 0);
01683 geographic_normals[12] = vector( 0, 1, 0);
01684 geographic_normals[14] = vector( 1, 1, 0);
01685
01686 geographic_normals[24] = vector( 1, 1, 1);
01687 geographic_normals[22] = vector( 0, 1, 1);
01688 geographic_normals[20] = vector(-1, 1, 1);
01689 fill_in_normals(geographic_normals);
01690
01691 static vbuffer::index_t back_indices[25] = { 57, 86, 87, 88, 76, 53, 89, 90, 91, 72, 49, 92, 93, 94, 68, 45, 95, 96, 97, 64, 0, 1, 2, 3, 4 };
01692 generate_vertices(back_quad, geographic_normals, 0, back_indices);
01693
01694
01695 if (root_nodes[0])
01696 {
01697 add_leaf_node(root_nodes[0]);
01698
01699 root_nodes[0]->adjacent_nodes[0] = root_nodes[5];
01700 root_nodes[0]->adjacent_nodes[1] = root_nodes[3];
01701 root_nodes[0]->adjacent_nodes[2] = root_nodes[1];
01702 root_nodes[0]->adjacent_nodes[3] = root_nodes[2];
01703 }
01704
01705 if (root_nodes[1])
01706 {
01707 add_leaf_node(root_nodes[1]);
01708
01709 root_nodes[1]->adjacent_nodes[0] = root_nodes[0];
01710 root_nodes[1]->adjacent_nodes[1] = root_nodes[3];
01711 root_nodes[1]->adjacent_nodes[2] = root_nodes[4];
01712 root_nodes[1]->adjacent_nodes[3] = root_nodes[2];
01713 }
01714
01715 if (root_nodes[2])
01716 {
01717 add_leaf_node(root_nodes[2]);
01718
01719 root_nodes[2]->adjacent_nodes[0] = root_nodes[0];
01720 root_nodes[2]->adjacent_nodes[1] = root_nodes[1];
01721 root_nodes[2]->adjacent_nodes[2] = root_nodes[4];
01722 root_nodes[2]->adjacent_nodes[3] = root_nodes[5];
01723 }
01724
01725 if (root_nodes[3])
01726 {
01727 add_leaf_node(root_nodes[3]);
01728
01729 root_nodes[3]->adjacent_nodes[0] = root_nodes[0];
01730 root_nodes[3]->adjacent_nodes[1] = root_nodes[5];
01731 root_nodes[3]->adjacent_nodes[2] = root_nodes[4];
01732 root_nodes[3]->adjacent_nodes[3] = root_nodes[1];
01733 }
01734
01735 if (root_nodes[4])
01736 {
01737 add_leaf_node(root_nodes[4]);
01738
01739 root_nodes[4]->adjacent_nodes[0] = root_nodes[1];
01740 root_nodes[4]->adjacent_nodes[1] = root_nodes[3];
01741 root_nodes[4]->adjacent_nodes[2] = root_nodes[5];
01742 root_nodes[4]->adjacent_nodes[3] = root_nodes[2];
01743 }
01744
01745 if (root_nodes[5])
01746 {
01747 add_leaf_node(root_nodes[5]);
01748
01749 root_nodes[5]->adjacent_nodes[0] = root_nodes[4];
01750 root_nodes[5]->adjacent_nodes[1] = root_nodes[3];
01751 root_nodes[5]->adjacent_nodes[2] = root_nodes[0];
01752 root_nodes[5]->adjacent_nodes[3] = root_nodes[2];
01753 }
01754
01755
01756 #ifdef DEBUG
01757 for (int i = 0; i < 6; ++i)
01758 {
01759 if (root_nodes[i])
01760 root_nodes[i]->path = string::format(L"%d", i);
01761 }
01762 #endif
01763 }
01764
01765
01766 sph_qt_node *spherical_quadtree::create_node(sph_qt_node *parent)
01767 {
01768 return new sph_qt_node(this, parent);
01769 }
01770
01771
01772 }
01773
01774
01775 }