예제 #1
0
/* multithreaded binning builder */
BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level)
{
	size_t size = range.size();
	float leafSAH = params.sah_triangle_cost * range.leafSAH;
	float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_triangle_cost * range.splitSAH;

	/* make leaf node when threshold reached or SAH tells us */
	if(params.small_enough_for_leaf(size, level) || (size <= params.max_leaf_size && leafSAH < splitSAH))
		return create_leaf_node(range);

	/* perform split */
	BVHObjectBinning left, right;
	range.split(&references[0], left, right);

	/* create inner node. */
	InnerNode *inner;

	if(range.size() < THREAD_TASK_SIZE) {
		/* local build */
		BVHNode *leftnode = build_node(left, level + 1);
		BVHNode *rightnode = build_node(right, level + 1);

		inner = new InnerNode(range.bounds(), leftnode, rightnode);
	}
	else {
		/* threaded build */
		inner = new InnerNode(range.bounds());

		task_pool.push(new BVHBuildTask(this, inner, 0, left, level + 1), true);
		task_pool.push(new BVHBuildTask(this, inner, 1, right, level + 1), true);
	}

	return inner;
}
예제 #2
0
/* single threaded spatial split builder */
BVHNode* BVHBuild::build_node(const BVHRange& range, int level)
{
	/* progress update */
	progress_update();
	if(progress.get_cancel())
		return NULL;

	/* small enough or too deep => create leaf. */
	if(!(range.size() > 0 && params.top_level && level == 0)) {
		if(params.small_enough_for_leaf(range.size(), level)) {
			progress_count += range.size();
			return create_leaf_node(range);
		}
	}

	/* splitting test */
	BVHMixedSplit split(this, range, level);

	if(!(range.size() > 0 && params.top_level && level == 0)) {
		if(split.no_split) {
			progress_count += range.size();
			return create_leaf_node(range);
		}
	}
	
	/* do split */
	BVHRange left, right;
	split.split(this, left, right, range);

	progress_total += left.size() + right.size() - range.size();
	size_t total = progress_total;

	/* leaft node */
	BVHNode *leftnode = build_node(left, level + 1);

	/* right node (modify start for splits) */
	right.set_start(right.start() + progress_total - total);
	BVHNode *rightnode = build_node(right, level + 1);

	/* inner node */
	return new InnerNode(range.bounds(), leftnode, rightnode);
}
예제 #3
0
파일: avl.c 프로젝트: asabeeh18/PROgrammin
// Function to insert a new node in AVL Tree
struct node* insert_node(struct node *tree, int num)
{
    int balance_factor;
    if (tree == NULL)
        return(create_leaf_node(num));
 
    if (tree->data > num)
        tree->left  = insert_node(tree->left, num);
    else
        tree->right = insert_node(tree->right, num);
 
    // Update height
    tree->height = max(compute_height(tree->left), compute_height(tree->right)) + 1;
 
    // Check AVL tree is balanced or not
    balance_factor = get_balance_factor(tree);
 
    // If unbalanced, then 4 cases of rotation
    // 1. Left Left Case - Only 1 Right Rotate will solve unbalancy
    if (balance_factor > 1 && num < tree->left->data)
        return right_rotate(tree);
 
    // 2. Right Right Case - Only 1 Left Rotate will solve unbalancy
    if (balance_factor < -1 && num >= tree->right->data)
        return left_rotate(tree);
 
    // 3. Left Right Case - Left rotation on left child will make it left left case
    if (balance_factor > 1 && num >= tree->left->data)
    {
        tree->left =  left_rotate(tree->left);
        return right_rotate(tree);
    }
 
    // 4. Right Left Case - Right rotation on right child will make it right right case
    if (balance_factor < -1 && num < tree->right->data)
    {
        tree->right = right_rotate(tree->right);
        return left_rotate(tree);
    }

