summaryrefslogtreecommitdiffstats
path: root/bench/libdimension/prtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'bench/libdimension/prtree.c')
-rw-r--r--bench/libdimension/prtree.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/bench/libdimension/prtree.c b/bench/libdimension/prtree.c
new file mode 100644
index 0000000..5ee32cf
--- /dev/null
+++ b/bench/libdimension/prtree.c
@@ -0,0 +1,170 @@
+/*************************************************************************
+ * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Test Suite. *
+ * *
+ * The Dimension Test Suite is free software; you can redistribute it *
+ * and/or modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Test Suite is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "../../libdimension/dimension_impl.h"
+#include <sandglass.h>
+#include <stdlib.h>
+
+bool
+dmnsn_fake_intersection_fn(const dmnsn_object *object, dmnsn_line line,
+ dmnsn_intersection *intersection)
+{
+ intersection->t = (object->bounding_box.min.z - line.x0.z)/line.n.z;
+ intersection->texture = object->texture;
+ return true;
+}
+
+void
+dmnsn_randomize_bounding_box(dmnsn_object *object)
+{
+ double rand1, rand2;
+
+ rand1 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ rand2 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ if (rand1 < rand2) {
+ object->bounding_box.min.x = rand1;
+ object->bounding_box.max.x = rand2;
+ } else {
+ object->bounding_box.max.x = rand1;
+ object->bounding_box.min.x = rand2;
+ }
+
+ rand1 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ rand2 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ if (rand1 < rand2) {
+ object->bounding_box.min.y = rand1;
+ object->bounding_box.max.y = rand2;
+ } else {
+ object->bounding_box.max.y = rand1;
+ object->bounding_box.min.y = rand2;
+ }
+
+ rand1 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ rand2 = 2.0*((double)rand())/RAND_MAX - 1.0;
+ if (rand1 < rand2) {
+ object->bounding_box.min.z = rand1;
+ object->bounding_box.max.z = rand2;
+ } else {
+ object->bounding_box.max.z = rand1;
+ object->bounding_box.min.z = rand2;
+ }
+}
+
+dmnsn_prtree_node *
+dmnsn_prtree_deepest_recursive(dmnsn_prtree_node *node,
+ unsigned int depth, unsigned int *deepest)
+{
+ dmnsn_prtree_node *left = NULL, *right = NULL;
+
+ if (node->contains) {
+ left = dmnsn_prtree_deepest_recursive(node->contains, depth + 1, deepest);
+ }
+ if (node->container) {
+ right = dmnsn_prtree_deepest_recursive(node->container,
+ depth + 1, deepest);
+ }
+
+ if (right) {
+ return right;
+ } else if (left) {
+ return left;
+ } else if (depth >= *deepest) {
+ *deepest = depth;
+ return node;
+ } else {
+ return NULL;
+ }
+}
+
+dmnsn_prtree_node *
+dmnsn_prtree_deepest(dmnsn_prtree *tree)
+{
+ unsigned int deepest = 0;
+ return dmnsn_prtree_deepest_recursive(tree->root, 0, &deepest);
+}
+
+int
+main()
+{
+ dmnsn_prtree *tree;
+ dmnsn_prtree_node *node;
+ dmnsn_intersection intersection;
+ dmnsn_line ray;
+ const unsigned int nobjects = 128;
+ dmnsn_object *objects[nobjects];
+ unsigned int i;
+ long grains;
+
+ sandglass_t sandglass;
+
+ if (sandglass_init_monotonic(&sandglass, SANDGLASS_CPUTIME) != 0) {
+ perror("sandglass_create()");
+ return EXIT_FAILURE;
+ }
+
+ tree = dmnsn_new_prtree();
+
+ for (i = 0; i < nobjects; ++i) {
+ objects[i] = dmnsn_new_object();
+
+ /* Generate a bounding box in (-1, -1, -1), (1, 1, 1) */
+ dmnsn_randomize_bounding_box(objects[i]);
+ objects[i]->intersection_fn = &dmnsn_fake_intersection_fn;
+ }
+
+ /* dmnsn_prtree_insert() */
+
+ grains = 0;
+ for (i = 0; i < nobjects; ++i) {
+ sandglass_bench_noprecache(&sandglass,
+ dmnsn_prtree_insert(tree, objects[i]));
+ sandglass.grains += grains;
+ grains = sandglass.grains;
+ }
+ printf("dmnsn_prtree_insert(): %ld\n", sandglass.grains/nobjects);
+
+ /* dmnsn_prtree_search() */
+
+ ray.x0 = dmnsn_new_vector(0.0, 0.0, -2.0);
+ ray.n = dmnsn_new_vector(0.0, 0.0, 1.0);
+
+ (*objects[0]->intersection_fn)(objects[0], ray, &intersection);
+ sandglass_bench_noprecache(&sandglass, {
+ dmnsn_prtree_search(tree, ray, &intersection);
+ });
+ printf("dmnsn_prtree_search(): %ld\n", sandglass.grains);
+
+ /* dmnsn_prtree_splay() */
+ grains = 0;
+ for (i = 0; i < nobjects; ++i) {
+ node = dmnsn_prtree_deepest(tree);
+ sandglass_bench_noprecache(&sandglass, dmnsn_prtree_splay(tree, node));
+ sandglass.grains += grains;
+ grains = sandglass.grains;
+ }
+ printf("dmnsn_prtree_splay(): %ld\n", sandglass.grains/nobjects);
+
+ /* Cleanup */
+ dmnsn_delete_prtree(tree);
+ for (i = 0; i < nobjects; ++i) {
+ dmnsn_delete_object(objects[i]);
+ }
+
+ return EXIT_SUCCESS;
+}