X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Froam.h;h=11eb171d444833212dd288483a35d4adacb2d6a9;hb=d1e2d70c4f601f09d2df0f728a6ea4eb1c12f8de;hp=3d2fced0a3e11cbf16ce271ad8094bbdc7222063;hpb=14cdbb4a9c369576a5485315260fad5285935e80;p=grits diff --git a/src/roam.h b/src/roam.h index 3d2fced..11eb171 100644 --- a/src/roam.h +++ b/src/roam.h @@ -1,16 +1,16 @@ /* - * Copyright (C) 2009 Andy Spencer - * + * Copyright (C) 2009-2010 Andy Spencer + * * 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 . */ @@ -19,7 +19,6 @@ #define __ROAM_H__ #include "gpqueue.h" -#include "wms.h" /* Roam */ typedef struct _RoamView RoamView; @@ -27,66 +26,132 @@ 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); +/** + * RoamHeightFunc: + * @lat: the latitude + * @lon: the longitude + * @user_data: user data passed to the function + * + * See #GisHeightFunc + * + * Returns: the elevation + */ +typedef gdouble (*RoamHeightFunc)(gdouble lat, gdouble lon, gpointer user_data); /* Misc */ +/** + * RoamView: + * @model: model view matrix + * @proj: projection matrix + * @view: viewport matrix + * @version: version + * + * Stores projection matrices + */ struct _RoamView { gdouble model[16]; - gdouble proj[16]; - gint view[4]; + gdouble proj[16]; + gint view[4]; + gint version; }; /************* * RoamPoint * *************/ +/** + * RoamPoint: + * + * Points are used as vertices for triangles. A single point my be shared among + * several triangles in order to conceive space and avoid recalculating + * projections. Points also store a lot of cached data. The normal vertex normal + * is the averaged surface normal of each associated triangle. + */ struct _RoamPoint { - gdouble x,y,z; // Model coordinates - gdouble px,py,pz; // Projected coordinates + /*< private >*/ + gdouble x, y, z; /* Model coordinates */ + gdouble px, py, pz; /* Projected coordinates */ + gint pversion; /* Version of cached projection */ - gboolean cached; // Height/projection cached + gint tris; /* Count of associated triangles */ + gdouble norm[3]; /* Vertex normal */ - gint tris; // Associated triangles - gdouble norm[3]; // Vertex normal + /* For get_intersect */ + gdouble lat, lon, elev; - WmsCacheNode *node; // TODO: don't depend on wms + /* For terrain */ + RoamHeightFunc height_func; + gpointer height_data; }; -RoamPoint *roam_point_new(double x, double y, double z); +RoamPoint *roam_point_new(double lat, double lon, double elev); 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); +void roam_point_update_projection(RoamPoint *point, RoamView *view); /**************** * RoamTriangle * ****************/ +/** + * RoamTriangle: + * + * Triangles are one of the key datatypes in ROAM. The surface is made up of + * triangles. Each triangle has an associated "error". When the surface is being + * updated after the view changes, each triangles error is updated. Afterwards + * the triangles with the most error are split int to triangles, each with a + * lower error than the original. + * + * Triangles store a lot of data about their location in the mesh so that they + * can be split and merged (unsplit) without having to recreate the mesh. + */ struct _RoamTriangle { + /*< private >*/ + /* Left, middle and right vertices */ struct { RoamPoint *l,*m,*r; } p; + + /* Left, base, and right neighbor triangles */ struct { RoamTriangle *l,*b,*r; } t; - RoamDiamond *parent; - double norm[3]; - double error; + + RoamPoint *split; /* Split point */ + RoamDiamond *parent; /* Parent diamond */ + double norm[3]; /* Surface normal */ + double error; /* Screen space error */ GPQueueHandle handle; - WmsCacheNode *nodes[5]; // TODO: don't depend on wms + /* For get_intersect */ + struct { gdouble n,s,e,w; } edge; + RoamTriangle *kids[2]; }; RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r); +void roam_triangle_free(RoamTriangle *triangle); 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(RoamTriangle *triangle); void roam_triangle_draw_normal(RoamTriangle *triangle); /*************** * RoamDiamond * ***************/ +/** + * RoamDiamond: + * + * When two adjacent triangles are split, they, along with the four new child + * triangles, are added to a diamond which keeps track of them. + * + * Like triangles, diamond have an error associated with it. However, when a + * diamonds error is small enough it is "merged". That is, the diamond along + * with the child triangles is removed and the original two triangles triangles + * are added back into the mesh. + */ struct _RoamDiamond { - RoamTriangle *kids[4]; - RoamTriangle *parents[2]; - double error; - gboolean active; + /*< private >*/ + RoamTriangle *kids[4]; /* Child triangles */ + RoamTriangle *parents[2]; /* Parent triangles */ + double error; /* Screen space error */ + gboolean active; /* For internal use */ GPQueueHandle handle; }; RoamDiamond *roam_diamond_new( @@ -96,27 +161,39 @@ 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 *diamond, RoamSphere *sphere); /************** * RoamSphere * **************/ +/** + * RoamSphere: + * + * The sphere keeps track of the triangles and diamonds in the mesh. + * + * Originally the sphere consists of only 8 triangles forming a octahedron. + * These triangles are quickly split to create a smoother sphere. + */ struct _RoamSphere { - GPQueue *triangles; - GPQueue *diamonds; - RoamView *view; - RoamTriFunc tri_func; - RoamHeightFunc height_func; - gpointer user_data; - gint polys; + /*< private >*/ + GPQueue *triangles; /* List of triangles */ + GPQueue *diamonds; /* List of diamonds */ + RoamView *view; /* Current projection */ + gint polys; /* Polygon count */ + + /* For get_intersect */ + RoamTriangle *roots[8]; /* Original 8 triangles */ }; -RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gpointer user_data); -void roam_sphere_update(RoamSphere *sphere); +RoamSphere *roam_sphere_new(); +void roam_sphere_update_view(RoamSphere *sphere); +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); void roam_sphere_draw(RoamSphere *sphere); void roam_sphere_draw_normals(RoamSphere *sphere); +GList *roam_sphere_get_intersect(RoamSphere *sphere, gboolean all, + gdouble n, gdouble s, gdouble e, gdouble w); void roam_sphere_free(RoamSphere *sphere); #endif