    // If balanced then return unchanged node 
    return tree;
}
예제 #4
0
/* multithreaded binning builder */
BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level)
{
    size_t size = range.size();
    float leafSAH = params.sah_primitive_cost * range.leafSAH;
    float splitSAH = params.sah_node_cost * range.bounds().half_area() + params.sah_primitive_cost * range.splitSAH;

    /* have at least one inner node on top level, for performance and correct
     * visibility tests, since object instances do not check visibility flag */
    if(!(range.size() > 0 && params.top_level && level == 0)) {
        /* make leaf node when threshold reached or SAH tells us */
        if(params.small_enough_for_leaf(size, level) || (range_within_max_leaf_size(range) && leafSAH < splitSAH))
            return create_leaf_node(range);
    }

    /* perform split */
    BVHObjectBinning left, right;
    range.split(&references[0], left, right);

    /* create inner node. */
    InnerNode *inner;

    if(range.size() < THREAD_TASK_SIZE) {
        /* local build */
        BVHNode *leftnode = build_node(left, level + 1);
        BVHNode *rightnode = build_node(right, level + 1);

        inner = new InnerNode(range.bounds(), leftnode, rightnode);
    }
    else {
        /* threaded build */
        inner = new InnerNode(range.bounds());

        task_pool.push(new BVHBuildTask(this, inner, 0, left, level + 1), true);
        task_pool.push(new BVHBuildTask(this, inner, 1, right, level + 1), true);
    }

    return inner;
}
예제 #5
0
파일: bvh.c 프로젝트: TomPeerdeman/GEGT2013
// Recursively subdivide triangles into two groups, by determining
// a split plane and sorting the triangles into "left-of" and "right-of".
static bvh_node*
bvh_build_recursive(int depth, boundingbox bbox, triangle* triangles, int num_triangles)
{
    vec3        bbox_size, bbox_center;
    int         i, j, t;
    int         sorted_dimensions[3];
    int         split_axis;
    float       split_value;
    int         num_triangles_left, num_triangles_right;
    boundingbox left_bbox, right_bbox;
    bvh_node    *left_child, *right_child;

    if (depth == max_depth || num_triangles <= acceptable_leaf_size)
    {
        // Create a leaf node
#ifdef VERBOSE
        if (num_triangles > acceptable_leaf_size)
            printf("[%d] Maximum depth reached, forced to create a leaf of %d triangles\n", depth, num_triangles);
        else
            printf("[%d] Creating a leaf node of %d triangles\n", depth, num_triangles);
#endif
        return create_leaf_node(bbox, triangles, num_triangles);
    }

    //
    // Split the triangles into two groups, using a split plane based
    // on largest bbox side
    //

    bbox_size = v3_subtract(bbox.max, bbox.min);
    bbox_center = v3_multiply(v3_add(bbox.min, bbox.max), 0.5);

    // Sort bbox sides by size in descending order

    sorted_dimensions[0] = 0;
    sorted_dimensions[1] = 1;
    sorted_dimensions[2] = 2;

    // Good old bubble sort :)
    for (i = 0; i < 2; i++)
    {
        for (j = i+1; j < 3; j++)
        {
            if (v3_component(bbox_size, sorted_dimensions[i])
                <
                v3_component(bbox_size, sorted_dimensions[j]))
            {
                t = sorted_dimensions[i];
                sorted_dimensions[i] = sorted_dimensions[j];
                sorted_dimensions[j] = t;
            }
        }
    }

    // Iterate over the three split dimensions in descending order of
    // bbox size on that dimension. When the triangles are unsplitable
    // (or not very favorably) continue to the next dimension. Create a
    // leaf with all triangles in case none of dimensions is a good
    // split candidate.

    for (i = 0; i < 3; i++)
    {
        // Partition the triangles on the chosen split axis, with the
        // split plane at the center of the bbox

        split_axis = sorted_dimensions[i];
        split_value = v3_component(bbox_center, split_axis);

#ifdef VERBOSE
        printf("[%d] Splitting on axis %d, value %.3f\n", depth, split_axis, split_value);
#endif

        partition_on_split_value(&num_triangles_left, &num_triangles_right,
            triangles, num_triangles, split_axis, split_value);

#ifdef VERBOSE
        printf("[%d] %d left, %d right\n", depth, num_triangles_left, num_triangles_right);
#endif

        if (num_triangles_left == 0 || num_triangles_right == 0)
            continue;

        // Determine bboxes for the two new groups of triangles

        left_bbox = bound_triangles(triangles, num_triangles_left);

        if (v3_component(v3_subtract(left_bbox.max, left_bbox.min), split_axis)
            >
            0.9 * v3_component(bbox_size, split_axis))
        {
            //printf("[%d] skipping dimension (left)\n", split_axis);
            continue;
        }

#ifdef VERBOSE
        printf("[%d] left bbox:  %.3f, %.3f, %.3f .. %.3f, %.3f, %.3f\n",
            depth, left_bbox.min.x, left_bbox.min.y, left_bbox.min.z,
            left_bbox.max.x, left_bbox.max.y, left_bbox.max.z);
#endif

        right_bbox = bound_triangles(triangles+num_triangles_left, num_triangles_right);

        if (v3_component(v3_subtract(right_bbox.max, right_bbox.min), split_axis)
            >
            0.9 * v3_component(bbox_size, split_axis))
        {
            //printf("[%d] skipping dimension (right)\n", split_axis);
            continue;
        }

#ifdef VERBOSE
        printf("[%d] right bbox: %.3f, %.3f, %.3f .. %.3f, %.3f, %.3f\n",
            depth, right_bbox.min.x, right_bbox.min.y, right_bbox.min.z,
            right_bbox.max.x, right_bbox.max.y, right_bbox.max.z);
#endif

        // Recurse using the two new groups

        left_child = bvh_build_recursive(depth+1, left_bbox, triangles, num_triangles_left);
        right_child = bvh_build_recursive(depth+1, right_bbox, triangles+num_triangles_left, num_triangles_right);

        // Create an inner code with two children

        return create_inner_node(left_child, right_child);
    }

    // Split dimensions exhausted, forced to create a leaf

#ifdef VERBOSE
    printf("Split dimensions exhausted, creating a leaf of %d triangles\n", num_triangles);
#endif

    return create_leaf_node(bbox, triangles, num_triangles);
}