1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 /**
3  *	Contains code for planes.
4  *	\file		IcePlane.h
5  *	\author		Pierre Terdiman
6  *	\date		April, 4, 2000
7  */
8 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9 
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 // Include Guard
12 #ifndef __ICEPLANE_H__
13 #define __ICEPLANE_H__
14 
15 	#define PLANE_EPSILON		(1.0e-7f)
16 
17 	class ICEMATHS_API Plane
18 	{
19 		public:
20 		//! Constructor
Plane()21 		inline_			Plane()															{												}
22 		//! Constructor from a normal and a distance
Plane(float nx,float ny,float nz,float d)23 		inline_			Plane(float nx, float ny, float nz, float d)					{ Set(nx, ny, nz, d);							}
24 		//! Constructor from a point on the plane and a normal
Plane(const Point & p,const Point & n)25 		inline_			Plane(const Point& p, const Point& n)							{ Set(p, n);									}
26 		//! Constructor from three points
Plane(const Point & p0,const Point & p1,const Point & p2)27 		inline_			Plane(const Point& p0, const Point& p1, const Point& p2)		{ Set(p0, p1, p2);								}
28 		//! Constructor from a normal and a distance
Plane(const Point & _n,float _d)29 		inline_			Plane(const Point& _n, float _d)								{ n = _n; d = _d;								}
30 		//! Copy constructor
Plane(const Plane & plane)31 		inline_			Plane(const Plane& plane) : n(plane.n), d(plane.d)				{												}
32 		//! Destructor
~Plane()33 		inline_			~Plane()														{												}
34 
Zero()35 		inline_	Plane&	Zero()															{ n.Zero(); d = 0.0f;			return *this;	}
Set(float nx,float ny,float nz,float _d)36 		inline_	Plane&	Set(float nx, float ny, float nz, float _d)						{ n.Set(nx, ny, nz); d = _d;	return *this;	}
Set(const Point & p,const Point & _n)37 		inline_	Plane&	Set(const Point& p, const Point& _n)							{ n = _n; d = - p | _n;			return *this;	}
38 				Plane&	Set(const Point& p0, const Point& p1, const Point& p2);
39 
Distance(const Point & p)40 		inline_	float	Distance(const Point& p)			const						{ return (p | n) + d;							}
Belongs(const Point & p)41 		inline_	bool	Belongs(const Point& p)				const						{ return fabsf(Distance(p)) < PLANE_EPSILON;	}
42 
Normalize()43 		inline_	void	Normalize()
44 						{
45 							float Denom = 1.0f / n.Magnitude();
46 							n.x	*= Denom;
47 							n.y	*= Denom;
48 							n.z	*= Denom;
49 							d	*= Denom;
50 						}
51 		public:
52 		// Members
53 				Point	n;		//!< The normal to the plane
54 				float	d;		//!< The distance from the origin
55 
56 		// Cast operators
Point()57 		inline_			operator Point()					const						{ return n;										}
HPoint()58 		inline_			operator HPoint()					const						{ return HPoint(n, d);							}
59 
60 		// Arithmetic operators
61 		inline_	Plane	operator*(const Matrix4x4& m)		const
62 						{
63 							// Old code from Irion. Kept for reference.
64 							Plane Ret(*this);
65 							return Ret *= m;
66 						}
67 
68 		inline_	Plane&	operator*=(const Matrix4x4& m)
69 						{
70 							// Old code from Irion. Kept for reference.
71 							Point n2 = HPoint(n, 0.0f) * m;
72 							d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2);
73 							n = n2;
74 							return *this;
75 						}
76 	};
77 
78 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 	/**
80 	 *	Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
81 	 *	\param		transformed	[out] transformed plane
82 	 *	\param		plane		[in] source plane
83 	 *	\param		transform	[in] transform matrix
84 	 *	\warning	the plane normal must be unit-length
85 	 */
86 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TransformPlane(Plane & transformed,const Plane & plane,const Matrix4x4 & transform)87 	inline_	void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform)
88 	{
89 		// Rotate the normal using the rotation part of the 4x4 matrix
90 		transformed.n = plane.n * Matrix3x3(transform);
91 
92 		// Compute new d
93 		transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n);
94 	}
95 
96 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 	/**
98 	 *	Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
99 	 *	\param		plane		[in/out] source plane (transformed on return)
100 	 *	\param		transform	[in] transform matrix
101 	 *	\warning	the plane normal must be unit-length
102 	 */
103 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TransformPlane(Plane & plane,const Matrix4x4 & transform)104 	inline_	void TransformPlane(Plane& plane, const Matrix4x4& transform)
105 	{
106 		// Rotate the normal using the rotation part of the 4x4 matrix
107 		plane.n *= Matrix3x3(transform);
108 
109 		// Compute new d
110 		plane.d -= Point(transform.GetTrans())|plane.n;
111 	}
112 
113 #endif // __ICEPLANE_H__
114