]> git.itanic.dy.fi Git - sdl-planets/blob - quadtree.h
Merge branch 'master' into dirty_work
[sdl-planets] / quadtree.h
1 #ifndef _QUADTREE_H_
2 #define _QUADTREE_H_
3
4 #include <string.h>
5
6 #include "list.h"
7 #include "utils.h"
8 #include "vector.h"
9
10 struct quadtree {
11         struct vector pos;
12         struct quadtree *child[4];
13         struct quadtree *parent;
14         struct list_head list;  /* This list is used when balancing the tree */
15
16         /* statistics */
17         long int children;      /* The total number of children */
18         long int depth;         /* The deepest subtree branch */
19 };
20
21 #define list_to_tree(list_head) container_of((list_head), struct quadtree, list)
22
23 struct quadtree_ops {
24         /*
25          * Calculates required statistical information for a node
26          */
27         void (*recalculate_stats)(struct quadtree *node);
28 };
29
30 static inline void init_quadtree(struct quadtree *t)
31 {
32         memset(t, 0, sizeof(*t));
33 }
34
35 #define QUADTREE_UPLEFT         0x1
36 #define QUADTREE_UPRIGHT        0x2
37 #define QUADTREE_DOWNLEFT       0x4
38 #define QUADTREE_DOWNRIGHT      0x8
39 #define QUADTREE_SELF           0x10
40
41 struct quadtree_iterator {
42         struct quadtree *head;
43         void *ptr;
44
45         int (*direction)(struct quadtree *head, struct quadtree_iterator *it);
46         void (*callback)(struct quadtree *head, struct quadtree_iterator *it);
47 };
48
49 struct quadtree *quadtree_add(struct quadtree *parent, struct quadtree *new,
50                               struct quadtree_ops *ops);
51
52 struct quadtree *quadtree_del(struct quadtree *node, struct quadtree_ops *ops);
53 struct quadtree *quadtree_move(struct quadtree *node, struct vector new_pos,
54                         struct quadtree_ops *ops);
55
56 int walk_quadtree(const struct quadtree_iterator *iterator);
57
58
59 /* quadtree_find_parent - return the highest parent of the node */
60 static inline struct quadtree *quadtree_find_parent(const struct quadtree *node)
61 {
62         struct quadtree *t = (struct quadtree *)node;
63         while (t->parent)
64                 t = t->parent;
65
66         return t;
67 }
68
69 /*
70  * Recursively walk through the tree and propagate changes made to the
71  * given node up until the highest parent.
72  */
73 static inline void quadtree_recalculate_parent_stats(struct quadtree *node,
74                                                      struct quadtree_ops *ops)
75 {
76         int i;
77
78         while (node) {
79                 node->depth = 0;
80                 node->children = 0;
81
82                 for (i = 0; i < 4; i++) {
83                         if (!node->child[i])
84                                 continue;
85
86                         node->depth = MAX(node->depth,
87                                           node->child[i]->depth + 1);
88                         node->children += node->child[i]->children + 1;
89                 }
90
91                 if (ops->recalculate_stats)
92                         ops->recalculate_stats(node);
93
94                 node = node->parent;
95         }
96 }
97
98 void _quadtree_validate_tree(const struct quadtree *node);
99
100 static inline void quadtree_validate_tree(struct quadtree *node)
101 {
102         if (debug)
103                 _quadtree_validate_tree(node);
104 }
105
106 #endif