Reorganize BMNG and SRTM into plugins
authorAndy Spencer <andy753421@gmail.com>
Fri, 30 Oct 2009 04:58:08 +0000 (04:58 +0000)
committerAndy Spencer <andy753421@gmail.com>
Fri, 30 Oct 2009 04:58:08 +0000 (04:58 +0000)
- Create dummy plugins in src/plugins for bmng and srtm.
- Optimize Roam code:
  - Fewer height and projection updates
  - Cache triangle l-r midpoints and share them with children
- Also remove a lot of trailing whitespace

32 files changed:
.gitignore
TODO
configure.ac
docs/api/Makefile.am
examples/plugin/teapot.c
examples/plugin/teapot.h
src/Makefile.am
src/gis-data.c
src/gis-data.h
src/gis-opengl.c
src/gis-opengl.h
src/gis-plugin.c
src/gis-plugin.h
src/gis-prefs.c
src/gis-prefs.h
src/gis-view.c
src/gis-view.h
src/gis-world.c
src/gis-world.h
src/gis.h
src/gis_test.c
src/gpqueue.c
src/gpqueue.h
src/plugins/Makefile.am [new file with mode: 0644]
src/plugins/bmng.c [new file with mode: 0644]
src/plugins/bmng.h [new file with mode: 0644]
src/plugins/srtm.c [new file with mode: 0644]
src/plugins/srtm.h [new file with mode: 0644]
src/roam.c
src/roam.h
src/wms.c
src/wms.h

index ccbb51d..3c8d2e7 100644 (file)
@@ -1,6 +1,7 @@
 *.bz2
 *.gz
 *~
+.*.swp
 Makefile
 Makefile.in
 aclocal.m4
diff --git a/TODO b/TODO
index 93116d3..b1a167e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,3 +5,42 @@ Road plan
   DisplayLists/
   glInterleavedArrays
 * States/cities/roads overlays
