summaryrefslogtreecommitdiffstats
path: root/bench/libdimension/bvst.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-01-15 14:24:13 -0500
committerTavian Barnes <tavianator@gmail.com>2010-01-15 14:24:13 -0500
commita868a2958dd7ea138b02543ef81cc78abf8622c7 (patch)
treea22e18fd379000ccc1a104ae711a499377e60a72 /bench/libdimension/bvst.c
parent26e8ad8ce8f15e25b856c5cbd7f526d090cda3ae (diff)
downloaddimension-a868a2958dd7ea138b02543ef81cc78abf8622c7.tar.xz
Rename kD splay trees to Bounding Volume Splay Trees.
Diffstat (limited to 'bench/libdimension/bvst.c')
-rw-r--r--bench/libdimension/bvst.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/bench/libdimension/bvst.c b/bench/libdimension/bvst.c
new file mode 100644
index 0000000..3d363ca
--- /dev/null
+++ b/bench/libdimension/bvst.c
@@ -0,0 +1,176 @@
+/*************************************************************************
+ * Copyright (C) 2009 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>
+
+dmnsn_intersection *
+dmnsn_fake_intersection_fn(const dmnsn_object *object, dmnsn_line line)
+{
+ dmnsn_intersection *intersection = dmnsn_new_intersection();
+ intersection->t = (object->min.z - line.x0.z)/line.n.z;
+ intersection->texture = object->texture;
+ return intersection;
+}
+
+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->min.x = rand1;
+ object->max.x = rand2;
+ } else {
+ object->max.x = rand1;
+ object->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->min.y = rand1;
+ object->max.y = rand2;
+ } else {
+ object->max.y = rand1;
+ object->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->min.z = rand1;
+ object->max.z = rand2;
+ } else {
+ object->max.z = rand1;
+ object->min.z = rand2;
+ }
+}
+
+dmnsn_bvst_node *
+dmnsn_bvst_deepest_recursive(dmnsn_bvst_node *node,
+ unsigned int depth, unsigned int *deepest)
+{
+ dmnsn_bvst_node *left = NULL, *right = NULL;
+
+ if (node->contains) {
+ left = dmnsn_bvst_deepest_recursive(node->contains, depth + 1, deepest);
+ }
+ if (node->container) {
+ right = dmnsn_bvst_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_bvst_node *
+dmnsn_bvst_deepest(dmnsn_bvst *tree)
+{
+ unsigned int deepest = 0;
+ return dmnsn_bvst_deepest_recursive(tree->root, 0, &deepest);
+}
+
+int
+main()
+{
+ dmnsn_bvst *tree;
+ dmnsn_bvst_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;
+ sandglass_attributes_t attr = { SANDGLASS_MONOTONIC, SANDGLASS_CPUTIME };
+
+ if (sandglass_create(&sandglass, &attr, &attr) != 0) {
+ perror("sandglass_create()");
+ return EXIT_FAILURE;
+ }
+
+ tree = dmnsn_new_bvst();
+
+ for (i = 0; i < nobjects; ++i) {
+ objects[i] = dmnsn_new_object();
+ if (!objects[i]) {
+ fprintf(stderr, "--- Couldn't allocate object! ---\n");
+ return EXIT_FAILURE;
+ }
+
+ /* 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_bvst_insert() */
+
+ grains = 0;
+ for (i = 0; i < nobjects; ++i) {
+ sandglass_bench_noprecache(&sandglass,
+ dmnsn_bvst_insert(tree, objects[i]));
+ sandglass.grains += grains;
+ grains = sandglass.grains;
+ }
+ printf("dmnsn_bvst_insert(): %ld\n", sandglass.grains/nobjects);
+
+ /* dmnsn_bvst_search() */
+
+ ray.x0 = dmnsn_new_vector(0.0, 0.0, -2.0);
+ ray.n = dmnsn_new_vector(0.0, 0.0, 1.0);
+
+ dmnsn_delete_intersection((*objects[0]->intersection_fn)(objects[0], ray));
+ sandglass_bench_noprecache(&sandglass, {
+ intersection = dmnsn_bvst_search(tree, ray);
+ });
+ dmnsn_delete_intersection(intersection);
+ printf("dmnsn_bvst_search(): %ld\n", sandglass.grains);
+
+ /* dmnsn_bvst_splay() */
+ grains = 0;
+ for (i = 0; i < nobjects; ++i) {
+ node = dmnsn_bvst_deepest(tree);
+ sandglass_bench_noprecache(&sandglass, dmnsn_bvst_splay(tree, node));
+ sandglass.grains += grains;
+ grains = sandglass.grains;
+ }
+ printf("dmnsn_bvst_splay(): %ld\n", sandglass.grains/nobjects);
+
+ /* Cleanup */
+ dmnsn_delete_bvst(tree);
+ for (i = 0; i < nobjects; ++i) {
+ dmnsn_delete_object(objects[i]);
+ }
+
+ return EXIT_SUCCESS;
+}