/****************************************************************************************************

		Geometry.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Julien
		Date:	2/17/2003

****************************************************************************************************/

#ifndef __Geometry__
#define __Geometry__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCBasicTypes.h"
#include "Vector3.h"

template<class T> class TMCArray;


// compute the intersection between the line (P0, P1) 
// and the plane define by (normal, V0). Return false if there's no intersection.
boolean IntersectLinePlane( const TVector3& P0, // first point of the line
							const TVector3& P1, // second point of the line
							const TVector3& V0, // point on the plane
							const TVector3& normal, // normal to the plane
							TVector3& result	);

// compute the intersection between the half-line [P0,P1)
// and the plane define by (normal, V0). Return false if there's no intersection.
boolean IntersectHalfLinePlane( const TVector3& P0, // first point of the line
								const TVector3& P1, // second point of the line
								const TVector3& V0, // point on the plane
								const TVector3& normal, // normal to the plane
								TVector3& result	);

// compute the intersection between the segment [P0,P1]
// and the plane define by (normal, V0). Return false if there's no intersection.
boolean IntersectSegmentPlane(	const TVector3& P0, // first point of the line
								const TVector3& P1, // second point of the line
								const TVector3& V0, // point on the plane
								const TVector3& normal, // normal to the plane
								TVector3& result	);

// compute the intersection between the line define by (linePoint, lineDirection) and the 
// plane define by (planeNormal, planePoint). Return false if there's no intersection.
boolean IntersectLinePlane2(const TVector3& linePoint,
							const TVector3& lineDirection,
							const TVector3& planeNormal,
							const TVector3& planePoint,
							TVector3& result	);

// Compute the distance between 2 lines (P0,u) and (Q0,v).
// Return the distance and the nearest points P and Q.
real32 DistanceBetweenLines(const TVector3& P0, const TVector3& u,
							const TVector3& Q0, const TVector3& v,
							TVector3& P, TVector3& Q, boolean& areParallel);

// Compute the distance between a point and a line(linePoint,v).
// Return the distance and the nearest point.
real32 DistancePointToLine( const TVector3& point,
						    const TVector3& linePoint, const TVector3& v,
							TVector3& result );

//
real32 DistancePointToPlane(const TVector3& point,
							const TVector3& planePoint, const TVector3& planeNormal,
							TVector3& result );

// Compute the angle between the vector v and the vector w
// u is a vector perpendicular to v and w and give an orientation to the angle (if (u,v,w)
// is direct, the angle will be positive, else it will be negative)
void AngleBetweenVectors(const TVector3& v,
						 const TVector3& w,
						 const TVector3& u,
						 real32& angle); // in degrees

// Same as previous but return the sin and cos of the angle (faster)
void AngleBetweenVectors(const TVector3& v,
						 const TVector3& w,
						 const TVector3& u,
						 real32& sin, real32& cos);

// return true if the points are aligned
boolean ArePointsAlingned( TMCArray<TVector3>& points );

// Return a colinear vector with the same magnitude with Z>0. If Z==0, orient the Y>0. 
// If Y==0 too, orient X>0
inline void OrientVectorUp(TVector3& vector)
{
	if(	vector.z<0 ||
		(vector.z==0 && vector.y<0) ||
		(vector.z==0 && vector.y==0 && vector.x<0) )
		vector=-vector;
}

// Return true if the 2 triangles have an intersection
boolean IntersectTriangles(const TVector3d verticesA[],const TVector3d verticesB[]);


//Returns the square of the distance between the point C and the segment [AB]
real GetSquareDistanceFromSegment(const TVector3& A, const TVector3& B, const TVector3& C, real* u=NULL);


//Returns the square of the distance between the point C and the segment [AB], 
//and the parameter u to compute the closest point P on [AB]: AP= u.AB
real GetSquareDistanceFromSegment(const TVector2& A, const TVector2& B, const TVector2& C, real& u);


#endif
