Esempio n. 1
0
void BuildTreeRecursive(bsptree_t *tree, bspnode_t *node, bspline_t *lines)
{
	plane_t		plane;
	bspline_t	*sides[2];

	if (!lines)
	{
		node->leafnext = tree->leafs;
		tree->leafs = node;

		tree->numleafs++;
		return;
	}

	plane = SelectSplitPlane(lines);

	PartitionLineList(plane, lines, sides);

	node->plane = plane;
	
	// add two new nodes to the tree
	node->children[0] = MallocBSPNode(tree, node);
	node->children[1] = MallocBSPNode(tree, node);
	
	// recurse down the front and back sides
	BuildTreeRecursive(tree, node->children[0], sides[0]);
	BuildTreeRecursive(tree, node->children[1], sides[1]);
}
Esempio n. 2
0
bsptree_t *BuildTree()
{
	 bspline_t *lines = MakeLineList();

	bsptree_t *tree = MakeEmptyTree();

	BuildTreeRecursive(tree, tree->root, lines);

	return tree;
}
void JRTHeuristicKDTreeBuilder::BuildTreeImpl(const JRTBoundingBox& rBounds,
                                              const std::vector<const JRTTriangle*>& rTris,
                                              std::vector<JRTKDNode>& rNodesOut,
                                              std::vector<UINT>&      rTrisOut)
{

    rNodesOut.push_back(JRTKDNode());        // create root node

    // extract triangle BBs
    BuildBBs(rTris, m_bbs);

    // extract split planes
    std::vector<Split> splits[3];

    for (int i = 0; i < 3; i++)
    {
        ExtractSplits(i, m_bbs, splits[i], rBounds);
    }

    // build vectors of pointers to these split planes for shuffling around
    SplitVec splitPtrs[3];

    for (int i = 0; i < 3; i++)
    {
        splitPtrs[i].resize(splits[i].size());

        for (int j = 0; j < (int)splits[i].size(); j++)
        {
            splitPtrs[i][j] = &splits[i][j];
        }
    }

    // build vectors of pointers to BBs, also for shuffling around
    std::vector<TriangleBB*> bbPtrs;

    for (int i = 0; i < (int)m_bbs.size(); i++)
    {
        bbPtrs.push_back(&m_bbs[i]);
    }

    BuildTreeRecursive(JRTKDTree::MAX_TREE_DEPTH, rBounds,  splitPtrs, bbPtrs,  &rNodesOut[0], rNodesOut, rTrisOut);



}
void JRTHeuristicKDTreeBuilder::BuildTreeRecursive(UINT nDepthLimit,
                                                   const JRTBoundingBox& rNodeBounds,
                                                   SplitVec splits[3],
                                                   std::vector<TriangleBB*>& rBBsThisNode,
                                                   JRTKDNode* pNode,
                                                   std::vector<JRTKDNode>& rNodesOut,
                                                   std::vector<UINT>& rTrisOut)
{
    UINT nTriCount = (UINT)rBBsThisNode.size();

    JRT_ASSERT(splits[0].size() == splits[1].size() && splits[1].size() == splits[2].size());

    // initialize best cost to cost of not splitting
    float fBestCost = INTERSECT_COST * nTriCount;

    // find the optimal split
    bool bSplit = false;
    float fSplitValue;
    UINT eSplitAxis = X_AXIS;


    float fNodeBBInvArea = 1.0f / Max(0.0000001f, rNodeBounds.GetSurfaceArea());
    float fNodeVolume = rNodeBounds.GetVolume();

    for (UINT axis = X_AXIS; axis <= Z_AXIS; axis++)
    {
        LocateBestSplit(fNodeBBInvArea, rNodeBounds, splits, axis, nTriCount, fBestCost, bSplit, eSplitAxis, fSplitValue);
    }


    if (!bSplit || nDepthLimit == 0)
    {
        // we either don't want to split, or can't split, so make a leaf
        pNode->leaf.is_leaf = true;
        pNode->leaf.triangle_count = 0;
        pNode->leaf.triangle_start = (UINT)rTrisOut.size();

        for (UINT i = 0; i < rBBsThisNode.size(); i++)
        {
            // do robust tri-box clipping at the leaves
            const Vec3f* pV1 = &rBBsThisNode[i]->pTri->GetV1();
            const Vec3f* pV2 = &rBBsThisNode[i]->pTri->GetV2();
            const Vec3f* pV3 = &rBBsThisNode[i]->pTri->GetV3();

            if (rNodeBounds.TriangleIntersect(pV1, pV2, pV3))
            {
                rTrisOut.push_back(rBBsThisNode[i]->nIndex);
                pNode->leaf.triangle_count++;
            }
        }
    }
    else
    {
        // make a non-leaf

        pNode->inner.axis = eSplitAxis;
        pNode->inner.is_leaf = false;
        pNode->inner.position = fSplitValue;

        JRT_ASSERT(fSplitValue > rNodeBounds.GetMin()[eSplitAxis] &&
                   fSplitValue < rNodeBounds.GetMax()[eSplitAxis]);

        ClassifyBBs(splits[0], m_bbs, eSplitAxis, fSplitValue);

        // partition the splits
        SplitVec frontSplits[3];
        SplitVec backSplits[3];

        for (int j = X_AXIS; j <= Z_AXIS; j++)
        {
            PartitionSplits(fSplitValue, eSplitAxis, splits[j], m_bbs, backSplits[j], frontSplits[j]);

            // clear old split vec to save memory
            splits[j].clear();
        }

        // partition BBs
        std::vector<TriangleBB*> backBBs;
        std::vector<TriangleBB*> frontBBs;
        PartitionBBs(eSplitAxis, fSplitValue, rBBsThisNode, backBBs, frontBBs);

        rBBsThisNode.clear(); // save memory

        // create new nodes
        // by convention, always create front child right before back child
        pNode->inner.front_offset = (UINT)rNodesOut.size();
        UINT nFront = (UINT)rNodesOut.size();
        UINT nBack = nFront + 1;
        rNodesOut.push_back(JRTKDNode());
        rNodesOut.push_back(JRTKDNode());

        // split the node bounding box
        JRTBoundingBox front_bounds, back_bounds;
        rNodeBounds.Split(eSplitAxis, fSplitValue, front_bounds, back_bounds);

        // recursively build the subtrees
        BuildTreeRecursive(nDepthLimit - 1, front_bounds, frontSplits, frontBBs,  &rNodesOut[ nFront ], rNodesOut, rTrisOut);
        BuildTreeRecursive(nDepthLimit - 1, back_bounds,  backSplits,  backBBs, &rNodesOut[ nBack ], rNodesOut, rTrisOut);
    }
}