int FrustumContainsBox( CD3DCamera * pCamera, Box3f BBox ) { Vector3f vCorner[8]; int iTotalIn = 0; Plane3f * plane = pCamera->GetCullInfo()->wmlPlaneFrustum; // get the corners of the box into the vCorner array BBox.ComputeVertices(vCorner); // test all 8 corners against the 6 sides // if all points are behind 1 specific plane, we are out // if we are in with all points, then we are fully in for(int p = 0; p < 6; ++p) { int iInCount = 8; int iPtIn = 1; for(int i = 0; i < 8; ++i) { // test this point against the planes if( plane[p].WhichSide(vCorner[i]) == Plane3f::NEGATIVE_SIDE ) { iPtIn = 0; --iInCount; } } // were all the points outside of plane p? if(iInCount == 0) { return(OUTSIDE); } // check if they were all on the right side of the plane iTotalIn += iPtIn; } // so if iTotalIn is 6, then all are inside the view if(iTotalIn == 6) { return(INSIDE); } // we must be partly in then otherwise return(INTERSECT); //WORKING }
void CQuadTree::AddReference( Box3f box, CEntity * pEntity, CQuadNode * node ) { assert( m_iLevels > 1 ); int iNumInside = 0; Box3f boxTemp = box; Box3f boxEnt = *pEntity->GetBoundingBox(); // move box to the entity's height boxTemp.Center().Y() = boxEnt.Center().Y(); boxTemp.Extent(1) = 100.0f; //extend this box infinitely bool bEntInQuad = false; Vector3f vBoxVerts[8]; bool abValid[8] = { 1,1,1,1,1,1,1,1 };//{ 0,0,0,0,0,0,0,0 }; bool bEntBoxInNode = false; bool bNodeInEntBox = false; //switch(TestIntersection( boxTemp, boxEnt ) ) switch(TestIntersection( boxEnt, boxTemp ) ) { case true: // box intersects node->m_EntMap[pEntity->GetId()] = pEntity; bEntInQuad = true; // find if the children intersect too break; case false: // ent box is INSIDE or OUTSIDE the node // get vertices for the bounding box boxEnt.ComputeVertices(vBoxVerts); // if entities box is contained in node box for (int j=0; j<8; j++ ) { if (InBox( vBoxVerts[j], boxTemp)) { bEntBoxInNode = true; } } if (bEntBoxInNode == true) { //if (ContOrientedBox (8, vBoxVerts, abValid, node->m_BBox)) { node->m_EntMap[pEntity->GetId()] = pEntity; //entity is in this node bEntInQuad = true; // find out what child quads also contain this iNumInside++; } else { // OUTSIDE or entities box contains the bounding box! boxTemp.ComputeVertices(vBoxVerts); // if node box is contained in entities box for (int j=0; j<8; j++ ) { if (InBox( vBoxVerts[j], boxEnt)) { bNodeInEntBox = true; } } if (bNodeInEntBox == true) { //if (ContOrientedBox (8, vBoxVerts, abValid, boxTemp)) { node->m_EntMap[pEntity->GetId()] = pEntity; //entity is in this node bEntInQuad = true; // find out what child quads also contain this } else { // entity is outside, so don't add bEntInQuad = false; return; } } break; } // now this box will also intersect/be contained in the children as well if (bEntInQuad == true ) { //check if we need to subdivide even further if (iNumInside >= MAX_ENTS_PER_NODE) { m_iLevels++; //increase the number of levels SubDivide(node, m_iLevels-1); } if (node->m_pChildNode[NE] != NULL) { AddReference( node->m_pChildNode[NE]->m_BBox, pEntity, node->m_pChildNode[NE]); //node->m_pChildNode[NE]->m_EntMap[pEntity->GetId()] = pEntity; } if (node->m_pChildNode[NW] != NULL) { AddReference( node->m_pChildNode[NW]->m_BBox, pEntity, node->m_pChildNode[NW]); //node->m_pChildNode[NW]->m_EntMap[pEntity->GetId()] = pEntity; } if (node->m_pChildNode[SE] != NULL) { AddReference( node->m_pChildNode[SE]->m_BBox, pEntity, node->m_pChildNode[SE]); //node->m_pChildNode[SE]->m_EntMap[pEntity->GetId()] = pEntity; } if (node->m_pChildNode[SW] != NULL) { AddReference( node->m_pChildNode[SW]->m_BBox, pEntity, node->m_pChildNode[SW]); //node->m_pChildNode[SW]->m_EntMap[pEntity->GetId()] = pEntity; } } return; }