bool Sphere::IntersectBox( aabb& a_Box ) { float dmin = 0; vector3 v1 = a_Box.GetPos(), v2 = a_Box.GetPos() + a_Box.GetSize(); if (m_Centre.x < v1.x) { dmin = dmin + (m_Centre.x - v1.x) * (m_Centre.x - v1.x); } else if (m_Centre.x > v2.x) { dmin = dmin + (m_Centre.x - v2.x) * (m_Centre.x - v2.x); } if (m_Centre.y < v1.y) { dmin = dmin + (m_Centre.y - v1.y) * (m_Centre.y - v1.y); } else if (m_Centre.y > v2.y) { dmin = dmin + (m_Centre.y - v2.y) * (m_Centre.y - v2.y); } if (m_Centre.z < v1.z) { dmin = dmin + (m_Centre.z - v1.z) * (m_Centre.z - v1.z); } else if (m_Centre.z > v2.z) { dmin = dmin + (m_Centre.z - v2.z) * (m_Centre.z - v2.z); } return (dmin <= m_SqRadius); }
bool PlanePrim::IntersectBox( aabb& a_Box ) { vector3 v[2]; v[0] = a_Box.GetPos(), v[1] = a_Box.GetPos() + a_Box.GetSize(); int side1, side2 = 0, i = 0; for ( side1 = 0, side2 = 0, i = 0; i < 8; i++ ) { vector3 p( v[i & 1].x, v[(i >> 1) & 1].y, v[(i >> 2) & 1].z ); if ((DOT( p, m_Plane.N ) + m_Plane.D) < 0) side1++; else side2++; } if ((side1 == 0) || (side2 == 0)) return false; else return true; }
void KDTree::GetBoxVertex(aabb box, Point3 *Pos) { Point3 start; Point3 end; for(int i = 0; i< 3; i++) { start.cell[i] = box.GetPos().cell[i]; end.cell[i] = box.GetPos().cell[i] + box.GetSize().cell[i]; } Pos[0].set(start); Pos[6].set(end); Pos[1].set(Point3(end.x,start.y,start.z)); Pos[2].set(Point3(end.x,start.y,end.z)); Pos[3].set(Point3(start.x,start.y,end.z)); Pos[4].set(Point3(start.x,end.y,start.z)); Pos[5].set(Point3(end.x,end.y,start.z)); Pos[7].set(Point3(start.x,end.y,end.z)); }
void KDTree::Optimize(KDTreeNode* R,Side s,aabb AABB) { if(!R) return; while(R->Type != LEFT) { if(s-2*R->m_Axis>=0&&s-2*R->m_Axis<=1) { if(s%2==0) R = R->m_rchild; else R = R->m_lchild; } else if(R->m_Split >=AABB.GetPos().cell[R->m_Axis]+AABB.GetSize().cell[R->m_Axis]) R = R->m_lchild; else if(R->m_Split <= AABB.GetPos().cell[R->m_Axis]) R = R->m_rchild; else break; } }
bool KDTree::findOptimalSplitPositon(TriangleList *list,aabb &box,int depth, real &splitPosition,aabb &frontBox, aabb &backBox) { bool foundOptimalSplit = false; //make a list of the split position candidates int axis = depth % Dimension; real pos1 = box.GetPos().cell[axis];//the rangle of the axis direction within the box real pos2 = box.GetPos().cell[axis] + box.GetSize().cell[axis]; bool *pright = new bool[list->GetCount()]; TriangleNode *tempList = list->GetHead(); SplitList* SList = new SplitList(); int aidx = 0; while(tempList) { real pos; pright[aidx++]= true; for(int i=0;i<3;i++) { pos = tempList->GetVertex(i).cell[axis]; if((pos >= pos1)&&(pos <= pos2)) SList->InsertSplitPos(pos); } tempList = tempList->GetNext(); } //determine nlcount / nrcont for each split position aabb tempFrontBox = box; aabb tempBackBox = box; float tempFrontBoxp1 = tempFrontBox.GetPos().cell[axis]; float tempBackBoxp2 = tempBackBox.GetPos().cell[axis] + tempBackBox.GetSize().cell[axis]; SplitNode* splist = SList->GetHead(); while(splist!=NULL) { tempBackBox.GetPos().cell[axis] = splist->splitpos; tempBackBox.GetSize().cell[axis] = pos2 - splist->splitpos; tempFrontBox.GetSize().cell[axis] = splist->splitpos - pos1; float tempFrontBoxp2 = tempFrontBox.GetPos().cell[axis] + tempFrontBox.GetSize().cell[axis]; float tempBackBoxp1 = tempBackBox.GetPos().cell[axis]; tempList = list->GetHead(); int i = 0; while(tempList) { if(pright[i]) { int position = partitionTriangle(tempList,depth,splist->splitpos); switch(position) { case kdBefore: splist->nlcount++; pright[i]=false; break; case kdAfter: splist->nrcount++; break; case kdIntersection: splist->nlcount++; splist->nrcount++; break; } }else { splist->nlcount++; } tempList = tempList->GetNext(); } splist = splist->next; i++; } delete pright; float bestPos = 0.0; float lowCost = caculateSingleVoxelCost(list->GetCount(),box); float bestCost = lowCost; splist = SList->GetHead(); while(splist) { tempBackBox.GetPos().cell[axis] = splist->splitpos; tempBackBox.GetSize().cell[axis] = pos2 - splist->splitpos; tempFrontBox.GetSize().cell[axis] = splist->splitpos - pos1; real splitcost = cTraversal * lowCost + caculateCost(splist,tempFrontBox,tempBackBox); if(splitcost < lowCost) { foundOptimalSplit = true; bestCost = splitcost; bestPos = splist->splitpos; frontBox = tempFrontBox; backBox = tempBackBox; } splist = splist->next; } splitPosition = bestPos; return foundOptimalSplit; }