65,187
社区成员




void KdTree::SAHBuildTree(int index, vector<TriangleEvent> *pEvent,float FatherCost)
{
int TempnPSide,leftTriangleNumber=0,rightTriangleNumber=0,planeTriangleNumber;
float CurCost=this->SAHFindPlane(index,pEvent,TempnPSide,TreeNode[index].planeAxis,TreeNode[index].splitPlane,leftTriangleNumber,rightTriangleNumber,planeTriangleNumber);
TreeNode[index].leftChild=-1;
TreeNode[index].rightChild=-1;
if(CurCost>=FatherCost) return;
leftTriangleNumber+=TempnPSide*planeTriangleNumber;
rightTriangleNumber+=(1-TempnPSide)*planeTriangleNumber;
TreeNode[index].leftChild=this->GetAvailableNodeIndex();
int leftChild=TreeNode[index].leftChild;
TreeNode[leftChild].TriangleNumber=leftTriangleNumber;
TreeNode[leftChild].trianglePtr=new int[leftTriangleNumber];
TreeNode[index].rightChild=this->GetAvailableNodeIndex();
int rightChild=TreeNode[index].rightChild;
TreeNode[rightChild].trianglePtr=new int[rightTriangleNumber];
int tempLIndex=0,tempRIndex=0;
for(int i=0;i<TreeNode[index].TriangleNumber;i++)//将三角形按照所选定的Split平面分给2个子结点
{
Triangle *p=&treeTriangle[TreeNode[index].trianglePtr[i]];
float v[3]={p->m_v1.x,p->m_v1.y,p->m_v1.z},v1[3]={p->m_v2.x,p->m_v2.y,p->m_v2.z},v2[3]={p->m_v3.x,p->m_v3.y,p->m_v3.z};
int Axis=TreeNode[index].planeAxis;
if(v[Axis]<TreeNode[index].splitPlane||v1[Axis]<TreeNode[index].splitPlane||v2[Axis]<TreeNode[index].splitPlane)
TreeNode[leftChild].trianglePtr[tempLIndex++]=TreeNode[index].trianglePtr[i];
if(v[Axis]>TreeNode[index].splitPlane||v1[Axis]>TreeNode[index].splitPlane||v2[Axis]>TreeNode[index].splitPlane)
TreeNode[rightChild].trianglePtr[tempRIndex++]=TreeNode[index].trianglePtr[i];
if(fabs(v[Axis]-TreeNode[index].splitPlane)<PRECISION&&fabs(v1[Axis]-TreeNode[index].splitPlane)<PRECISION
&&fabs(v2[Axis]-TreeNode[index].splitPlane)<PRECISION)
{
if(TempnPSide)
TreeNode[leftChild].trianglePtr[tempLIndex++]=TreeNode[index].trianglePtr[i];
else
TreeNode[rightChild].trianglePtr[tempRIndex++]=TreeNode[index].trianglePtr[i];
}
}
///ClassifyLeftRightBoth(T,E, ˆp) 将EVENT进行分类给左右子结点,从此往下都是为了计算子结点的event队列
int eventSize=pEvent->size();
vector<TriangleEvent>leftEvent; leftEvent.clear();
vector<TriangleEvent>tempLeftEvent; tempLeftEvent.clear();
vector<TriangleEvent>rightEvent; rightEvent.clear();
vector<TriangleEvent>tempRightEvent; tempRightEvent.clear();
vector<TriangleEvent>bothTriangle; bothTriangle.clear();
for(int i=0;i<eventSize;i++)
{
TriangleEvent tempEvent=(pEvent->at(i));
Triangle *p=&treeTriangle[tempEvent.triangleIndex];
float v[3]={p->m_v1.x,p->m_v1.y,p->m_v1.z},v1[3]={p->m_v2.x,p->m_v2.y,p->m_v2.z},v2[3]={p->m_v3.x,p->m_v3.y,p->m_v3.z};
if(v[tempEvent.planeAxis]<TreeNode[index].splitPlane&&v1[tempEvent.planeAxis]<TreeNode[index].splitPlane&&v2[tempEvent.planeAxis]<TreeNode[index].splitPlane)
{
try
{
leftEvent.push_back(tempEvent);
}
catch(bad_alloc &ba)
{
printf("%s\n",ba.what());
};
}
else if(v[tempEvent.planeAxis]>TreeNode[index].splitPlane&&v1[tempEvent.planeAxis]>TreeNode[index].splitPlane&&v2[tempEvent.planeAxis]>TreeNode[index].splitPlane)
rightEvent.push_back(tempEvent);
else
bothTriangle.push_back(tempEvent);
}
//给左右子节点的上下界赋值
memcpy(TreeNode[leftChild].MinCoordinate,TreeNode[index].MinCoordinate,sizeof(TYPE)*DIMENS);
memcpy(TreeNode[leftChild].MaxCoordinate,TreeNode[index].MaxCoordinate,sizeof(TYPE)*DIMENS);
TreeNode[leftChild].MaxCoordinate[TreeNode[index].planeAxis]=TreeNode[index].splitPlane;
memcpy(TreeNode[rightChild].MinCoordinate,TreeNode[index].MinCoordinate,sizeof(TYPE)*DIMENS);
memcpy(TreeNode[rightChild].MaxCoordinate,TreeNode[index].MaxCoordinate,sizeof(TYPE)*DIMENS);
TreeNode[rightChild].MinCoordinate[TreeNode[index].planeAxis]=TreeNode[index].splitPlane;
//对于跨俩侧的三角形,予以分割给左右子结点
for(unsigned int i=0;i<bothTriangle.size();i++)
{
SplitTriangle(bothTriangle[i].triangleIndex,TreeNode[leftChild].MinCoordinate,TreeNode[leftChild].MaxCoordinate,&tempLeftEvent);
SplitTriangle(bothTriangle[i].triangleIndex,TreeNode[rightChild].MinCoordinate,TreeNode[rightChild].MaxCoordinate,&tempRightEvent);
}
sort(tempLeftEvent.begin(),tempLeftEvent.end(),lessmark);
sort(tempRightEvent.begin(),tempRightEvent.end(),lessmark);
//分别对左右子结点进行归并排序
vector<TriangleEvent>curLeftEvent; curLeftEvent.clear();
unsigned int iTemp=0,iLeft=0,iRight=0;
//归并操作
while(iTemp<tempLeftEvent.size()||iLeft<leftEvent.size())
{
if(iTemp>=tempLeftEvent.size())
curLeftEvent.push_back(leftEvent[iLeft++]);
else if(iLeft>=leftEvent.size())
curLeftEvent.push_back(tempLeftEvent[iTemp++]);
else
{
if(tempLeftEvent[iTemp].planeAxis<leftEvent[iLeft].planeAxis)
curLeftEvent.push_back(tempLeftEvent[iTemp++]);
else if(tempLeftEvent[iTemp].planeAxis==leftEvent[iLeft].planeAxis&&tempLeftEvent[iTemp].splitPlane<leftEvent[iLeft].splitPlane)
curLeftEvent.push_back(tempLeftEvent[iTemp++]);
else if(tempLeftEvent[iTemp].planeAxis==leftEvent[iLeft].planeAxis&&fabs(tempLeftEvent[iTemp].splitPlane-leftEvent[iLeft].splitPlane)<PRECISION
&&tempLeftEvent[iTemp].triangleDirection<leftEvent[iLeft].triangleDirection)
curLeftEvent.push_back(tempLeftEvent[iTemp++]);
else curLeftEvent.push_back(leftEvent[iLeft++]);
}
}
iTemp=0;
vector<TriangleEvent>curRightEvent; curRightEvent.clear();
while(iTemp<tempRightEvent.size()||iRight<rightEvent.size())
{
if(iTemp>=tempRightEvent.size())
curRightEvent.push_back(rightEvent[iRight++]);
else if(iRight>=rightEvent.size())
curRightEvent.push_back(tempRightEvent[iTemp++]);
else
{
if(tempRightEvent[iTemp].planeAxis<rightEvent[iRight].planeAxis)
curRightEvent.push_back(tempRightEvent[iTemp++]);
else if(tempRightEvent[iTemp].planeAxis==rightEvent[iRight].planeAxis&&tempRightEvent[iTemp].splitPlane<rightEvent[iRight].splitPlane)
curRightEvent.push_back(tempRightEvent[iTemp++]);
else if(tempRightEvent[iTemp].planeAxis==rightEvent[iRight].planeAxis&&fabs(tempRightEvent[iTemp].splitPlane-rightEvent[iRight].splitPlane)<PRECISION
&&tempRightEvent[iTemp].triangleDirection<rightEvent[iRight].triangleDirection)
curRightEvent.push_back(tempRightEvent[iTemp++]);
else curRightEvent.push_back(rightEvent[iRight++]);
}
}
vector<TriangleEvent>().swap(tempLeftEvent);
vector<TriangleEvent>().swap(leftEvent);
vector<TriangleEvent>().swap(tempRightEvent);
vector<TriangleEvent>().swap(rightEvent);
vector<TriangleEvent>().swap((*pEvent));
SAHBuildTree(leftChild,&curLeftEvent,INTERSECTION_TIME*TreeNode[leftChild].TriangleNumber);
SAHBuildTree(rightChild,&curRightEvent,INTERSECTION_TIME*TreeNode[rightChild].TriangleNumber);
}
for(int i=0;i<TreeNode[index].TriangleNumber;i++)//将三角形按照所选定的Split平面分给2个子结点
{
Triangle *p=&treeTriangle[TreeNode[index].trianglePtr[i]];
float v[3]={p->m_v1.x,p->m_v1.y,p->m_v1.z},v1[3]={p->m_v2.x,p->m_v2.y,p->m_v2.z},v2[3]={p->m_v3.x,p->m_v3.y,p->m_v3.z};
int Axis=TreeNode[index].planeAxis;
if(v[Axis]<TreeNode[index].splitPlane||v1[Axis]<TreeNode[index].splitPlane||v2[Axis]<TreeNode[index].splitPlane)
TreeNode[leftChild].trianglePtr[tempLIndex++]=TreeNode[index].trianglePtr[i];
if(v[Axis]>TreeNode[index].splitPlane||v1[Axis]>TreeNode[index].splitPlane||v2[Axis]>TreeNode[index].splitPlane)
TreeNode[rightChild].trianglePtr[tempRIndex++]=TreeNode[index].trianglePtr[i];
if(fabs(v[Axis]-TreeNode[index].splitPlane)<PRECISION&&fabs(v1[Axis]-TreeNode[index].splitPlane)<PRECISION
&&fabs(v2[Axis]-TreeNode[index].splitPlane)<PRECISION)
{
if(TempnPSide)
TreeNode[leftChild].trianglePtr[tempLIndex++]=TreeNode[index].trianglePtr[i];
else
TreeNode[rightChild].trianglePtr[tempRIndex++]=TreeNode[index].trianglePtr[i];
}
}