summaryrefslogtreecommitdiff
path: root/src/ix3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ix3.c')
-rw-r--r--src/ix3.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/ix3.c b/src/ix3.c
index 26a65b6..b5ac3cd 100644
--- a/src/ix3.c
+++ b/src/ix3.c
@@ -29,6 +29,8 @@
#include <assert.h>
#include <stdlib.h>
+#include <pad.h>
+
#include "ix3.h"
#include "list.h"
@@ -71,6 +73,9 @@ struct ix3_node_t {
};
typedef struct ix3_t {
+ pad_t *node_pad; /* ix3_node_t allocator */
+ pad_t *ref_pad; /* ix3_object_ref_t allocator */
+ pad_t *object_pad; /* ix3_object_t allocator */
bb3f_t aabb; /* spatial bounds of ix3 root */
unsigned max_per_node; /* maximum number of objects to put in a node until max_depth reached */
unsigned max_depth; /* maximum depth of ix3 tree where nodes cease being divided further */
@@ -281,7 +286,7 @@ static void unlink_object(ix3_object_t *object, list_head_t *references_cache)
continue;
}
- free(ref);
+ pad_put(ref);
}
}
@@ -291,7 +296,7 @@ static void unlink_object(ix3_object_t *object, list_head_t *references_cache)
* Returns the reference on success, NULL on failure
* On falure the supplied object is left intact.
*/
-static ix3_object_ref_t * link_object(ix3_object_t *object, ix3_node_t *node, ix3_object_ref_t **cached_ref)
+static ix3_object_ref_t * link_object(ix3_t *ix3, ix3_object_t *object, ix3_node_t *node, ix3_object_ref_t **cached_ref)
{
ix3_object_ref_t *ref = NULL;
@@ -305,7 +310,7 @@ static ix3_object_ref_t * link_object(ix3_object_t *object, ix3_node_t *node, ix
}
if (!ref)
- ref = calloc(1, sizeof(ix3_object_ref_t));
+ ref = pad_get(ix3->ref_pad, sizeof(ix3_object_ref_t));
if (!ref)
return NULL;
@@ -342,7 +347,7 @@ static void remove_object(ix3_object_t *object)
assert(object);
unlink_object(object, NULL);
- free(object);
+ pad_put(object);
}
@@ -362,7 +367,7 @@ static ix3_node_t * split_node(ix3_t *ix3, unsigned *depth, ix3_node_t *node, bb
assert(node_aabb);
/* allocate and setup the children nodes */
- node->children = calloc(8, sizeof(ix3_node_t));
+ node->children = pad_get(ix3->node_pad, 8 * sizeof(ix3_node_t));
if (!node->children)
goto _fail;
@@ -436,7 +441,7 @@ static ix3_object_t * add_object(ix3_t *ix3, unsigned *depth, ix3_node_t *node,
}
/* Node is a leaf, optimistically link the object to the node */
- if (!link_object(object, node, reference_cache))
+ if (!link_object(ix3, object, node, reference_cache))
goto _fail;
/* If the node is overflowing, split it */
@@ -470,7 +475,7 @@ ix3_t * ix3_new(bb3f_t *aabb, unsigned max_per_node, unsigned max_depth)
ix3 = calloc(1, sizeof(ix3_t));
if (!ix3)
- return NULL;
+ goto fail_ix3;
init_node(&ix3->root, aabb);
@@ -478,7 +483,28 @@ ix3_t * ix3_new(bb3f_t *aabb, unsigned max_per_node, unsigned max_depth)
ix3->max_per_node = max_per_node;
ix3->max_depth = max_depth;
+ ix3->node_pad = pad_new(sizeof(ix3_node_t) * 32, PAD_FLAGS_ZERO);
+ if (!ix3->node_pad)
+ goto fail_node_pad;
+
+ ix3->ref_pad = pad_new(sizeof(ix3_object_ref_t) * 128, PAD_FLAGS_ZERO);
+ if (!ix3->ref_pad)
+ goto fail_ref_pad;
+
+ ix3->object_pad = pad_new(sizeof(ix3_object_t) * 32, PAD_FLAGS_ZERO);
+ if (!ix3->object_pad)
+ goto fail_object_pad;
+
return ix3;
+
+fail_object_pad:
+ pad_free(ix3->ref_pad);
+fail_ref_pad:
+ pad_free(ix3->node_pad);
+fail_node_pad:
+ free(ix3);
+fail_ix3:
+ return NULL;
}
@@ -486,7 +512,11 @@ ix3_t * ix3_new(bb3f_t *aabb, unsigned max_per_node, unsigned max_depth)
/* Note the external objects which have been indexed are not freed */
void ix3_free(ix3_t *ix3)
{
- /* TODO: free everything */
+ assert(ix3);
+
+ pad_free(ix3->node_pad);
+ pad_free(ix3->ref_pad);
+ pad_free(ix3->object_pad);
free(ix3);
}
@@ -503,7 +533,7 @@ ix3_object_t * ix3_object_new(ix3_t *ix3, v3f_t *object_position, v3f_t *object_
assert(object_aabb->min.y <= object_aabb->max.y);
assert(object_aabb->min.z <= object_aabb->max.z);
- o = calloc(1, sizeof(ix3_object_t));
+ o = pad_get(ix3->object_pad, sizeof(ix3_object_t));
if (!o)
return NULL;
© All Rights Reserved