octree

class ZXFOctree

{

public:

     ZFXOctree();

     virtual~ZFXOctree();

    

     void   BuildTree(const  ZFXPolygon*,UINT);

     void   Traverse(ZFXPolylist*,ZFXPolylist*,const ZFXPlane*);

   

     ZFXAabb  GetAabb(){ return m_Aabb;}

 

    bool   GetFloor (const  ZFXVector&, float *, ZFXPlane*);

    bool   TestCollision(const ZFXAabb&, ZFXPlane*);

    bool   TestCollision(const ZFXRay&, float, float*);

private:

   ZFXAabb    m_Aabb;

   ZFXPolygon  *m_pPolys;   //if  leaf

   UINT   m_NumPolys;        //if  leaf

   ZFXOctree    *m_pChild[8] ;   // 8 children

   ZFXOctree    *m_pRoot;

   ZFXOctree    *m_pParent;

   int                 m_Pos;   //  NO,NW

 

  void  CalcBonudingBox(const  ZFXPolygon*, UINT);

  void  InitChildObject(int  ChildID, ZFXOctree *pP);

  void  ChopListToMe(ZFXPolygon *,UINT);

  void  CreateChilds(ZFXOctree *pRoot);

  void  GetAabbAsPolygons(ZFXPolylist *);

  bool  IntersectsDownwardsRay(const  ZFXVector&, float);

 

  bool  IsLeaf(){ return (m_pChild[0]==NULL);}

  void  SetBoundingBox(const ZFXAabb &Aabb){memcpy(&m_Aabb,&Aabb,sizeof(ZFXAabb));}

 

};

 

ZFXOctree::ZFXOctree()

{

       m_NumPolys=0;

       m_Pos        = -1;

       m_pPolys  = NULL;

       m_pRoot   = NULL;

       m_pParent  = NULL;

 

      for( int i=0;i<8;i++)m_pChild[i] = NULL;

   

       memset(&m_Aabb, 0,sizeof(ZFXAabb));

}

 

ZFXOctree::~ZFXOctree()

{

      m_NumPolys = 0;

     

      SAFE_DELETE_A(m_pPolys);

      for(int i=0;i<8;i++)

         SAFE_DELETE(m_pChild[i]);

}

 

初始化子节点

void  ZFXOctree::InitChildObject(int ChildID,ZFXOctree *pParent)

{

       ZFXAabb  aabb;

      

       float xmin = m_Aabb.vcMin.x ,  xcen = m_Aabb.vcCenter.x , xmax = m_Aabb.vcMax.x;

       float ymin = m_Aabb.vcMin.y ,  xcen = m_Aabb.vcCenter.y , xmax = m_Aabb.vcMax.y;

       float zmin = m_Aabb.vcMin.z ,  xcen = m_Aabb.vcCenter.z , xmax = m_Aabb.vcMax.z;

      

       switch(ChildID)

       {

         case UP_NW:

               aabb.vcMax = ZFXVector(xcen , ymax, zmax);

               aabb.vcMin = ZFXVector(xmin , ycen ,zmin);

               break;

         case UP_NE:

               aabb.vcMax = m_Aabb.vcMax;

               aabb.vcMin = m_Aabb.vcCenter;

               break;

         case UP_SW:

               aabb.vcMax = ZFXVector(xcen , ymax, zcen);

               aabb.vcMin = ZFXVector(xmin , ycen ,zmin);

               break;

  

         case UP_SE:

               aabb.vcMax = ZFXVector(xmax , ymax, zcen);

               aabb.vcMin = ZFXVector(xcen , ycen ,zmin);

               break;

         case LW_NW:

               aabb.vcMax = ZFXVector(xcen , ycen, zmax);

               aabb.vcMin = ZFXVector(xmin , ymin ,zcen);

               break;

   

         case LW_NE:

               aabb.vcMax = ZFXVector(xmax , ycen, zmax);

               aabb.vcMin = ZFXVector(xcen , ymin ,zcen);

               break;

  

         case LW_SW:

               aabb.vcMax = m_Aabb.vcCenter;

               aabb.vcMin = m_Aabb.vcMin;

               break;

         case LW_SE:

               aabb.vcMax = ZFXVector(xmax , ycen, zcen);

               aabb.vcMin = ZFXVector(xcen , ymin ,zmin);

               break;

        default: break;

        }

       aabb.vcCenter = (aabb.vcMax + aabb.vcMin)/2.0f;

      

       m_pChild[ChildID] = new ZFXOctree();

       m_pChild[ChildID]->SetBoundingBox(aabb);

       m_pChild[ChildID]->m_Pos  = ChildID;

       m_pChild[ChildID]->m_pParent = pParent;

}

 

void ZFXOctree::BuildTree(const ZFXPolygon *pPolys, UINT Num)

{

       m_pRoot = this;

       if(Num<1) return;

 

       //calculate AABB for the root node

       CalcBoundingBox(pPolys,Num);

      

       m_pPolys=new ZFXPolygon[Num];

       m_NumPolys = Num;

      

       for(UINT i=0; i<Num; i++)

            m_pPolys[i].Copyof( pPolys[i]);

       CreateChilds(this);

      

       SAFE_DELETE_A(m_pPolys);

}

 

void ZFXOctree::CreateChilds(ZFXOctree *pRoot)

{

       m_pRoot = pRoot;

  

        if((pRoot ==this) || (m_NumPolys > POLYS_PER_LEAF))

       {

               for(int i=0;i<8;i++)

               {

                      InitChildObject(i , this);

 

                      m_pChild[i]->ChopListToMe(m_pPolys, m_NumPolys);

                      m_pChild[i]->CreateChilds(pRoot);

                 }

          SAFE_DELETE_A(m_pPolys);

           }

      else return;

}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值