Ejemplo n.º 1
0
void DTerrain::SetEnvironment( const DProjector& ViewFrustum, float FogStart, float FogEnd, float LODStartFromFogStart, float LODEndFromFogStart )
{
	s_aOriginalViewPlane[0] = SPlane( ViewFrustum.m_plLeftPlane.a,	 ViewFrustum.m_plLeftPlane.b,   ViewFrustum.m_plLeftPlane.c,   -ViewFrustum.m_plLeftPlane.d   );
	s_aOriginalViewPlane[1] = SPlane( ViewFrustum.m_plRightPlane.a,  ViewFrustum.m_plRightPlane.b,  ViewFrustum.m_plRightPlane.c,  -ViewFrustum.m_plRightPlane.d  );
	s_aOriginalViewPlane[2] = SPlane( ViewFrustum.m_plTopPlane.a,	 ViewFrustum.m_plTopPlane.b,	   ViewFrustum.m_plTopPlane.c,	 -ViewFrustum.m_plTopPlane.d    );
	s_aOriginalViewPlane[3] = SPlane( ViewFrustum.m_plBottomPlane.a, ViewFrustum.m_plBottomPlane.b, ViewFrustum.m_plBottomPlane.c, -ViewFrustum.m_plBottomPlane.d );
	s_aOriginalViewPlane[4] = SPlane( SVector( 0.f, 0.f, ViewFrustum.Near() ), SVector( 0.f, 0.f, -1.f ));

	s_fFarCullDistance = FogEnd;
	s_fFarCullDistance *= s_fFarCullDistance;

	//hjk
	s_fDistOfNearPlane = ViewFrustum.Near();
	s_fDistOfFarPlane = ViewFrustum.Far();
	s_fFOV = ViewFrustum.Fov();
	//hjk end
}
Ejemplo n.º 2
0
Frustum::Frustum( const SMatrix4x4& matrix )
{
	//  build a view frustum based on the current view & projection matrices...
	SVector4 column4( matrix._14, matrix._24, matrix._34, matrix._44 );
	SVector4 column1( matrix._11, matrix._21, matrix._31, matrix._41 );
	SVector4 column2( matrix._12, matrix._22, matrix._32, matrix._42 );
	SVector4 column3( matrix._13, matrix._23, matrix._33, matrix._43 );

	SVector4 planes[6];
	planes[0] = column4 - column1;  // left
	planes[1] = column4 + column1;  // right
	planes[2] = column4 - column2;  // bottom
	planes[3] = column4 + column2;  // top
	planes[4] = column4 - column3;  // near
	planes[5] = column4 + column3;  // far

	int p;

	for (p=0; p<6; p++)  // normalize the planes
	{
		float dot = planes[p].x*planes[p].x + planes[p].y*planes[p].y + planes[p].z*planes[p].z;
		dot = 1.0f / sqrtf(dot);
		planes[p] = planes[p] * dot;
	}

	for (p=0; p<6; p++)
		camPlanes[p] = SPlane( planes[p].x, planes[p].y, planes[p].z, planes[p].w );

	//  build a bit-field that will tell us the indices for the nearest and farthest vertices from each plane...
	for (int i=0; i<6; i++)
		nVertexLUT[i] = ((planes[i].x<0.f)?1:0) | ((planes[i].y<0.f)?2:0) | ((planes[i].z<0.f)?4:0);

	for( int i=0; i<8; ++i ) // compute extrema
	{
		const SPlane& p0 = (i&1)?camPlanes[4] : camPlanes[5];
		const SPlane& p1 = (i&2)?camPlanes[3] : camPlanes[2];
		const SPlane& p2 = (i&4)?camPlanes[0] : camPlanes[1];

		PlaneIntersection( &pntList[i], p0, p1, p2 );
	}
}
Ejemplo n.º 3
0
SCollisionResult CMovement::Trace( CArray<STriangle> &triangles, Vector3 start, Vector3 bboxMax, Vector3 boxdir[3], Vector3 displacement )
{
	float fraction = 1.0f;
	SCollisionResult trace, closest;
	float dist, mindist = 99999.0f;
	CArray<STriangle> colliding;

	ZeroMemory(&closest, sizeof(closest));
	ZeroMemory(&trace, sizeof(trace));

	// Find the collisions with the closest triangles	
	for (int i=0; i<triangles.Size(); i++)
	{
		STriangle &t = triangles[i];
		
		CArray<Vector3> vlist;
		vlist.AddToTail(t.v[0]);
		vlist.AddToTail(t.v[1]);
		vlist.AddToTail(t.v[2]);

		if ( CCollision::OBBPolygon( vlist, start, bboxMax, boxdir, displacement, OUT trace ) )
		{
			if ( trace.fraction <= fraction + 0.1f )
			{
				//if ( trace.fraction < fraction + 0.1f ) colliding.Clear();

				// check if all points of our bbox are in front of the face
				SPlane plane = SPlane( t.v[0], t.v[1], t.v[2] );
				Vector3 size = bboxMax * 2.0f;
				Vector3 min = start - bboxMax;
				Vector3 max = start + bboxMax;

				//Debug("collided: %f %f %f", plane.normal.x, plane.normal.y, plane.normal.z);

				if ( plane.GetSide( min, OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( max, OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( min + Vector3( size.x, 0, 0 ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( min + Vector3( 0, size.y, 0 ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( min + Vector3( 0, 0, size.z ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( max - Vector3( size.x, 0, 0 ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( max - Vector3( 0, size.y, 0 ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;
				if ( plane.GetSide( max - Vector3( 0, 0, size.z ), OUT dist ) == EPlaneSide::Back ) continue; if ( dist < mindist ) mindist = dist;

				
				fraction = trace.fraction;
				closest = trace;
				t.normal = -(t.v[2] - t.v[0]).Cross(t.v[1] - t.v[0]).Normalize();
				closest.normal = t.normal;
				colliding.AddToTail( t );				// add triangle to colliding triangles list	
				//triangleList.Add( t );

				//Debug("COLLIDED!");
			}
		}
	}

	Vector3 dir = displacement;
	Vector3 normal = closest.normal;
	Vector3 endpoint = start;

	// If collided, process the collision
	if ( fraction < 1 )
	{
		// OK
		float m = 0.005f;								// distance from the surface
		float f = closest.fraction;						// fraction of the full dir distance to the contact point
		Vector3 dirNorm = dir; dirNorm.Normalize();
		if ( Vector3::Dot( -dir, normal ) != 0 )
		{
			// PERFECT !!!
			float ndir = dir.Length() * (m / Vector3::Dot( -dir, normal ));
			float x = (f * dir.Length() - ndir);				// distance we move along the dir direction to stay away from the surface
			//Debug.WriteLine( "normal: " + closest.normal + " x: " + x + "   f: " + f + "   ndir: " + ndir + "    distance to surf: " + mindist + "  ndir.Y: " );

			endpoint = start + dirNorm * x;

			Vector3 slide = ClipVelocity( dir, closest.normal, 1.00f );
			float left = 1.0f - (f - ndir / dir.Length());

			closest.slide = slide * left;
		}
	}
	else
		endpoint = start + dir;

	closest.collision = fraction != 1.0f;
	closest.endpoint = endpoint;
	return closest;
}