From: Andy Spencer Date: Mon, 1 Nov 2010 03:37:53 +0000 (+0000) Subject: Give extra weight to "edge" triangles when splitting X-Git-Tag: v0.5~47 X-Git-Url: http://pileus.org/git/?p=grits;a=commitdiff_plain;h=907e81475ed6b87e2a2a918aa32836345005074a;hp=850e596cffb982eab6672930c15eb078f1cb737b Give extra weight to "edge" triangles when splitting "Edge" triangles are triangles where one of the edges of the triangle makes up an edge off the mesh. For example, the triangle E below is an edge triangle due to the top edge. This helps prevent jagged "edges" on the tops of mountains, etc. It also helps round out the edges of the globe when viewed from far away. ________________ \ ______ / \ /\ E /\ / \/__\ /__\/ \/ --- diff --git a/src/roam.c b/src/roam.c index 21b1393..0f4995e 100644 --- a/src/roam.c +++ b/src/roam.c @@ -319,7 +319,6 @@ static void roam_triangle_sync_neighbors(RoamTriangle *neigh, RoamTriangle *old, 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) @@ -338,6 +337,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 @@ -375,6 +388,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 *= 500; } } @@ -554,6 +573,11 @@ 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);