#pragma once #include "GrpScreen.h" #include "../eterbase/Singleton.h" #include "../SphereLib/spherepack.h" class CGraphicObjectInstance; template struct RangeTester : public SpherePackCallback { T * f; float dist; RangeTester(T * fn, float distance=-1) : f(fn), dist(distance) {} virtual ~RangeTester() {} virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray const Vector3d &dir, // dest pos of ray float distance, const Vector3d §, SpherePack *sphere) { #ifdef SPHERELIB_STRICT if (sphere->IS_SPHERE) puts("RangeTester::RayTraceCallback"); #endif if (dist<=0.0f || dist>=distance) (*f)((CGraphicObjectInstance *)sphere->GetUserData()); }; virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state){}; virtual void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state) { #ifdef SPHERELIB_STRICT if (sphere->IS_SPHERE) puts("RangeTester::RangeTestCallback"); #endif if (state!=VS_OUTSIDE) (*f)((CGraphicObjectInstance *)sphere->GetUserData()); } virtual void PointTest2dCallback(const Vector3d &p, SpherePack *sphere,ViewState state) { #ifdef SPHERELIB_STRICT if (sphere->IS_SPHERE) puts("RangeTester::PointTest2dCallback"); #endif if (state!=VS_OUTSIDE) { #ifdef SPHERELIB_STRICT puts("FIND!!"); #endif (*f)((CGraphicObjectInstance *)sphere->GetUserData()); } } }; class CCullingManager : public CSingleton, public SpherePackCallback, private CScreen { public: typedef SpherePack * CullingHandle; typedef std::vector TRangeList; CCullingManager(); virtual ~CCullingManager(); virtual void RayTraceCallback(const Vector3d &p1, // source pos of ray const Vector3d &dir, // dest pos of ray float distance, const Vector3d §, SpherePack *sphere); virtual void VisibilityCallback(const Frustum &f,SpherePack *sphere,ViewState state); void RangeTestCallback(const Vector3d &p,float distance,SpherePack *sphere,ViewState state); void Reset(); void Update(); void Process(); void FindRange(const Vector3d &p, float radius); void FindRay(const Vector3d &p1, const Vector3d &dir); void FindRayDistance(const Vector3d &p1, const Vector3d &dir, float distance); void RangeTest(const Vector3d& p, float radius, SpherePackCallback* callback) { m_Factory->RangeTest(p, radius, callback); } void PointTest2d(const Vector3d& p, SpherePackCallback* callback) { m_Factory->PointTest2d(p, callback); } template void ForInRange2d(const Vector3d& p, T* pFunc) { RangeTester r(pFunc); m_Factory->PointTest2d(p, &r); } template void ForInRange(const Vector3d &p, float radius, T* pFunc) { RangeTester r(pFunc); m_Factory->RangeTest(p, radius, &r/*this*/); } template void ForInRay(const Vector3d &p1, const Vector3d &dir, T* pFunc) { RangeTester r(pFunc); /*Vector3d p2; //p2.Set(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f)); p2.x = p.x+50000.0f*dir.x; p2.y = p.y+50000.0f*dir.y; p2.z = p.z+50000.0f*dir.z; // p + (50000.0f*dir);//(p.x+(dir.x*50000.0f),p.y+(dir.y*50000.0f),p.z+(dir.z*50000.0f));*/ m_Factory->RayTrace(p1, dir, &r/*this*/); } template void ForInRayDistance(const Vector3d &p, const Vector3d &dir, float distance, T* pFunc) { RangeTester r(pFunc, distance); m_Factory->RayTrace(p, dir, &r/*this*/); } CullingHandle Register(CGraphicObjectInstance * ob); void Unregister(CullingHandle h); TRangeList::iterator begin() { return m_list.begin(); } TRangeList::iterator end() { return m_list.end(); } protected: TRangeList m_list; float m_RayFarDistance; SpherePackFactory * m_Factory; };