X-Git-Url: http://pileus.org/git/?p=grits;a=blobdiff_plain;f=src%2Froam.c;h=a3bc847f40a01dbabe957039f737def9f10c4741;hp=7f131825d4735bb57fc95ffda639325705e3b486;hb=d2fbd2408edd0a39253b2c30f98dcafefcef508f;hpb=b11fd4c409529141ee61781fc99aa2238f93e9ce diff --git a/src/roam.c b/src/roam.c index 7f13182..a3bc847 100644 --- a/src/roam.c +++ b/src/roam.c @@ -1,5 +1,5 @@ /* - * 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 @@ -101,7 +101,7 @@ void roam_point_update_projection(RoamPoint *self, RoamSphere *sphere) static int count = 0; static int version = 0; if (version != sphere->view->version) { - g_debug("Projected %d points", count); + g_debug("RoamPoint: Projected %d points", count); count = 0; version = sphere->view->version; } @@ -296,6 +296,8 @@ void roam_triangle_split(RoamTriangle *self, RoamSphere *sphere) if (self != self->t.b->t.b) roam_triangle_split(self->t.b, sphere); + if (self != self->t.b->t.b) + g_assert_not_reached(); RoamTriangle *base = self->t.b; @@ -600,18 +602,19 @@ void roam_sphere_draw_normals(RoamSphere *self) g_debug("RoamSphere: draw_normal"); g_pqueue_foreach(self->triangles, (GFunc)roam_triangle_draw_normal, NULL); } -static GList *_roam_sphere_get_leaves(RoamTriangle *tri, GList *list) +static GList *_roam_sphere_get_leaves(RoamTriangle *tri, GList *list, gboolean all) { if (tri->kids[0] && tri->kids[1]) { - list = _roam_sphere_get_leaves(tri->kids[0], list); - list = _roam_sphere_get_leaves(tri->kids[1], list); + if (all) list = g_list_prepend(list, tri); + list = _roam_sphere_get_leaves(tri->kids[0], list, all); + list = _roam_sphere_get_leaves(tri->kids[1], list, all); return list; } else { - return g_list_append(list, tri); + return g_list_prepend(list, tri); } } static GList *_roam_sphere_get_intersect_rec(RoamTriangle *tri, GList *list, - gdouble n, gdouble s, gdouble e, gdouble w) + gboolean all, gdouble n, gdouble s, gdouble e, gdouble w) { gdouble tn = tri->edge.n; gdouble ts = tri->edge.s; @@ -629,23 +632,28 @@ static GList *_roam_sphere_get_intersect_rec(RoamTriangle *tri, GList *list, /* No intersect */ if (debug) g_message("no intersect"); return list; - } else if (tn < n && ts > s && te < e && tw > w) { + } else if (tn <= n && ts >= s && te <= e && tw >= w) { /* Triangle is completely contained */ if (debug) g_message("contained"); - return _roam_sphere_get_leaves(tri, list); + if (all) list = g_list_prepend(list, tri); + return _roam_sphere_get_leaves(tri, list, all); } else if (tri->kids[0] && tri->kids[1]) { /* Paritial intersect with children */ if (debug) g_message("edge w/ child"); - list = _roam_sphere_get_intersect_rec(tri->kids[0], list, n, s, e, w); - list = _roam_sphere_get_intersect_rec(tri->kids[1], list, n, s, e, w); + if (all) list = g_list_prepend(list, tri); + list = _roam_sphere_get_intersect_rec(tri->kids[0], list, all, n, s, e, w); + list = _roam_sphere_get_intersect_rec(tri->kids[1], list, all, n, s, e, w); return list; } else { /* This triangle is an edge case */ if (debug) g_message("edge"); - return g_list_append(list, tri); + return g_list_prepend(list, tri); } } -GList *roam_sphere_get_intersect(RoamSphere *self, +/* Warning: This grabs pointers to triangles which can be changed by other + * calls, e.g. split_merge. If you use this, you need to do some locking to + * prevent the returned list from becomming stale. */ +GList *roam_sphere_get_intersect(RoamSphere *self, gboolean all, gdouble n, gdouble s, gdouble e, gdouble w) { /* I think this is correct.. @@ -655,7 +663,7 @@ GList *roam_sphere_get_intersect(RoamSphere *self, GList *list = NULL; for (int i = 0; i < G_N_ELEMENTS(self->roots); i++) list = _roam_sphere_get_intersect_rec(self->roots[i], - list, n, s, e, w); + list, all, n, s, e, w); return list; } void roam_sphere_free_tri(RoamTriangle *tri) @@ -667,6 +675,7 @@ void roam_sphere_free_tri(RoamTriangle *tri) } void roam_sphere_free(RoamSphere *self) { + g_debug("RoamSphere: free"); /* Slow method, but it should work */ while (self->polys > 8) roam_sphere_merge_one(self);