示例#1
0
文件: octree.cpp 项目: monthero/nau
void 
Octree::_place (nau::scene::SceneObject *aSceneObject)
{
	static std::list<nau::scene::OctreeNode*> tmpVector;
	static int octant = 0;

	OctreeNode* aNode = reinterpret_cast<OctreeNode*> (aSceneObject);

	if (0 == m_pOctreeRootNode) {
		m_pOctreeRootNode = aNode;
		tmpVector.push_back (m_pOctreeRootNode);
		return;
	}

	if (aNode->m_NodeId < octant) {
		tmpVector.pop_front();
	}

	OctreeNode* currentNode = *(tmpVector.begin());
	octant = aNode->m_NodeId;

	currentNode->_setChild(octant, aNode);
	if (aNode->_getChildCount() > 0) {
		tmpVector.push_back (aNode);
	}
	
}
示例#2
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);
	}
}
//virtual 
void LLViewerOctreeGroup::unbound()
{
	if (isDirty())
	{
		return;
	}

	setState(DIRTY);
	
	//all the parent nodes need to rebound this child
	if (mOctreeNode)
	{
		OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent();
		while (parent != NULL)
		{
			LLViewerOctreeGroup* group = (LLViewerOctreeGroup*) parent->getListener(0);
			if (!group || group->isDirty())
			{
				return;
			}
			
			group->setState(DIRTY);
			parent = (OctreeNode*) parent->getParent();
		}
	}
}
// Returns the number of collision tests with the octree.
unsigned int OctreeNode::CollisionTest(const SceneObject& sceneObject)
{
	if(!ObjectIsInside(sceneObject))
		return 0;

	bool leaf= true;
	unsigned int collisionTestsCounter = 0;

	// Find the leaf wich contained the sceneObject.
	OctreeNode* currentNode = this->FindLeaf(sceneObject);

	if(currentNode == NULL)
		return collisionTestsCounter;

	// For each contained object : increase the collisionTestsCounter and set the green color (collision test are execute on green spheres).
	for(unsigned int i = 0; i < currentNode->GetContainedObjectsSize(); ++i)
	{
		collisionTestsCounter++;
		currentNode->GetContainedObject(i)->SetColor(ColorRGB::PureGreen);
	}

	currentNode->SetColor(ColorRGB::PureRed);

	return collisionTestsCounter;
}
示例#5
0
void Octree::CollectNodes(Vector<Pair<OctreeNode*, float> >& result, const Octant* octant, const Ray& ray, unsigned short nodeFlags,
    float maxDistance, unsigned layerMask) const
{
    float octantDist = ray.HitDistance(octant->cullingBox);
    if (octantDist >= maxDistance)
        return;

    const Vector<OctreeNode*>& octantNodes = octant->nodes;
    for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it)
    {
        OctreeNode* node = *it;
        if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask))
        {
            float distance = ray.HitDistance(node->WorldBoundingBox());
            if (distance < maxDistance)
                result.Push(MakePair(node, distance));
        }
    }

    for (size_t i = 0; i < NUM_OCTANTS; ++i)
    {
        if (octant->children[i])
            CollectNodes(result, octant->children[i], ray, nodeFlags, maxDistance, layerMask);
    }
}
示例#6
0
void Octree::DeleteChildOctants(Octant* octant, bool deletingOctree)
{
    for (auto it = octant->nodes.Begin(); it != octant->nodes.End(); ++it)
    {
        OctreeNode* node = *it;
        node->octant = nullptr;
        node->SetFlag(NF_OCTREE_UPDATE_QUEUED, false);
        if (deletingOctree)
            node->octree = nullptr;
    }
    octant->nodes.Clear();
    octant->numNodes = 0;

    for (size_t i = 0; i < NUM_OCTANTS; ++i)
    {
        if (octant->children[i])
        {
            DeleteChildOctants(octant->children[i], deletingOctree);
            octant->children[i] = nullptr;
        }
    }

    if (octant != &root)
        allocator.Free(octant);
}
示例#7
0
			void LightManager::CreateOctreeNode(Light* pLight)
			{
				ASSERT_PREDICATE_RETURN(pLight->GetUserObjectBindings().HasKey(m_StrOctreeNodeKey) == false);
				OctreeNode<float64>* pOctreeNode = new OctreeNode_64();
				pLight->GetUserObjectBindings().SetUserAny(m_StrOctreeNodeKey, pOctreeNode);
				// Store a back pointer
				pOctreeNode->GetUserObjectBindings().SetUserAny(m_StrLightKey, pLight);
			}
