]> Pileus Git - grits/commitdiff
Add grits_viewer_unproject function
authorAndy Spencer <andy753421@gmail.com>
Mon, 6 Feb 2012 06:32:35 +0000 (06:32 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 6 Feb 2012 06:32:35 +0000 (06:32 +0000)
This does the opposite of the grits_viewer_project function and can be
used to get the lat-lon-elev point corresponding to a point on the
screen, such as the pointer location. This currently has an undefined
output if the screen coordinates do not map to the location of an object
in the viewer.

This should not be used to determine if an objects has been selected or
clicked on. OpenGL picking should be used for that by connecting to one
of the GritsObject mouse event signals.

src/grits-opengl.c
src/grits-viewer.c
src/grits-viewer.h

index 961a875207c57b1109503d64877a38399c31c4d5..3d7b7dd12a718ddf6bac02c83509e2c5df706f8e 100644 (file)
@@ -316,6 +316,11 @@ static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpo
        g_ptr_array_free(objects, TRUE);
        g_mutex_unlock(opengl->objects_lock);
 
+       /* Test unproject */
+       gdouble lat, lon, elev;
+       grits_viewer_unproject(GRITS_VIEWER(opengl),
+                       gl_x, gl_y, -1, &lat, &lon, &elev);
+
        /* Cleanup */
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
@@ -459,6 +464,30 @@ static void grits_opengl_project(GritsViewer *_opengl,
                px, py, pz);
 }
 
+static void grits_opengl_unproject(GritsViewer *_opengl,
+               gdouble px, gdouble py, gdouble pz,
+               gdouble *lat, gdouble *lon, gdouble *elev)
+{
+       GritsOpenGL *opengl = GRITS_OPENGL(_opengl);
+       gdouble x, y, z;
+       if (pz < 0) {
+               gfloat tmp = 0;
+               glReadPixels(px, py, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &tmp);
+               pz = tmp;
+       }
+       gluUnProject(px, py, pz,
+               opengl->sphere->view->model,
+               opengl->sphere->view->proj,
+               opengl->sphere->view->view,
+               &x, &y, &z);
+       xyz2lle(x, y, z, lat, lon, elev);
+       //g_message("GritsOpenGL: unproject - "
+       //              "%4.0lf,%4.0lf,(%5.3lf) -> "
+       //              "%8.0lf,%8.0lf,%8.0lf -> "
+       //              "%6.2lf,%7.2lf,%4.0lf",
+       //      px, py, pz, x, y, z, *lat, *lon, *elev);
+}
+
 static void grits_opengl_set_height_func(GritsViewer *_opengl, GritsBounds *bounds,
                RoamHeightFunc height_func, gpointer user_data, gboolean update)
 {
@@ -615,6 +644,7 @@ static void grits_opengl_class_init(GritsOpenGLClass *klass)
        GritsViewerClass *viewer_class = GRITS_VIEWER_CLASS(klass);
        viewer_class->center_position   = grits_opengl_center_position;
        viewer_class->project           = grits_opengl_project;
+       viewer_class->unproject         = grits_opengl_unproject;
        viewer_class->clear_height_func = grits_opengl_clear_height_func;
        viewer_class->set_height_func   = grits_opengl_set_height_func;
        viewer_class->add               = grits_opengl_add;
index 08d73bbf29c45ea2d748aa903e4475d144513ada..d9e28878dbcd53ed03c1875c59769186a776af50 100644 (file)
@@ -445,8 +445,8 @@ void grits_viewer_center_position(GritsViewer *viewer,
  * grits_viewer_project:
  * @viewer: the viewer
  * @lat:  the latitude
- * @lon:  the latitude
- * @elev: the latitude
+ * @lon:  the longitude
+ * @elev: the elevation
  * @px:   the project x coordinate
  * @py:   the project y coordinate
  * @pz:   the project z coordinate
@@ -465,6 +465,31 @@ void grits_viewer_project(GritsViewer *viewer,
        klass->project(viewer, lat, lon, elev, px, py, pz);
 }
 
+/**
+ * grits_viewer_unproject:
+ * @viewer: the viewer
+ * @x:    x coordinate in screen space
+ * @y:    y coordinate in screen space
+ * @z:    z coordinate in screen space, or -1 to use the value
+ *        from the depth buffer at x and y as the z value
+ * @lat:  the latitude
+ * @lon:  the longitude
+ * @elev: the elevation
+ *
+ * Project a x, y point in screen space to a latitude, longitude, and elevation
+ * point. Useful for finding the position of the cursor or another on-screen
+ * object in world coordinates.
+ */
+void grits_viewer_unproject(GritsViewer *viewer,
+               gdouble px, gdouble py, gdouble pz,
+               gdouble *lat, gdouble *lon, gdouble *elev)
+{
+       GritsViewerClass *klass = GRITS_VIEWER_GET_CLASS(viewer);
+       if (!klass->unproject)
+               g_warning("GritsViewer: unproject - Unimplemented");
+       klass->unproject(viewer, px, py, pz, lat, lon, elev);
+}
+
 /**
  * grits_viewer_clear_height_func:
  * @viewer: the viewer
index 15d9d70cdeffde2ed9c956ba6190165835a4d10d..8991cb5f3b2bd9754c555b8871cd8c9225aef562 100644 (file)
@@ -131,6 +131,9 @@ struct _GritsViewerClass {
        void (*project)          (GritsViewer *viewer,
                                  gdouble lat, gdouble lon, gdouble elev,
                                  gdouble *px, gdouble *py, gdouble *pz);
+       void (*unproject)        (GritsViewer *viewer,
+                                 gdouble px, gdouble py,gdouble pz,
+                                 gdouble *lat, gdouble *lon, gdouble *elev);
 
        void (*clear_height_func)(GritsViewer *viewer);
        void (*set_height_func)  (GritsViewer *viewer, GritsBounds *bounds,
@@ -171,6 +174,9 @@ void grits_viewer_center_position(GritsViewer *viewer,
 void grits_viewer_project(GritsViewer *viewer,
                gdouble lat, gdouble lon, gdouble elev,
                gdouble *px, gdouble *py, gdouble *pz);
+void grits_viewer_unproject(GritsViewer *viewer,
+               gdouble px, gdouble py, gdouble pz,
+               gdouble *lat, gdouble *lon, gdouble *elev);
 
 void grits_viewer_clear_height_func(GritsViewer *viewer);
 void grits_viewer_set_height_func(GritsViewer *viewer, GritsBounds *bounds,