clray

diff src/scene.cc @ 37:ca445da26588

out of resources?!
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Aug 2010 01:00:04 +0100
parents 4dec8853bf75
children 4bcf78e572d6
line diff
     1.1 --- a/src/scene.cc	Thu Aug 26 20:33:27 2010 +0100
     1.2 +++ b/src/scene.cc	Fri Aug 27 01:00:04 2010 +0100
     1.3 @@ -7,6 +7,10 @@
     1.4  #include "ogl.h"
     1.5  
     1.6  
     1.7 +#define MIN(a, b)	((a) < (b) ? (a) : (b))
     1.8 +#define MAX(a, b)	((a) > (b) ? (a) : (b))
     1.9 +
    1.10 +
    1.11  static void flatten_kdtree(const KDNode *node, KDNodeGPU *kdbuf, int *count, std::map<const KDNode*, int> *flatmap);
    1.12  static void fix_child_links(const KDNode *node, KDNodeGPU *kdbuf, const std::map<const KDNode*, int> &flatmap);
    1.13  static void draw_kdtree(const KDNode *node, int level = 0);
    1.14 @@ -341,7 +345,7 @@
    1.15  		glVertex3f(bleft->max[0], bleft->min[1], bleft->max[2]);
    1.16  		glVertex3f(bleft->max[0], bleft->min[1], bleft->min[2]);
    1.17  		break;
    1.18 -	
    1.19 +
    1.20  	case 1:
    1.21  		glVertex3f(bleft->min[0], bleft->min[1], bleft->max[2]);
    1.22  		glVertex3f(bleft->min[0], bleft->max[1], bleft->max[2]);
    1.23 @@ -352,7 +356,7 @@
    1.24  		glVertex3f(bleft->max[0], bleft->min[1], bleft->max[2]);
    1.25  		glVertex3f(bleft->min[0], bleft->min[1], bleft->max[2]);
    1.26  		break;
    1.27 -	
    1.28 +
    1.29  	case 2:
    1.30  		glVertex3f(bleft->min[0], bleft->max[1], bleft->min[2]);
    1.31  		glVertex3f(bleft->max[0], bleft->max[1], bleft->min[2]);
    1.32 @@ -427,47 +431,74 @@
    1.33  	return true;
    1.34  }
    1.35  
    1.36 +struct Split {
    1.37 +	int axis;
    1.38 +	float pos;
    1.39 +	float sum_cost;
    1.40 +	float cost_left, cost_right;
    1.41 +};
    1.42 +
    1.43 +static void find_best_split(const KDNode *node, int axis, const Face *faces, Split *split)
    1.44 +{
    1.45 +	Split best_split;
    1.46 +	best_split.sum_cost = FLT_MAX;
    1.47 +
    1.48 +	for(size_t i=0; i<node->face_idx.size(); i++) {
    1.49 +		const Face *face = faces + node->face_idx[i];
    1.50 +
    1.51 +		float splitpt[2];
    1.52 +		splitpt[0] = MIN(face->v[0].pos[axis], MIN(face->v[1].pos[axis], face->v[2].pos[axis]));
    1.53 +		splitpt[1] = MAX(face->v[0].pos[axis], MAX(face->v[1].pos[axis], face->v[2].pos[axis]));
    1.54 +
    1.55 +		for(int j=0; j<2; j++) {
    1.56 +			AABBox aabb_left, aabb_right;
    1.57 +			aabb_left = aabb_right = node->aabb;
    1.58 +			aabb_left.max[axis] = splitpt[j];
    1.59 +			aabb_right.min[axis] = splitpt[j];
    1.60 +
    1.61 +			float left_cost = eval_cost(faces, &node->face_idx[0], node->face_idx.size(), aabb_left, axis);
    1.62 +			float right_cost = eval_cost(faces, &node->face_idx[0], node->face_idx.size(), aabb_right, axis);
    1.63 +			float sum_cost = left_cost + right_cost - accel_param[ACCEL_PARAM_COST_TRAVERSE]; // tcost is added twice
    1.64 +
    1.65 +			if(sum_cost < best_split.sum_cost) {
    1.66 +				best_split.cost_left = left_cost;
    1.67 +				best_split.cost_right = right_cost;
    1.68 +				best_split.sum_cost = sum_cost;
    1.69 +				best_split.pos = splitpt[j];
    1.70 +			}
    1.71 +		}
    1.72 +	}
    1.73 +
    1.74 +	assert(split);
    1.75 +	*split = best_split;
    1.76 +	split->axis = axis;
    1.77 +}
    1.78 +
    1.79  static bool build_kdtree(KDNode *kd, const Face *faces, int level)
    1.80  {
    1.81  	int opt_max_depth = accel_param[ACCEL_PARAM_MAX_TREE_DEPTH];
    1.82  	int opt_max_items = accel_param[ACCEL_PARAM_MAX_NODE_ITEMS];
    1.83 -	int tcost = accel_param[ACCEL_PARAM_COST_TRAVERSE];
    1.84  
    1.85  	if(kd->face_idx.empty() || level >= opt_max_depth) {
    1.86  		return true;
    1.87  	}
    1.88  
    1.89 -	int axis = level % 3;
    1.90 +	Split best_split;
    1.91 +	best_split.sum_cost = FLT_MAX;
    1.92  
    1.93 -	float best_cost[2], best_sum_cost = FLT_MAX;
    1.94 -	float best_split;
    1.95 +	for(int i=0; i<1; i++) {
    1.96 +		Split split;
    1.97 +		find_best_split(kd, i, faces, &split);
    1.98  
    1.99 -	for(size_t i=0; i<kd->face_idx.size(); i++) {
   1.100 -		const Face *face = faces + kd->face_idx[i];
   1.101 -
   1.102 -		for(int j=0; j<3; j++) {
   1.103 -			AABBox aabb_left, aabb_right;
   1.104 -			const float *split = face->v[j].pos;
   1.105 -
   1.106 -			aabb_left = aabb_right = kd->aabb;
   1.107 -			aabb_left.max[axis] = split[axis];
   1.108 -			aabb_right.min[axis] = split[axis];
   1.109 -
   1.110 -			float left_cost = eval_cost(faces, &kd->face_idx[0], kd->face_idx.size(), aabb_left, axis);
   1.111 -			float right_cost = eval_cost(faces, &kd->face_idx[0], kd->face_idx.size(), aabb_right, axis);
   1.112 -			float sum_cost = left_cost + right_cost - tcost;	// tcost is added twice
   1.113 -
   1.114 -			if(sum_cost < best_sum_cost) {
   1.115 -				best_cost[0] = left_cost;
   1.116 -				best_cost[1] = right_cost;
   1.117 -				best_sum_cost = sum_cost;
   1.118 -				best_split = split[axis];
   1.119 -			}
   1.120 +		if(split.sum_cost < best_split.sum_cost) {
   1.121 +			best_split = split;
   1.122  		}
   1.123  	}
   1.124  
   1.125 +	kd->axis = best_split.axis;
   1.126 +
   1.127  	//printf("current cost: %f,   best_cost: %f\n", kd->cost, best_sum_cost);
   1.128 -	if(best_sum_cost > kd->cost && (opt_max_items == 0 || (int)kd->face_idx.size() <= opt_max_items)) {
   1.129 +	if(best_split.sum_cost > kd->cost && (opt_max_items == 0 || (int)kd->face_idx.size() <= opt_max_items)) {
   1.130  		return true;	// stop splitting if it doesn't reduce the cost
   1.131  	}
   1.132  
   1.133 @@ -478,25 +509,25 @@
   1.134  
   1.135  	kdleft->aabb = kdright->aabb = kd->aabb;
   1.136  
   1.137 -	kdleft->aabb.max[axis] = best_split;
   1.138 -	kdright->aabb.min[axis] = best_split;
   1.139 +	kdleft->aabb.max[kd->axis] = best_split.pos;
   1.140 +	kdright->aabb.min[kd->axis] = best_split.pos;
   1.141  
   1.142 -	kdleft->cost = best_cost[0];
   1.143 -	kdright->cost = best_cost[1];
   1.144 +	kdleft->cost = best_split.cost_left;
   1.145 +	kdright->cost = best_split.cost_right;
   1.146  
   1.147  	// TODO would it be much better if we actually split faces that straddle the splitting plane?
   1.148  	for(size_t i=0; i<kd->face_idx.size(); i++) {
   1.149  		int fidx = kd->face_idx[i];
   1.150  		const Face *face = faces + fidx;
   1.151  
   1.152 -		if(face->v[0].pos[axis] < best_split ||
   1.153 -				face->v[1].pos[axis] < best_split ||
   1.154 -				face->v[2].pos[axis] < best_split) {
   1.155 +		if(face->v[0].pos[kd->axis] < best_split.pos ||
   1.156 +				face->v[1].pos[kd->axis] < best_split.pos ||
   1.157 +				face->v[2].pos[kd->axis] < best_split.pos) {
   1.158  			kdleft->face_idx.push_back(fidx);
   1.159  		}
   1.160 -		if(face->v[0].pos[axis] >= best_split ||
   1.161 -				face->v[1].pos[axis] >= best_split ||
   1.162 -				face->v[2].pos[axis] >= best_split) {
   1.163 +		if(face->v[0].pos[kd->axis] >= best_split.pos ||
   1.164 +				face->v[1].pos[kd->axis] >= best_split.pos ||
   1.165 +				face->v[2].pos[kd->axis] >= best_split.pos) {
   1.166  			kdright->face_idx.push_back(fidx);
   1.167  		}
   1.168  	}