#ifndef __SPATIAL_TREE_ITER_H__ #define __SPATIAL_TREE_ITER_H__ #include #include #include #include #include #include #include #include //#include typedef int tMark; class SpatialTreeIter { public: SpatialTreeIter(); ~SpatialTreeIter(); void SetToRoot( SpatialTree& irTree ); void Clear(); //Allocation&Placement Navigation /* void Place( ISpatialProxyAA& irTVolume, T* ipT ); void ReservePlaceT( ISpatialProxyAA& irTVolume, int iCount ); void Place( ISpatialProxyAA& irTVolume, D* ipD ); void ReservePlaceD( ISpatialProxyAA& irTVolume, int iCount ); void Place( ISpatialProxyAA& irIVolume, I* ipI ); void ReservePlaceI( ISpatialProxyAA& irIVolume, int iCount ); void AllocateAllReservations(); */ //Node Retrieval Methods SpatialNode& rSeekNode( ISpatialProxyAA& irTVolume, int iCurNodeOffset=0 ); SpatialNode& rIthNode( int iIth ); int NumNodes(); void SeekSubNodes( ISpatialProxyAA& irTVolume, UseArray& orNodeOffsets, int iCurNodeOffset=0 ); void SeekAllNodes( ISpatialProxyAA& irTVolume, UseArray& orNodeOffsets, int iCurNodeOffset=0 ); void SetUpNodeList( UseArray& orNodeOffsets ); //Iteration Initialization void MarkAll( SphereSP& irDesiredVolume, tMark iMark ); void MarkAllSphere( SphereSP& irSphere, tMark iMark ); void MarkSubTrees( ISpatialProxyAA& irDesiredVolume, tMark iMark ); void MarkTree( tMark iMark ); void AndTree( tMark iMark ); void OrTree( tMark iMark ); void OrTreeVis( tMark iMark ); //Iteration Navigation SpatialNode& rSeekLeaf( Vector3f& irPt ); void SetIterFilter( tMark iMark ); void MoveToFirst(); SpatialNode& rCurrent(); inline SpatialNode* pCurrent(); void MoveToNext(bool ibIncludeVis=false); SpatialNode& rMoveToNext(bool ibIncludeVis=false); SpatialNode* pMoveToNext(bool ibIncludeVis=false); bool NotDone(); bool IsCurrentLeaf(); //Debug Functionality // void DisplayBoundingBox(); void DisplayCurrentBoundingBox( const tColour& irColour ); bool IsSetUp(); BoxPts* CurrentBBox(); BoxPts& rBBox(); void BuildBBoxes( BoxPts iBoxPts, int iCurNodeOffset = 0); enum { msFilterInvisible = 0xF0000000, msFilterVisible = 0x0F000000, msFilterAll = 0x00FFFFFF }; SwapArray mCurNodes; SwapArray mCurAlwaysVisNodes; protected: SwapArray* mpCurNodeList; ContiguousBinNode< SpatialNode >* mpRootNode; ContiguousBinNode< SpatialNode >* mpCurNode; int mCurNodeOffset; FixedArray mNodeMarks; tMark mCurMarkFilter; int mCurNodeI; //Bounding Box is left as series of defining points to make iteration simpler BoxPts mBBox; SpatialNode& rSeekLeaf( int iCurNodeOffset, Vector3f& irPt ); void MarkAll( int ipCurNode, BoxPts& irBoxPts, SphereSP& irDesiredVolume, tMark iMark ); void MarkSubTrees( int ipCurNode, BoxPts& irBoxPts, ISpatialProxyAA& irDesiredVolume, tMark iMark ); void MarkAllSphere( int ipCurNode, BoxPts& irBoxPts, SphereSP& irSphere, tMark iMark ); void MarkAllSphereIntersect( int ipCurNode, BoxPts& irBoxPts, SphereSP& irSphere, tMark iMark ); void MarkSubTree( int iCurNodeOffset, tMark iMark ); /* void Place( int iCurNodeOffset, ISpatialProxyAA& irTVolume, T* ipT ); void ReservePlaceT( int iCurNodeOffset, ISpatialProxyAA& irTVolume, int iCount ); void Place( int iCurNodeOffset, ISpatialProxyAA& irTVolume, D* ipD ); void ReservePlaceD( int iCurNodeOffset, ISpatialProxyAA& irTVolume, int iCount ); void Place( int iCurNodeOffset, ISpatialProxyAA& irIVolume, I* ipI ); void ReservePlaceI( int iCurNodeOffset, ISpatialProxyAA& irIVolume, int iCount ); */ //Debug functionality // void DisplayBoundingBox( int iCurNodeOffset, BoxPts& orBBox, tColour colour ); void DisplayBoundingBox( BoxPts& irBBox, tColour colour ); }; ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialTreeIter::SpatialTreeIter() : mpRootNode( NULL ) { } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline bool SpatialTreeIter::IsSetUp() { return ( mpRootNode != NULL ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialTreeIter::~SpatialTreeIter() { } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::SetToRoot( SpatialTree& irTree ) { mpRootNode = irTree.GetRoot(); mBBox.SetTo( irTree.GetBounds() ); mNodeMarks.Allocate( mpRootNode->GetSubTreeSize()+1 ); mCurNodes.Allocate( mpRootNode->GetSubTreeSize()+1 ); mCurAlwaysVisNodes.Allocate( mpRootNode->GetSubTreeSize()+1 ); mpCurNodeList = &mCurNodes; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::Clear() { mpRootNode = NULL; } //======================================================================== // SpatialTreeIter:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== inline SpatialNode& SpatialTreeIter::rIthNode ( int iIth ) { return (mpRootNode+iIth)->mData; } //======================================================================== // SpatialTreeIter:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== inline int SpatialTreeIter::NumNodes ( ) { return (mpRootNode->GetSubTreeSize()+1); } //======================================================================== // SpatialTreeIter:: //======================================================================== // // Description: // // Parameters: None. // // Return: None. // // Constraints: None. // //======================================================================== inline void SpatialTreeIter::SetUpNodeList ( UseArray& orNodeOffsets ) { orNodeOffsets.Allocate( mpRootNode->GetSubTreeSize()+1 ); } /* ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceD( ISpatialProxyAA& irDVolume, int iCount) { ReservePlaceD( 0, irDVolume, iCount ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceD ( int iCurNodeOffset, ISpatialProxyAA& irDVolume, int iCount ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irDVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { ReservePlaceD( iCurNodeOffset + pCurNode->LChildOffset(), irDVolume, iCount ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { ReservePlaceD( iCurNodeOffset + pCurNode->RChildOffset(), irDVolume, iCount ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mDynamicElems.Reserve(iCount); } } } else { pCurNode->mData.mDynamicElems.Reserve(iCount); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceT( ISpatialProxyAA& irTVolume, int iCount) { ReservePlaceT( 0, irTVolume, iCount ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceT ( int iCurNodeOffset, ISpatialProxyAA& irTVolume, int iCount ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irTVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { ReservePlaceT( iCurNodeOffset + pCurNode->LChildOffset(), irTVolume, iCount ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { ReservePlaceT( iCurNodeOffset + pCurNode->RChildOffset(), irTVolume, iCount ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mSpatialElems.Reserve(iCount); } } } else { pCurNode->mData.mSpatialElems.Reserve(iCount); } } */ ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialNode& SpatialTreeIter::rSeekLeaf( Vector3f& irPt ) { return rSeekLeaf( 0, irPt ); } /* ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceI( ISpatialProxyAA& irIVolume, int iCount) { ReservePlaceI( 0, irIVolume, iCount ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::ReservePlaceI ( int iCurNodeOffset, ISpatialProxyAA& irIVolume, int iCount ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irIVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { ReservePlaceI( iCurNodeOffset + pCurNode->LChildOffset(), irIVolume, iCount ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { ReservePlaceI( iCurNodeOffset + pCurNode->RChildOffset(), irIVolume, iCount ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mIntersectElems.Reserve(iCount); } } } else { pCurNode->mData.mIntersectElems.Reserve(iCount); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place( ISpatialProxyAA& irDVolume, D* ipD ) { Place( 0, irDVolume, ipD ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place ( int iCurNodeOffset, ISpatialProxyAA& irDVolume, D* ipD ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irDVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { Place( iCurNodeOffset + pCurNode->LChildOffset(), irDVolume, ipD ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { Place( iCurNodeOffset + pCurNode->RChildOffset(), irDVolume, ipD ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mDynamicElems.Add(ipD); } } } else { pCurNode->mData.mDynamicElems.Add(ipD); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place( ISpatialProxyAA& irTVolume, T* ipT ) { Place( 0, irTVolume, ipT ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place ( int iCurNodeOffset, ISpatialProxyAA& irTVolume, T* ipT ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irTVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { Place( iCurNodeOffset + pCurNode->LChildOffset(), irTVolume, ipT ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { Place( iCurNodeOffset + pCurNode->RChildOffset(), irTVolume, ipT ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mSpatialElems.Add(ipT); } } } else { pCurNode->mData.mSpatialElems.Add(ipT); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place( ISpatialProxyAA& irIVolume, I* ipI ) { Place( 0, irIVolume, ipI ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::Place ( int iCurNodeOffset, ISpatialProxyAA& irIVolume, I* ipI ) { ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { float PlaneVolResult = irIVolume.CompareTo( pCurNode->mData.mSubDivPlane ); if( PlaneVolResult > 0.0f ) //The Plane is greater than TVolume in Posn, so TVolume is in the LT Partitiion.. { Place( iCurNodeOffset + pCurNode->LChildOffset(), irIVolume, ipI ); } else { if( PlaneVolResult < 0.0f ) //The Plane is less han TVolume in Posn, so TVolume is in the GT Partitiion.. { Place( iCurNodeOffset + pCurNode->RChildOffset(), irIVolume, ipI ); } else // PlaneVolResult == 0 { //pCurNode = pCurNode->Parent(); pCurNode->mData.mIntersectElems.Add(ipI); } } } else { pCurNode->mData.mIntersectElems.Add(ipI); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::AllocateAllReservations() { int TreeSize = mpRootNode->GetSubTreeSize(); for( int i=0; i<=TreeSize; i++ ) { (mpRootNode+i)->mData.mSpatialElems.Allocate(); (mpRootNode+i)->mData.mDynamicElems.Allocate(); (mpRootNode+i)->mData.mIntersectElems.Allocate(); } } */ ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MarkAll( SphereSP& irDesiredVolume, tMark iMark ) { mCurNodes.ClearUse(); BoxPts tmpBBox(mBBox); MarkAll( 0, tmpBBox, irDesiredVolume, iMark ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MarkAllSphere( SphereSP& irSphere, tMark iMark ) { mCurNodes.ClearUse(); BoxPts tmpBBox(mBBox); MarkAllSphere( 0, tmpBBox, irSphere, iMark ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MarkSubTrees( ISpatialProxyAA& irDesiredVolume, tMark iMark ) { BoxPts tmpBBox(mBBox); MarkSubTrees( 0, tmpBBox, irDesiredVolume, iMark ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /*inline void SpatialTreeIter::CallBackAll( ISpatialProxyAA& irDesiredVolume, void (*pCB)(SpatialNode*) ) { BoxPts tmpBBox(mBBox); CallBackAll( 0, tmpBBox, irDesiredVolume, pCB ); } */ ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline BoxPts* SpatialTreeIter::CurrentBBox() { return &(mpCurNode->mData.mBBox); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /* void SpatialTreeIter::DisplayBoundingBox( ) { BoxPts tmpBBox( mBBox ); DisplayBoundingBox( 0, tmpBBox, tColour(0,255,0) ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// void SpatialTreeIter::DisplayBoundingBox( int iCurNodeOffset, BoxPts& orBBox, tColour colour ) { DisplayBoundingBox( orBBox, colour ); ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); if( pCurNode->GetSubTreeSize() > 0 ) { //split subspace representation, and recurse BoxPts BBoxLT; BBoxLT = orBBox; BBoxLT.CutOffGT( pCurNode->mData.mSubDivPlane ); DisplayBoundingBox( iCurNodeOffset + pCurNode->LChildOffset(), BBoxLT, colour ); orBBox.CutOffLT( pCurNode->mData.mSubDivPlane ); DisplayBoundingBox( iCurNodeOffset + pCurNode->RChildOffset(), orBBox, colour ); } } */ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// inline BoxPts& SpatialTreeIter::rBBox() { return mBBox; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::DisplayBoundingBox( BoxPts& irBBox, tColour colour ) { //#if PURE3D_VERSION_MAJOR < 15 // tShader* testMat = p3d::find("p3d_default"); //#endif //#if PURE3D_VERSION_MAJOR < 15 // pddiPrimStream* stream = p3d::pddi->BeginPrims(testMat->GetShader(), PDDI_PRIM_LINESTRIP, PDDI_V_C ); //#else pddiPrimStream* stream = p3d::pddi->BeginPrims(NULL, PDDI_PRIM_LINESTRIP, PDDI_V_C, 5); //#endif stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMin.z); p3d::pddi->EndPrims(stream); //#if PURE3D_VERSION_MAJOR < 15 // stream = p3d::pddi->BeginPrims(testMat->GetShader(), PDDI_PRIM_LINESTRIP, PDDI_V_C ); //#else stream = p3d::pddi->BeginPrims(NULL, PDDI_PRIM_LINESTRIP, PDDI_V_C, 5); //#endif stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); p3d::pddi->EndPrims(stream); //#if PURE3D_VERSION_MAJOR < 15 // stream = p3d::pddi->BeginPrims(testMat->GetShader(), PDDI_PRIM_LINESTRIP, PDDI_V_C ); //#else stream = p3d::pddi->BeginPrims(NULL, PDDI_PRIM_LINESTRIP, PDDI_V_C, 5); //#endif stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMax.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); p3d::pddi->EndPrims(stream); //#if PURE3D_VERSION_MAJOR < 15 // stream = p3d::pddi->BeginPrims(testMat->GetShader(), PDDI_PRIM_LINESTRIP, PDDI_V_C ); //#else stream = p3d::pddi->BeginPrims(NULL, PDDI_PRIM_LINESTRIP, PDDI_V_C, 5); //#endif stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMax.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMin.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMin.z); stream->Colour(colour); stream->Coord(irBBox.mBounds.mMin.x, irBBox.mBounds.mMax.y, irBBox.mBounds.mMax.z); p3d::pddi->EndPrims(stream); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialNode* SpatialTreeIter::pCurrent() { return (*mpCurNodeList)[mCurNodeI]; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::DisplayCurrentBoundingBox( const tColour& irColour ) { DisplayBoundingBox( pCurrent()->mBBox, irColour ); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MarkTree( tMark iMark ) { for( int i=mNodeMarks.mSize-1; i>= 0; i-- ) { mNodeMarks[i] = iMark; } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::AndTree( tMark iMark ) { //If we're clearing all flags including the visibility flags, then we want //to clear away our extra visible set of nodes if(iMark==0x00000000) { mCurAlwaysVisNodes.ClearUse(); } for( int i=mNodeMarks.mSize-1; i>= 0; i-- ) { mNodeMarks[i] &= iMark; } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::OrTree( tMark iMark ) { for( int i=mNodeMarks.mSize-1; i>= 0; i-- ) { mNodeMarks[i] |= iMark; } } inline void SpatialTreeIter::OrTreeVis( tMark iMark ) { mCurNodes.ClearUse(); SpatialNode* pFuckinCast; for( int i=mNodeMarks.mSize-1; i>= 0; i-- ) { mNodeMarks[i] |= iMark; pFuckinCast = &(mpRootNode[i].mData); mCurNodes.Add( pFuckinCast ); } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MarkSubTree( int iCurNodeOffset, tMark iMark ) { SpatialNode* pSNCastPtr; ContiguousBinNode< SpatialNode >* pCurNode = (mpRootNode+iCurNodeOffset); int StopCondition = iCurNodeOffset+pCurNode->GetSubTreeSize(); for( int i=iCurNodeOffset; i<=StopCondition; i++, pCurNode++ ) { if((iMark & msFilterVisible)&&(mNodeMarks[i] & msFilterInvisible)) { //Skip over invisible branches, if we're doing an visible pass i+=pCurNode->GetSubTreeSize(); pCurNode+=pCurNode->GetSubTreeSize(); } else { mNodeMarks[i] |= iMark; pSNCastPtr = &(pCurNode->mData); (*mpCurNodeList).Add( pSNCastPtr ); } } /* SpatialNode* pSNCastPtr; for( int i=mpRootNode->GetSubTreeSize(); i>=iCurNodeOffset; i-- ) { mNodeMarks[i] |= iMark; pSNCastPtr = &(this->rIthNode(i)); mCurNodes.Add(pSNCastPtr); } */ /* mNodeMarks[iCurNodeOffset] = iMark; if( (mpRootNode+iCurNodeOffset)->GetSubTreeSize() > 0 ) { int newOffset = (mpRootNode+iCurNodeOffset)->LChildOffset(); MarkSubTree( newOffset + iCurNodeOffset, iMark ); newOffset = (mpRootNode+iCurNodeOffset)->RChildOffset(); MarkSubTree( newOffset + iCurNodeOffset, iMark ); } */ } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::SetIterFilter( tMark iMark ) { mCurMarkFilter = iMark; } ///////////////////////////////////////////////////////////////////////////////////// //-------------------------Iteration Navigation------------------------------------// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MoveToFirst() { mpCurNode = mpRootNode; mCurNodeOffset = 0; mCurNodeI = 0; mpCurNodeList = &mCurNodes; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialNode& SpatialTreeIter::rCurrent() { return *(*mpCurNodeList)[mCurNodeI]; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline void SpatialTreeIter::MoveToNext(bool ibIncludeVis) { mCurNodeI++; if(ibIncludeVis && (mCurNodeI >= (*mpCurNodeList).mUseSize) && (mpCurNodeList != &mCurAlwaysVisNodes)) { mpCurNodeList= &mCurAlwaysVisNodes; mCurNodeI=0; } } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialNode& SpatialTreeIter::rMoveToNext(bool ibIncludeVis) { MoveToNext(ibIncludeVis); return *(*mpCurNodeList)[mCurNodeI]; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline SpatialNode* SpatialTreeIter::pMoveToNext(bool ibIncludeVis) { MoveToNext(ibIncludeVis); return (*mpCurNodeList)[mCurNodeI]; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline bool SpatialTreeIter::NotDone() { return (mCurNodeI < (*mpCurNodeList).mUseSize); } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// inline bool SpatialTreeIter::IsCurrentLeaf() { return ((*mpCurNodeList)[mCurNodeI]->mSubDivPlane.mAxis == -1); } #endif