Exemple #1
0
// pick best split plane among all possible splits
float Bvh::pickBestSplit( unsigned& axis , float& split_pos , Bvh_Node* node , unsigned _start , unsigned _end )
{
	BBox inner;
	for( unsigned i = _start ; i < _end ; i++ )
		inner.Union( m_bvhpri[i].m_centroid );

	unsigned tri_num = _end - _start;
	axis = inner.MaxAxisId();
	float min_sah = FLT_MAX;

	// distribute the triangles into bins
	unsigned	bin[BVH_SPLIT_COUNT];
	BBox		bbox[BVH_SPLIT_COUNT];
	BBox		rbox[BVH_SPLIT_COUNT-1];
	memset( bin , 0 , sizeof( unsigned ) * BVH_SPLIT_COUNT );
	float split_start = inner.m_Min[axis];
	float split_delta = inner.Delta(axis) * BVH_INV_SPLIT_COUNT;
	float inv_split_delta = 1.0f / split_delta;
    for( unsigned i = _start ; i < _end ; i++ ){
		int index = (int)((m_bvhpri[i].m_centroid[axis] - split_start) * inv_split_delta);
		index = min( index , (int)(BVH_SPLIT_COUNT - 1) );
		bin[index]++;
		bbox[index].Union( m_bvhpri[i].GetBBox() );
	}

	rbox[BVH_SPLIT_COUNT-2].Union( bbox[BVH_SPLIT_COUNT-1] );
	for( int i = BVH_SPLIT_COUNT-3; i >= 0 ; i-- )
		rbox[i] = Union( rbox[i+1] , bbox[i+1] );

	unsigned	left = bin[0];
	BBox		lbox = bbox[0];
	float pos = split_delta + split_start ;
	for( unsigned i = 0 ; i < BVH_SPLIT_COUNT - 1 ; i++ ){
		float sah_value = sah( left , tri_num - left , lbox , rbox[i] , node->bbox );
		if( sah_value < min_sah ){
			min_sah = sah_value;
			split_pos = pos;
		}
		left += bin[i+1];
		lbox.Union( bbox[i+1] );
		pos += split_delta;
	}

	return min_sah;
}
Exemple #2
0
bool Collision::collide(const BBox &targetBound, const Matrix4D &treeMat,
	const KdAccelNode* treeNode, const KdTreeAccel* tree,
	BBox* &collisionBound, vector<Point3D*> &primpts)
{
	if (!collideP(treeNode->bbox, treeMat, targetBound))
	{
		return false;
	}
	// If collideP check if node is leaf
	if (!treeNode->isLeaf())
	{
		auto belowNode = treeNode->belowNode;
		auto aboveNode = treeNode->aboveNode;
		bool res = collide(targetBound, treeMat, belowNode, tree, collisionBound, primpts);
		//if (!res)
		{
			res |= collide(targetBound, treeMat, aboveNode, tree, collisionBound, primpts);
		}
		return res;
	}
	else// If node is leaf
	{
		/*collisionBound = new BBox(treeNode->bbox);
		return true;*/
		BBox* imBox = new BBox;
		treeNode->primIndex;
		vector<Point3D*> curPrimPts;
		for (auto idx : treeNode->primIndex)
		{
			auto prim = dynamic_cast<Triangle*>(tree->primitives[idx]);
			for (auto pt : prim->p)
			{
				auto wPt = new Point3D((treeMat * Vector4D(*pt, 1.0)).toVector3D());
				imBox->Union(*wPt);
				curPrimPts.push_back(wPt);
				//primpts.push_back(wPt);
			}
		}
		if (collideP(*imBox, targetBound))
		{
			collisionBound = imBox;
			//primpts.push_back(curPrimPts);
			primpts.insert(primpts.end(), curPrimPts.begin(), curPrimPts.end());

			return true;
		}
		for (auto pt : curPrimPts)
		{
			delete pt;
		}
		curPrimPts.clear();
		delete imBox;
		return false;
	}
}