00001 #ifndef PERIAPSIS_SPACE_SPHERICAL_QUADTREE_H
00002 #define PERIAPSIS_SPACE_SPHERICAL_QUADTREE_H
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
00035
00036
00037 #include "space/space.hpp"
00038 #include "space/scenery_patch_set.hpp"
00039
00040 #include "data/stack.hpp"
00041 #include "platform/vbuffer.hpp"
00042 #include "platform/buffer_pool.hpp"
00043 #include "platform/shader.hpp"
00044
00045
00046 namespace gsgl
00047 {
00048 namespace scenegraph
00049 {
00050 class context;
00051 class node;
00052 }
00053 }
00054
00055
00056 namespace periapsis
00057 {
00058
00059 namespace space
00060 {
00061
00062
00063 class SPACE_API sph_qt_node
00064 {
00065 protected:
00066 friend class spherical_quadtree;
00067 spherical_quadtree *parent_quadtree;
00068
00069 int level;
00070 bool dirty;
00071
00072 sph_qt_node *parent_node;
00073 sph_qt_node *children[4];
00074 sph_qt_node *adjacent_nodes[4];
00075
00076 gsgl::index_t vertex_indices[25];
00077
00078 gsgl::platform::buffer_pool::object_record buffer_pool_rec;
00079 gsgl::data::simple_array<gsgl::index_t> triangle_fan_indices;
00080 int num_indices_in_quadrants[4];
00081
00082 gsgl::real_t radius_in_world_space;
00083 gsgl::real_t radius_in_screen_space;
00084 unsigned long last_radius_frame;
00085 unsigned long last_merge_frame;
00086 unsigned long last_split_frame;
00087
00088 gsgl::index_t pos_in_leaf_node_array;
00089 gsgl::index_t pos_in_merge_node_array;
00090
00091 #ifdef DEBUG
00092 gsgl::string path;
00093 #endif
00094
00095 public:
00096 sph_qt_node(spherical_quadtree *parent_quadtree, sph_qt_node *parent);
00097 virtual ~sph_qt_node();
00098
00099 virtual void draw(gsgl::scenegraph::context *c);
00100
00101 bool is_a_leaf() const;
00102
00103 private:
00104 void update_fan_indices();
00105 };
00106
00107
00108
00109
00110 class SPACE_API spherical_quadtree
00111 {
00112 friend class sph_qt_node;
00113
00114 protected:
00115 gsgl::scenegraph::node *parent_sg_node;
00116 gsgl::real_t polar_radius, equatorial_radius;
00117
00118 gsgl::data::simple_array<float> global_vertices;
00119 gsgl::data::simple_array<float> global_normals;
00120
00121
00122
00123 gsgl::data::simple_array<float> global_polar_coords;
00124
00125 gsgl::data::simple_array<gsgl::platform::vbuffer::index_t> index_refcounts;
00126 gsgl::data::simple_stack<gsgl::platform::vbuffer::index_t> freed_vertex_indices;
00127
00128 gsgl::platform::buffer_pool *buffers;
00129
00130 sph_qt_node *root_nodes[6];
00131
00132
00133 int last_frame_viewport[4];
00134 gsgl::math::transform last_frame_modelview_projection;
00135
00136 gsgl::math::vector eye_pos_in_object_space;
00137 typedef gsgl::data::pair<gsgl::data::simple_array<sph_qt_node *> *, gsgl::data::simple_stack<gsgl::index_t> *> node_level_rec;
00138
00139 gsgl::data::simple_array<node_level_rec *> leaf_nodes;
00140 gsgl::index_t num_leaf_nodes, last_num_leaf_nodes;
00141
00142 gsgl::data::simple_array<node_level_rec *> merge_nodes;
00143 gsgl::index_t num_merge_nodes, last_num_merge_nodes;
00144
00145 public:
00146 spherical_quadtree(gsgl::scenegraph::node *parent_sg_node, const gsgl::real_t & polar_radius, const gsgl::real_t & equatorial_radius);
00147 virtual ~spherical_quadtree();
00148
00149 gsgl::scenegraph::node *get_parent_sg_node() { return parent_sg_node; }
00150
00151 virtual void init(gsgl::scenegraph::context *c);
00152 virtual void draw(gsgl::scenegraph::context *c);
00153 virtual void update(gsgl::scenegraph::context *c, const bool not_visible);
00154 virtual void cleanup();
00155
00156 protected:
00157 virtual sph_qt_node *create_node(sph_qt_node *parent);
00158
00159 private:
00160 void add_leaf_node(sph_qt_node *qtn);
00161 void remove_leaf_node(sph_qt_node *qtn);
00162
00163 void add_merge_node(sph_qt_node *qtn);
00164 void remove_merge_node(sph_qt_node *qtn);
00165
00166 gsgl::real_t node_cos_angle(sph_qt_node *qtn, const gsgl::math::transform & modelview);
00167 gsgl::real_t node_radius(sph_qt_node *qtn, const gsgl::scenegraph::context *c);
00168 sph_qt_node *get_adjacent(sph_qt_node *candidate, const gsgl::platform::vbuffer::index_t & index0, const gsgl::platform::vbuffer::index_t & index1,
00169 sph_qt_node ***peer_handle, gsgl::platform::vbuffer::index_t *side0 = 0, gsgl::platform::vbuffer::index_t *side1 = 0);
00170
00171
00172 bool neighbor_allows_merge(sph_qt_node *qtn, sph_qt_node *adj);
00173 void merge_node_aux(sph_qt_node *qtn);
00174 bool merge_node(sph_qt_node *qtn, const gsgl::math::transform & modelview, const gsgl::scenegraph::context *c);
00175
00176 void split_node_aux(sph_qt_node *qtn, int force_level);
00177 bool split_node(sph_qt_node *qtn, const gsgl::math::transform & modelview, const gsgl::scenegraph::context *c, bool no_visual_check, int force_level);
00178
00179
00180 void init_root_nodes();
00181 void fill_in_normals(gsgl::math::vector *);
00182 void generate_vertices(sph_qt_node *quad, gsgl::math::vector *normals, const bool *vertex_flags, gsgl::platform::vbuffer::index_t *quad_indices);
00183
00184
00185 const gsgl::platform::vbuffer::index_t & attach_vertex_index(const gsgl::platform::vbuffer::index_t & index);
00186 gsgl::platform::vbuffer::index_t get_new_vertex_index();
00187 void free_vertex_index(const gsgl::platform::vbuffer::index_t & index);
00188 };
00189
00190
00191 }
00192
00193 }
00194
00195 #endif