Example #1
0
void csBSPTree::Build (csTriangle* triangles, csPlane3* planes,
	size_t num_triangles, const csVector3* vertices,
	const csArray<int>& triidx)
{
  CS_ASSERT (triidx.GetSize () > 0);
  if (triidx.GetSize () == 1)
  {
    splitters.Push (triidx[0]);
    return;
  }

  size_t idx = FindBestSplitter (triangles, planes, num_triangles, vertices,
  	triidx);
  CS_ASSERT (idx != (size_t)-1);
  splitters.Push (triidx[idx]);

  csArray<int> left;
  csArray<int> right;
  size_t i;
  split_plane = planes[triidx[idx]];
  for (i = 0 ; i < triidx.GetSize () ; i++)
    if (i != idx)
    {
      int idxi = triidx[i];
      csTriangle& trj = triangles[idxi];
      int cla = ClassifyPlane (split_plane, vertices[trj.a]);
      int clb = ClassifyPlane (split_plane, vertices[trj.b]);
      int clc = ClassifyPlane (split_plane, vertices[trj.c]);
      if ((cla == -clb && cla != 0) ||
	  (cla == -clc && cla != 0) ||
	  (clb == -clc && clb != 0))
      {
	// There is a split.
	left.Push (idxi);
	right.Push (idxi);
      }
      else
      {
	if (cla == -1 || clb == -1 || clc == -1)
	  left.Push (idxi);
	else if (cla == 1 || clb == 1 || clc == 1)
	  right.Push (idxi);
        else
	  splitters.Push (idxi);
      }
    }
  if (left.GetSize () > 0)
  {
    child1 = TreeNodes()->Alloc ();
    child1->Build (triangles, planes, num_triangles, vertices, left);
  }
  if (right.GetSize () > 0)
  {
    child2 = TreeNodes()->Alloc ();
    child2->Build (triangles, planes, num_triangles, vertices, right);
  }
}
Example #2
0
void HQBSPTreeNode::CreateChilds()
{
	this->CalBoundingBox();
	if(!FindBestSplitter())//this is leaf node, polygons in list form a convex group
	{
		this->tree->numPoly += this->numPoly;
		return;
	}
	

	frontNode = HQ_NEW HQBSPTreeNode();
	backNode = HQ_NEW HQBSPTreeNode();
	
	frontNode->tree = backNode->tree = this->tree;
	frontNode->parentNode = backNode->parentNode = this;

	HQPolyListNode *pNode = headNode;
	

	//chia danh sách polygon làm 2 nhánh sau và trước mặt splitter
	while(pNode != NULL)
	{
		const HQPolygon3D* poly = pNode->GetPolygon();

		HQPlane::Side side = splitter.CheckSide(*poly);

		switch(side)
		{
		case HQPlane::FRONT_PLANE:
			frontNode->AddPolygon(poly);
			break;
		case HQPlane::BACK_PLANE:
			backNode->AddPolygon(poly);
			break;
		case HQPlane::IN_PLANE://nằm trên mặt splitter
			{
				hq_float32 dot = splitter.N * poly->GetPlane().N;
				if(dot >= 0.0f)//pháp vector polygon cùng hướng với pháp vector của splitter
					frontNode->AddPolygon(poly);
				else
					backNode->AddPolygon(poly);
			}
			break;
		case HQPlane::BOTH_SIDE://cắt splitter
			{
#ifdef HQ_EXPLICIT_ALIGN
				HQ_DECL_STACK_VAR_ARRAY(HQPolygon3D, polys, 2);
				HQPolygon3D &front = polys[0];
				HQPolygon3D &back = polys[1];
#else
				HQPolygon3D front,back;
#endif
				poly->Clip(splitter , &front, &back);//chia polygon làm 2 polygon phía sau và trước splitter
				backNode->AddPolygon(&back);
				frontNode->AddPolygon(&front);
			}
			break;
		}

		pNode = pNode->pNext;
	}
	
	this->ClearPolyList();

	frontNode->CreateChilds();
	backNode->CreateChilds();
}