clray

diff src/scene.cc @ 28:97cfd9675310

trying to pass the kdtree to the kernel
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Aug 2010 03:42:49 +0100
parents 8b2f2ad14ae7
children 353d80127627
line diff
     1.1 --- a/src/scene.cc	Tue Aug 17 20:35:00 2010 +0100
     1.2 +++ b/src/scene.cc	Sat Aug 21 03:42:49 2010 +0100
     1.3 @@ -9,12 +9,12 @@
     1.4  static bool build_kdtree(KDNode *kd, int level = 0);
     1.5  static float eval_cost(const std::list<const Face*> &faces, const AABBox &aabb, int axis, float par_sarea = 1.0);
     1.6  static void free_kdtree(KDNode *node);
     1.7 -static int kdtree_depth(const KDNode *node);
     1.8 +static void kdtree_gpu_flatten(KDNodeGPU *kdbuf, int idx, const KDNode *node, const Face *facebuf);
     1.9  static void print_item_counts(const KDNode *node, int level);
    1.10  
    1.11  
    1.12  static int accel_param[NUM_ACCEL_PARAMS] = {
    1.13 -	75,	// max tree depth
    1.14 +	40,	// max tree depth
    1.15  	0,	// max items per node (0 means ignore limit)
    1.16  	5,	// estimated traversal cost
    1.17  	15	// estimated interseciton cost
    1.18 @@ -70,11 +70,15 @@
    1.19  	facebuf = 0;
    1.20  	num_faces = -1;
    1.21  	kdtree = 0;
    1.22 +	num_kdnodes = -1;
    1.23 +	kdbuf = 0;
    1.24  }
    1.25  
    1.26  Scene::~Scene()
    1.27  {
    1.28  	delete [] facebuf;
    1.29 +	delete [] kdbuf;
    1.30 +	free_kdtree(kdtree);
    1.31  }
    1.32  
    1.33  bool Scene::add_mesh(Mesh *m)
    1.34 @@ -158,6 +162,35 @@
    1.35  	return facebuf;
    1.36  }
    1.37  
    1.38 +const KDNodeGPU *Scene::get_kdtree_buffer() const
    1.39 +{
    1.40 +	if(kdbuf) {
    1.41 +		return kdbuf;
    1.42 +	}
    1.43 +
    1.44 +	if(!kdtree) {
    1.45 +		((Scene*)this)->build_kdtree();
    1.46 +	}
    1.47 +
    1.48 +	if(!get_num_kdnodes()) {
    1.49 +		return 0;
    1.50 +	}
    1.51 +
    1.52 +	kdbuf = new KDNodeGPU[num_kdnodes + 1];
    1.53 +	kdtree_gpu_flatten(kdbuf, 1, kdtree, get_face_buffer());
    1.54 +	return kdbuf;
    1.55 +}
    1.56 +
    1.57 +int Scene::get_num_kdnodes() const
    1.58 +{
    1.59 +	if(num_kdnodes >= 0) {
    1.60 +		return num_kdnodes;
    1.61 +	}
    1.62 +
    1.63 +	num_kdnodes = kdtree_nodes(kdtree);
    1.64 +	return num_kdnodes;
    1.65 +}
    1.66 +
    1.67  
    1.68  void Scene::draw_kdtree() const
    1.69  {
    1.70 @@ -175,22 +208,10 @@
    1.71  
    1.72  static float palette[][3] = {
    1.73  	{0, 1, 0},
    1.74 -	{0, 1, 0},
    1.75 -	{0, 1, 0},
    1.76 -	{1, 0, 0},
    1.77 -	{1, 0, 0},
    1.78  	{1, 0, 0},
    1.79  	{0, 0, 1},
    1.80 -	{0, 0, 1},
    1.81 -	{0, 0, 1},
    1.82 -	{1, 1, 0},
    1.83 -	{1, 1, 0},
    1.84  	{1, 1, 0},
    1.85  	{0, 0, 1},
    1.86 -	{0, 0, 1},
    1.87 -	{0, 0, 1},
    1.88 -	{1, 0, 1},
    1.89 -	{1, 0, 1},
    1.90  	{1, 0, 1}
    1.91  };
    1.92  static int pal_size = sizeof palette / sizeof *palette;
    1.93 @@ -291,10 +312,11 @@
    1.94  
    1.95  static bool build_kdtree(KDNode *kd, int level)
    1.96  {
    1.97 +	int opt_max_depth = accel_param[ACCEL_PARAM_MAX_TREE_DEPTH];
    1.98  	int opt_max_items = accel_param[ACCEL_PARAM_MAX_NODE_ITEMS];
    1.99  	int tcost = accel_param[ACCEL_PARAM_COST_TRAVERSE];
   1.100  
   1.101 -	if(kd->num_faces == 0) {
   1.102 +	if(kd->num_faces == 0 || level >= opt_max_depth) {
   1.103  		return true;
   1.104  	}
   1.105  
   1.106 @@ -410,7 +432,7 @@
   1.107  	}
   1.108  }
   1.109  
   1.110 -static int kdtree_depth(const KDNode *node)
   1.111 +int kdtree_depth(const KDNode *node)
   1.112  {
   1.113  	if(!node) return 0;
   1.114  
   1.115 @@ -419,6 +441,36 @@
   1.116  	return (left > right ? left : right) + 1;
   1.117  }
   1.118  
   1.119 +int kdtree_nodes(const KDNode *node)
   1.120 +{
   1.121 +	if(!node) return 0;
   1.122 +	return kdtree_nodes(node->left) + kdtree_nodes(node->right) + 1;
   1.123 +}
   1.124 +
   1.125 +#define MAX_FACES	(sizeof dest->face_idx / sizeof *dest->face_idx)
   1.126 +static void kdtree_gpu_flatten(KDNodeGPU *kdbuf, int idx, const KDNode *node, const Face *facebuf)
   1.127 +{
   1.128 +	KDNodeGPU *dest = kdbuf + idx;
   1.129 +
   1.130 +	dest->aabb = node->aabb;
   1.131 +	dest->num_faces = 0;
   1.132 +
   1.133 +	std::list<const Face*>::const_iterator it = node->faces.begin();
   1.134 +	while(it != node->faces.end()) {
   1.135 +		if(dest->num_faces >= (int)MAX_FACES) {
   1.136 +			fprintf(stderr, "kdtree_gpu_flatten WARNING: more than %d faces in node, skipping!\n", (int)MAX_FACES);
   1.137 +			break;
   1.138 +		}
   1.139 +		dest->face_idx[dest->num_faces++] = *it - facebuf;
   1.140 +	}
   1.141 +
   1.142 +	if(node->left) {
   1.143 +		assert(node->right);
   1.144 +		kdtree_gpu_flatten(kdbuf, idx * 2, node->left, facebuf);
   1.145 +		kdtree_gpu_flatten(kdbuf, idx * 2 + 1, node->right, facebuf);
   1.146 +	}
   1.147 +}
   1.148 +
   1.149  static void print_item_counts(const KDNode *node, int level)
   1.150  {
   1.151  	if(!node) return;