forked from metin2/client
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);
|
|||
|
}
|