示例#1
0
void Octree::getFullLeafsWithinSphere(double* p, double radius, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;
	double nodeCenterToSphereCenterDist;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Get the distance between the node center and the sphere center
		nodeCenterToSphereCenterDist = Vector::dist3(p, node->getCenter());

		// Check if the current node is completely contained in the sphere.
		// If yes -> add all its full children to 'out'.
		if ( nodeCenterToSphereCenterDist + node->getVoxelRadius() <= radius )
			this->pushBackFullLeafsFromNode(node, out);
		// Check if the sphere intersects the current node
		else if ( fabs(radius - nodeCenterToSphereCenterDist) <= node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
				for ( i = 0 ; i < 8 ; ++i )
					nodes.push_back(node->getChild(i));
			else if ( node->isFull() )
				out.push_back(node);
		}
	}
}
示例#2
0
void Octree::getFullLeafsNearPlane(const double* p, const double* n, double dist, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Check if the sphere intersects the current node
		if ( fabs(Vector::signedDistToPlane3(p, n, node->getCenter())) <= dist + node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
			{
				for ( i = 0 ; i < 8 ; ++i )
					nodes.push_back(node->getChild(i));
			}
			else if ( node->isFull() )
				out.push_back(node);
		}
	}
}
示例#3
0
void Octree::fillOctree()
{
	double p[3];
	const double *center;
	int i, l, id, numOfPoints = mInputPoints->GetNumberOfPoints();
	OctreeNode* node;

	for ( i = 0 ; i < numOfPoints ; ++i )
	{
		// Some initialization
		mInputPoints->GetPoint(i, p);
		node = mRoot;

		// Go down to the right leaf
		for ( l = 0 ; l < mTreeLevels ; ++l )
		{
			node->createChildren(); // If this node already has children -> nothing will happen
			center = node->getCenter();
			id = 0;

			if ( p[0] >= center[0] ) id |= 4;
			if ( p[1] >= center[1] ) id |= 2;
			if ( p[2] >= center[2] ) id |= 1;

			node->fullDescendantsFlagsBitwiseOR((unsigned char)0x01 << id);
			node = node->getChild(id);
		}

		this->fillOctreeLeaf(node, i, p);
	}
}
示例#4
0
void Octree::getFullLeafsInRange(double* p, double r1, double r2, list<OctreeNode*>& out)
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i;
	double d1, d2, dist;

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element in the list
		nodes.pop_back();

#ifdef OCTREE_TEST_MODE
		++mNodeRangeTestCounter;
#endif

		// Get the distance between the sphere radius and the node center
		dist = Vector::dist3(p, node->getCenter());
		d1 = dist + node->getVoxelRadius();
		d2 = dist - node->getVoxelRadius();

		if ( d1 >= r1 && d2 <= r2 )
		{
			// Check if we have the special case that the voxel is completely between both spheres
			if ( d1 <= r2 && d2 >= r1 )
				this->pushBackFullLeafsFromNode(node, out);
			else
			{
				if ( node->hasChildren() )
				{
					// Push back the children for further processing
					for ( i = 0 ; i < 8 ; ++i )
						nodes.push_back(node->getChild(i));
				}
				// We have reached a leaf -> save it in 'out' if it's full
				else if ( node->isFull() )
					out.push_back(node);
			}
		}
	}
}
示例#5
0
OctreeNode* Octree::getRandomFullLeafOnSphere(const double* p, double radius) const
{
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);
	int i, rand_id;
	vector<int> tmp_ids;
	tmp_ids.reserve(8);

	while ( nodes.size() )
	{
		// Get the last element in the list
		OctreeNode* node = nodes.back();
		// Remove the last element from the list
		nodes.pop_back();

		// Check if the sphere intersects the current node
		if ( fabs(radius - Vector::dist3(p, node->getCenter())) <= node->getVoxelRadius() )
		{
			// We have an intersection -> push back the children of the current node
			if ( node->hasChildren() )
			{
				// Prepare the tmp id vector
				for ( i = 0 ; i < 8 ; ++i )
					tmp_ids.push_back(i);

				// Push back the children in random order
				for ( i = 0 ; i < 8 ; ++i )
				{
					rand_id = mRandGen.getRandomInteger(0, tmp_ids.size()-1);
					nodes.push_back(node->getChild(tmp_ids[rand_id]));
					// Remove the randomly selected id
					tmp_ids.erase(tmp_ids.begin() + rand_id);
				}
			}
			else if ( node->isFull() )
				return node;
		}
	}

	return NULL;
}