示例#1
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);
		}
	}
}
示例#2
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);
		}
	}
}
示例#3
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);
			}
		}
	}
}
示例#4
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;
}
示例#5
0
OctreeNode* Octree::getRandomFullLeaf()
{
	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();

		// 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;
}