Line data Source code
1 : /* Copyright (C) 2009 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : /*
19 : * A Plane in R3 and several utility methods.
20 : */
21 :
22 : // Note that the format used for the plane equation is
23 : // Ax + By + Cz + D = 0, where <A,B,C> is the normal vector.
24 :
25 : #include "precompiled.h"
26 :
27 : #include "Plane.h"
28 : #include "MathUtil.h"
29 :
30 : const float CPlane::m_EPS = 0.001f;
31 :
32 370 : CPlane::CPlane()
33 : {
34 370 : m_Dist = 0.0f;
35 370 : }
36 :
37 : //sets the plane equation from 3 points on that plane
38 0 : void CPlane::Set(const CVector3D& p1, const CVector3D& p2, const CVector3D& p3)
39 : {
40 0 : CVector3D D1, D2;
41 0 : CVector3D Norm;
42 :
43 : //calculate two vectors on the surface of the plane
44 0 : D1 = p2-p1;
45 0 : D2 = p3-p1;
46 :
47 : //cross multiply gives normal
48 0 : Norm = D2.Cross(D1);
49 :
50 0 : Set(Norm, p1);
51 0 : }
52 :
53 : //sets the plane equation from a normal and a point on
54 : //that plane
55 0 : void CPlane::Set(const CVector3D& norm, const CVector3D& point)
56 : {
57 0 : m_Norm = norm;
58 :
59 0 : m_Dist = - (norm.X * point.X + norm.Y * point.Y + norm.Z * point.Z);
60 :
61 : // Normalize ();
62 0 : }
63 :
64 : //normalizes the plane equation
65 24 : void CPlane::Normalize()
66 : {
67 24 : float Scale = 1.0f/m_Norm.Length();
68 :
69 24 : m_Norm.X *= Scale;
70 24 : m_Norm.Y *= Scale;
71 24 : m_Norm.Z *= Scale;
72 24 : m_Dist *= Scale;
73 24 : }
74 :
75 : //returns the side of the plane on which this point
76 : //lies.
77 0 : PLANESIDE CPlane::ClassifyPoint(const CVector3D& point) const
78 : {
79 0 : float Dist = DistanceToPlane(point);
80 :
81 0 : if (Dist > m_EPS)
82 0 : return PS_FRONT;
83 0 : else if (Dist < -m_EPS)
84 0 : return PS_BACK;
85 :
86 0 : return PS_ON;
87 : }
88 :
89 : //calculates the intersection point of a line with this
90 : //plane. Returns false if there is no intersection
91 12 : bool CPlane::FindLineSegIntersection(const CVector3D& start, const CVector3D& end, CVector3D* intsect) const
92 : {
93 12 : float dist1 = DistanceToPlane(start);
94 12 : float dist2 = DistanceToPlane(end);
95 :
96 12 : if( (dist1 < 0 && dist2 < 0) || (dist1 >= 0 && dist2 >= 0) )
97 4 : return false;
98 :
99 8 : float t = (-dist1) / (dist2-dist1);
100 8 : *intsect = Interpolate(start, end, t);
101 :
102 8 : return true;
103 : }
104 :
105 0 : bool CPlane::FindRayIntersection(const CVector3D& start, const CVector3D& direction, CVector3D* intsect) const
106 : {
107 0 : float dot = m_Norm.Dot(direction);
108 0 : if (dot == 0.0f)
109 0 : return false;
110 :
111 0 : *intsect = start - (direction * (DistanceToPlane(start)/dot));
112 0 : return true;
113 3 : }
|