Example #1
0
//  this function tests if the projection of a bounding sphere along the light direction intersects
//  the view frustum 
bool SweptSpherePlaneIntersect( float& t0, float& t1, const SPlane& plane, const SVector3& pos, float radius, const SVector3& sweepDir )
{
	float b_dot_n = D3DXPlaneDotCoord(&plane, &pos);
	float d_dot_n = D3DXPlaneDotNormal(&plane, &sweepDir);

	if (d_dot_n == 0.f)
	{
		if (b_dot_n <= radius)
		{
			//  effectively infinity
			t0 = 0.f;
			t1 = 1e32f;
			return true;
		}
		else
			return false;
	}
	else
	{
		float tmp0 = ( radius - b_dot_n) / d_dot_n;
		float tmp1 = (-radius - b_dot_n) / d_dot_n;
		t0 = min(tmp0, tmp1);
		t1 = max(tmp0, tmp1);
		return true;
	}
}
Example #2
0
TEST( Plane, dotNormal )
{
   Plane plane;
   Vector testPt;

   testPt.set( 3, 2, -1 );
   plane.set( Quad_1000, FastFloat::fromFloat( 10.0f ) );
   float dxDot = D3DXPlaneDotNormal( ( const D3DXPLANE* )&plane, ( const D3DXVECTOR3* )&testPt );
   float tamyDot = plane.dotNormal( testPt ).getFloat();
   CPPUNIT_ASSERT_DOUBLES_EQUAL( dxDot, tamyDot, 1e-3f );

   testPt.set( 3, 2, -1 );
   plane.set( Quad_Neg_0100, FastFloat::fromFloat( -12.0f ) );
   dxDot = D3DXPlaneDotNormal( ( const D3DXPLANE* )&plane, ( const D3DXVECTOR3* )&testPt );
   tamyDot = plane.dotNormal( testPt ).getFloat();
   CPPUNIT_ASSERT_DOUBLES_EQUAL( dxDot, tamyDot, 1e-3f );
}
Example #3
0
ViewFrustum::Containment ViewFrustum::ContainsBox(const BoundingBox& box) const
{
    // Do OBB-plane test for each frustum plane
    for(size_t f = 0; f < 6; ++f)
    {
        D3DXVECTOR4 extent;

        extent.x = abs(D3DXPlaneDotNormal(&frustum[f], &box.vx));
        extent.y = abs(D3DXPlaneDotNormal(&frustum[f], &box.vy));
        extent.z = abs(D3DXPlaneDotNormal(&frustum[f], &box.vz));
        extent.w = D3DXPlaneDotCoord(&frustum[f], &box.center);

        // Fail if centre + projected extents is outside the halfspace
        if(extent.w + extent.x + extent.y + extent.z < 0)
            return OUTSIDE;
    }

    // Neglect to test frustum multi-plane corner cases to save time; this still culls conservatively

    return INSIDE;
}
Example #4
0
RWinding *ClipToSeperators ( RWinding *source, RWinding *pass, RWinding *target, CLIP_SEPERATOR_DIR clipdir )
{
	long	cur_src_point;
	long	next_src_point;
	long	cur_pass_point;
	rvector	v1, v2;
	rplane	plane;

	long	i;
	float	d;
	float	length;
	long	front_count;

	if( ! source || ! pass ) return target;

	//	source의 모서리와 pass의 한점을 선택하는 모든 조합을 만든다.
	for (cur_src_point=0 ; cur_src_point<source->nCount; cur_src_point++)
	{
		// source 로부터 한 모서리를 선택한다.
		next_src_point = (cur_src_point+1)%source->nCount;
		v1 = source->pVertices[next_src_point] - source->pVertices[cur_src_point];

		for (cur_pass_point=0 ; cur_pass_point<pass->nCount; cur_pass_point++)
		{
			// pass 로부터 한 점을 선택한다.
			v2 = pass->pVertices[cur_pass_point] - source->pVertices[cur_src_point];

			// 선택한 모서리와 점으로 평면(plane)을 만든다.
			rvector normal;
			CrossProduct( &normal,  v1 ,v2  );
			length = DotProduct( normal, normal );			
			if (length < ON_EPSILON)
				continue;
			length = (float)sqrt(length);
			plane.a = normal.x/length;
			plane.b = normal.y/length;
			plane.c = normal.z/length;
			plane.d = -D3DXPlaneDotNormal(&plane,&pass->pVertices[cur_pass_point]);

			// plane과 source의위치관계를 조사한다.
			front_count = 0;
			for (i=0 ; i<source->nCount ; i++)
			{
				if (i == cur_src_point || i == next_src_point)
					continue;
				d = D3DXPlaneDotCoord(&plane,&source->pVertices[i]);
				if (d < -ON_EPSILON)
					break;
				if (d > ON_EPSILON)
				{
					front_count++;
					// source는 plane의 양쪽에 걸쳐져 있을 수 없다.
					// 따라서 한점만 앞에있어도 source가 앞에있다고 판단.
					break;
				}
			}
			// source가 plane상에 있는경우는 취급하지 않는다.
			// 이것은 [ 가시성 판단 3 ] 에서 처리한다.
			// [ 가시성 판단 3 ] 을 수행하지 않고 이 함수를 수행하려 한다면
			// 함수가 좀 복잡해진다.
			if (i == source->nCount)
				continue;

			// source가 plane의 뒤쪽에 위치하도록 평면방정식을 조정한다.			
			if ( front_count )
				plane=-plane;

			// plane과 pass의위치관계를 조사한다.
			// pass가 plane의 앞쪽에 완전히 포함되는 경우,
			// plane으로 target을 클리핑한다.
			front_count = 0;
			for (i=0 ; i<pass->nCount; i++)
			{
				if (i==cur_pass_point)
					continue;
				d = D3DXPlaneDotCoord(&plane,&pass->pVertices[i]);
				if (d < -ON_EPSILON)
					break;
				if (d > ON_EPSILON)
					front_count++;
			}
			// 한점이라도 plane의 뒤쪽에 있으면 안된다.
			if (i != pass->nCount)
				continue;
			// pass가 평면에 포함되어서도 안된다.
			if ( ! front_count )
				continue;

			// 입력된 parameter 가
			// source -> pass -> target 순이 아니라
			// pass -> source -> target 순이라면 plane을 뒤집어야 한다.
			if ( clipdir == CLIP_SEPERATOR_BACKWARD )
			{
				plane=-plane;
			}

			// 여기까지 왔다면 plane은 뷰볼륨을 이루는 평면이다.
			// target을 잘라낸다.
			target = ClipWinding (target, plane);
			if (!target)
				return NULL;		// target is not visible
		}
	}

	return target;
}