X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Froam.c;h=d8bff628b33f939151e1def1c2c1f069a76b17d9;hb=5d4daa2b86d30c77c9828447ca1828a45713b5d6;hp=2fe0acfb65a0b9a58883790759b5e6530e0d5138;hpb=84ce9447b38df46ae3adbdb1de9333feda77f68c;p=grits diff --git a/src/roam.c b/src/roam.c index 2fe0acf..d8bff62 100644 --- a/src/roam.c +++ b/src/roam.c @@ -21,8 +21,8 @@ * * A spherical version of the Realtime Optimally-Adapting Meshes (ROAM) * algorithm is use for drawing the surface of the planet. ROAM provide a - * continuous level-of-detail mesh of the planet which is used by #GisOpenGL - * when drawing surface textures for GisTiles. + * continuous level-of-detail mesh of the planet which is used by #GritsOpenGL + * when drawing surface textures for GritsTiles. * * This implementation of the ROAM algorithm is based on an octahedron as the * base model. @@ -35,7 +35,7 @@ #include #include "gpqueue.h" -#include "gis-util.h" +#include "grits-util.h" #include "roam.h" /* @@ -206,27 +206,10 @@ RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r, // triangle->split->lat, l->lat); /* Update normal */ - double pa[3]; - double pb[3]; - pa[0] = triangle->p.l->x - triangle->p.m->x; - pa[1] = triangle->p.l->y - triangle->p.m->y; - pa[2] = triangle->p.l->z - triangle->p.m->z; - - pb[0] = triangle->p.r->x - triangle->p.m->x; - pb[1] = triangle->p.r->y - triangle->p.m->y; - pb[2] = triangle->p.r->z - triangle->p.m->z; - - triangle->norm[0] = pa[1] * pb[2] - pa[2] * pb[1]; - triangle->norm[1] = pa[2] * pb[0] - pa[0] * pb[2]; - triangle->norm[2] = pa[0] * pb[1] - pa[1] * pb[0]; - - double total = sqrt(triangle->norm[0] * triangle->norm[0] + - triangle->norm[1] * triangle->norm[1] + - triangle->norm[2] * triangle->norm[2]); - - triangle->norm[0] /= total; - triangle->norm[1] /= total; - triangle->norm[2] /= total; + crossd3((gdouble*)triangle->p.l, + (gdouble*)triangle->p.m, + (gdouble*)triangle->p.r, triangle->norm); + normd(triangle->norm); /* Store bounding box, for get_intersect */ RoamPoint *p[] = {l,m,r}; @@ -313,12 +296,12 @@ void roam_triangle_remove(RoamTriangle *triangle, RoamSphere *sphere) g_pqueue_remove(sphere->triangles, triangle->handle); } -static void roam_triangle_sync_neighbors(RoamTriangle *new, RoamTriangle *old, RoamTriangle *neigh) +/* (neight->t.? == old) = new */ +static void roam_triangle_sync_neighbors(RoamTriangle *neigh, RoamTriangle *old, RoamTriangle *new) { if (neigh->t.l == old) neigh->t.l = new; else if (neigh->t.b == old) neigh->t.b = new; else if (neigh->t.r == old) neigh->t.r = new; - else g_assert_not_reached(); } static gboolean roam_triangle_visible(RoamTriangle *triangle, RoamSphere *sphere) @@ -337,6 +320,20 @@ static gboolean roam_triangle_visible(RoamTriangle *triangle, RoamSphere *sphere l->pz < 1 && m->pz < 1 && r->pz < 1; } +static gboolean roam_triangle_backface(RoamTriangle *triangle, RoamSphere *sphere) +{ + RoamPoint *l = triangle->p.l; + RoamPoint *m = triangle->p.m; + RoamPoint *r = triangle->p.r; + roam_point_update_projection(l, sphere->view); + roam_point_update_projection(m, sphere->view); + roam_point_update_projection(r, sphere->view); + double size = -( l->px * (m->py - r->py) + + m->px * (r->py - l->py) + + r->px * (l->py - m->py) ) / 2.0; + return size < 0; +} + /** * roam_triangle_update_errors: * @triangle: the triangle @@ -374,6 +371,12 @@ void roam_triangle_update_errors(RoamTriangle *triangle, RoamSphere *sphere) /* Size < 0 == backface */ triangle->error *= size; + + /* Give some preference to "edge" faces */ + if (roam_triangle_backface(triangle->t.l, sphere) || + roam_triangle_backface(triangle->t.b, sphere) || + roam_triangle_backface(triangle->t.r, sphere)) + triangle->error *= 50; } } @@ -414,10 +417,10 @@ void roam_triangle_split(RoamTriangle *triangle, RoamSphere *sphere) roam_triangle_add(bl, br, b->t.l, sr, sphere); roam_triangle_add(br, sl, b->t.r, bl, sphere); - roam_triangle_sync_neighbors(sl, s, s->t.l); - roam_triangle_sync_neighbors(sr, s, s->t.r); - roam_triangle_sync_neighbors(bl, b, b->t.l); - roam_triangle_sync_neighbors(br, b, b->t.r); + roam_triangle_sync_neighbors(s->t.l, s, sl); + roam_triangle_sync_neighbors(s->t.r, s, sr); + roam_triangle_sync_neighbors(b->t.l, b, bl); + roam_triangle_sync_neighbors(b->t.r, b, br); /* Remove old triangles */ roam_triangle_remove(s, sphere); @@ -553,13 +556,18 @@ void roam_diamond_merge(RoamDiamond *diamond, RoamSphere *sphere) b->kids[0] = b->kids[1] = NULL; /* Add original triangles */ + roam_triangle_sync_neighbors(s->t.l, sl, s); + roam_triangle_sync_neighbors(s->t.r, sr, s); + roam_triangle_sync_neighbors(b->t.l, bl, b); + roam_triangle_sync_neighbors(b->t.r, br, b); + roam_triangle_add(s, sl->t.b, b, sr->t.b, sphere); roam_triangle_add(b, bl->t.b, s, br->t.b, sphere); - roam_triangle_sync_neighbors(s, sl, sl->t.b); - roam_triangle_sync_neighbors(s, sr, sr->t.b); - roam_triangle_sync_neighbors(b, bl, bl->t.b); - roam_triangle_sync_neighbors(b, br, br->t.b); + roam_triangle_sync_neighbors(sl->t.b, sl, s); + roam_triangle_sync_neighbors(sr->t.b, sr, s); + roam_triangle_sync_neighbors(bl->t.b, bl, b); + roam_triangle_sync_neighbors(br->t.b, br, b); /* Remove child triangles */ roam_triangle_remove(sl, sphere); @@ -752,6 +760,7 @@ void roam_sphere_merge_one(RoamSphere *sphere) gint roam_sphere_split_merge(RoamSphere *sphere) { gint iters = 0, max_iters = 500; + //gint target = 20000; //gint target = 4000; gint target = 2000; //gint target = 500;