Esempio n. 1
0
BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int *result)
{
	int j;
	unsigned int total = 0;
	BVHTreeOverlap *overlap = NULL, *to = NULL;
	BVHOverlapData **data;
	
	/* check for compatibility of both trees (can't compare 14-DOP with 18-DOP) */
	if ((tree1->axis != tree2->axis) && (tree1->axis == 14 || tree2->axis == 14) && (tree1->axis == 18 || tree2->axis == 18))
		return NULL;
	
	/* fast check root nodes for collision before doing big splitting + traversal */
	if (!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf],
	                  min_axis(tree1->start_axis, tree2->start_axis),
	                  min_axis(tree1->stop_axis, tree2->stop_axis)))
	{
		return NULL;
	}

	data = MEM_callocN(sizeof(BVHOverlapData *) * tree1->tree_type, "BVHOverlapData_star");
	
	for (j = 0; j < tree1->tree_type; j++) {
		data[j] = (BVHOverlapData *)MEM_callocN(sizeof(BVHOverlapData), "BVHOverlapData");
		
		/* init BVHOverlapData */
		data[j]->overlap = (BVHTreeOverlap *)malloc(sizeof(BVHTreeOverlap) * max_ii(tree1->totleaf, tree2->totleaf));
		data[j]->tree1 = tree1;
		data[j]->tree2 = tree2;
		data[j]->max_overlap = max_ii(tree1->totleaf, tree2->totleaf);
		data[j]->i = 0;
		data[j]->start_axis = min_axis(tree1->start_axis, tree2->start_axis);
		data[j]->stop_axis  = min_axis(tree1->stop_axis,  tree2->stop_axis);
	}

#pragma omp parallel for private(j) schedule(static)
	for (j = 0; j < MIN2(tree1->tree_type, tree1->nodes[tree1->totleaf]->totnode); j++) {
		traverse(data[j], tree1->nodes[tree1->totleaf]->children[j], tree2->nodes[tree2->totleaf]);
	}
	
	for (j = 0; j < tree1->tree_type; j++)
		total += data[j]->i;
	
	to = overlap = (BVHTreeOverlap *)MEM_callocN(sizeof(BVHTreeOverlap) * total, "BVHTreeOverlap");
	
	for (j = 0; j < tree1->tree_type; j++) {
		memcpy(to, data[j]->overlap, data[j]->i * sizeof(BVHTreeOverlap));
		to += data[j]->i;
	}
	
	for (j = 0; j < tree1->tree_type; j++) {
		free(data[j]->overlap);
		MEM_freeN(data[j]);
	}
	MEM_freeN(data);
	
	(*result) = total;
	return overlap;
}
Esempio n. 2
0
static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2)
{
	int j;
	
	if (tree_overlap(node1, node2, data->start_axis, data->stop_axis)) {
		// check if node1 is a leaf
		if (!node1->totnode) {
			// check if node2 is a leaf
			if (!node2->totnode) {
				
				if (node1 == node2) {
					return;
				}
					
				if (data->i >= data->max_overlap) {
					// try to make alloc'ed memory bigger
					data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2);
					
					if (!data->overlap) {
						printf("Out of Memory in traverse\n");
						return;
					}
					data->max_overlap *= 2;
				}
				
				// both leafs, insert overlap!
				data->overlap[data->i].indexA = node1->index;
				data->overlap[data->i].indexB = node2->index;

				data->i++;
			}
			else {
				for (j = 0; j < data->tree2->tree_type; j++) {
					if (node2->children[j])
						traverse(data, node1, node2->children[j]);
				}
			}
		}
		else {
			for (j = 0; j < data->tree2->tree_type; j++) {
				if (node1->children[j])
					traverse(data, node1->children[j], node2);
			}
		}
	}
	return;
}