Files
Client/GameTools/Zallad3D SceneClass/OctreeScene.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

254 lines
6.2 KiB
C++
Raw Blame History

// OctreeScene.cpp: implementation of the COctreeScene class.
//
//////////////////////////////////////////////////////////////////////
#include "OctreeScene.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define FLOAT_TO_INT(fValue) (*(int *)&(fValue))
#define IS_SIGNBIT(fValue) (FLOAT_TO_INT(fValue) & 0x80000000)
COctreeScene::COctreeScene()
{
m_pOctree=NULL;
}
COctreeScene::~COctreeScene()
{
for(int i=0;i<m_PolyList.num;i++)
{
delete m_PolyList[i];
}
m_PolyList.num=0;
delete m_pOctree;
}
void COctreeScene::AddPoly(vector3 *vecPoly)
{
if(m_pOctree==NULL)
m_pOctree=new COctree();
PolyNode *pNode=new PolyNode(vecPoly);
m_PolyList.Add(pNode);
//m_pOctree->m_PolyList.Add(pNode);
}
void COctreeScene::GenerateOctree()
{
for(int cPolyNode=0;cPolyNode<m_PolyList.num;cPolyNode++)
{
m_pOctree->m_PolyNodeID.Add(cPolyNode);
}
m_pOctree->CalcBoundBox(m_PolyList);
m_pOctree->SplitNode(3,m_PolyList);
//m_pOctree->CalcBoundBox();
//m_pOctree->SplitNode(3);
}
void COctreeScene::Render(LPDIRECT3DDEVICE8 pd3dDevice)
{
m_pOctree->Render(pd3dDevice);
}
void COctreeScene::Save(FILE *fp)
{
fwrite(&m_PolyList.num,sizeof(int),1,fp);
for(int cNode=0;cNode<m_PolyList.num;cNode++)
{
fwrite(m_PolyList[cNode]->m_vecPoly,sizeof(vector3)*3,1,fp);
}
m_pOctree->Save(fp);
}
void COctreeScene::Load(FILE *fp)
{
int cTotalNode=0;
vector3 vecPoly[3];
fread(&cTotalNode,sizeof(int),1,fp);
for(int cNode=0;cNode<cTotalNode;cNode++)
{
fread(vecPoly,sizeof(vector3)*3,1,fp);
AddPoly(vecPoly);
}
m_pOctree->Load(fp);
}
void COctreeScene::CullSphere(vector3 vecCenter, float fRad,List<PolyNode*> &CullPoly)
{
List<int> CullID;
m_pOctree->CullSphere(vecCenter,fRad,m_PolyList,CullID);
vector3 vecPoly[3];
vector3 vecRadius=vector3(150.0f,200.0f,150.0);
vector3 vecMaxRadius=vecCenter+vecRadius;
vector3 vecMinRadius=vecCenter-vecRadius;
for(int cNode=0;cNode<CullID.num;cNode++)
{
m_PolyList[CullID[cNode]]->m_used=0;
vecPoly[0]=m_PolyList[CullID[cNode]]->m_vecPoly[0];
vecPoly[1]=m_PolyList[CullID[cNode]]->m_vecPoly[1];
vecPoly[2]=m_PolyList[CullID[cNode]]->m_vecPoly[2];
if( vecPoly[0].x < vecMinRadius.x &&
vecPoly[1].x < vecMinRadius.x &&
vecPoly[2].x < vecMinRadius.x )
continue;
if( vecPoly[0].y < vecMinRadius.y &&
vecPoly[1].y < vecMinRadius.y &&
vecPoly[2].y < vecMinRadius.y)
continue;
if( vecPoly[0].z < vecMinRadius.z &&
vecPoly[1].z < vecMinRadius.z &&
vecPoly[2].z < vecMinRadius.z )
continue;
if( vecPoly[0].x > vecMaxRadius.x &&
vecPoly[1].x > vecMaxRadius.x &&
vecPoly[2].x > vecMaxRadius.x )
continue;
if( vecPoly[0].y > vecMaxRadius.y &&
vecPoly[1].y > vecMaxRadius.y &&
vecPoly[2].y > vecMaxRadius.y )
continue;
if( vecPoly[0].z > vecMaxRadius.z &&
vecPoly[1].z > vecMaxRadius.z &&
vecPoly[2].z > vecMaxRadius.z )
continue;
CullPoly.Add(m_PolyList[CullID[cNode]]);
}
}
void COctreeScene::CullFrustum(CViewCamera *pCamera,List<PolyNode*> &CullPoly)
{
List<int> CullID;
m_pOctree->CullFrustum(pCamera,m_PolyList,CullID);
for(int cNode=0;cNode<CullID.num;cNode++)
{
CullPoly.Add(m_PolyList[CullID[cNode]]);
m_PolyList[CullID[cNode]]->m_used=0;
}
}
void COctreeScene::CullRay(vector3 vecStart, vector3 vecDir, float fLens,List<PolyNode*> &CullPoly)
{
List<int> CullID;
m_pOctree->CullRay(vecStart,vecDir,fLens,m_PolyList,CullID);
for(int cNode=0;cNode<CullID.num;cNode++)
{
CullPoly.Add(m_PolyList[CullID[cNode]]);
m_PolyList[CullID[cNode]]->m_used=0;
}
}
bool COctreeScene::CollisionToRay(const D3DXVECTOR3 &vecStart,const D3DXVECTOR3 &vecDir,const float &fDist)
{
if(!m_pOctree)
return false;
static float fNear,fFar;
static COctree *pStack[64];
if(m_pOctree->IntersectionRay(vecStart,vecDir,fNear,fFar) == -1)
return 0;
COctree *pCurrent;
int iStack = 1;
int i;
pStack[0] = m_pOctree;
while(iStack)
{
pCurrent = pStack[--iStack];
if(pCurrent->m_PolyNodeID.num == 0)
{
for(i = 0; i < 8;i++)
{
if(pCurrent->m_pChild[i] && pCurrent->m_pChild[i]->IntersectionRay(vecStart,vecDir,fNear,fFar) != -1)
pStack[iStack++] = pCurrent->m_pChild[i];
}
}
else
{
long iCurrentFaceId;
for(i = 0; i < (int)pCurrent->m_PolyNodeID.num; i++)
{
iCurrentFaceId = pCurrent->m_PolyNodeID[i];
if(CollisionTriangleToRay(iCurrentFaceId,vecStart,vecDir,fDist))
{
return true;
}
}
}
}
return false;
}
bool COctreeScene::CollisionTriangleToRay(long iFaceIndex,const D3DXVECTOR3 &vecStart,const D3DXVECTOR3 &vecDir,const float &fDist)
{
D3DXVECTOR3 vecPos[3];
D3DXVECTOR3 vecTmp1,vecTmp2;
D3DXVECTOR3 vecNormal;
float ffDist;
vecPos[0] = D3DXVECTOR3(m_PolyList[iFaceIndex]->m_vecPoly[0].x,m_PolyList[iFaceIndex]->m_vecPoly[0].y,m_PolyList[iFaceIndex]->m_vecPoly[0].z);
vecPos[1] = D3DXVECTOR3(m_PolyList[iFaceIndex]->m_vecPoly[1].x,m_PolyList[iFaceIndex]->m_vecPoly[1].y,m_PolyList[iFaceIndex]->m_vecPoly[1].z);
vecPos[2] = D3DXVECTOR3(m_PolyList[iFaceIndex]->m_vecPoly[2].x,m_PolyList[iFaceIndex]->m_vecPoly[2].y,m_PolyList[iFaceIndex]->m_vecPoly[2].z);
vecTmp1 = vecPos[1] - vecPos[0];
vecTmp2 = vecPos[2] - vecPos[0];
D3DXVec3Cross(&vecNormal,&vecTmp1,&vecTmp2);
D3DXVec3Normalize(&vecNormal,&vecNormal);
ffDist = D3DXVec3Dot(&vecNormal,&(vecPos[0]));
float fDot = D3DXVec3Dot(&vecNormal,&vecDir);
if(IS_SIGNBIT(fDot) == 0) // <20><><EFBFBD>ְ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̰ų<CCB0> 90<39><30> <20><><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD> (BackFace Check)
return false;
float fffDist = (ffDist - D3DXVec3Dot(&vecNormal,&(vecStart))) / fDot; // ray<61><79> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>浹 üũ (rayOrigin + dir * t <20><> t<><74> <20><><EFBFBD><EFBFBD>)
if(IS_SIGNBIT(fffDist) || (fffDist >= fDist)) //t<><74> <20><><EFBFBD><EFBFBD><EFBFBD>̰ų<CCB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD≯<EFBFBD> <20>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>.
return false;
D3DXVECTOR3 vec1 = vecStart + vecDir * fffDist; //ve1 : intersect point.
// Edge Normal <20><> dot <20>ؼ<EFBFBD> 90 <20>Ѿ<D1BE><EEB0A1> <20>ܺ<EFBFBD>.
D3DXVECTOR3 Edges[3];
int i;
for(i = 0; i < 3; i++ )
{
D3DXVECTOR3 vecTmp = vecPos[(i + 1) % 3] - vecPos[i];
D3DXVec3Cross(&(Edges[i]),&vecTmp,&vecNormal);
D3DXVec3Normalize(&(Edges[i]),&(Edges[i]));
}
for(i = 0; i < 3; i++ )
{
if ((vec1.x - vecPos[i].x) * Edges[i].x + (vec1.y - vecPos[i].y) * Edges[i].y + (vec1.z - vecPos[i].z)* Edges[i].z > 0)
return false;
}
return true;
}