Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / Roma / PLANE

.CPP
Скачиваний:
21
Добавлен:
16.04.2013
Размер:
5 Кб
Скачать
☆
#include "vector.cpp"
class PLANE {
	public :
		enum { LINEINPLANE, PARALLEL, INTERSECTION };
		VECTOR 	Normal;
		POINT Point;

		/*	The `d' value from ax+bx+cx+d=0 */
		REAL	d;

		/*	Operation to create
			a null plane.	*/
		PLANE ( void );

		PLANE ( VECTOR& n, POINT& Point );
		void Set ( VECTOR& n, POINT& Point );
		int Intersection ( POINT *p1, POINT *p2, POINT *Result );
		BOOL IsInside ( POINT *p );

		/*	Clip a polygon
			to the plane.	*/
		int Intersection ( POINT *p1, POINT *p2, POINT *Result, INTPOINT *t1, INTPOINT *t2, INTPOINT *tResult );

		/*	Clip a textured
			polygon to a plane.	*/
		BOOL Clip ( int *nVerts, POINT *In, POINT *Out, INTPOINT *InTex, INTPOINT *OutTex );

		/*	Project a polygon onto a plane
			( shadow attenuation ).	*/
//		void Project ( POINT *Light, int nVerts, POINT *In, POINT *Out );

	};

// Create a plane object with undefined location and normal.                //

PLANE :: PLANE ( void ){
}

// Create a plane using a point on the plane and the normal to the plane.   //

PLANE :: PLANE ( VECTOR& n, POINT& Point ){
	Set ( n, Point );
}

// Assign a plane using a point on the plane and the normal to the plane.   //

void PLANE :: Set ( VECTOR& n, POINT& p ){
Point = p;
Normal = n;
d = -Normal.Dot ( ( VECTOR& ) Point );
}

// Calculates the intersection of a line and a plane.                       //

int PLANE :: Intersection ( POINT *p1, POINT *p2, POINT *Result, INTPOINT *t1, INTPOINT *t2, INTPOINT *tResult ){
	REAL	t, p, q;
	VECTOR	r ( *p2 );

	r -= *p1;
	p = Normal.Dot ( ( VECTOR& ) *p1 ) + d;
	q = Normal.Dot ( ( VECTOR& ) r );
	if ( q == 0 ) {
		if ( p == 0 ) {

			//	The line was in the plane.
			return ( LINEINPLANE );
		} else {

			//	Does not intersect at all.
			return ( PARALLEL );
		}
	}

	//	From x = x1 + ( x2 - x1 ) find the t value.
	t = - ( p / q );
	r *= t;

	//	Store back into result.
	*Result = *p1;
	*Result += r;

	//	Find out how much the line changed by.
	VECTOR Old ( p1, p2 ), New ( p1, Result );
	REAL   Scale, lOld, lNew;

	//	Get the lengths of the lines.
	lOld = Old.Length ();
	lNew = New.Length ();

	//	Find the scale value.
	Scale = ( lNew / lOld );

	//	Alter the texture co-ordinates.
	tResult->x = t1->x + ( ( REAL ) ( t2->x - t1->x ) * Scale );
	tResult->y = t1->y + ( ( REAL ) ( t2->y - t1->y ) * Scale );

	//	Intersection is in `Result'.
	return ( INTERSECTION );
}

// Calculates the intersection of a line and a plane.                       //

int PLANE :: Intersection ( POINT *p1, POINT *p2, POINT *Result ){
	REAL	t, p, q;
	VECTOR	r ( *p2 );

	r -= *p1;
	p = Normal.Dot ( ( VECTOR& ) *p1 ) + d;
	q = Normal.Dot ( ( VECTOR& ) r );
	if ( q == 0 ) {
		if ( p == 0 ) {

			//	The line was in	the plane.
			return ( LINEINPLANE );
		} else {

			//	Does not intersect at all.
			return ( PARALLEL );
		}
	}

	//	From x = x1 + ( x2 - x1 ) * t find the t value.
	t = - ( p / q );
	r *= t;

	//	Store back into result.
	*Result = *p1;
	*Result += r;

	return ( INTERSECTION );
}

// Determine which side of a plane a point lies on.                         //

BOOL PLANE :: IsInside ( POINT *p ){
	REAL   Result;
	VECTOR Temp ( Point, *p );
	Result = Normal.Dot ( Temp );
	return ( ( Result < 0 ) );
}

// Clips a polygon to this plane.                                           //

BOOL PLANE :: Clip ( int *nVerts, POINT *In, POINT *Out, INTPOINT *InTex, INTPOINT *OutTex ){
	int		i, Next;
	BOOL		cIsIn, nIsIn;
	POINT		*cIn = In, *cOut = Out;
	INTPOINT	*tIn = InTex, *tOut = OutTex;

	//	If x < z, then point is outside plane.
	cIsIn = IsInside ( &cIn [0] );
	if ( ( InTex != NULL ) && ( OutTex != NULL ) ) {
		for ( i = 0; i < *nVerts; i++ ) {
			//	Keep first vertex if it's inside plane.
			if ( cIsIn == TRUE ) {
				*cOut++ = *cIn;
				*tOut++ = *tIn;
			}
			//	Get the next vertex.
			Next = ( i + 1 ) % *nVerts;
			//	Classify with respect to the plane.
			nIsIn = IsInside ( &In [Next] );
			//	If either is outside the plane, add clipped vertex.
			if ( nIsIn != cIsIn ) {
				Intersection ( cIn, &In [Next], cOut++, tIn, &InTex [Next], tOut++ );
			}
			//	Make the next result the current result.
			cIsIn = nIsIn;
			//	And go to the next input vertex.
			cIn++;
			tIn++;
		}
	} else {
		//	Clipping without texture clipping.
		for ( i = 0; i < *nVerts; i++ ) {
			//	Keep first vertex if it's inside plane.
			if ( cIsIn == TRUE ) {
				*cOut++ = *cIn;
			}
			//	Get the next vertex.
			Next = ( i + 1 ) % *nVerts;
			//	Classify with respect to the plane.
			nIsIn = IsInside ( &In [Next] );
			//	If either is outside the plane, add clipped vertex.
			if ( nIsIn != cIsIn ) {
				Intersection ( cIn, &In [Next], cOut++ );
			}
			//	Make the next result the current result.
			cIsIn = nIsIn;
			//	And go to the next input vertex.
			cIn++;
		}
	}

	//	Find the total number of emitted vertices.
	*nVerts = ( int) ( cOut - Out );
	//	And return the result of clipping.
	if ( *nVerts < 3 ) {
		return ( FALSE );
	} else {
		return ( TRUE );
	}
}

// Projects a polygon from a light source onto a plane.                     //

/*void PLANE :: Project ( POINT *Light, int nVerts, POINT *In, POINT *Out ){
	int i;

	for ( i = 0; i < nVerts; i++ ) {
		Intersection ( Light, &In [i], &Out [i], NULL, NULL, NULL );
	}
} */

Соседние файлы в папке Roma