+
+Roam update
+-----------
+
+  x # Gis:
+  x gis_update_tiles(tiles);
+  x   for (tile in tiles)
+  x     if (need_split(tiles))
+  x       tiles << split(tile)
+  x gis_render_surface(Image *img)
+  x   polys = roam_get_intersecting_polies(img)
+  x   for (poly in plies)
+  x     render(img, poly)
+
+    # Roam:
+    on_view_change:
+      roam_update_errors(roam)
+    on_timeout:
+      split_merge:
+        if (height_func())
+           vertex_heght = roam->height_func()
+        else
+           vertex_heght = 0
+
+  x # GisPluginSrtm:
+  x on_view_change:
+  x   roam->height_func = srtm_height_func
+  x   gis_update_tiles(tiles)
+  x   for (new_tiles in tiles)
+  x     points = roam_get_intersecting_points(tile)
+  x     for (poly in plies)
+  x       render(img, poly)
+
+  x # GisPluginBmng:
+  x on_view_change:
+  x   gis_update_tiles(tiles)
+  x on_render:
+  x   for tile in tiles:
+  x     gis_render_surface(gis, tile)
index a11226e..d3b9360 100644 (file)
@@ -20,6 +20,7 @@ PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.26)
 AC_CONFIG_FILES([
        Makefile
        src/Makefile
+       src/plugins/Makefile
        src/libgis.pc
        docs/Makefile
        docs/api/Makefile
index 89d9401..57a416d 100644 (file)
@@ -1,11 +1,13 @@
 AM_CPPFLAGS=$(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
-GTKDOC_LIBS=$(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/src/libgis.la
-IGNORE_HFILES= 
-DOC_MODULE=libgis
-DOC_SOURCE_DIR=$(top_srcdir)/src/
-DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
-MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+GTKDOC_LIBS        = $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/src/libgis.la
+DOC_MODULE         = libgis
+DOC_SOURCE_DIR     = $(top_srcdir)/src/
+DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.sgml
+MKDB_OPTIONS       = --sgml-mode --output-format=xml
 include $(top_srcdir)/gtk-doc.make
+
 CLEANFILES += libgis-sections.txt
+
 MAINTAINERCLEANFILES=\
        tmpl/* Makefile.in libgis-docs.sgml libgis-overrides.txt libgis.types libgis-scan.*
index fd551cc..9ecfd88 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 5008e04..1baf358 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index ff7181c..97ec6ba 100644 (file)
@@ -1,3 +1,5 @@
+SUBDIRS = plugins
+
 AM_CFLAGS   = -Wall --std=gnu99 
 AM_CPPFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(SOUP_CFLAGS)
 AM_LDADD    = $(GLIB_LIBS) $(GTK_LIBS) $(SOUP_LIBS)
@@ -56,10 +58,10 @@ test: all
        ./gis_test
 
 gdb: all
-       LD_LIBRARY_PATH=.libs gdb .libs/gis_test
+       gdb ./gis_test
 
 ddd: all
-       LD_LIBRARY_PATH=.libs ddd .libs/gis_test
+       ddd ./gis_test
 
 memcheck: all
        LD_LIBRARY_PATH=.libs                      \
index 56c39b4..8c88c22 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 5fe9067..7deb4e6 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 78491b8..f0ac518 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -34,7 +34,7 @@
 #define FOV_DIST   2000.0
 #define MPPX(dist) (4*dist/FOV_DIST)
 
-// #define ROAM_DEBUG
+//#define ROAM_DEBUG
 
 /*************
  * ROAM Code *
@@ -44,191 +44,6 @@ void roam_queue_draw(WmsCacheNode *node, gpointer _self)
        gtk_widget_queue_draw(GTK_WIDGET(_self));
 }
 
-void roam_height_func(RoamPoint *point, gpointer _self)
-{
-       GisOpenGL *self = _self;
-
-       gdouble lat, lon, elev;
-       xyz2lle(point->x, point->y, point->z, &lat, &lon, &elev);
-
-#ifdef ROAM_DEBUG
-       lle2xyz(lat, lon, 0, &point->x, &point->y, &point->z);
-       return;
-#endif
-
-       gdouble cam_lle[3], cam_xyz[3];
-       gis_view_get_location(self->view, &cam_lle[0], &cam_lle[1], &cam_lle[2]);
-       lle2xyz(cam_lle[0], cam_lle[1], cam_lle[2], &cam_xyz[0], &cam_xyz[1], &cam_xyz[2]);
-
-       gdouble res = MPPX(distd(cam_xyz, (double*)point));
-       //g_message("lat=%f, lon=%f, res=%f", lat, lon, res);
-
-       point->node = wms_info_fetch_cache(self->srtm, point->node,
-                       res, lat, lon, NULL, roam_queue_draw, self);
-
-       if (point->node) {
-               WmsBil *bil = point->node->data;
-
-               gint w = bil->width;
-               gint h = bil->height;
-
-               gdouble xmin  = point->node->latlon[0];
-               gdouble ymin  = point->node->latlon[1];
-               gdouble xmax  = point->node->latlon[2];
-               gdouble ymax  = point->node->latlon[3];
-
-               gdouble xdist = xmax - xmin;
-               gdouble ydist = ymax - ymin;
-
-               gdouble x =    (lon-xmin)/xdist  * w;
-               gdouble y = (1-(lat-ymin)/ydist) * h;
-
-               gdouble x_rem = x - (int)x;
-               gdouble y_rem = y - (int)y;
-               guint x_flr = (int)x;
-               guint y_flr = (int)y;
-
-               /* TODO: Fix interpolation at edges:
-                *   - Pad these at the edges instead of wrapping/truncating
-                *   - Figure out which pixels to index (is 0,0 edge, center, etc) */
-               gint16 px00 = bil->data[MIN((y_flr  ),h-1)*w + MIN((x_flr  ),w-1)];
-                gint16 px10 = bil->data[MIN((y_flr  ),h-1)*w + MIN((x_flr+1),w-1)];
-                gint16 px01 = bil->data[MIN((y_flr+1),h-1)*w + MIN((x_flr  ),w-1)];
-                gint16 px11 = bil->data[MIN((y_flr+1),h-1)*w + MIN((x_flr+1),w-1)];
-
-               elev =  px00 * (1-x_rem) * (1-y_rem) +
-                       px10 * (  x_rem) * (1-y_rem) +
-                       px01 * (1-x_rem) * (  y_rem) +
-                       px11 * (  x_rem) * (  y_rem);
-               //g_message("elev=%f -- %hd %hd %hd %hd",
-               //      elev, px00, px10, px01, px11);
-       } else {
-               elev = 0;
-       }
-
-       lle2xyz(lat, lon, elev, &point->x, &point->y, &point->z);
-}
-
-void roam_tri_func(RoamTriangle *tri, gpointer _self)
-{
-#ifdef ROAM_DEBUG
-       glBegin(GL_TRIANGLES);
-       glNormal3dv(tri->p.r->norm); glVertex3dv((double*)tri->p.r); 
-       glNormal3dv(tri->p.m->norm); glVertex3dv((double*)tri->p.m); 
-       glNormal3dv(tri->p.l->norm); glVertex3dv((double*)tri->p.l); 
-       glEnd();
-       return;
-#endif
-
-       GisOpenGL *self = _self;
-       if (tri->error < 0) return;
-
-       /* Get lat-lon min and maxes for the triangle */
-       gdouble lat[3], lon[3], elev[3];
-       xyz2lle(tri->p.r->x, tri->p.r->y, tri->p.r->z, &lat[0], &lon[0], &elev[0]);
-       xyz2lle(tri->p.m->x, tri->p.m->y, tri->p.m->z, &lat[1], &lon[1], &elev[1]);
-       xyz2lle(tri->p.l->x, tri->p.l->y, tri->p.l->z, &lat[2], &lon[2], &elev[2]);
-       gdouble lat_max = MAX(MAX(lat[0], lat[1]), lat[2]);
-       gdouble lat_min = MIN(MIN(lat[0], lat[1]), lat[2]);
-       gdouble lat_avg = (lat_min+lat_max)/2;
-       gdouble lon_max = MAX(MAX(lon[0], lon[1]), lon[2]);
-       gdouble lon_min = MIN(MIN(lon[0], lon[1]), lon[2]);
-       gdouble lon_avg = (lon_min+lon_max)/2;
-
-       /* Get target resolution */
-       gdouble cam_lle[3], cam_xyz[3];
-       gis_view_get_location(self->view, &cam_lle[0], &cam_lle[1], &cam_lle[2]);
-       lle2xyz(cam_lle[0], cam_lle[1], cam_lle[2], &cam_xyz[0], &cam_xyz[1], &cam_xyz[2]);
-       gdouble distr = distd(cam_xyz, (double*)tri->p.r);
-       gdouble distm = distd(cam_xyz, (double*)tri->p.m);
-       gdouble distl = distd(cam_xyz, (double*)tri->p.l);
-       double res = MPPX(MIN(MIN(distr, distm), distl));
-
-       /* TODO: 
-        *   - Fetch needed textures, not all corners
-        *   - Also fetch center textures that aren't touched by a corner
-        *   - Idea: send {lat,lon}{min,max} to fetch_cache and handle it in the recursion */
-       /* Fetch textures */
-       tri->nodes[0] = wms_info_fetch_cache(self->bmng, tri->nodes[0], res, lat_min, lon_min, NULL, roam_queue_draw, self);
-       tri->nodes[1] = wms_info_fetch_cache(self->bmng, tri->nodes[1], res, lat_max, lon_min, NULL, roam_queue_draw, self);
-       tri->nodes[2] = wms_info_fetch_cache(self->bmng, tri->nodes[2], res, lat_min, lon_max, NULL, roam_queue_draw, self);
-       tri->nodes[3] = wms_info_fetch_cache(self->bmng, tri->nodes[3], res, lat_max, lon_max, NULL, roam_queue_draw, self);
-       tri->nodes[4] = wms_info_fetch_cache(self->bmng, tri->nodes[4], res, lat_avg, lon_avg, NULL, roam_queue_draw, self);
-       /* Hopefully get all textures at the same resolution to prevent overlaps */
-       //gdouble maxres = 0;
-       //for (int i = 0; i < 5; i++)
-       //      if (tri->nodes[i] && tri->nodes[i]->res > maxres)
-       //              maxres = tri->nodes[i]->res;
-       //if (maxres != 0) {
-       //      tri->nodes[0] = wms_info_fetch_cache(self->bmng, tri->nodes[0], maxres, lat_min, lon_min, NULL, roam_queue_draw, self);
-       //      tri->nodes[1] = wms_info_fetch_cache(self->bmng, tri->nodes[1], maxres, lat_max, lon_min, NULL, roam_queue_draw, self);
-       //      tri->nodes[2] = wms_info_fetch_cache(self->bmng, tri->nodes[2], maxres, lat_min, lon_max, NULL, roam_queue_draw, self);
-       //      tri->nodes[3] = wms_info_fetch_cache(self->bmng, tri->nodes[3], maxres, lat_max, lon_max, NULL, roam_queue_draw, self);
-       //      tri->nodes[4] = wms_info_fetch_cache(self->bmng, tri->nodes[4], maxres, lat_avg, lon_avg, NULL, roam_queue_draw, self);
-       //}
-
-       /* Vertex color for hieght map viewing, 8848m == Everest */
-       gfloat colors[] = {
-               (elev[0]-EARTH_R)/8848,
-               (elev[1]-EARTH_R)/8848,
-               (elev[2]-EARTH_R)/8848,
-       };
-
-       /* Draw each texture */
-       /* TODO: Prevent double exposure when of hi-res textures on top of
-        * low-res textures when some high-res textures are not yet loaded. */
-       glBlendFunc(GL_ONE, GL_ZERO);
-       for (int i = 0; i < 5; i++) {
-               /* Skip missing textures */
-               if (tri->nodes[i] == NULL)
-                       continue;
-               /* Skip already drawn textures */
-               switch (i) {
-               case 4: if (tri->nodes[i] == tri->nodes[3]) continue;
-               case 3: if (tri->nodes[i] == tri->nodes[2]) continue;
-               case 2: if (tri->nodes[i] == tri->nodes[1]) continue;
-               case 1: if (tri->nodes[i] == tri->nodes[0]) continue;
-               }
-
-               WmsCacheNode *node = tri->nodes[i];
-
-               if (node->latlon[0] == -180) {
-                       if (lon[0] < -90 || lon[1] < -90 || lon[2] < -90) {
-                               if (lon[0] > 90) lon[0] -= 360;
-                               if (lon[1] > 90) lon[1] -= 360;
-                               if (lon[2] > 90) lon[2] -= 360;
-                       }
-               } else if (node->latlon[2] == 180.0) {
-                       if (lon[0] < -90) lon[0] += 360;
-                       if (lon[1] < -90) lon[1] += 360;
-                       if (lon[2] < -90) lon[2] += 360;
-               }
-
-               gdouble xmin  = node->latlon[0];
-               gdouble ymin  = node->latlon[1];
-               gdouble xmax  = node->latlon[2];
-               gdouble ymax  = node->latlon[3];
-
-               gdouble xdist = xmax - xmin;
-               gdouble ydist = ymax - ymin;
-
-               gdouble xy[][3] = {
-                       {(lon[0]-xmin)/xdist, 1-(lat[0]-ymin)/ydist},
-                       {(lon[1]-xmin)/xdist, 1-(lat[1]-ymin)/ydist},
-                       {(lon[2]-xmin)/xdist, 1-(lat[2]-ymin)/ydist},
-               };
-
-               glBindTexture(GL_TEXTURE_2D, *(guint*)node->data);
-
-               glBegin(GL_TRIANGLES);
-               glColor3fv(colors); glNormal3dv(tri->p.r->norm); glTexCoord2dv(xy[0]); glVertex3dv((double*)tri->p.r); 
-               glColor3fv(colors); glNormal3dv(tri->p.m->norm); glTexCoord2dv(xy[1]); glVertex3dv((double*)tri->p.m); 
-               glColor3fv(colors); glNormal3dv(tri->p.l->norm); glTexCoord2dv(xy[2]); glVertex3dv((double*)tri->p.l); 
-               glEnd();
-               glBlendFunc(GL_ONE, GL_ONE);
-       }
-}
-
 static void set_camera(GisOpenGL *self)
 {
        glMatrixMode(GL_MODELVIEW);
@@ -310,6 +125,7 @@ static void set_visuals(GisOpenGL *self)
 static void on_realize(GisOpenGL *self, gpointer _)
 {
        set_visuals(self);
+       roam_sphere_update_errors(self->sphere);
 }
 static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer _)
 {
@@ -326,7 +142,7 @@ static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer
        gluPerspective(rad2deg(ang)*2, width/height, 1, 20*EARTH_R);
 
 #ifndef ROAM_DEBUG
-       roam_sphere_update(self->sphere);
+       roam_sphere_update_errors(self->sphere);
 #endif
 
        gis_opengl_end(self);
@@ -352,21 +168,17 @@ static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _)
 #ifndef ROAM_DEBUG
        set_visuals(self);
        glEnable(GL_TEXTURE_2D);
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        roam_sphere_draw(self->sphere);
-#endif
-
-#ifdef  ROAM_DEBUG
+#else
        set_visuals(self);
        glColor4f(0.0, 0.0, 9.0, 0.6);
        glDisable(GL_TEXTURE_2D);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        roam_sphere_draw(self->sphere);
-#endif
 
-       //glDisable(GL_TEXTURE_2D);
-       //glEnable(GL_COLOR_MATERIAL);
-       //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-       //roam_sphere_draw(self->sphere);
+       //roam_sphere_draw_normals(self->sphere);
+#endif
 
        gis_plugins_foreach(self->plugins, G_CALLBACK(on_expose_plugin), self);
 
@@ -409,7 +221,7 @@ static gboolean on_key_press(GisOpenGL *self, GdkEventKey *event, gpointer _)
        else if (kv == GDK_n) roam_sphere_split_one(self->sphere);
        else if (kv == GDK_p) roam_sphere_merge_one(self->sphere);
        else if (kv == GDK_r) roam_sphere_split_merge(self->sphere);
-       else if (kv == GDK_u) roam_sphere_update(self->sphere);
+       else if (kv == GDK_u) roam_sphere_update_errors(self->sphere);
        gtk_widget_queue_draw(GTK_WIDGET(self));
 #endif
 
@@ -422,7 +234,7 @@ static void on_view_changed(GisView *view,
        gis_opengl_begin(self);
        set_visuals(self);
 #ifndef ROAM_DEBUG
-       roam_sphere_update(self->sphere);
+       roam_sphere_update_errors(self->sphere);
 #endif
        gis_opengl_redraw(self);
        gis_opengl_end(self);
@@ -455,7 +267,7 @@ GisOpenGL *gis_opengl_new(GisWorld *world, GisView *view, GisPlugins *plugins)
        g_signal_connect(self->view, "rotation-changed", G_CALLBACK(on_view_changed), self);
 
        /* TODO: update point eights sometime later so we have heigh-res heights for them */
-       self->sphere = roam_sphere_new(roam_tri_func, roam_height_func, self);
+       self->sphere = roam_sphere_new(self);
 
        return g_object_ref(self);
 }
index fcaaa0e..069456f 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index c874095..2ba5ca6 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -99,6 +99,7 @@ GList *gis_plugins_available(GisPlugins *self)
        g_debug("GisPlugins: available");
        GList *list = NULL;
        gchar *dirs[] = {self->dir, PLUGINSDIR};
+       g_debug("pluginsdir=%s", PLUGINSDIR);
        for (int i = 0; i<2; i++) {
                GDir *dir = g_dir_open(dirs[i], 0, NULL);
                if (dir == NULL)
index 6390f47..7fd75a7 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 4a1ee0d..02d456d 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index ac9cde6..bbd720b 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 0caf3f0..a2bc30f 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -40,14 +40,14 @@ static guint signals[NUM_SIGNALS];
 /* Signal helpers */
 static void _gis_view_emit_location_changed(GisView *view)
 {
-       g_signal_emit(view, signals[SIG_LOCATION_CHANGED], 0, 
+       g_signal_emit(view, signals[SIG_LOCATION_CHANGED], 0,
                        view->location[0],
                        view->location[1],
                        view->location[2]);
 }
 static void _gis_view_emit_rotation_changed(GisView *view)
 {
-       g_signal_emit(view, signals[SIG_ROTATION_CHANGED], 0, 
+       g_signal_emit(view, signals[SIG_ROTATION_CHANGED], 0,
                        view->rotation[0],
                        view->rotation[1],
                        view->rotation[2]);
@@ -238,13 +238,13 @@ static void gis_view_class_init(GisViewClass *klass)
                g_param_spec_pointer(
                        "time",
                        "time of the current frame",
-                       "(format unknown)", 
+                       "(format unknown)",
                        G_PARAM_READWRITE));
        g_object_class_install_property(gobject_class, PROP_SITE,
                g_param_spec_pointer(
                        "site",
                        "site seen by the viewport",
-                       "Site of the viewport. Currently this is the name of the radar site.", 
+                       "Site of the viewport. Currently this is the name of the radar site.",
                        G_PARAM_READWRITE));
        signals[SIG_TIME_CHANGED] = g_signal_new(
                        "time-changed",
index 3eb57ad..ec84b84 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index b8611ab..6e9beaa 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index 78ca130..7994df2 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -36,7 +36,7 @@
  * px     - Pixels, for screen-based distances
  *
  * height - Height, the distance above the geoid (ground)
- * elev   - Elevation, the distance above the spheroid 
+ * elev   - Elevation, the distance above the spheroid
  * rad    - Radius, the distance from the center of the earth
  *
  * lat    - Latitude, amount north-south, -90 (S) .. 90 (N)
@@ -60,8 +60,8 @@
  * lle2xyz:    0.0,   0.0,   0.0 ->    0.0,   0.0,  10.0
  * lle2xyz:   90.0,   0.0,   0.0 ->    0.0,  10.0,   0.0
  * lle2xyz:    0.0,  90.0,   0.0 ->   10.0,   0.0,   0.0
- * 
- *               x      y      z ->    lat    lon   elev 
+ *
+ *               x      y      z ->    lat    lon   elev
  * xyz2lle:   10.0,   0.0,   0.0 ->    0.0,  90.0,   0.0
  * xyz2lle:    0.0,  10.0,   0.0 ->   90.0,   0.0,   0.0
  * xyz2lle:    0.0,   0.0,  10.0 ->    0.0,   0.0,   0.0
index 772c239..365c843 100644 (file)
--- a/src/gis.h
+++ b/src/gis.h
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
index d587936..054373e 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -52,7 +52,8 @@ int main(int argc, char **argv)
 
        //gis_plugins_load(plugins, "radar",   world, view, opengl, prefs);
        //gis_plugins_load(plugins, "ridge",   world, view, opengl, prefs);
-       //gis_plugins_load(plugins, "example", world, view, opengl, prefs);
+       gis_plugins_load(plugins, "bmng", world, view, opengl, prefs);
+       gis_plugins_load(plugins, "srtm", world, view, opengl, prefs);
 
        GtkWidget  *window  = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect(window,  "destroy",         G_CALLBACK(gtk_main_quit), NULL);
index 5989987..0e408c5 100644 (file)
@@ -5,7 +5,7 @@
  * SECTION:priority_queues
  * @short_description: a collection of data entries with associated priority
  * values that returns entries one by one in order of priority
- * 
+ *
  * <para>
  * The #GPQueue structure and its associated functions provide a sorted
  * collection of objects. Entries can be inserted in any order and at any time,
@@ -58,11 +58,11 @@ struct _GPQueue {
  *   they are equal, a negative value if the first comes before the second, and
  *   a positive value if the second comes before the first.
  * @compare_userdata: user data passed to @compare_func
- * 
+ *
  * Creates a new #GPQueue.
- * 
+ *
  * Returns: a new #GPQueue.
- * 
+ *
  * Since: 2.x
  **/
 GPQueue*
@@ -81,11 +81,11 @@ g_pqueue_new (GCompareDataFunc compare_func,
 /**
  * g_pqueue_is_empty:
  * @pqueue: a #GPQueue.
- * 
+ *
  * Returns %TRUE if the queue is empty.
- * 
+ *
  * Returns: %TRUE if the queue is empty.
- * 
+ *
  * Since: 2.x
  **/
 gboolean
@@ -114,7 +114,7 @@ g_pqueue_node_foreach (GPQueueNode *node,
  * @user_data: user data to pass to func
  *
  * Calls func for each element in the pqueue passing user_data to the function.
- * 
+ *
  * Since: 2.x
  */
 void
@@ -138,7 +138,7 @@ g_pqueue_add_ptr_cb (gpointer obj, GPtrArray *ptrs)
  * updating the priorities of all the elements in pqueue.
  *
  * Returns: A GPtrArray containing a pointer to each item in pqueue
- * 
+ *
  * Since: 2.x
  */
 GPtrArray *
@@ -196,18 +196,18 @@ g_pqueue_node_insert_after (GPQueueNode *dest,
  * g_pqueue_push:
  * @pqueue: a #GPQueue.
  * @data: the object to insert into the priority queue.
- * 
+ *
  * Inserts a new entry into a #GPQueue.
- * 
+ *
  * The returned handle can be used in calls to g_pqueue_remove() and
  * g_pqueue_priority_changed(). Never make such calls for entries that have
  * already been removed from the queue. The same @data can be inserted into
  * a #GPQueue more than once, but remember that in this case,
  * g_pqueue_priority_changed() needs to be called for
  * <emphasis>every</emphasis> handle for that object if its priority changes.
- * 
+ *
  * Returns: a handle for the freshly inserted entry.
- * 
+ *
  * Since: 2.x
  **/
 GPQueueHandle
@@ -239,15 +239,15 @@ g_pqueue_push (GPQueue *pqueue,
 /**
  * g_pqueue_peek:
  * @pqueue: a #GPQueue.
- * 
+ *
  * Returns the topmost entry's data pointer, or %NULL if the queue is empty.
- * 
+ *
  * If you need to tell the difference between an empty queue and a queue
  * that happens to have a %NULL pointer at the top, check if the queue is
  * empty first.
- * 
+ *
  * Returns: the topmost entry's data pointer, or %NULL if the queue is empty.
- * 
+ *
  * Since: 2.x
  **/
 gpointer
@@ -382,17 +382,17 @@ g_pqueue_remove_root (GPQueue *pqueue,
 /**
  * g_pqueue_pop:
  * @pqueue: a #GPQueue.
- * 
+ *
  * Removes the topmost entry from a #GPQueue and returns its data pointer.
  * Calling this on an empty #GPQueue is not an error, but removes nothing
  * and returns %NULL.
- * 
+ *
  * If you need to tell the difference between an empty queue and a queue
  * that happens to have a %NULL pointer at the top, check if the queue is
  * empty first.
- * 
+ *
  * Returns: the topmost entry's data pointer, or %NULL if the queue was empty.
- * 
+ *
  * Since: 2.x
  **/
 gpointer
@@ -468,13 +468,13 @@ g_pqueue_cut_tree (GPQueue *pqueue,
  * g_pqueue_remove:
  * @pqueue: a #GPQueue.
  * @entry: a #GPQueueHandle for an entry in @pqueue.
- * 
+ *
  * Removes one entry from a #GPQueue.
- * 
+ *
  * Make sure that @entry refers to an entry that is actually part of
  * @pqueue at the time, otherwise the behavior of this function is
  * undefined (expect crashes).
- * 
+ *
  * Since: 2.x
  **/
 void
@@ -489,18 +489,18 @@ g_pqueue_remove (GPQueue* pqueue,
  * g_pqueue_priority_changed:
  * @pqueue: a #GPQueue.
  * @entry: a #GPQueueHandle for an entry in @pqueue.
- * 
+ *
  * Notifies the #GPQueue that the priority of one entry has changed.
  * The internal representation is updated accordingly.
- * 
+ *
  * Make sure that @entry refers to an entry that is actually part of
  * @pqueue at the time, otherwise the behavior of this function is
  * undefined (expect crashes).
- * 
+ *
  * Do not attempt to change the priorities of several entries at once.
  * Every time a single object is changed, the #GPQueue needs to be updated
  * by calling g_pqueue_priority_changed() for that object.
- * 
+ *
  * Since: 2.x
  **/
 void
@@ -522,14 +522,14 @@ g_pqueue_priority_changed (GPQueue* pqueue,
  * g_pqueue_priority_decreased:
  * @pqueue: a #GPQueue.
  * @entry: a #GPQueueHandle for an entry in @pqueue.
- * 
+ *
  * Notifies the #GPQueue that the priority of one entry has
  * <emphasis>decreased</emphasis>.
- * 
+ *
  * This is a special case of g_pqueue_priority_changed(). If you are absolutely
  * sure that the new priority of @entry is lower than it was before, you
  * may call this function instead of g_pqueue_priority_changed().
- * 
+ *
  * <note>
  *   <para>
  *     In the current implementation, an expensive step in
@@ -539,7 +539,7 @@ g_pqueue_priority_changed (GPQueue* pqueue,
  *     is undefined.
  *   </para>
  * </note>
- * 
+ *
  * Since: 2.x
  **/
 void
@@ -562,9 +562,9 @@ g_pqueue_node_free_all (GPQueueNode *node)
 /**
  * g_pqueue_clear:
  * @pqueue: a #GPQueue.
- * 
+ *
  * Removes all entries from a @pqueue.
- * 
+ *
  * Since: 2.x
  **/
 void
@@ -577,10 +577,10 @@ g_pqueue_clear (GPQueue* pqueue)
 /**
  * g_pqueue_free:
  * @pqueue: a #GPQueue.
- * 
+ *
  * Deallocates the memory used by @pqueue itself, but not any memory pointed
  * to by the data pointers of its entries.
- * 
+ *
  * Since: 2.x
  **/
 void
index 3cadf18..b938b9c 100644 (file)
@@ -11,18 +11,18 @@ typedef struct _GPQueueNode GPQueueNode;
 
 /**
  * GPQueue:
- * 
+ *
  * An opaque structure representing a priority queue.
- * 
+ *
  * Since: 2.x
  **/
 typedef struct _GPQueue GPQueue;
 
 /**
  * GPQueueHandle:
- * 
+ *
  * An opaque value representing one entry in a #GPQueue.
- * 
+ *
  * Since: 2.x
  **/
 typedef GPQueueNode* GPQueueHandle;
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
new file mode 100644 (file)
index 0000000..4f59779
--- /dev/null
@@ -0,0 +1,18 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CFLAGS       = -Wall --std=gnu99  -I../
+AM_CPPFLAGS     = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(SOUP_CFLAGS)
+AM_LDFLAGS      = -module -avoid-version
+LIBS            = $(top_srcdir)/src/libgis.la
+
+pluginsdir  = $(pkglibdir)
+
+plugins_LTLIBRARIES  = bmng.la srtm.la
+bmng_la_SOURCES      = bmng.c bmng.h
+srtm_la_SOURCES      = srtm.c srtm.h
+
+# Fixme...
+bmng_la_DEPENDENCIES = $(top_srcdir)/src/libgis.la
+srtm_la_DEPENDENCIES = $(top_srcdir)/src/libgis.la
+$(top_srcdir)/src/libgis.la:
+       ( cd ../; make libgis.la )
diff --git a/src/plugins/bmng.c b/src/plugins/bmng.c
new file mode 100644 (file)
index 0000000..bc61d06
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
+
+#include <gis.h>
+
+#include "bmng.h"
+
+/***********
+ * Helpers *
+ ***********/
+static gboolean rotate(gpointer _self)
+{
+       GisPluginBmng *self = _self;
+       if (gtk_toggle_button_get_active(self->button)) {
+               self->rotation += 1.0;
+               gis_opengl_redraw(self->opengl);
+       }
+       return TRUE;
+}
+
+
+/***********
+ * Methods *
+ ***********/
+GisPluginBmng *gis_plugin_bmng_new(GisWorld *world, GisView *view, GisOpenGL *opengl)
+{
+       g_debug("GisPluginBmng: new");
+       GisPluginBmng *self = g_object_new(GIS_TYPE_PLUGIN_BMNG, NULL);
+       self->opengl = opengl;
+
+       return self;
+}
+
+static GtkWidget *gis_plugin_bmng_get_config(GisPlugin *_self)
+{
+       GisPluginBmng *self = GIS_PLUGIN_BMNG(_self);
+       return GTK_WIDGET(self->button);
+}
+
+static void gis_plugin_bmng_expose(GisPlugin *_self)
+{
+       GisPluginBmng *self = GIS_PLUGIN_BMNG(_self);
+       g_debug("GisPluginBmng: expose");
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(1,-1, -1,1, -10,10);
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       float light_ambient[]  = {0.1f, 0.1f, 0.0f, 1.0f};
+       float light_diffuse[]  = {0.9f, 0.9f, 0.9f, 1.0f};
+       float light_position[] = {-30.0f, 50.0f, 40.0f, 1.0f};
+       glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
+       glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
+       glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+       glEnable(GL_COLOR_MATERIAL);
+
+       glTranslatef(-0.5, -0.5, -2);
+       glRotatef(self->rotation, 1, 1, 0);
+       glColor4f(0.9, 0.9, 0.7, 1.0);
+       glDisable(GL_CULL_FACE);
+       gdk_gl_draw_teapot(TRUE, 0.25);
+}
+
+
+/****************
+ * GObject code *
+ ****************/
+/* Plugin init */
+static void gis_plugin_bmng_plugin_init(GisPluginInterface *iface);
+G_DEFINE_TYPE_WITH_CODE(GisPluginBmng, gis_plugin_bmng, G_TYPE_OBJECT,
+               G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN,
+                       gis_plugin_bmng_plugin_init));
+static void gis_plugin_bmng_plugin_init(GisPluginInterface *iface)
+{
+       g_debug("GisPluginBmng: plugin_init");
+       /* Add methods to the interface */
+       iface->expose     = gis_plugin_bmng_expose;
+       iface->get_config = gis_plugin_bmng_get_config;
+}
+/* Class/Object init */
+static void gis_plugin_bmng_init(GisPluginBmng *self)
+{
+       g_debug("GisPluginBmng: init");
+       /* Set defaults */
+       self->button    = GTK_TOGGLE_BUTTON(gtk_toggle_button_new_with_label("Rotate"));
+       self->rotate_id = g_timeout_add(1000/60, rotate, self);
+       self->rotation  = 30.0;
+       self->opengl    = NULL;
+}
+static void gis_plugin_bmng_dispose(GObject *gobject)
+{
+       g_debug("GisPluginBmng: dispose");
+       GisPluginBmng *self = GIS_PLUGIN_BMNG(gobject);
+       g_source_remove(self->rotate_id);
+       /* Drop references */
+       G_OBJECT_CLASS(gis_plugin_bmng_parent_class)->dispose(gobject);
+}
+static void gis_plugin_bmng_finalize(GObject *gobject)
+{
+       g_debug("GisPluginBmng: finalize");
+       GisPluginBmng *self = GIS_PLUGIN_BMNG(gobject);
+       /* Free data */
+       G_OBJECT_CLASS(gis_plugin_bmng_parent_class)->finalize(gobject);
+
+}
+static void gis_plugin_bmng_class_init(GisPluginBmngClass *klass)
+{
+       g_debug("GisPluginBmng: class_init");
+       GObjectClass *gobject_class = (GObjectClass*)klass;
+       gobject_class->dispose  = gis_plugin_bmng_dispose;
+       gobject_class->finalize = gis_plugin_bmng_finalize;
+}
diff --git a/src/plugins/bmng.h b/src/plugins/bmng.h
new file mode 100644 (file)
index 0000000..73701d8
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BMNG_H__
+#define __BMNG_H__
+
+#include <glib-object.h>
+
+#define GIS_TYPE_PLUGIN_BMNG            (gis_plugin_bmng_get_type ())
+#define GIS_PLUGIN_BMNG(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PLUGIN_BMNG, GisPluginBmng))
+#define GIS_IS_PLUGIN_BMNG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PLUGIN_BMNG))
+#define GIS_PLUGIN_BMNG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PLUGIN_BMNG, GisPluginBmngClass))
+#define GIS_IS_PLUGIN_BMNG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PLUGIN_BMNG))
+#define GIS_PLUGIN_BMNG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PLUGIN_BMNG, GisPluginBmngClass))
+
+typedef struct _GisPluginBmng      GisPluginBmng;
+typedef struct _GisPluginBmngClass GisPluginBmngClass;
+
+struct _GisPluginBmng {
+       GObject parent_instance;
+
+       /* instance members */
+       GtkToggleButton *button;
+       guint            rotate_id;
+       float            rotation;
+       GisOpenGL       *opengl;
+};
+
+struct _GisPluginBmngClass {
+       GObjectClass parent_class;
+};
+
+GType gis_plugin_bmng_get_type();
+
+/* Methods */
+GisPluginBmng *gis_plugin_bmng_new(GisWorld *world, GisView *view, GisOpenGL *opengl);
+
+#endif
diff --git a/src/plugins/srtm.c b/src/plugins/srtm.c
new file mode 100644 (file)
index 0000000..3beb2bc
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
+
+#include <gis.h>
+
+#include "srtm.h"
+
+/***********
+ * Helpers *
+ ***********/
+static gboolean rotate(gpointer _self)
+{
+       GisPluginSrtm *self = _self;
+       if (gtk_toggle_button_get_active(self->button)) {
+               self->rotation += 1.0;
+               gis_opengl_redraw(self->opengl);
+       }
+       return TRUE;
+}
+
+
+/***********
+ * Methods *
+ ***********/
+GisPluginSrtm *gis_plugin_srtm_new(GisWorld *world, GisView *view, GisOpenGL *opengl)
+{
+       g_debug("GisPluginSrtm: new");
+       GisPluginSrtm *self = g_object_new(GIS_TYPE_PLUGIN_SRTM, NULL);
+       self->opengl = opengl;
+
+       return self;
+}
+
+static GtkWidget *gis_plugin_srtm_get_config(GisPlugin *_self)
+{
+       GisPluginSrtm *self = GIS_PLUGIN_SRTM(_self);
+       return GTK_WIDGET(self->button);
+}
+
+static void gis_plugin_srtm_expose(GisPlugin *_self)
+{
+       GisPluginSrtm *self = GIS_PLUGIN_SRTM(_self);
+       g_debug("GisPluginSrtm: expose");
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(1,-1, -1,1, -10,10);
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       float light_ambient[]  = {0.1f, 0.1f, 0.0f, 1.0f};
+       float light_diffuse[]  = {0.9f, 0.9f, 0.9f, 1.0f};
+       float light_position[] = {-30.0f, 50.0f, 40.0f, 1.0f};
+       glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
+       glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
+       glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+       glEnable(GL_COLOR_MATERIAL);
+
+       glTranslatef(0.5, -0.5, -2);
+       glRotatef(self->rotation, 1, 1, 0);
+       glColor4f(0.9, 0.9, 0.7, 1.0);
+       glDisable(GL_CULL_FACE);
+       gdk_gl_draw_teapot(TRUE, 0.25);
+}
+
+
+/****************
+ * GObject code *
+ ****************/
+/* Plugin init */
+static void gis_plugin_srtm_plugin_init(GisPluginInterface *iface);
+G_DEFINE_TYPE_WITH_CODE(GisPluginSrtm, gis_plugin_srtm, G_TYPE_OBJECT,
+               G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN,
+                       gis_plugin_srtm_plugin_init));
+static void gis_plugin_srtm_plugin_init(GisPluginInterface *iface)
+{
+       g_debug("GisPluginSrtm: plugin_init");
+       /* Add methods to the interface */
+       iface->expose     = gis_plugin_srtm_expose;
+       iface->get_config = gis_plugin_srtm_get_config;
+}
+/* Class/Object init */
+static void gis_plugin_srtm_init(GisPluginSrtm *self)
+{
+       g_debug("GisPluginSrtm: init");
+       /* Set defaults */
+       self->button    = GTK_TOGGLE_BUTTON(gtk_toggle_button_new_with_label("Rotate"));
+       self->rotate_id = g_timeout_add(1000/60, rotate, self);
+       self->rotation  = 30.0;
+       self->opengl    = NULL;
+}
+static void gis_plugin_srtm_dispose(GObject *gobject)
+{
+       g_debug("GisPluginSrtm: dispose");
+       GisPluginSrtm *self = GIS_PLUGIN_SRTM(gobject);
+       g_source_remove(self->rotate_id);
+       /* Drop references */
+       G_OBJECT_CLASS(gis_plugin_srtm_parent_class)->dispose(gobject);
+}
+static void gis_plugin_srtm_finalize(GObject *gobject)
+{
+       g_debug("GisPluginSrtm: finalize");
+       GisPluginSrtm *self = GIS_PLUGIN_SRTM(gobject);
+       /* Free data */
+       G_OBJECT_CLASS(gis_plugin_srtm_parent_class)->finalize(gobject);
+
+}
+static void gis_plugin_srtm_class_init(GisPluginSrtmClass *klass)
+{
+       g_debug("GisPluginSrtm: class_init");
+       GObjectClass *gobject_class = (GObjectClass*)klass;
+       gobject_class->dispose  = gis_plugin_srtm_dispose;
+       gobject_class->finalize = gis_plugin_srtm_finalize;
+}
diff --git a/src/plugins/srtm.h b/src/plugins/srtm.h
new file mode 100644 (file)
index 0000000..8953788
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SRTM_H__
+#define __SRTM_H__
+
+#include <glib-object.h>
+
+#define GIS_TYPE_PLUGIN_SRTM            (gis_plugin_srtm_get_type ())
+#define GIS_PLUGIN_SRTM(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PLUGIN_SRTM, GisPluginSrtm))
+#define GIS_IS_PLUGIN_SRTM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PLUGIN_SRTM))
+#define GIS_PLUGIN_SRTM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PLUGIN_SRTM, GisPluginSrtmClass))
+#define GIS_IS_PLUGIN_SRTM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PLUGIN_SRTM))
+#define GIS_PLUGIN_SRTM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PLUGIN_SRTM, GisPluginSrtmClass))
+
+typedef struct _GisPluginSrtm      GisPluginSrtm;
+typedef struct _GisPluginSrtmClass GisPluginSrtmClass;
+
+struct _GisPluginSrtm {
+       GObject parent_instance;
+
+       /* instance members */
+       GtkToggleButton *button;
+       guint            rotate_id;
+       float            rotation;
+       GisOpenGL       *opengl;
+};
+
+struct _GisPluginSrtmClass {
+       GObjectClass parent_class;
+};
+
+GType gis_plugin_srtm_get_type();
+
+/* Methods */
+GisPluginSrtm *gis_plugin_srtm_new(GisWorld *world, GisView *view, GisOpenGL *opengl);
+
+#endif
index a95c697..4f3bc1d 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  */
 
 /* Misc */
-RoamView *roam_view_get()
+RoamView *roam_view_new()
 {
-       RoamView *view = g_new0(RoamView, 1);
-       glGetDoublev (GL_MODELVIEW_MATRIX,  view->model); 
-       glGetDoublev (GL_PROJECTION_MATRIX, view->proj); 
-       glGetIntegerv(GL_VIEWPORT,          view->view);          
-       return view;
+       return g_new0(RoamView, 1);
+}
+void roam_view_update(RoamView *view)
+{
+       glGetDoublev (GL_MODELVIEW_MATRIX,  view->model);
+       glGetDoublev (GL_PROJECTION_MATRIX, view->proj);
+       glGetIntegerv(GL_VIEWPORT,          view->view);
+       view->version++;
 }
 
 /* For GPQueue comparators */
@@ -89,28 +92,42 @@ void roam_point_remove_triangle(RoamPoint *self, RoamTriangle *triangle)
                self->norm[i] -= triangle->norm[i];
        }
        self->tris--;
-       for (int i = 0; i < 3; i++)
-               self->norm[i] /= self->tris;
+       if (self->tris)
+               for (int i = 0; i < 3; i++)
+                       self->norm[i] /= self->tris;
+}
+void roam_point_update_height(RoamPoint *self, RoamSphere *sphere)
+{
+       if (sphere->height_func) {
+               sphere->height_func(self, sphere->user_data);
+       } else {
+               gdouble dist = sqrt(self->x * self->x +
+                                   self->y * self->y +
+                                   self->z * self->z);
+               self->x = self->x/dist * 6371000;
+               self->y = self->y/dist * 6371000;
+               self->z = self->z/dist * 6371000;
+       }
 }
-void roam_point_update(RoamPoint *self, RoamSphere *sphere, gboolean do_height)
+void roam_point_update_projection(RoamPoint *self, RoamSphere *sphere)
 {
-       if (!self->cached) {
-               /* Cache height */
-               if (do_height)
-                       sphere->height_func(self, sphere->user_data);
+       static int count   = 0;
+       static int version = 0;
+       if (version != sphere->view->version) {
+               g_debug("Projected %d points", count);
+               count   = 0;
+               version = sphere->view->version;
+       }
 
+       if (self->pversion != sphere->view->version) {
                /* Cache projection */
                gluProject(self->x, self->y, self->z,
                        sphere->view->model, sphere->view->proj, sphere->view->view,
                        &self->px, &self->py, &self->pz);
-
-               self->cached = TRUE;
+               self->pversion = sphere->view->version;
+               count++;
        }
 }
-void roam_point_clear(RoamPoint *self)
-{
-       self->cached = FALSE;
-}
 
 /****************
  * RoamTriangle *
@@ -122,6 +139,10 @@ RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r)
        self->p.l = l;
        self->p.m = m;
        self->p.r = r;
+       self->split = roam_point_new(
+               (l->x + r->x)/2,
+               (l->y + r->y)/2,
+               (l->z + r->z)/2);
 
        self->error = 0;
 
@@ -147,11 +168,17 @@ RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r)
        self->norm[0] /= total;
        self->norm[1] /= total;
        self->norm[2] /= total;
-       
+
        //g_message("roam_triangle_new: %p", self);
        return self;
 }
 
+void roam_triangle_free(RoamTriangle *self)
+{
+       g_free(self->split);
+       g_free(self);
+}
+
 void roam_triangle_add(RoamTriangle *self,
                RoamTriangle *left, RoamTriangle *base, RoamTriangle *right,
                RoamSphere *sphere)
@@ -165,7 +192,7 @@ void roam_triangle_add(RoamTriangle *self,
        roam_point_add_triangle(self->p.r, self);
 
        if (sphere->view)
-               roam_triangle_update(self, sphere);
+               roam_triangle_update_errors(self, sphere);
 
        self->handle = g_pqueue_push(sphere->triangles, self);
 }
@@ -211,12 +238,13 @@ gboolean roam_triangle_visible(RoamTriangle *self, RoamSphere *sphere)
               roam_point_visible(self->p.r, sphere);
 }
 
-void roam_triangle_update(RoamTriangle *self, RoamSphere *sphere)
+void roam_triangle_update_errors(RoamTriangle *self, RoamSphere *sphere)
 {
        /* Update points */
-       roam_point_update(self->p.l, sphere, TRUE);
-       roam_point_update(self->p.m, sphere, TRUE);
-       roam_point_update(self->p.r, sphere, TRUE);
+       roam_point_update_projection(self->p.l, sphere);
+       roam_point_update_projection(self->p.m, sphere);
+       roam_point_update_projection(self->p.r, sphere);
+       roam_point_update_projection(self->split, sphere);
 
        /* Not exactly correct, could be out on both sides (middle in) */
        if (!roam_triangle_visible(self, sphere)) {
@@ -225,17 +253,13 @@ void roam_triangle_update(RoamTriangle *self, RoamSphere *sphere)
                RoamPoint *l = self->p.l;
                RoamPoint *m = self->p.m;
                RoamPoint *r = self->p.r;
+               RoamPoint *split = self->split;
 
-               /* TODO: share this with the base */
-               RoamPoint base = { (l->x + r->x)/2,
-                                  (l->y + r->y)/2,
-                                  (l->z + r->z)/2 };
-               RoamPoint good = base;
-               roam_point_update(&base, sphere, FALSE);
-               roam_point_update(&good, sphere, TRUE);
+               /*               l-r midpoint        projected l-r midpoint */
+               gdouble pxdist = (l->px + r->px)/2 - split->px;
+               gdouble pydist = (l->py + r->py)/2 - split->py;
 
-               self->error = sqrt((base.px - good.px) * (base.px - good.px) +
-                                  (base.py - good.py) * (base.py - good.py));
+               self->error = sqrt(pxdist*pxdist + pydist*pydist);
 
                /* Multiply by size of triangle */
                double size = -( l->px * (m->py - r->py) +
@@ -247,14 +271,6 @@ void roam_triangle_update(RoamTriangle *self, RoamSphere *sphere)
        }
 }
 
-void roam_triangle_clear(RoamTriangle *self)
-{
-       /* Clear points */
-       roam_point_clear(self->p.l);
-       roam_point_clear(self->p.m);
-       roam_point_clear(self->p.r);
-}
-
 void roam_triangle_split(RoamTriangle *self, RoamSphere *sphere)
 {
        //g_message("roam_triangle_split: %p, e=%f\n", self, self->error);
@@ -266,19 +282,19 @@ void roam_triangle_split(RoamTriangle *self, RoamSphere *sphere)
 
        RoamTriangle *base = self->t.b;
 
-       /* Duplicate midpoint */
-       RoamPoint *mid = roam_point_new(
-                       (self->p.l->x + self->p.r->x)/2,
-                       (self->p.l->y + self->p.r->y)/2,
-                       (self->p.l->z + self->p.r->z)/2);
-       roam_point_update(mid, sphere, TRUE);
 
        /* Add new triangles */
+       RoamPoint *mid = self->split;
        RoamTriangle *sl = roam_triangle_new(self->p.m, mid, self->p.l); // Self Left
        RoamTriangle *sr = roam_triangle_new(self->p.r, mid, self->p.m); // Self Right
        RoamTriangle *bl = roam_triangle_new(base->p.m, mid, base->p.l); // Base Left
        RoamTriangle *br = roam_triangle_new(base->p.r, mid, base->p.m); // Base Right
 
+       roam_point_update_height(sl->split, sphere);
+       roam_point_update_height(sr->split, sphere);
+       roam_point_update_height(bl->split, sphere);
+       roam_point_update_height(br->split, sphere);
+
        /*                tri,l,  base,      r,  sphere */
        roam_triangle_add(sl, sr, self->t.l, br, sphere);
        roam_triangle_add(sr, bl, self->t.r, sl, sphere);
@@ -296,12 +312,22 @@ void roam_triangle_split(RoamTriangle *self, RoamSphere *sphere)
 
        /* Add/Remove diamonds */
        RoamDiamond *diamond = roam_diamond_new(self, base, sl, sr, bl, br);
-       roam_diamond_update(diamond, sphere);
+       roam_diamond_update_errors(diamond, sphere);
        roam_diamond_add(diamond, sphere);
        roam_diamond_remove(self->parent, sphere);
        roam_diamond_remove(base->parent, sphere);
 }
 
+void roam_triangle_draw(RoamTriangle *self)
+{
+       glBegin(GL_TRIANGLES);
+       glNormal3dv(self->p.r->norm); glVertex3dv((double*)self->p.r);
+       glNormal3dv(self->p.m->norm); glVertex3dv((double*)self->p.m);
+       glNormal3dv(self->p.l->norm); glVertex3dv((double*)self->p.l);
+       glEnd();
+       return;
+}
+
 void roam_triangle_draw_normal(RoamTriangle *self)
 {
        double center[] = {
@@ -310,9 +336,9 @@ void roam_triangle_draw_normal(RoamTriangle *self)
                (self->p.l->z + self->p.m->z + self->p.r->z)/3.0,
        };
        double end[] = {
-               center[0]+self->norm[0]/2,
-               center[1]+self->norm[1]/2,
-               center[2]+self->norm[2]/2,
+               center[0]+self->norm[0]*2000000,
+               center[1]+self->norm[1]*2000000,
+               center[2]+self->norm[2]*2000000,
        };
        glBegin(GL_LINES);
        glVertex3dv(center);
@@ -335,10 +361,10 @@ RoamDiamond *roam_diamond_new(
        self->kids[2] = kid2;
        self->kids[3] = kid3;
 
-       kid0->parent = self; 
-       kid1->parent = self; 
-       kid2->parent = self; 
-       kid3->parent = self; 
+       kid0->parent = self;
+       kid1->parent = self;
+       kid2->parent = self;
+       kid3->parent = self;
 
        self->parents[0] = parent0;
        self->parents[1] = parent1;
@@ -388,44 +414,41 @@ void roam_diamond_merge(RoamDiamond *self, RoamSphere *sphere)
        /* Add/Remove triangles */
        if (tri->t.l->t.l == tri->t.r->t.r &&
            tri->t.l->t.l != tri && tri->parent) {
-               roam_diamond_update(tri->parent, sphere);
+               roam_diamond_update_errors(tri->parent, sphere);
                roam_diamond_add(tri->parent, sphere);
        }
 
        if (base->t.l->t.l == base->t.r->t.r &&
            base->t.l->t.l != base && base->parent) {
-               roam_diamond_update(base->parent, sphere);
+               roam_diamond_update_errors(base->parent, sphere);
                roam_diamond_add(base->parent, sphere);
        }
+
        /* Remove and free diamond and child triangles */
        roam_diamond_remove(self, sphere);
        g_assert(self->kids[0]->p.m == self->kids[1]->p.m &&
                 self->kids[1]->p.m == self->kids[2]->p.m &&
                 self->kids[2]->p.m == self->kids[3]->p.m);
        g_assert(self->kids[0]->p.m->tris == 0);
-       g_free(self->kids[0]->p.m);
-       g_free(self->kids[0]);
-       g_free(self->kids[1]);
-       g_free(self->kids[2]);
-       g_free(self->kids[3]);
+       roam_triangle_free(self->kids[0]);
+       roam_triangle_free(self->kids[1]);
+       roam_triangle_free(self->kids[2]);
+       roam_triangle_free(self->kids[3]);
        g_free(self);
 }
-void roam_diamond_update(RoamDiamond *self, RoamSphere *sphere)
+void roam_diamond_update_errors(RoamDiamond *self, RoamSphere *sphere)
 {
-       roam_triangle_update(self->parents[0], sphere);
-       roam_triangle_update(self->parents[1], sphere);
+       roam_triangle_update_errors(self->parents[0], sphere);
+       roam_triangle_update_errors(self->parents[1], sphere);
        self->error = MAX(self->parents[0]->error, self->parents[1]->error);
 }
 
 /**************
  * RoamSphere *
  **************/
-RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gpointer user_data)
+RoamSphere *roam_sphere_new(gpointer user_data)
 {
        RoamSphere *self = g_new0(RoamSphere, 1);
-       self->tri_func    = tri_func;
-       self->height_func = height_func;
        self->user_data   = user_data;
        self->polys       = 12;
        self->triangles   = g_pqueue_new((GCompareDataFunc)tri_cmp, NULL);
@@ -458,12 +481,16 @@ RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gp
        };
        RoamTriangle *triangles[12];
 
+       for (int i = 0; i < 8; i++)
+               roam_point_update_height(vertexes[i], self);
        for (int i = 0; i < 12; i++)
                triangles[i] = roam_triangle_new(
                        vertexes[_triangles[i][0][0]],
                        vertexes[_triangles[i][0][1]],
                        vertexes[_triangles[i][0][2]]);
        for (int i = 0; i < 12; i++)
+               roam_point_update_height(triangles[i]->split, self);
+       for (int i = 0; i < 12; i++)
                roam_triangle_add(triangles[i],
                        triangles[_triangles[i][1][0]],
                        triangles[_triangles[i][1][1]],
@@ -472,26 +499,25 @@ RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gp
 
        return self;
 }
-void roam_sphere_update(RoamSphere *self)
+void roam_sphere_update_errors(RoamSphere *self)
 {
        g_debug("RoamSphere: update - polys=%d", self->polys);
-       if (self->view) g_free(self->view);
-       self->view = roam_view_get();
+       if (!self->view)
+               self->view = roam_view_new();
+       roam_view_update(self->view);
 
        GPtrArray *tris = g_pqueue_get_array(self->triangles);
        GPtrArray *dias = g_pqueue_get_array(self->diamonds);
 
        for (int i = 0; i < tris->len; i++) {
-               /* Note: this also updates points */
                RoamTriangle *tri = tris->pdata[i];
-               roam_triangle_clear(tri);
-               roam_triangle_update(tri, self);
+               roam_triangle_update_errors(tri, self);
                g_pqueue_priority_changed(self->triangles, tri->handle);
        }
 
        for (int i = 0; i < dias->len; i++) {
                RoamDiamond *dia = dias->pdata[i];
-               roam_diamond_update(dia, self);
+               roam_diamond_update_errors(dia, self);
                g_pqueue_priority_changed(self->diamonds, dia->handle);
        }
 
@@ -514,7 +540,7 @@ void roam_sphere_merge_one(RoamSphere *self)
 gint roam_sphere_split_merge(RoamSphere *self)
 {
        gint iters = 0, max_iters = 500;
-       gint target = 2000;
+       gint target = 4000;
 
        if (!self->view)
                return 0;
@@ -538,18 +564,20 @@ gint roam_sphere_split_merge(RoamSphere *self)
 }
 void roam_sphere_draw(RoamSphere *self)
 {
-       g_pqueue_foreach(self->triangles, (GFunc)self->tri_func, self->user_data);
+       g_message("RoamSphere: draw");
+       g_pqueue_foreach(self->triangles, (GFunc)roam_triangle_draw, NULL);
 }
 void roam_sphere_draw_normals(RoamSphere *self)
 {
+       g_message("RoamSphere: draw_normal");
        g_pqueue_foreach(self->triangles, (GFunc)roam_triangle_draw_normal, NULL);
 }
-static void roam_sphere_free_tri(RoamTriangle *tri)
+void roam_sphere_free_tri(RoamTriangle *tri)
 {
        if (--tri->p.l->tris == 0) g_free(tri->p.l);
        if (--tri->p.m->tris == 0) g_free(tri->p.m);
        if (--tri->p.r->tris == 0) g_free(tri->p.r);
-       g_free(tri);
+       roam_triangle_free(tri);
 }
 void roam_sphere_free(RoamSphere *self)
 {
index 3d2fced..c4a0898 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -27,14 +27,14 @@ typedef struct _RoamPoint    RoamPoint;
 typedef struct _RoamTriangle RoamTriangle;
 typedef struct _RoamDiamond  RoamDiamond;
 typedef struct _RoamSphere   RoamSphere;
-typedef void (*RoamTriFunc)(RoamTriangle *triangle, gpointer user_data);
 typedef void (*RoamHeightFunc)(RoamPoint *point, gpointer user_data);
 
 /* Misc */
 struct _RoamView {
        gdouble model[16];
-       gdouble proj[16]; 
-       gint view[4]; 
+       gdouble proj[16];
+       gint view[4];
+       gint version;
 };
 
 /*************
@@ -43,8 +43,7 @@ struct _RoamView {
 struct _RoamPoint {
        gdouble  x,y,z;     // Model coordinates
        gdouble  px,py,pz;  // Projected coordinates
-
-       gboolean cached;    // Height/projection cached
+       gint     pversion;  // Version of cached projection
 
        gint     tris;      // Associated triangles
        gdouble  norm[3];   // Vertex normal
@@ -54,8 +53,8 @@ struct _RoamPoint {
 RoamPoint *roam_point_new(double x, double y, double z);
 void roam_point_add_triangle(RoamPoint *point, RoamTriangle *triangle);
 void roam_point_remove_triangle(RoamPoint *point, RoamTriangle *triangle);
-void roam_point_update(RoamPoint *point, RoamSphere *sphere, gboolean do_height);
-void roam_point_clear(RoamPoint *self);
+void roam_point_update_height(RoamPoint *point, RoamSphere *sphere);
+void roam_point_update_projection(RoamPoint *point, RoamSphere *sphere);
 
 /****************
  * RoamTriangle *
@@ -63,6 +62,7 @@ void roam_point_clear(RoamPoint *self);
 struct _RoamTriangle {
        struct { RoamPoint    *l,*m,*r; } p;
        struct { RoamTriangle *l,*b,*r; } t;
+       RoamPoint *split;
        RoamDiamond *parent;
        double norm[3];
        double error;
@@ -75,7 +75,7 @@ void roam_triangle_add(RoamTriangle *triangle,
                RoamTriangle *left, RoamTriangle *base, RoamTriangle *right,
                RoamSphere *sphere);
 void roam_triangle_remove(RoamTriangle *triangle, RoamSphere *sphere);
-void roam_triangle_update(RoamTriangle *triangle, RoamSphere *sphere);
+void roam_triangle_update_errors(RoamTriangle *triangle, RoamSphere *sphere);
 void roam_triangle_split(RoamTriangle *triangle, RoamSphere *sphere);
 void roam_triangle_draw_normal(RoamTriangle *triangle);
 
@@ -96,7 +96,7 @@ RoamDiamond *roam_diamond_new(
 void roam_diamond_add(RoamDiamond *diamond, RoamSphere *sphere);
 void roam_diamond_remove(RoamDiamond *diamond, RoamSphere *sphere);
 void roam_diamond_merge(RoamDiamond *diamond, RoamSphere *sphere);
-void roam_diamond_update(RoamDiamond *self, RoamSphere *sphere);
+void roam_diamond_update_errors(RoamDiamond *self, RoamSphere *sphere);
 
 /**************
  * RoamSphere *
@@ -105,13 +105,12 @@ struct _RoamSphere {
        GPQueue *triangles;
        GPQueue *diamonds;
        RoamView *view;
-       RoamTriFunc tri_func;
        RoamHeightFunc height_func;
        gpointer user_data;
        gint polys;
 };
-RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gpointer user_data);
-void roam_sphere_update(RoamSphere *sphere);
+RoamSphere *roam_sphere_new(gpointer user_data);
+void roam_sphere_update_errors(RoamSphere *sphere);
 void roam_sphere_split_one(RoamSphere *sphere);
 void roam_sphere_merge_one(RoamSphere *sphere);
 gint roam_sphere_split_merge(RoamSphere *sphere);
index 92a3476..2aba9dc 100644 (file)
--- a/src/wms.c
+++ b/src/wms.c
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -27,7 +27,7 @@
  * FORMAT=image/jpeg&
  * WIDTH=600&
  * HEIGHT=300
- * 
+ *
  * http://www.nasa.network.com/elev?
  * SERVICE=WMS&
  * VERSION=1.1.0&
@@ -245,7 +245,7 @@ void wms_info_cache(WmsInfo *info, gdouble resolution, gdouble lat, gdouble lon,
                xmin = xmin + xdist*(xpos+0);
                ymin = ymin + ydist*(ypos+0);
                xmax = xmin + xdist;
-               ymax = ymin + ydist; 
+               ymax = ymin + ydist;
                cur_lat = MIN(ABS(ymin), ABS(ymax));
 
                /* Update target for correct sub-tile */
@@ -267,7 +267,7 @@ void wms_info_cache(WmsInfo *info, gdouble resolution, gdouble lat, gdouble lon,
                state->user_done_cb  = done_callback;
                state->user_data     = user_data;
                g_idle_add(wms_info_cache_loader_cb, state);
-       } else { 
+       } else {
                g_free(approx_path);
        }
 
@@ -398,7 +398,7 @@ static WmsCacheNode *wms_info_gc_cb(WmsInfo *self, WmsCacheNode *node)
                        }
        if (empty) {
                g_debug("WmsInfo: gc - empty branch %p", node);
-               /* 
+               /*
                 * TODO: Don't prune nodes while we're caching WmsCacheNodes in the Roam triangles
                 * and points
                g_free(node);
@@ -507,8 +507,8 @@ void srtm_pixbuf_loader(WmsCacheNode *node, const gchar *path, gint width, gint
        guchar    *pixels = gdk_pixbuf_get_pixels(pixbuf);
        gint       stride = gdk_pixbuf_get_rowstride(pixbuf);
 
-       gint16 *data; 
-       gchar **char_data = (gchar**)&data; 
+       gint16 *data;
+       gchar **char_data = (gchar**)&data;
        g_file_get_contents(path, char_data, NULL, NULL);
        for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
index a419e74..591befe 100644 (file)
--- a/src/wms.h
+++ b/src/wms.h
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */