last_fps_time = ticks;
}
- printf(" \rFrames/s: %.2f, steps/s: %.2f, planets: %d"
- ", scale %.2f, zoom %.2f, step %ld, visible %d",
+ printf(" \rfps: %.2f, steps/s: %.2f, planets: %d"
+ ", scale %.2f, zoom %.2f, step %ld, visible %d,"
+ " depth %ld, c:%ld",
last_fps, last_sps, planets, status.time_scale,
- camera.zoom, step_count, visible_planets);
+ camera.zoom, step_count, visible_planets,
+ planet_root->tree.depth, planet_root->tree.children);
fflush(stdout);
#include <stdlib.h>
#include "quadtree.h"
+#include "utils.h"
#ifdef DEBUG
#define debug 1
static void validate_subtree(const struct quadtree *node)
{
int i;
+ long int children;
+ children = 0;
for (i = 0; i < 4; i++) {
if (!node->child[i])
__func__, __LINE__, i, node);
trap();
}
+
if (node->parent) {
if (node->child[i] == node->parent) {
printf("%s:%d Fatal! Tree loop detected "
}
}
+ children += node->child[i] + 1;
+
validate_subtree(node->child[i]);
}
+
+ if (node->children < 0) {
+ printf("%s:%d Tree statistics inconsistency detected! "
+ "Negative child count: %ld\n",
+ __func__, __LINE__, node->children);
+ }
+
+ if (node->depth < 0) {
+ printf("%s:%d Tree statistics inconsistency detected! "
+ "Negative depth: %ld\n",
+ __func__, __LINE__, node->depth);
+ }
+
+ if (node->children != children) {
+ printf("%s:%d Tree statistics inconsistency detected! "
+ "child count mismatch. Expected %ld, got %ld\n",
+ __func__, __LINE__, children, node->children);
+ trap();
+ }
+
+ for (i = 0; i < 4 && node->children; i++) {
+ if (!node->child[i])
+ continue;
+
+ if (node->depth == node->child[i]->depth + 1)
+ break;
+
+ if (node->child[i]->depth > node->depth) {
+ printf("%s:%d Tree statistics inconsistency detected! "
+ "child depth mismatch %ld > %ld\n",
+ __func__, __LINE__, node->child[i]->depth,
+ node->depth);
+ }
+ }
+
+ if (i == 4) {
+ printf("%s:%d Tree statistics inconsistency detected! "
+ "child depth mismatch.",
+ __func__, __LINE__);
+ trap();
+ }
}
static void validate_tree(const struct quadtree *node)
return 0;
}
- if (parent->child[ret])
- return quadtree_add(parent->child[ret], new, compare);
+ parent->children++;
+
+ if (parent->child[ret]) {
+ quadtree_add(parent->child[ret], new, compare);
+ parent->depth = MAX(parent->depth,
+ parent->child[ret]->depth + 1);
+ return new;
+ }
parent->child[ret] = new;
new->parent = parent;
node->child[i] = 0;
}
+ /* There are no children left, reset stats */
+ node->depth = 0;
+ node->children = 0;
+
/* Then remove this node under the new root. */
quadtree_add(root, node, compare);
}
int (*compare)(struct quadtree *a,
struct quadtree *b))
{
- struct quadtree *parent = 0;
+ struct quadtree *parent = 0, *tmp;
int i;
/*
node->child[i] = 0;
}
+ /* Fix parent stats */
+ tmp = parent;
+ while (tmp) {
+ tmp->children -= node->children;
+ tmp->depth = 0;
+ for (i = 0; i < 4; i++) {
+ if (tmp->child[i])
+ tmp->depth = MAX(tmp->depth,
+ tmp->child[i]->depth + 1);
+ }
+ tmp = tmp->parent;
+ }
+
parent = quadtree_find_parent(node);
node->parent = 0;
+ node->children = 0;
+ node->depth = 0;
+
validate_tree(parent);
return parent;
}