Ejemplo n.º 1
0
BOOL CActor::CanPickItem(const CFrustum& frustum, const Fvector& from, CObject* item)
{
	BOOL	bOverlaped		= FALSE;
	Fvector dir,to; 
	item->Center			(to);
	float range				= dir.sub(to,from).magnitude();
	if (range>0.25f){
		if (frustum.testSphere_dirty(to,item->Radius())){
			dir.div						(range);
			collide::ray_defs			RD(from, dir, range, CDB::OPT_CULL, collide::rqtBoth);
			VERIFY						(!fis_zero(RD.dir.square_magnitude()));
			RQR.r_clear					();
			Level().ObjectSpace.RayQuery(RQR,RD, info_trace_callback, &bOverlaped, NULL, item);
		}
	}
	return !bOverlaped;
}
Ejemplo n.º 2
0
bool CEditShape::FrustumPick(const CFrustum& frustum)
{
	const Fmatrix& M	= _Transform();
	for (ShapeIt it=shapes.begin(); it!=shapes.end(); it++){
		switch (it->type){
		case cfSphere:{
		    Fvector 	C;
            Fsphere&	T	= it->data.sphere;
		    M.transform_tiny(C,T.P);
        	if (frustum.testSphere_dirty(C,T.R*FScale.x)) return true;
		}break;
		case cfBox:{
        	Fbox 			box;
            box.identity	();
            Fmatrix B		= it->data.box;
            B.mulA_43 		(_Transform());
            box.xform		(B);
			u32 mask		= 0xff;
            if (frustum.testAABB(box.data(),mask)) return true;
		}break;
		}
    }
	return false;
}
Ejemplo n.º 3
0
bool ESoundSource::FrustumPick(const CFrustum& frustum)
{
    return (frustum.testSphere_dirty(m_Params.position,VIS_RADIUS))?true:false;
}
Ejemplo n.º 4
0
bool EParticlesObject::FrustumPick(const CFrustum& frustum)
{
    return (frustum.testSphere_dirty(PPosition,PSOBJECT_SIZE))?true:false;
}
Ejemplo n.º 5
0
void CSector::traverse			(CFrustum &F, _scissor& R_scissor)
{
	// Register traversal process
	if (r_marker	!=	PortalTraverser.i_marker)	{
		r_marker							=	PortalTraverser.i_marker;
		PortalTraverser.r_sectors.push_back	(this);
		r_frustums.clear					();
		r_scissors.clear					();
	}
	r_frustums.push_back		(F);
	r_scissors.push_back		(R_scissor);

	// Search visible portals and go through them
	sPoly	S,D;
	for	(u32 I=0; I<m_portals.size(); I++)
	{
		if (m_portals[I]->marker == PortalTraverser.i_marker) continue;

		CPortal* PORTAL = m_portals[I];
		CSector* pSector;

		// Select sector (allow intersecting portals to be finely classified)
		if (PORTAL->bDualRender) {
			pSector = PORTAL->getSector						(this);
		} else {
			pSector = PORTAL->getSectorBack					(PortalTraverser.i_vBase);
			if (pSector==this)								continue;
			if (pSector==PortalTraverser.i_start)			continue;
		}

		// Early-out sphere
		if (!F.testSphere_dirty(PORTAL->S.P,PORTAL->S.R))	continue;

		// SSA	(if required)
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SSA)
		{
			Fvector				dir2portal;
			dir2portal.sub		(PORTAL->S.P,	PortalTraverser.i_vBase);
			float R				=	PORTAL->S.R	;
			float distSQ		=	dir2portal.square_magnitude();
			float ssa			=	R*R/distSQ;
			dir2portal.div		(_sqrt(distSQ));
			ssa					*=	_abs(PORTAL->P.n.dotproduct(dir2portal));
			if (ssa<r_ssaDISCARD)	continue;

			if (PortalTraverser.i_options&CPortalTraverser::VQ_FADE)	{
				if (ssa<r_ssaLOD_A)	PortalTraverser.fade_portal			(PORTAL,ssa);
				if (ssa<r_ssaLOD_B)	continue							;
			}
		}

		// Clip by frustum
		svector<Fvector,8>&	POLY = PORTAL->getPoly();
		S.assign			(&*POLY.begin(),POLY.size()); D.clear();
		sPoly* P			= F.ClipPoly(S,D);
		if (0==P)			continue;

		// Scissor and optimized HOM-testing
		_scissor			scissor	;
		if (PortalTraverser.i_options&CPortalTraverser::VQ_SCISSOR && (!PORTAL->bDualRender))
		{
			// Build scissor rectangle in projection-space
			Fbox2	bb;	bb.invalidate(); float depth = flt_max;
			sPoly&	p	= *P;
			for		(u32 vit=0; vit<p.size(); vit++)	{
				Fvector4	t;	
				Fmatrix&	M	= PortalTraverser.i_mXFORM_01;
				Fvector&	v	= p[vit];

				t.x = v.x*M._11 + v.y*M._21 + v.z*M._31 + M._41;
				t.y = v.x*M._12 + v.y*M._22 + v.z*M._32 + M._42;
				t.z = v.x*M._13 + v.y*M._23 + v.z*M._33 + M._43;
				t.w = v.x*M._14 + v.y*M._24 + v.z*M._34 + M._44;
				t.mul	(1.f/t.w);

				if (t.x < bb.min.x)	bb.min.x	= t.x; 
				if (t.x > bb.max.x) bb.max.x	= t.x;
				if (t.y < bb.min.y)	bb.min.y	= t.y; 
				if (t.y > bb.max.y) bb.max.y	= t.y;
				if (t.z < depth)	depth		= t.z;
			}
			// Msg	("bb(%s): (%f,%f)-(%f,%f), d=%f", PORTAL->bDualRender?"true":"false",bb.min.x, bb.min.y, bb.max.x, bb.max.y,depth);
			if (depth<EPS)	{
				scissor	= R_scissor;

				// Cull by HOM (slower algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(*P))
					)	continue;
			} else {
				// perform intersection (this is just to be sure, it is probably clipped in 3D already)
				if (bb.min.x > R_scissor.min.x)	scissor.min.x = bb.min.x; else scissor.min.x = R_scissor.min.x;
				if (bb.min.y > R_scissor.min.y)	scissor.min.y = bb.min.y; else scissor.min.y = R_scissor.min.y;
				if (bb.max.x < R_scissor.max.x) scissor.max.x = bb.max.x; else scissor.max.x = R_scissor.max.x;
				if (bb.max.y < R_scissor.max.y) scissor.max.y = bb.max.y; else scissor.max.y = R_scissor.max.y;
				scissor.depth	= depth;

				// Msg	("scissor: (%f,%f)-(%f,%f)", scissor.min.x, scissor.min.y, scissor.max.x, scissor.max.y);
				// Check if box is non-empty
				if (scissor.min.x >= scissor.max.x)	continue;
				if (scissor.min.y >= scissor.max.y)	continue;

				// Cull by HOM (faster algo)
				if  (
					(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
					(!RImplementation.HOM.visible(scissor,depth))
					)	continue;
			}
		} else {
			scissor	= R_scissor;

			// Cull by HOM (slower algo)
			if  (
				(PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && 
				(!RImplementation.HOM.visible(*P))
				)	continue;
		}

		// Create _new_ frustum and recurse
		CFrustum				Clip;
		Clip.CreateFromPortal	(P, PORTAL->P.n, PortalTraverser.i_vBase,PortalTraverser.i_mXFORM);
		PORTAL->marker			= PortalTraverser.i_marker;
		PORTAL->bDualRender		= FALSE;
		pSector->traverse		(Clip,scissor);
	}
}
Ejemplo n.º 6
0
bool CLight::FrustumPick(const CFrustum& frustum)
{
//    return (frustum.testSphere(m_Position,m_Range))?true:false;
    return (frustum.testSphere_dirty(PPosition,VIS_RADIUS))?true:false;
}
Ejemplo n.º 7
0
bool CGlow::FrustumPick(const CFrustum& frustum)
{
    return (frustum.testSphere_dirty(PPosition,m_fRadius))?true:false;
}