double range)
{
struct sim_status status;
- struct planet *planet, *pl1, *pl2;
+ struct planet *planet, *pl1, *pl2, *planet_root;
struct camera camera;
+ struct planet_search_iterator itr;
+
int planets;
int framecount = 0, last_fps_time = 0;
int last_framecount = 0, last_step_count = 0;
unsigned long step_count = 0;
double last_fps = 0, last_sps = 0;
double step_time = 0, true_time = 0;
+ int visible_planets;
init_camera(&camera);
status.screen = screen;
status.tracers_enabled = 0;
+ itr.screen = screen;
+ itr.cam = &camera;
+ itr.qt_iterator.direction = planet_search_rectangular;
+ itr.qt_iterator.callback = planet_draw_iterator;
+
planet = malloc(sizeof(*planet));
init_planet(planet);
create_planets(planet, num_of_planets, total_mass, range);
pl2 = ptmp;
}
- move_planet(pl1, step_time);
+ planet_root = move_planet(pl1, step_time);
+ planets++;
}
move_camera(&camera, true_time);
clear_buf(screen);
}
- list_for_each_entry(pl1, &planet->list, list) {
- draw_planet(screen, pl1, &camera);
- planets++;
- }
+ //itr.limit.x = cam->zoom
+ itr.qt_iterator.head = planet_root;
+
+ visible_planets = walk_quadtree(&itr.qt_iterator);
SDL_UnlockSurface(screen);
last_fps_time = ticks;
}
-
printf(" \rFrames/s: %.2f, steps/s: %.2f, planets: %d"
- ", scale %.2f, zoom %.2f, step %ld",
+ ", scale %.2f, zoom %.2f, step %ld, visible %d",
last_fps, last_sps, planets, status.time_scale,
- camera.zoom, step_count);
+ camera.zoom, step_count, visible_planets);
fflush(stdout);
return 2;
return 3;
}
+
+int planet_search_rectangular(struct quadtree *node,
+ struct quadtree_iterator *itr)
+{
+ struct planet_search_iterator *it = qt_itr_to_planet_itr(itr);
+ struct planet *p = tree_to_planet(node);
+ int directions = 0, i;
+ int up[2], left[2], right[2], down[2];
+
+ for (i = 0; i < 2; i++) {
+ if (it->limit[i].x < p->pos.x)
+ left[i] = 1;
+ else
+ right[i] = 1;
+ if (it->limit[i].y < p->pos.y)
+ up[i] = 1;
+ else
+ down[i] = 1;
+ }
+
+ directions |= left[0] | left[1] | up [0] | up[1] ?
+ QUADTREE_UPLEFT : 0;
+ directions |= right[0] | right[1] | up [0] | up[1] ?
+ QUADTREE_UPRIGHT : 0;
+ directions |= left[0] | left[1] | down [0] | down[1] ?
+ QUADTREE_DOWNLEFT :0;
+ directions |= right[0] | right[1] | down [0] | down[1] ?
+ QUADTREE_DOWNRIGHT :0;
+ directions |= (directions == (QUADTREE_UPLEFT | QUADTREE_UPRIGHT |
+ QUADTREE_DOWNLEFT | QUADTREE_DOWNRIGHT)) ?
+ QUADTREE_SELF : 0;
+
+ return directions;
+}
+
+void planet_draw_iterator(struct quadtree *node, struct quadtree_iterator *it)
+{
+ struct planet *p = tree_to_planet(node);
+ struct planet_search_iterator *i = qt_itr_to_planet_itr(it);
+
+ draw_planet(i->screen, p, i->cam);
+}
unsigned char r, g, b;
};
+struct planet_search_iterator {
+ struct quadtree_iterator qt_iterator;
+ struct vector limit[2];
+ struct camera *cam;
+ SDL_Surface *screen;
+};
+
#define list_to_planet(list_head) container_of((list_head), struct planet, list)
+
#define tree_to_planet(qt) container_of((qt), struct planet, tree)
+#define qt_itr_to_planet_itr(qt) \
+ container_of((qt), struct planet_search_iterator, qt_iterator)
+
void init_planet(struct planet *p);
void create_planets(struct planet *p, int num, double total_mass,
double radius);
void print_planet(const struct planet *p);
int planet_spatial_compare(struct quadtree *a, struct quadtree *b);
+int planet_search_rectangular(struct quadtree *node,
+ struct quadtree_iterator *itr);
+void planet_draw_iterator(struct quadtree *node, struct quadtree_iterator *it);
#endif
{
int direction, count = 0;
- direction = it->direction(head, it->ptr);
+ direction = it->direction(head, it);
if ((direction & QUADTREE_UPLEFT) && head->child[0])
count += _walk_tree(head->child[0], it);
struct quadtree *head;
void *ptr;
- int (*direction)(struct quadtree *head, void *ptr);
- void (*callback)(struct quadtree *head, void *ptr);
+ int (*direction)(struct quadtree *head, struct quadtree_iterator *it);
+ void (*callback)(struct quadtree *head, struct quadtree_iterator *it);
};
struct quadtree *quadtree_add(struct quadtree *parent,