Files
Client/GameTools/Zallad3D SceneClass/Octree.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

737 lines
20 KiB
C++

// Octree.cpp: implementation of the COctree class.
//
//////////////////////////////////////////////////////////////////////
#include "Octree.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define MIN_EPSILON 1.0e-4f
#define MAX_EPSILON 1.0e+10f
COctree::COctree()
{
for(int i=0;i<8;i++)
{
m_pChild[i]=NULL;
}
m_MaxBox.x=0.0f;
m_MaxBox.y=0.0f;
m_MaxBox.z=0.0f;
m_MinBox.x=0.0f;
m_MinBox.y=0.0f;
m_MinBox.z=0.0f;
}
COctree::~COctree()
{
for(int i=0;i<8;i++)
{
if(m_pChild[i])
{
delete m_pChild[i];
}
}
}
void COctree::Load(FILE *fp)
{
unsigned char HaveChild=0x0;
fread(&HaveChild,sizeof(unsigned char),1,fp);
for(int i=0;i<8;i++)
{
if(HaveChild & 0x1<<i)
{
m_pChild[i]=new COctree();
}
}
fread(&m_MaxBox,sizeof(vector3),1,fp);
fread(&m_MinBox,sizeof(vector3),1,fp);
int cPolyList;
fread(&cPolyList,sizeof(int),1,fp);
int NodeID;
for(i=0;i<cPolyList;i++)
{
fread(&NodeID,sizeof(int),1,fp);
m_PolyNodeID.Add(NodeID);
}
for(i=0;i<8;i++)
{
if(m_pChild[i])
m_pChild[i]->Load(fp);
}
}
//DEL void COctree::AddPoly(vector3 *vecPoly[])
//DEL {
//DEL }
void COctree::SplitNode(int DepthNode,List<PolyNode *> &PolyList)
{
if(DepthNode==0)
return;
float fBoxSizeX,fBoxSizeY,fBoxSizeZ;
fBoxSizeX=m_MaxBox.x-m_MinBox.x;
fBoxSizeY=m_MaxBox.y-m_MinBox.y;
fBoxSizeZ=m_MaxBox.z-m_MinBox.z;
int BoxMoveX[8]={1,0,1,0,1,0,1,0};
int BoxMoveY[8]={1,1,1,1,0,0,0,0};
int BoxMoveZ[8]={1,1,0,0,1,1,0,0};
vector3 vecBoundBox[8];
vector3 vecBoundPlaneNormal[6];
float fDistance[6];
for(int cNode=0;cNode<8;cNode++)
{
m_pChild[cNode]=new COctree();
for(int cBoxVertex=0;cBoxVertex<8;cBoxVertex++)
{
vecBoundBox[cBoxVertex].x=m_MinBox.x+(BoxMoveX[cNode]*fBoxSizeX*0.5f)+(BoxMoveX[cBoxVertex]*fBoxSizeX*0.5f);
vecBoundBox[cBoxVertex].y=m_MinBox.y+(BoxMoveY[cNode]*fBoxSizeY*0.5f)+(BoxMoveY[cBoxVertex]*fBoxSizeY*0.5f);
vecBoundBox[cBoxVertex].z=m_MinBox.z+(BoxMoveZ[cNode]*fBoxSizeZ*0.5f)+(BoxMoveZ[cBoxVertex]*fBoxSizeZ*0.5f);
}
m_pChild[cNode]->m_MaxBox=vecBoundBox[0];
m_pChild[cNode]->m_MinBox=vecBoundBox[7];
vecBoundPlaneNormal[0]=(vecBoundBox[4]-vecBoundBox[0])^(vecBoundBox[5]-vecBoundBox[4]);
vecBoundPlaneNormal[1]=(vecBoundBox[3]-vecBoundBox[2])^(vecBoundBox[7]-vecBoundBox[3]);
vecBoundPlaneNormal[2]=(vecBoundBox[2]-vecBoundBox[0])^(vecBoundBox[6]-vecBoundBox[2]);
vecBoundPlaneNormal[3]=(vecBoundBox[1]-vecBoundBox[3])^(vecBoundBox[5]-vecBoundBox[1]);
vecBoundPlaneNormal[4]=(vecBoundBox[1]-vecBoundBox[0])^(vecBoundBox[3]-vecBoundBox[1]);
vecBoundPlaneNormal[5]=(vecBoundBox[7]-vecBoundBox[6])^(vecBoundBox[5]-vecBoundBox[7]);
vecBoundPlaneNormal[0].Normalize();
vecBoundPlaneNormal[1].Normalize();
vecBoundPlaneNormal[2].Normalize();
vecBoundPlaneNormal[3].Normalize();
vecBoundPlaneNormal[4].Normalize();
vecBoundPlaneNormal[5].Normalize();
for(int cPoly=0;cPoly<m_PolyNodeID.num;cPoly++)
//for(int cPoly=0;cPoly<m_PolyList.num;cPoly++)
{
//vector3 *v=&m_PolyList[cPoly]->m_vecPoly[0];
vector3 *v=&PolyList[m_PolyNodeID[cPoly]]->m_vecPoly[0];
fDistance[0]=vecBoundPlaneNormal[0]*(*v-vecBoundBox[0]);
fDistance[1]=vecBoundPlaneNormal[1]*(*v-vecBoundBox[2]);
fDistance[2]=vecBoundPlaneNormal[2]*(*v-vecBoundBox[0]);
fDistance[3]=vecBoundPlaneNormal[3]*(*v-vecBoundBox[3]);
fDistance[4]=vecBoundPlaneNormal[4]*(*v-vecBoundBox[0]);
fDistance[5]=vecBoundPlaneNormal[5]*(*v-vecBoundBox[6]);
if( fDistance[0] > 0.0f && fDistance[1] > 0.0f && fDistance[2] > 0.0f && fDistance[3] > 0.0f && fDistance[4] > 0.0f && fDistance[5] > 0.0f)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
v=&PolyList[m_PolyNodeID[cPoly]]->m_vecPoly[1];
//v=&m_PolyList[cPoly]->m_vecPoly[1];
fDistance[0]=vecBoundPlaneNormal[0]*(*v-vecBoundBox[0]);
fDistance[1]=vecBoundPlaneNormal[1]*(*v-vecBoundBox[2]);
fDistance[2]=vecBoundPlaneNormal[2]*(*v-vecBoundBox[0]);
fDistance[3]=vecBoundPlaneNormal[3]*(*v-vecBoundBox[3]);
fDistance[4]=vecBoundPlaneNormal[4]*(*v-vecBoundBox[0]);
fDistance[5]=vecBoundPlaneNormal[5]*(*v-vecBoundBox[6]);
if( fDistance[0] > 0.0f && fDistance[1] > 0.0f && fDistance[2] > 0.0f && fDistance[3] > 0.0f && fDistance[4] > 0.0f && fDistance[5] > 0.0f)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
v=&PolyList[m_PolyNodeID[cPoly]]->m_vecPoly[2];
//v=&m_PolyList[cPoly]->m_vecPoly[2];
fDistance[0]=vecBoundPlaneNormal[0]*(*v-vecBoundBox[0]);
fDistance[1]=vecBoundPlaneNormal[1]*(*v-vecBoundBox[2]);
fDistance[2]=vecBoundPlaneNormal[2]*(*v-vecBoundBox[0]);
fDistance[3]=vecBoundPlaneNormal[3]*(*v-vecBoundBox[3]);
fDistance[4]=vecBoundPlaneNormal[4]*(*v-vecBoundBox[0]);
fDistance[5]=vecBoundPlaneNormal[5]*(*v-vecBoundBox[6]);
if( fDistance[0] > 0.0f && fDistance[1] > 0.0f && fDistance[2] > 0.0f && fDistance[3] > 0.0f && fDistance[4] > 0.0f && fDistance[5] > 0.0f)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vector3 vecCheckBox[3];
vecCheckBox[0]=vecBoundBox[0];
vecCheckBox[1]=vecBoundBox[4];
vecCheckBox[2]=vecBoundBox[5];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[0];
vecCheckBox[1]=vecBoundBox[5];
vecCheckBox[2]=vecBoundBox[1];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[2];
vecCheckBox[1]=vecBoundBox[3];
vecCheckBox[2]=vecBoundBox[7];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[2];
vecCheckBox[1]=vecBoundBox[7];
vecCheckBox[2]=vecBoundBox[6];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[0];
vecCheckBox[1]=vecBoundBox[2];
vecCheckBox[2]=vecBoundBox[6];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[3];
vecCheckBox[1]=vecBoundBox[1];
vecCheckBox[2]=vecBoundBox[5];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[3];
vecCheckBox[1]=vecBoundBox[5];
vecCheckBox[2]=vecBoundBox[7];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[0];
vecCheckBox[1]=vecBoundBox[1];
vecCheckBox[2]=vecBoundBox[3];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[0];
vecCheckBox[1]=vecBoundBox[3];
vecCheckBox[2]=vecBoundBox[2];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[6];
vecCheckBox[1]=vecBoundBox[7];
vecCheckBox[2]=vecBoundBox[5];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
vecCheckBox[0]=vecBoundBox[6];
vecCheckBox[1]=vecBoundBox[5];
vecCheckBox[2]=vecBoundBox[4];
if(CIntersection::PolygonToPolygon(PolyList[m_PolyNodeID[cPoly]]->m_vecPoly,vecCheckBox)==1)
//if(CIntersection::PolygonToPolygon(m_PolyList[cPoly]->m_vecPoly,vecCheckBox)==1)
{
m_pChild[cNode]->m_PolyNodeID.Add(m_PolyNodeID[cPoly]);
//m_pChild[cNode]->m_PolyList.Add(m_PolyList[cPoly]);
continue;
}
}
if(m_pChild[cNode]->m_PolyNodeID.num==0)
{
delete m_pChild[cNode];
m_pChild[cNode]=NULL;
}
else
{
m_pChild[cNode]->SplitNode(DepthNode-1,PolyList);
}
}
if(DepthNode!=0)
{
m_PolyNodeID.num=0;
//m_PolyList.num=0;
}
}
void COctree::CalcBoundBox(List<PolyNode *> &PolyList)
{
float minx,miny,minz,maxx,maxy,maxz;
if(PolyList.num==0)
return;
maxx=minx=PolyList[0]->m_vecPoly[0].x;
maxy=miny=PolyList[0]->m_vecPoly[0].y;
maxz=minz=PolyList[0]->m_vecPoly[0].z;
for(int i=0;i<PolyList.num;i++)
{
for(int cv=0;cv<3;cv++)
{
if(maxx<PolyList[i]->m_vecPoly[cv].x)
maxx=PolyList[i]->m_vecPoly[cv].x;
if(maxy<PolyList[i]->m_vecPoly[cv].y)
maxy=PolyList[i]->m_vecPoly[cv].y;
if(maxz<PolyList[i]->m_vecPoly[cv].z)
maxz=PolyList[i]->m_vecPoly[cv].z;
if(minx>PolyList[i]->m_vecPoly[cv].x)
minx=PolyList[i]->m_vecPoly[cv].x;
if(miny>PolyList[i]->m_vecPoly[cv].y)
miny=PolyList[i]->m_vecPoly[cv].y;
if(minz>PolyList[i]->m_vecPoly[cv].z)
minz=PolyList[i]->m_vecPoly[cv].z;
}
}
const float Remain=100.0f;
m_MaxBox.x=maxx+Remain;
m_MaxBox.y=maxy+Remain;
m_MaxBox.z=maxz+Remain;
m_MinBox.x=minx-Remain;
m_MinBox.y=miny-Remain;
m_MinBox.z=minz-Remain;
}
void COctree::Render(LPDIRECT3DDEVICE8 pd3dDevice)
{
/*
MultiVertex BoxVertex[8];
WORD Indices[24];
WORD *pIndices=Indices;
BoxVertex[0].v.x=m_MaxBox.x;
BoxVertex[0].v.y=m_MaxBox.y;
BoxVertex[0].v.z=m_MaxBox.z;
BoxVertex[1].v.x=m_MinBox.x;
BoxVertex[1].v.y=m_MaxBox.y;
BoxVertex[1].v.z=m_MaxBox.z;
BoxVertex[2].v.x=m_MaxBox.x;
BoxVertex[2].v.y=m_MaxBox.y;
BoxVertex[2].v.z=m_MinBox.z;
BoxVertex[3].v.x=m_MinBox.x;
BoxVertex[3].v.y=m_MaxBox.y;
BoxVertex[3].v.z=m_MinBox.z;
BoxVertex[4].v.x=m_MaxBox.x;
BoxVertex[4].v.y=m_MinBox.y;
BoxVertex[4].v.z=m_MaxBox.z;
BoxVertex[5].v.x=m_MinBox.x;
BoxVertex[5].v.y=m_MinBox.y;
BoxVertex[5].v.z=m_MaxBox.z;
BoxVertex[6].v.x=m_MaxBox.x;
BoxVertex[6].v.y=m_MinBox.y;
BoxVertex[6].v.z=m_MinBox.z;
BoxVertex[7].v.x=m_MinBox.x;
BoxVertex[7].v.y=m_MinBox.y;
BoxVertex[7].v.z=m_MinBox.z;
*(pIndices++)=0;
*(pIndices++)=1;
*(pIndices++)=1;
*(pIndices++)=3;
*(pIndices++)=3;
*(pIndices++)=2;
*(pIndices++)=2;
*(pIndices++)=0;
*(pIndices++)=4;
*(pIndices++)=5;
*(pIndices++)=5;
*(pIndices++)=7;
*(pIndices++)=7;
*(pIndices++)=6;
*(pIndices++)=6;
*(pIndices++)=4;
*(pIndices++)=0;
*(pIndices++)=4;
*(pIndices++)=1;
*(pIndices++)=5;
*(pIndices++)=3;
*(pIndices++)=7;
*(pIndices++)=2;
*(pIndices++)=6;
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetTexture(1,NULL);
pd3dDevice->SetVertexShader(MultiFVF);
pd3dDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST,0,8,12,Indices,D3DFMT_INDEX16,BoxVertex,sizeof(MultiVertex));
for(int cNode=0;cNode<8;cNode++)
{
if(m_pChild[cNode]!=NULL)
{
m_pChild[cNode]->Render(pd3dDevice);
}
}
*/
}
//DEL void COctree::CullRay(vector3 vecStart, vector3 vecEnd,List<PolyNode*> &PolyList)
//DEL {
//DEL /*
//DEL int BoxMoveX[8]={1,0,1,0,1,0,1,0};
//DEL int BoxMoveY[8]={1,1,1,1,0,0,0,0};
//DEL int BoxMoveZ[8]={1,1,0,0,1,1,0,0};
//DEL
//DEL vector3 vecSourceBox[8];
//DEL vector3 vecSourceSize=m_MaxBox-m_MinBox;
//DEL
//DEL for(int cBoxVertex=0;cBoxVertex<8;cBoxVertex++)
//DEL {
//DEL vecSourceBox[cBoxVertex].x=m_MinBox.x+(BoxMoveX[cBoxVertex]*vecSourceSize.x);
//DEL vecSourceBox[cBoxVertex].y=m_MinBox.y+(BoxMoveY[cBoxVertex]*vecSourceSize.y);
//DEL vecSourceBox[cBoxVertex].z=m_MinBox.z+(BoxMoveZ[cBoxVertex]*vecSourceSize.z);
//DEL }
//DEL vector3 *vecIntersectionPoly[24];
//DEL vector3 **pVec=vecIntersectionPoly;
//DEL *(pVec++)=&vecSourceBox[0];
//DEL *(pVec++)=&vecSourceBox[1];
//DEL *(pVec++)=&vecSourceBox[3];
//DEL *(pVec++)=&vecSourceBox[2];
//DEL
//DEL *(pVec++)=&vecSourceBox[4];
//DEL *(pVec++)=&vecSourceBox[5];
//DEL *(pVec++)=&vecSourceBox[7];
//DEL *(pVec++)=&vecSourceBox[6];
//DEL
//DEL *(pVec++)=&vecSourceBox[0];
//DEL *(pVec++)=&vecSourceBox[1];
//DEL *(pVec++)=&vecSourceBox[5];
//DEL *(pVec++)=&vecSourceBox[4];
//DEL
//DEL *(pVec++)=&vecSourceBox[2];
//DEL *(pVec++)=&vecSourceBox[3];
//DEL *(pVec++)=&vecSourceBox[7];
//DEL *(pVec++)=&vecSourceBox[6];
//DEL
//DEL *(pVec++)=&vecSourceBox[0];
//DEL *(pVec++)=&vecSourceBox[2];
//DEL *(pVec++)=&vecSourceBox[6];
//DEL *(pVec++)=&vecSourceBox[4];
//DEL
//DEL *(pVec++)=&vecSourceBox[1];
//DEL *(pVec++)=&vecSourceBox[3];
//DEL *(pVec++)=&vecSourceBox[7];
//DEL *(pVec++)=&vecSourceBox[5];
//DEL pVec=vecIntersectionPoly;
//DEL
//DEL float fInter;
//DEL if( CIntersection::BoxToRay(vecStart,vecEnd,pVec,fInter) ||
//DEL CIntersection::BoxToRay(vecStart,vecEnd,pVec+4,fInter) ||
//DEL CIntersection::BoxToRay(vecStart,vecEnd,pVec+8,fInter) ||
//DEL CIntersection::BoxToRay(vecStart,vecEnd,pVec+12,fInter) ||
//DEL CIntersection::BoxToRay(vecStart,vecEnd,pVec+16,fInter) ||
//DEL CIntersection::BoxToRay(vecStart,vecEnd,pVec+20,fInter) )
//DEL {
//DEL
//DEL for(int cPoly=0;cPoly<m_PolyList.num;cPoly++)
//DEL {
//DEL if(m_PolyList[cPoly]->m_used==0)
//DEL {
//DEL PolyList.Add(m_PolyList[cPoly]);
//DEL m_PolyList[cPoly]->m_used++;
//DEL }
//DEL }
//DEL for(int cNode=0;cNode<8;cNode++)
//DEL {
//DEL if(m_pChild[cNode])
//DEL m_pChild[cNode]->CullRay(vecStart,vecEnd,PolyList);
//DEL }
//DEL
//DEL //}
//DEL */
//DEL }
void COctree::CullSphere(vector3 vecCenter, float fRad,List<PolyNode *> &PolyList,List<int> &PolyID)
{
vector3 vecBoundCenter=m_MinBox+(m_MaxBox-m_MinBox)/2.0f;
vector3 vecDiagol=m_MaxBox-vecBoundCenter;
float fBoundRad=vecDiagol.GetLens();
vector3 vecInter=vecCenter-vecBoundCenter;
float fInter=vecInter.GetLens();
if( fInter < fRad+fBoundRad)
{
for(int cPoly=0;cPoly<m_PolyNodeID.num;cPoly++)
{
if(PolyList[m_PolyNodeID[cPoly]]->m_used==0)
{
PolyID.Add(m_PolyNodeID[cPoly]);
PolyList[m_PolyNodeID[cPoly]]->m_used++;
}
}
for(int cNode=0;cNode<8;cNode++)
{
if(m_pChild[cNode])
m_pChild[cNode]->CullSphere(vecCenter,fRad,PolyList,PolyID);
}
}
}
void COctree::Save(FILE *fp)
{
unsigned char HaveChild=0x0;
for(int i=0;i<8;i++)
{
if(m_pChild[i])
{
HaveChild|=(0x01<<i);
}
}
fwrite(&HaveChild,sizeof(unsigned char),1,fp);
fwrite(&m_MaxBox,sizeof(vector3),1,fp);
fwrite(&m_MinBox,sizeof(vector3),1,fp);
//fwrite(&m_PolyList.num,sizeof(int),1,fp);
fwrite(&m_PolyNodeID.num,sizeof(int),1,fp);
for(i=0;i<m_PolyNodeID.num;i++)
{
fwrite(&m_PolyNodeID[i],sizeof(int),1,fp);
//fwrite(m_PolyList[i]->m_vecPoly,sizeof(vector3)*3,1,fp);
}
for(i=0;i<8;i++)
{
if(m_pChild[i])
{
m_pChild[i]->Save(fp);
}
}
}
void COctree::CullFrustum(CViewCamera *pCamera,List<PolyNode *> &PolyList,List<int> &PolyID)
{
if( CIntersection::PlaneAABBBox(pCamera->m_vecFrustumTop,-pCamera->m_vecFrustumNormal[0],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumBottom,-pCamera->m_vecFrustumNormal[1],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumLeft,-pCamera->m_vecFrustumNormal[2],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumRight,-pCamera->m_vecFrustumNormal[3],m_MaxBox,m_MinBox) < 0.0f)
{
for(int cPoly=0;cPoly<m_PolyNodeID.num;cPoly++)
{
if(PolyList[m_PolyNodeID[cPoly]]->m_used==0)
{
PolyID.Add(m_PolyNodeID[cPoly]);
PolyList[m_PolyNodeID[cPoly]]->m_used++;
}
}
for(int cNode=0;cNode<8;cNode++)
{
if(m_pChild[cNode])
m_pChild[cNode]->CullFrustum(pCamera,PolyList,PolyID);
}
}
}
void COctree::CullRay(vector3 vecStart,vector3 vecDir, float fLens,List<PolyNode *> &PolyList,List<int> &PolyID)
{
vector3 vecEnd=vecStart+vecDir*fLens;
if(vecDir.x >= 0.0f)
{
if(m_MaxBox.x < vecStart.x)
return;
if(m_MinBox.x > vecEnd.x)
return;
/*
fRate=(m_MinBox.x-vecStart.x)/vecDir.x;
if(fRate<0.0f)
vecStart=vecStart+fRate*vecDir;
fRate=(m_MaxBox.x-vecEnd.x)/vecDir.x;
if(fRate>0.0f)
vecEnd=vecEnd-fRate*vecDir;
*/
}
else
{
if(m_MaxBox.x < vecEnd.x)
return;
if(m_MinBox.x > vecStart.x)
return;
/*
fRate=(m_MinBox.x-vecEnd.x)/vecDir.x;
if(fRate<0.0f)
vecStart=vecEnd+fRate*vecDir;
fRate=(m_MaxBox.x-vecStart.x)/vecDir.x;
if(fRate>0.0f)
vecEnd=vecStart-fRate*vecDir;
*/
}
if(vecDir.y >= 0.0f)
{
if(m_MaxBox.y < vecStart.y)
return;
if(m_MinBox.y > vecEnd.y)
return;
/*
fRate=(m_MinBox.y-vecStart.x)/vecDir.y;
if(fRate<0.0f)
vecStart=vecStart+fRate*vecDir;
fRate=(m_MaxBox.y-vecEnd.y)/vecDir.y;
if(fRate>0.0f)
vecEnd=vecEnd-fRate*vecDir;
*/
}
else
{
if(m_MaxBox.y < vecEnd.y)
return;
if(m_MinBox.y > vecStart.y)
return;
/*
fRate=(m_MinBox.y-vecEnd.y)/vecDir.y;
if(fRate<0.0f)
vecStart=vecEnd+fRate*vecDir;
fRate=(m_MaxBox.y-vecStart.y)/vecDir.x;
if(fRate>0.0f)
vecEnd=vecStart-fRate*vecDir;
*/
}
if(vecDir.z>=0.0f)
{
if(m_MaxBox.z < vecStart.z)
return;
if(m_MinBox.z > vecEnd.z)
return;
}
else
{
if(m_MaxBox.z < vecEnd.z)
return;
if(m_MinBox.z > vecStart.z)
return;
}
for(int cPoly=0;cPoly<m_PolyNodeID.num;cPoly++)
{
if(PolyList[m_PolyNodeID[cPoly]]->m_used==0)
{
PolyID.Add(m_PolyNodeID[cPoly]);
PolyList[m_PolyNodeID[cPoly]]->m_used++;
}
}
for(int cNode=0;cNode<8;cNode++)
{
if(m_pChild[cNode])
m_pChild[cNode]->CullRay(vecStart,vecDir,fLens,PolyList,PolyID);
}
}
int COctree::IntersectionRay(const D3DXVECTOR3 &vecRayOrigin,const D3DXVECTOR3 &vecRayDir,float &fNear,float &fFar)
{
fNear = -MAX_EPSILON;
fFar = MAX_EPSILON;
float t1,t2,t;
int iReturnValue = -1;
int i,j;
for(i = 0; i < 3; i++)
{
float fMinValue,fMaxValue;
switch(i)
{
case 0:
fMinValue = m_MinBox.x;
fMaxValue = m_MaxBox.x;
break;
case 1:
fMinValue = m_MinBox.y;
fMaxValue = m_MaxBox.y;
break;
case 2:
fMinValue = m_MinBox.z;
fMaxValue = m_MaxBox.z;
break;
};
if(vecRayDir[i] > -MIN_EPSILON && vecRayDir[i] < MIN_EPSILON)
{
if(vecRayOrigin[i] < fMinValue || vecRayOrigin[i] > fMaxValue)
return -1;
}
else
{
t1=(fMinValue-vecRayOrigin[i])/vecRayDir[i];
t2=(fMaxValue-vecRayOrigin[i])/vecRayDir[i];
if (t1>t2)
{
t=t1; t1=t2; t2=t;
j=3+i;
}
else
j=i;
if (t1>fNear)
{
fNear=t1;
iReturnValue=j;
}
if (t2<fFar)
fFar=t2;
if (fNear>fFar || fFar<MIN_EPSILON)
return -1;
}
}
if (fNear>fFar || fFar<MIN_EPSILON)
return -1;
return iReturnValue;
}