aboutsummaryrefslogtreecommitdiff
path: root/primedev/core/math/vplane.h
blob: 8b8de4233860989f84d56f0eabe7ca0c399c4aba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

typedef int SideType;

// Used to represent sides of things like planes.
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2

#define VP_EPSILON 0.01f

class VPlane
{
public:
	VPlane();
	VPlane(const Vector3& vNormal, float dist);
	VPlane(const Vector3& vPoint, const QAngle& ang);

	void Init(const Vector3& vNormal, float dist);

	// Return the distance from the point to the plane.
	float DistTo(const Vector3& vVec) const;

	// Copy.
	VPlane& operator=(const VPlane& thePlane);

	// Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK.
	// The epsilon for SIDE_ON can be passed in.
	SideType GetPointSide(const Vector3& vPoint, float sideEpsilon = VP_EPSILON) const;

	// Returns SIDE_FRONT or SIDE_BACK.
	SideType GetPointSideExact(const Vector3& vPoint) const;

	// Get a point on the plane (normal*dist).
	Vector3 GetPointOnPlane() const;

	// Snap the specified point to the plane (along the plane's normal).
	Vector3 SnapPointToPlane(const Vector3& vPoint) const;

public:
	Vector3 m_Normal;
	float m_Dist;
};

//-----------------------------------------------------------------------------
// Inlines.
//-----------------------------------------------------------------------------
inline VPlane::VPlane() {}

inline VPlane::VPlane(const Vector3& vNormal, float dist)
{
	m_Normal = vNormal;
	m_Dist = dist;
}

inline VPlane::VPlane(const Vector3& vPoint, const QAngle& ang)
{
	m_Normal = ang.GetNormal();
	m_Dist = vPoint.x * m_Normal.x + vPoint.y * m_Normal.y + vPoint.z * m_Normal.z;
}

inline void VPlane::Init(const Vector3& vNormal, float dist)
{
	m_Normal = vNormal;
	m_Dist = dist;
}

inline float VPlane::DistTo(const Vector3& vVec) const
{
	return vVec.Dot(m_Normal) - m_Dist;
}

inline VPlane& VPlane::operator=(const VPlane& thePlane)
{
	m_Normal = thePlane.m_Normal;
	m_Dist = thePlane.m_Dist;
	return *this;
}

inline Vector3 VPlane::GetPointOnPlane() const
{
	return m_Normal * m_Dist;
}

inline Vector3 VPlane::SnapPointToPlane(const Vector3& vPoint) const
{
	return vPoint - m_Normal * DistTo(vPoint);
}

inline SideType VPlane::GetPointSide(const Vector3& vPoint, float sideEpsilon) const
{
	float fDist;

	fDist = DistTo(vPoint);
	if (fDist >= sideEpsilon)
		return SIDE_FRONT;
	else if (fDist <= -sideEpsilon)
		return SIDE_BACK;
	else
		return SIDE_ON;
}

inline SideType VPlane::GetPointSideExact(const Vector3& vPoint) const
{
	return DistTo(vPoint) > 0.0f ? SIDE_FRONT : SIDE_BACK;
}