176 lines
3.8 KiB
C++
176 lines
3.8 KiB
C++
#include "StdAfx.h"
|
||
#include "CullingManager.h"
|
||
#include "GrpObjectInstance.h"
|
||
|
||
//#define COUNT_SHOWING_SPHERE
|
||
|
||
#ifdef COUNT_SHOWING_SPHERE
|
||
int showingcount = 0;
|
||
#endif
|
||
|
||
void CCullingManager::RayTraceCallback(const Vector3d &/*p1*/, // source pos of ray
|
||
const Vector3d &/*dir*/, // dest pos of ray
|
||
float distance,
|
||
const Vector3d &/*sect*/,
|
||
SpherePack *sphere)
|
||
{
|
||
//if (state!=VS_OUTSIDE)
|
||
//{
|
||
if (m_RayFarDistance<=0.0f || m_RayFarDistance>=distance)
|
||
{
|
||
#ifdef SPHERELIB_STRICT
|
||
if (sphere->IS_SPHERE)
|
||
puts("CCullingManager::RayTraceCallback");
|
||
#endif
|
||
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
|
||
}
|
||
//f((CGraphicObjectInstance *)sphere->GetUserData());
|
||
//}
|
||
}
|
||
|
||
|
||
void CCullingManager::VisibilityCallback(const Frustum &/*f*/,SpherePack *sphere,ViewState state)
|
||
{
|
||
#ifdef SPHERELIB_STRICT
|
||
if (sphere->IS_SPHERE)
|
||
puts("CCullingManager::VisibilityCallback");
|
||
#endif
|
||
|
||
CGraphicObjectInstance * pInstance = (CGraphicObjectInstance*)sphere->GetUserData();
|
||
/*if (state == VS_PARTIAL)
|
||
{
|
||
Vector3d v;
|
||
float r;
|
||
pInstance->GetBoundingSphere(v,r);
|
||
state = f.ViewVolumeTest(v,r);
|
||
}*/
|
||
if (state == VS_OUTSIDE)
|
||
{
|
||
#ifdef COUNT_SHOWING_SPHERE
|
||
if (pInstance->isShow())
|
||
{
|
||
Tracef("SH : %p ",sphere->GetUserData());
|
||
showingcount--;
|
||
Tracef("show size : %5d\n",showingcount);
|
||
}
|
||
|
||
#endif
|
||
pInstance->Hide();
|
||
}
|
||
else
|
||
{
|
||
#ifdef COUNT_SHOWING_SPHERE
|
||
if (!pInstance->isShow())
|
||
{
|
||
Tracef("HS : %p ",sphere->GetUserData());
|
||
showingcount++;
|
||
Tracef("show size : %5d\n",showingcount);
|
||
}
|
||
#endif
|
||
pInstance->Show();
|
||
}
|
||
}
|
||
|
||
void CCullingManager::RangeTestCallback(const Vector3d &/*p*/,float /*distance*/,SpherePack *sphere,ViewState state)
|
||
{
|
||
#ifdef SPHERELIB_STRICT
|
||
if (sphere->IS_SPHERE)
|
||
puts("CCullingManager::RangeTestCallback");
|
||
#endif
|
||
if (state!=VS_OUTSIDE)
|
||
{
|
||
m_list.push_back((CGraphicObjectInstance *)sphere->GetUserData());
|
||
//f((CGraphicObjectInstance *)sphere->GetUserData());
|
||
}
|
||
//assert(false && "NOT REACHED");
|
||
}
|
||
|
||
void CCullingManager::Reset()
|
||
{
|
||
m_Factory->Reset();
|
||
}
|
||
|
||
void CCullingManager::Update()
|
||
{
|
||
// TODO : update each object
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ϰ<EFBFBD> <20>غ<EFBFBD><D8BA><EFBFBD>
|
||
|
||
//DWORD time = ELTimer_GetMSec();
|
||
//Reset();
|
||
|
||
m_Factory->Process();
|
||
//Tracef("cull update : %3d ",ELTimer_GetMSec()-time);
|
||
}
|
||
|
||
void CCullingManager::Process()
|
||
{
|
||
//DWORD time = ELTimer_GetMSec();
|
||
//Frustum f;
|
||
UpdateViewMatrix();
|
||
UpdateProjMatrix();
|
||
BuildViewFrustum();
|
||
m_Factory->FrustumTest(GetFrustum(), this);
|
||
//Tracef("cull process : %3d ",ELTimer_GetMSec()-time);
|
||
}
|
||
|
||
CCullingManager::CullingHandle CCullingManager::Register(CGraphicObjectInstance * obj)
|
||
{
|
||
assert(obj);
|
||
#ifdef COUNT_SHOWING_SPHERE
|
||
Tracef("CR : %p ",obj);
|
||
showingcount++;
|
||
Tracef("show size : %5d\n",showingcount);
|
||
#endif
|
||
Vector3d center;
|
||
float radius;
|
||
obj->GetBoundingSphere(center,radius);
|
||
return m_Factory->AddSphere_(center,radius,obj, false);
|
||
}
|
||
|
||
void CCullingManager::Unregister(CullingHandle h)
|
||
{
|
||
#ifdef COUNT_SHOWING_SPHERE
|
||
if (((CGraphicObjectInstance*)h->GetUserData())->isShow())
|
||
{
|
||
Tracef("DE : %p ",h->GetUserData());
|
||
showingcount--;
|
||
Tracef("show size : %5d\n",showingcount);
|
||
}
|
||
#endif
|
||
m_Factory->Remove(h);
|
||
}
|
||
|
||
CCullingManager::CCullingManager()
|
||
{
|
||
m_Factory = new SpherePackFactory(
|
||
10000, // maximum count
|
||
6400, // root radius
|
||
1600, // leaf radius
|
||
400 // extra radius
|
||
);
|
||
}
|
||
|
||
CCullingManager::~CCullingManager()
|
||
{
|
||
delete m_Factory;
|
||
}
|
||
|
||
void CCullingManager::FindRange(const Vector3d &p, float radius)
|
||
{
|
||
m_list.clear();
|
||
m_Factory->RangeTest(p, radius, this);
|
||
}
|
||
|
||
void CCullingManager::FindRay(const Vector3d &p1, const Vector3d &dir)
|
||
{
|
||
m_RayFarDistance = -1;
|
||
m_list.clear();
|
||
m_Factory->RayTrace(p1,dir,this);
|
||
}
|
||
|
||
void CCullingManager::FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance)
|
||
{
|
||
m_RayFarDistance = distance;
|
||
m_list.clear();
|
||
m_Factory->RayTrace(p1,dir,this);
|
||
} |