/*
	Twilight Prophecy 3D/Multimedia SDK
	A multi-platform development system for virtual reality and multimedia.

	Copyright (C) 1997-2001 by Twilight 3D Finland Oy Ltd.
*/
#ifndef PRMATH_PLANE_HPP
#define PRMATH_PLANE_HPP



namespace prmath
{
	
	struct Plane
	{
		// members
		Vector3		normal;
		float		dist;
		
		// constructors
inline	Plane() {}
inline	Plane(const Vector3& normal, float dist);
inline	Plane(const Vector3& normal, const Vector3& point);
inline	Plane(const Vector3& v1, const Vector3& v2, const Vector3& v3);
inline	Plane(const Plane& plane);

		// methods		
inline	float		Intersect(const Vector3& origin, const Vector3& direction) const;
inline	float		GetOffset(const Vector3& point) const;
inline	bool		IsFront(const Vector3& point) const;
inline	bool		IsBack(const Vector3& point) const;
	};


	// implementation

inline Plane::Plane(const Vector3& normal_, float dist_)
: normal(normal_), dist(dist_)
{
}

inline Plane::Plane(const Vector3& normal_, const Vector3& point)
{
	normal = normal_;
	dist = DotProduct(point,normal);
}

inline Plane::Plane(const Vector3& v1, const Vector3& v2, const Vector3& v3)
{
	normal = Normalize(CrossProduct(v2-v1,v3-v1));
	dist = DotProduct(v1,normal);
}

inline Plane::Plane(const Plane& plane)
: normal(plane.normal), dist(plane.dist)
{
}
	
inline float Plane::Intersect(const Vector3& origin, const Vector3& direction) const
{
	float ndot = DotProduct(normal,direction);
	return ndot ? ((dist - DotProduct(normal,origin)) / ndot) : 0;
}

inline float Plane::GetOffset(const Vector3& point) const
{
	return DotProduct(normal,point) - dist;
}

inline bool Plane::IsFront(const Vector3& point) const
{
	return GetOffset(point) > 0;
}

inline bool Plane::IsBack(const Vector3& point) const
{
	return GetOffset(point) < 0;
}

} // namespace prmath



#endif