Esempio n. 1
0
/// <summary>
/// Generates the hierarchy.  http://devblogs.nvidia.com/parallelforall/wp-content/uploads/sites/3/2012/11/karras2012hpg_paper.pdf
/// </summary>
/// <param name="boxes">The boxes.</param>
void BVH::generateHierarchyFullParallel(std::vector<AABBox>& boxes)
{
	ProgressBar progressBar;

#if !_DEBUG
#pragma omp parallel for schedule(dynamic,1)
#endif
	for (int i = 0; i < (boxes.size() - 1); i++)
	{
		//first, find the range this node corresponds to
		//d == -1 means range ends at i, d == +1 means range starts at i
		int d = sign(commonPrefix(boxes, i, i + 1) - commonPrefix(boxes, i, i - 1));

		//find a maximum and minimum value for the range this node covers.  Must be a power of two for easy binary searching
		int min = commonPrefix(boxes, i, i - d);
		int max = 128;

		while (commonPrefix(boxes, i, i + (max * d)) > min)
		{
			max *= 4;
		}

		//use binary serach to find the farthest common prefis that is greater than min
		int l = 0;
		for (int t = max >> 1; t >= 1; t = t >> 1)
		{
			if (commonPrefix(boxes, i, i + (l + t) * d) > min)
			{
				//serach to the right of this value
				l += t;
			}
		}

		//end of range
		int j = i + l * d;
		int first = i;

		if (d < 0)
		{
			first = j;
			j = i;
		}


		// Determine where to split the range.
		int split = findSplit(boxes, first, j);

		Node* rightChild;
		if (split == first)
		{
			rightChild = &m_leafNodes[split];
		}
		else
		{
			rightChild = &m_branchNodes[split];
		}

		Node* leftChild;
		if (split + 1 == j)
		{
			leftChild = &m_leafNodes[split + 1];
		}
		else
		{
			leftChild = &m_branchNodes[split + 1];
		}

//		m_branchNodes[i].m = max;
//		m_branchNodes[i].re = first;
//		m_branchNodes[i].rs = j;
//		m_branchNodes[i].s = split;
		m_branchNodes[i].rightChild = rightChild;
		m_branchNodes[i].leftChild = leftChild;
//		leftChild->parent = &m_branchNodes[i];
//		rightChild->parent = &m_branchNodes[i];

#pragma omp critical
		{
			progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
		}
	}

	progressBar.end();
}
Esempio n. 2
0
void BVH::generateHierarchyStackLinear(std::vector<AABBox>& boxes)
{
	std::stack<constructData *> dataStack;
	dataStack.push(new constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1)));

	//	constructData *dataStackArray = new constructData[1024];
	//	dataStackArray[0] = constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1));
	//	uint32_t stackSize = 1;

	int i = 0;
	ProgressBar progressBar;

	do
	{
		constructData* data = dataStack.top();
		dataStack.pop();

		//		--stackSize;
		//		constructData data = dataStackArray[stackSize];

		// Determine where to split the range.
		int split = findSplit(boxes, data->first, data->last);

		Node* rightChild;
		if (split == data->first)
		{
			rightChild = &m_leafNodes[split];
		}
		else
		{
			rightChild = &m_branchNodes[split];

			//push next node
			dataStack.push(new constructData(rightChild, data->first, split));
			//			dataStackArray[stackSize] = constructData(rightChild, data.first, split);
			//			++stackSize;
		}

		Node* leftChild;
		if (split + 1 == data->last)
		{
			leftChild = &m_leafNodes[split + 1];
		}
		else
		{
			leftChild = &m_branchNodes[split + 1];

			//push next node
			dataStack.push(new constructData(leftChild, split + 1, data->last));
			//			dataStackArray[stackSize] = constructData(leftChild, split + 1, data.last);
			//			++stackSize;
		}

		//		m_branchNodes[i].m = max;
		//		data.node->re = data.last;
		//		data.node->rs = data.first;
		//		data.node->s = split;
		data->node->rightChild = rightChild;
		data->node->leftChild = leftChild;
		//		leftChild->parent = data.node;
		//		rightChild->parent = data.node;

		delete data;

		i++;
		progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
	}
	while (!dataStack.empty());

	progressBar.end();
}