示例#8
0
template <typename PointT, typename NormalT> bool
cpu_tsdf::TSDFVolumeOctree::integrateCloud (
  const pcl::PointCloud<PointT> &cloud, 
  const pcl::PointCloud<NormalT> &normals,
  const Eigen::Affine3d &trans)
{
  Eigen::Affine3f trans_inv = trans.inverse ().cast<float> ();

  // First, sample a few points and force their containing voxels to split
  int px_step = 1;
  int nsplit = 0;
  for (size_t u = 0; u < cloud.width; u += px_step)
  {
    for (size_t v = 0; v < cloud.height; v += px_step)
    {
      const PointT &pt_surface_orig = cloud (u, v);
      if (pcl_isnan (pt_surface_orig.z))
        continue;
      // Look at surroundings
      int nstep = 0;
      Eigen::Vector3f ray = pt_surface_orig.getVector3fMap ().normalized ();
      for (int perm = 0; perm < num_random_splits_; perm++)
      {
        // Get containing voxels
        PointT pt_trans; 
        float scale = (float)rand () / (float)RAND_MAX * 0.03;
        Eigen::Vector3f noise = Eigen::Vector3f::Random ().normalized () * scale;;
        if (perm == 0) noise *= 0;
        pt_trans.getVector3fMap () = trans.cast<float> () * (pt_surface_orig.getVector3fMap ()+ noise);
        OctreeNode* voxel = octree_->getContainingVoxel (pt_trans.x, pt_trans.y, pt_trans.z);
        if (voxel != NULL)
        {
          while (voxel->getMinSize () > xsize_ / xres_)
          {
            nsplit++;
            voxel->split ();
            voxel = voxel->getContainingVoxel (pt_trans.x, pt_trans.y, pt_trans.z);
            
          }
        }
      }
    }
  }
  
  // Do Frustum Culling to get rid of unseen voxels
  std::vector<cpu_tsdf::OctreeNode::Ptr> voxels_culled;
  getFrustumCulledVoxels(trans, voxels_culled);
#pragma omp parallel for
  for (size_t i = 0; i < voxels_culled.size (); i++)
  {
    updateVoxel (voxels_culled[i], cloud, normals, trans_inv);
  }
  // Cloud is no longer empty
  is_empty_ = false;
  return (true);
}
示例#9
0
//==============================================================================
void Octree::placeSceneNode(SceneNode* sn)
{
	SpatialComponent* sp = sn->getSpatial();
	ANKI_ASSERT(sp != nullptr);
	OctreeNode* toBePlacedNode = place(sp->getAabb());

	if(toBePlacedNode != nullptr)
	{
		toBePlacedNode->addSceneNode(sn);
	}
}
示例#10
0
OctreeNode * OctreeScene::_InsideChild(OctreeNode * node, const Aabb & bound)
{
    const Aabb & ndbound = node->GetBound();

    Vec3 _half = ndbound.GetHalfSize();
    Vec3 _min = bound.minimum - ndbound.minimum;
    Vec3 _max = bound.maximum - ndbound.minimum;

    int ix0 = 0, iy0 = 0, iz0 = 0;
    int ix1 = 0, iy1 = 0, iz1 = 0;
    Aabb clbound(ndbound.minimum, ndbound.minimum);

    if (_min.x >= _half.x)
    {
        ix0 = 1;
        clbound.minimum.x += _half.x;
    }
    if (_min.y >= _half.y)
    {
        iy0 = 1;
        clbound.minimum.y += _half.y;
    }
    if (_min.z >= _half.z)
    {
        iz0 = 1;
        clbound.minimum.z += _half.z;
    }

    if (_max.x >= _half.x)
        ix1 = 1;
    if (_max.y >= _half.y)
        iy1 = 1;
    if (_max.z >= _half.z)
        iz1 = 1;

    clbound.maximum = clbound.minimum + _half;

    if (ix0 != ix1 || iy0 != iy1 || iz0 != iz1)
        return NULL;

    d_assert (Math::AABBInside(clbound, bound));

    int index = _MAKE_POSITION(ix0, iy1, iz1);

    OctreeNode * child = node->_GetChild(index);
    if (child == NULL)
    {
        child = AllocOctNode();
        child->SetBound(clbound);
        node->_SetChild(index, child);
    }

    return child;
}
示例#11
0
void Octree::Update()
{
    PROFILE(UpdateOctree);

    for (auto it = updateQueue.Begin(); it != updateQueue.End(); ++it)
    {
        OctreeNode* node = *it;
        // If node was removed before update could happen, a null pointer will be in its place
        if (node)
        {
            node->SetFlag(NF_OCTREE_UPDATE_QUEUED, false);

            // Do nothing if still fits the current octant
            const BoundingBox& box = node->WorldBoundingBox();
            Vector3 boxSize = box.Size();
            Octant* oldOctant = node->octant;
            if (oldOctant && oldOctant->cullingBox.IsInside(box) == INSIDE && oldOctant->FitBoundingBox(box, boxSize))
                continue;

            // Begin reinsert process. Start from root and check what level child needs to be used
            Octant* newOctant = &root;
            Vector3 boxCenter = box.Center();

            for (;;)
            {
                bool insertHere;
                // If node does not fit fully inside root octant, must remain in it
                if (newOctant == &root)
                    insertHere = newOctant->cullingBox.IsInside(box) != INSIDE || newOctant->FitBoundingBox(box, boxSize);
                else
                    insertHere = newOctant->FitBoundingBox(box, boxSize);

                if (insertHere)
                {
                    if (newOctant != oldOctant)
                    {
                        // Add first, then remove, because node count going to zero deletes the octree branch in question
                        AddNode(node, newOctant);
                        if (oldOctant)
                            RemoveNode(node, oldOctant);
                    }
                    break;
                }
                else
                    newOctant = CreateChildOctant(newOctant, newOctant->ChildIndex(boxCenter));
            }
        }
    }

    updateQueue.Clear();
}
SceneNode * OctreeSceneManager::createSceneNode( const String &name )
{
    // Check name not used
    if (mSceneNodes.find(name) != mSceneNodes.end())
    {
        OGRE_EXCEPT(
            Exception::ERR_DUPLICATE_ITEM,
            "A scene node with the name " + name + " already exists",
            "OctreeSceneManager::createSceneNode" );
    }
    OctreeNode * on = new OctreeNode( this, name );
    mSceneNodes[ on->getName() ] = on;
    return on;
}
示例#13
0
void OctreeScene::RemoveSceneNode(SceneNode * node)
{
   OctreeNode::_dirt dirt = *(OctreeNode::_dirt*)node->_GetSceneDirtData();
   dirt.node->RemoveNode(node);

   OctreeNode * eraseNode = dirt.node;
   if (eraseNode->_IsNil())
   {
       OctreeNode * parent = dirt.node->_GetParent();
       parent->_NotifyErase(eraseNode);
       FreeOctNode(eraseNode);
       eraseNode = parent;
   }
}
示例#14
0
void OctreeNode::removeAllChildren()
{
	ChildNodeMap::iterator i, iend;
	iend = mChildren.end();
	for (i = mChildren.begin(); i != iend; ++i)
	{
		OctreeNode* on = static_cast<OctreeNode*>(i->second);
		on->setParent(0);
		on->_removeNodeAndChildren();
	}
	mChildren.clear();
	mChildrenToUpdate.clear();
	
}
示例#15
0
// Returns the leaf wich contained the sceneObject.
// Returns NULL if the sceneObject parameter is not contained in the node.
OctreeNode* OctreeNode::FindLeaf(const SceneObject& sceneObject)
{
	if(!this->ObjectIsInside(sceneObject))
		return NULL;

	OctreeNode* currentNode = this;

	while(currentNode != NULL && !currentNode->IsALeaf())
	{
		currentNode = currentNode->FindNextNode(sceneObject);
	}

	return currentNode;
}
示例#16
0
void Octree::CollectNodes(Vector<OctreeNode*>& result, const Octant* octant, unsigned short nodeFlags, unsigned layerMask) const
{
    const Vector<OctreeNode*>& octantNodes = octant->nodes;
    for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it)
    {
        OctreeNode* node = *it;
        if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask))
            result.Push(node);
    }

    for (size_t i = 0; i < NUM_OCTANTS; ++i)
    {
        if (octant->children[i])
            CollectNodes(result, octant->children[i], nodeFlags, layerMask);
    }
}
示例#17
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);
		}
	}
}
示例#18
0
// Generates the octree.
// Divides the node into 8 children while the contained object is superior to the maxElementPerNode parameter.
void OctreeNode::GenerateOctree(vector<SceneObject*>& sceneObjectsList, unsigned int maxElementPerNode)
{
	stack<OctreeNode*> recursivityStack;

	recursivityStack.push(this);

	while(!recursivityStack.empty())
	{
		OctreeNode* currentNode = recursivityStack.top();
		recursivityStack.pop();
		
		// Add the sceneObjects which are inside the node to the contained list.
		for(vector<SceneObject*>::iterator it = sceneObjectsList.begin(); it != sceneObjectsList.end(); ++it)
		{
			if(currentNode->ObjectIsInside((**it)))
			{
				currentNode->m_containedObjects.push_back(&(**it));
			}
		}

		if(currentNode->m_containedObjects.size() > maxElementPerNode)
		{
			//Sons creation.
			float newSize = abs((currentNode->GetAABBMax().X() - currentNode->GetAABBMin().X()) / 2);

			currentNode->m_children[0] = new OctreeNode(Vector3(currentNode->GetAABBMin().X(), currentNode->GetAABBMin().Y(), currentNode->GetAABBMin().Z()), Vector3(currentNode->GetAABBMax().X() - newSize, currentNode->GetAABBMax().Y() - newSize, currentNode->GetAABBMax().Z() - newSize), ColorRGB::PureBlue);
			currentNode->m_children[1] = new OctreeNode(Vector3(currentNode->GetAABBMin().X() + newSize, currentNode->GetAABBMin().Y(), currentNode->GetAABBMin().Z()), Vector3(currentNode->GetAABBMax().X(), currentNode->GetAABBMax().Y() - newSize, currentNode->GetAABBMax().Z() - newSize), ColorRGB::PureBlue);
			currentNode->m_children[2] = new OctreeNode(Vector3(currentNode->GetAABBMin().X(), currentNode->GetAABBMin().Y() + newSize, currentNode->GetAABBMin().Z()), Vector3(currentNode->GetAABBMax().X() - newSize, currentNode->GetAABBMax().Y(), currentNode->GetAABBMax().Z() - newSize), ColorRGB::PureBlue);
			currentNode->m_children[3] = new OctreeNode(Vector3(currentNode->GetAABBMin().X() + newSize, currentNode->GetAABBMin().Y() + newSize, currentNode->GetAABBMin().Z()), Vector3(currentNode->GetAABBMax().X(), currentNode->GetAABBMax().Y(), currentNode->GetAABBMax().Z() - newSize), ColorRGB::PureBlue);
			currentNode->m_children[4] = new OctreeNode(Vector3(currentNode->GetAABBMin().X(), currentNode->GetAABBMin().Y(), currentNode->GetAABBMin().Z() + newSize), Vector3(currentNode->GetAABBMax().X() - newSize, currentNode->GetAABBMax().Y() - newSize, currentNode->GetAABBMax().Z()), ColorRGB::PureBlue);
			currentNode->m_children[5] = new OctreeNode(Vector3(currentNode->GetAABBMin().X() + newSize, currentNode->GetAABBMin().Y(), currentNode->GetAABBMin().Z() + newSize), Vector3(currentNode->GetAABBMax().X(), currentNode->GetAABBMax().Y() - newSize, currentNode->GetAABBMax().Z()), ColorRGB::PureBlue);
			currentNode->m_children[6] = new OctreeNode(Vector3(currentNode->GetAABBMin().X(), currentNode->GetAABBMin().Y() + newSize, currentNode->GetAABBMin().Z() + newSize), Vector3(currentNode->GetAABBMax().X() - newSize, currentNode->GetAABBMax().Y(), currentNode->GetAABBMax().Z()), ColorRGB::PureBlue);
			currentNode->m_children[7] = new OctreeNode(Vector3(currentNode->GetAABBMin().X() + newSize, currentNode->GetAABBMin().Y() + newSize, currentNode->GetAABBMin().Z() + newSize), currentNode->GetAABBMax(), ColorRGB::PureBlue);
		}

		for(unsigned int i = 0; i < 8; i++)
		{
			if(currentNode->GetChild(i) != NULL)
				recursivityStack.push(currentNode->GetChild(i));
		}
	}
}
示例#19
0
OctreeNode*
sps_real(CBface_list& input_faces,
         CBBOX& box,
         int height,
         double regularity,
         double min_dist,
         Bface_list& flist,
         ARRAY<Wvec>& blist,
         double& spacing
   ) 
{
   clock_t start, end;
   double duration; 
   flist.clear();
   blist.clear();

   OctreeNode* root = new OctreeNode(box.min(), box.max(), 1, NULL);
   if (height == 1) {
      root->set_leaf(true);
      root->set_disp(true);
   }
   root->intersects() = input_faces;

   start = clock();
   root->build_octree(height);
   end = clock();   
  
   duration = (double)(end - start) / CLOCKS_PER_SEC;
   err_adv(debug, "step 1 time: %f", duration); 
  
   start = clock();
   visit(root, regularity, flist, blist);
   end = clock();
   duration = (double)(end - start) / CLOCKS_PER_SEC;
   err_adv(debug, "step 2 time: %f", duration);

   // remove bad samples
   start = clock();
   double dist = min_dist * box.dim().length() / (1<<(height-1));
   spacing = dist;
   root->set_neibors();

   root->set_terms();

   remove_nodes(flist, blist, dist, root->terms());
   end = clock();
   duration = (double)(end - start) / CLOCKS_PER_SEC;
   err_adv(debug, "step 3 time: %f", duration);   
   err_adv(debug, "no of points: %d", flist.num());

   return root;
}
示例#20
0
void Octree::CollectNodes(Vector<RaycastResult>& result, const Octant* octant, const Ray& ray, unsigned short nodeFlags, 
    float maxDistance, unsigned layerMask) const
{
    float octantDist = ray.HitDistance(octant->cullingBox);
    if (octantDist >= maxDistance)
        return;

    const Vector<OctreeNode*>& octantNodes = octant->nodes;
    for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it)
    {
        OctreeNode* node = *it;
        if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask))
            node->OnRaycast(result, ray, maxDistance);
    }

    for (size_t i = 0; i < NUM_OCTANTS; ++i)
    {
        if (octant->children[i])
            CollectNodes(result, octant->children[i], ray, nodeFlags, maxDistance, layerMask);
    }
}
LLViewerOctreeGroup* LLViewerOctreeGroup::getParent()
{
	if (isDead())
	{
		return NULL;
	}

	if(!mOctreeNode)
	{
		return NULL;
	}
	
	OctreeNode* parent = mOctreeNode->getOctParent();

	if (parent)
	{
		return (LLViewerOctreeGroup*) parent->getListener(0);
	}

	return NULL;
}
示例#22
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);
		}
	}
}
示例#23
0
void Octree::buildNeighbourhoodStructure()
{
	if ( !mRoot )
		return;

	int i;
	OctreeNode* node;
	list<OctreeNode*> nodes;
	nodes.push_back(mRoot);

	while ( nodes.size() )
	{
		node = nodes.back();
		nodes.pop_back();

		if ( node->hasChildren() )
			for ( i = 0 ; i < 8 ; ++i )
				nodes.push_back(node->getChild(i));
		else if ( node->hasData() )
			this->collectFullNeighbours(node);
	}
}
示例#24
0
void OctreeScene::AddSceneNode(SceneNode * node)
{
    const Aabb & bound = node->GetWorldAabb();

    // check in this scene
    Scene * scene = node->_GetScene();
    if (scene == this)
        return;
    else if (scene)
        scene->RemoveSceneNode(node);

    // if not in root, force in root.
    if (!Math::AABBInside(m_root->GetBound(), bound))
    {
        m_root->AddNode(node);
    }
    else
    {
        OctreeNode * ocnode = _InsideNode(m_root, 0, bound);
        ocnode->AddNode(node);
    }
}
示例#25
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;
}
示例#26
0
void 
OctreeNode::build_octree(int height) 
{

   if (_leaf || _height == height) 
      return;

   int i, j;
   Wpt_list pts;
   points(pts);

   for (i = 0; i < 8; i++) {
      _children[i] = new OctreeNode((pts[0]+pts[i])/2, (pts[i]+pts[7])/2, 
                                    _height+1, this);
   }

   for (j = 0; j < _intersects.num(); j++) {
      Bface* f = _intersects[j];

      for (i = 0; i < 8; i++) {
         OctreeNode* n = _children[i];
         if (n->contains(f->v1()->loc()) && n->contains(f->v2()->loc())
             && n->contains(f->v3()->loc())) {
            n->intersects() += f;
            break;
         } else if (n->overlaps(bface_bbox(f))) {
            n->intersects() += f;
         }
      }
   }

   for (i = 0; i < 8; i++) {
      if (_height+1 == height) {
         _children[i]->set_leaf(true);
         _children[i]->set_disp(true);
      }
      if (_children[i]->intersects().empty()) {
         _children[i]->set_leaf(true);
         _children[i]->set_disp(false);
      }
      _children[i]->build_octree(height);
   }

}
示例#27
0
void
OctreeNode::set_neibors()
{
   OctreeNode* n;
   BBOX test_box = BBOX(min()-0.5*dim(), max()+0.5*dim());

   if ((!_leaf || _display) && _height != 1) {
      for (int i = 0; i < 8; i++) {
         n = _parent->get_children()[i];
         if (n != this && (!n->get_leaf() || n->get_disp())) {
            _neibors += n;
         }
      }

      _parent->neibors().num();

      for (int i = 0; i < _parent->neibors().num(); i++) {
         n = _parent->neibors()[i];
         if (!n->get_leaf()) {
            for (int j = 0; j < 8; j++) {
               if (n->get_children()[j]->overlaps(test_box) &&
                   (!n->get_children()[j]->get_leaf() || 
                    n->get_children()[j]->get_disp())) {
                  //XXX - crashing here...
                  _neibors += n->get_children()[j];
               }
            }
         }
      }
        
   }

   if (!_leaf) {
      for (int i = 0; i < 8; i++) {
         _children[i]->set_neibors();
      }
   }
}
示例#28
0
void OctreeNode::updateObjectPosition(Object3D* object){

	OctreeNode* actualNode = object->getOctreeNode();
	actualNode->objects.remove(object);
	if(actualNode->objectsInBranch()==0){
		actualNode->clearChildren();
	}
	if (actualNode->objectFits(object)){
		actualNode->addObject(object);
		return;
	}
	OctreeNode* parent =actualNode->getParent();
	if(parent == NULL){
		actualNode->objects.push_back(object);
		return;
	}
	object->setOctreeNode(parent);
	updateObjectPosition(object);
}
示例#29
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);
			}
		}
	}
}
示例#30
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;
}