#ifndef __PLANEH__
#define __PLANEH__
#include "mathlib.h"
static const float Epsilon = 1.0e-05f;
struct plane_t
{
plane_t() {d = 0;}
virtual ~plane_t() { }
void Reset(void) {n.Set(0, 0, 0); d = 0;}
// Returns 1 if the point, 'pt', is in front of the plane
bool IsFront(vec3_t &pt) {return (GetPointDistance(pt) > 0.0f) ? 1 : 0;}
// Returns 1 if the point, 'pt', is behind the plane
bool IsBack(vec3_t &pt) {return !(IsFront(pt));}
// Returns 1 if the point, 'pt', is on the plane
inline bool IsOn(vec3_t &pt);
// Calculates the plane equation given three points
inline void CalcPlane(vec3_t &pta, vec3_t &ptb, vec3_t &ptc);
// Returns 1 if the line from 'start' to 'end' intersects the plane.
// 'point' is a point on the plane and 'result' is the point of
// intersection if there is one, if there is no intersection 'result' is
// not modified.
inline bool LineIntersect(vec3_t &start, vec3_t &end, vec3_t &point,
vec3_t &result);
// Returns the distance that a point, 'pt', is from the plane
float GetPointDistance(vec3_t &pt) {return n.Dot(pt) + d;}
// Returns the normal, A B and C in the plane equation
const vec3_t &GetNormal(void) {return n;}
// Returns the D component of the plane equation
const float &GetD(void) {return d;}
protected:
vec3_t n;
float d;
};
inline bool plane_t::IsOn(vec3_t &pt)
{
float d = GetPointDistance(pt);
return (d > -Epsilon && d < Epsilon) ? 1 : 0;
}
inline void plane_t::CalcPlane(vec3_t &pta, vec3_t &ptb, vec3_t &ptc)
{
n.Cross(ptb - pta, ptc - pta);
n.Normalize();
d = -ptc.Dot(n);
}
inline bool plane_t::LineIntersect(vec3_t &start, vec3_t &end, vec3_t &point,
vec3_t &result)
{
float denom, numer, u;
vec3_t dir;
dir = end - start;
denom = n.Dot(dir);
// No divide by zero!
if (denom > -Epsilon && denom < Epsilon)
return 0; // Line is parallel to the plane
numer = n.Dot(point - start);
u = numer / denom;
// Is there an intersection along the line?
if (u <= 0.0f || u > 1.0f)
return 0;
result = start + dir * u; // point of intersection
return 1;
}
#endif |