diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/include/plane3d.h | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/include/plane3d.h b/libraries/irrlicht-1.8/include/plane3d.h new file mode 100644 index 0000000..9056dcd --- /dev/null +++ b/libraries/irrlicht-1.8/include/plane3d.h | |||
@@ -0,0 +1,245 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #ifndef __IRR_PLANE_3D_H_INCLUDED__ | ||
6 | #define __IRR_PLANE_3D_H_INCLUDED__ | ||
7 | |||
8 | #include "irrMath.h" | ||
9 | #include "vector3d.h" | ||
10 | |||
11 | namespace irr | ||
12 | { | ||
13 | namespace core | ||
14 | { | ||
15 | |||
16 | //! Enumeration for intersection relations of 3d objects | ||
17 | enum EIntersectionRelation3D | ||
18 | { | ||
19 | ISREL3D_FRONT = 0, | ||
20 | ISREL3D_BACK, | ||
21 | ISREL3D_PLANAR, | ||
22 | ISREL3D_SPANNING, | ||
23 | ISREL3D_CLIPPED | ||
24 | }; | ||
25 | |||
26 | //! Template plane class with some intersection testing methods. | ||
27 | /** It has to be ensured, that the normal is always normalized. The constructors | ||
28 | and setters of this class will not ensure this automatically. So any normal | ||
29 | passed in has to be normalized in advance. No change to the normal will be | ||
30 | made by any of the class methods. | ||
31 | */ | ||
32 | template <class T> | ||
33 | class plane3d | ||
34 | { | ||
35 | public: | ||
36 | |||
37 | // Constructors | ||
38 | |||
39 | plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); } | ||
40 | |||
41 | plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); } | ||
42 | |||
43 | plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); } | ||
44 | |||
45 | plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) | ||
46 | { setPlane(point1, point2, point3); } | ||
47 | |||
48 | plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { } | ||
49 | |||
50 | // operators | ||
51 | |||
52 | inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);} | ||
53 | |||
54 | inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);} | ||
55 | |||
56 | // functions | ||
57 | |||
58 | void setPlane(const vector3d<T>& point, const vector3d<T>& nvector) | ||
59 | { | ||
60 | Normal = nvector; | ||
61 | recalculateD(point); | ||
62 | } | ||
63 | |||
64 | void setPlane(const vector3d<T>& nvect, T d) | ||
65 | { | ||
66 | Normal = nvect; | ||
67 | D = d; | ||
68 | } | ||
69 | |||
70 | void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) | ||
71 | { | ||
72 | // creates the plane from 3 memberpoints | ||
73 | Normal = (point2 - point1).crossProduct(point3 - point1); | ||
74 | Normal.normalize(); | ||
75 | |||
76 | recalculateD(point1); | ||
77 | } | ||
78 | |||
79 | |||
80 | //! Get an intersection with a 3d line. | ||
81 | /** \param lineVect Vector of the line to intersect with. | ||
82 | \param linePoint Point of the line to intersect with. | ||
83 | \param outIntersection Place to store the intersection point, if there is one. | ||
84 | \return True if there was an intersection, false if there was not. | ||
85 | */ | ||
86 | bool getIntersectionWithLine(const vector3d<T>& linePoint, | ||
87 | const vector3d<T>& lineVect, | ||
88 | vector3d<T>& outIntersection) const | ||
89 | { | ||
90 | T t2 = Normal.dotProduct(lineVect); | ||
91 | |||
92 | if (t2 == 0) | ||
93 | return false; | ||
94 | |||
95 | T t =- (Normal.dotProduct(linePoint) + D) / t2; | ||
96 | outIntersection = linePoint + (lineVect * t); | ||
97 | return true; | ||
98 | } | ||
99 | |||
100 | //! Get percentage of line between two points where an intersection with this plane happens. | ||
101 | /** Only useful if known that there is an intersection. | ||
102 | \param linePoint1 Point1 of the line to intersect with. | ||
103 | \param linePoint2 Point2 of the line to intersect with. | ||
104 | \return Where on a line between two points an intersection with this plane happened. | ||
105 | For example, 0.5 is returned if the intersection happened exactly in the middle of the two points. | ||
106 | */ | ||
107 | f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1, | ||
108 | const vector3d<T>& linePoint2) const | ||
109 | { | ||
110 | vector3d<T> vect = linePoint2 - linePoint1; | ||
111 | T t2 = (f32)Normal.dotProduct(vect); | ||
112 | return (f32)-((Normal.dotProduct(linePoint1) + D) / t2); | ||
113 | } | ||
114 | |||
115 | //! Get an intersection with a 3d line, limited between two 3d points. | ||
116 | /** \param linePoint1 Point 1 of the line. | ||
117 | \param linePoint2 Point 2 of the line. | ||
118 | \param outIntersection Place to store the intersection point, if there is one. | ||
119 | \return True if there was an intersection, false if there was not. | ||
120 | */ | ||
121 | bool getIntersectionWithLimitedLine( | ||
122 | const vector3d<T>& linePoint1, | ||
123 | const vector3d<T>& linePoint2, | ||
124 | vector3d<T>& outIntersection) const | ||
125 | { | ||
126 | return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) && | ||
127 | outIntersection.isBetweenPoints(linePoint1, linePoint2)); | ||
128 | } | ||
129 | |||
130 | //! Classifies the relation of a point to this plane. | ||
131 | /** \param point Point to classify its relation. | ||
132 | \return ISREL3D_FRONT if the point is in front of the plane, | ||
133 | ISREL3D_BACK if the point is behind of the plane, and | ||
134 | ISREL3D_PLANAR if the point is within the plane. */ | ||
135 | EIntersectionRelation3D classifyPointRelation(const vector3d<T>& point) const | ||
136 | { | ||
137 | const T d = Normal.dotProduct(point) + D; | ||
138 | |||
139 | if (d < -ROUNDING_ERROR_f32) | ||
140 | return ISREL3D_BACK; | ||
141 | |||
142 | if (d > ROUNDING_ERROR_f32) | ||
143 | return ISREL3D_FRONT; | ||
144 | |||
145 | return ISREL3D_PLANAR; | ||
146 | } | ||
147 | |||
148 | //! Recalculates the distance from origin by applying a new member point to the plane. | ||
149 | void recalculateD(const vector3d<T>& MPoint) | ||
150 | { | ||
151 | D = - MPoint.dotProduct(Normal); | ||
152 | } | ||
153 | |||
154 | //! Gets a member point of the plane. | ||
155 | vector3d<T> getMemberPoint() const | ||
156 | { | ||
157 | return Normal * -D; | ||
158 | } | ||
159 | |||
160 | //! Tests if there is an intersection with the other plane | ||
161 | /** \return True if there is a intersection. */ | ||
162 | bool existsIntersection(const plane3d<T>& other) const | ||
163 | { | ||
164 | vector3d<T> cross = other.Normal.crossProduct(Normal); | ||
165 | return cross.getLength() > core::ROUNDING_ERROR_f32; | ||
166 | } | ||
167 | |||
168 | //! Intersects this plane with another. | ||
169 | /** \param other Other plane to intersect with. | ||
170 | \param outLinePoint Base point of intersection line. | ||
171 | \param outLineVect Vector of intersection. | ||
172 | \return True if there is a intersection, false if not. */ | ||
173 | bool getIntersectionWithPlane(const plane3d<T>& other, | ||
174 | vector3d<T>& outLinePoint, | ||
175 | vector3d<T>& outLineVect) const | ||
176 | { | ||
177 | const T fn00 = Normal.getLength(); | ||
178 | const T fn01 = Normal.dotProduct(other.Normal); | ||
179 | const T fn11 = other.Normal.getLength(); | ||
180 | const f64 det = fn00*fn11 - fn01*fn01; | ||
181 | |||
182 | if (fabs(det) < ROUNDING_ERROR_f64 ) | ||
183 | return false; | ||
184 | |||
185 | const f64 invdet = 1.0 / det; | ||
186 | const f64 fc0 = (fn11*-D + fn01*other.D) * invdet; | ||
187 | const f64 fc1 = (fn00*-other.D + fn01*D) * invdet; | ||
188 | |||
189 | outLineVect = Normal.crossProduct(other.Normal); | ||
190 | outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1; | ||
191 | return true; | ||
192 | } | ||
193 | |||
194 | //! Get the intersection point with two other planes if there is one. | ||
195 | bool getIntersectionWithPlanes(const plane3d<T>& o1, | ||
196 | const plane3d<T>& o2, vector3d<T>& outPoint) const | ||
197 | { | ||
198 | vector3d<T> linePoint, lineVect; | ||
199 | if (getIntersectionWithPlane(o1, linePoint, lineVect)) | ||
200 | return o2.getIntersectionWithLine(linePoint, lineVect, outPoint); | ||
201 | |||
202 | return false; | ||
203 | } | ||
204 | |||
205 | //! Test if the triangle would be front or backfacing from any point. | ||
206 | /** Thus, this method assumes a camera position from | ||
207 | which the triangle is definitely visible when looking into | ||
208 | the given direction. | ||
209 | Note that this only works if the normal is Normalized. | ||
210 | Do not use this method with points as it will give wrong results! | ||
211 | \param lookDirection: Look direction. | ||
212 | \return True if the plane is front facing and | ||
213 | false if it is backfacing. */ | ||
214 | bool isFrontFacing(const vector3d<T>& lookDirection) const | ||
215 | { | ||
216 | const f32 d = Normal.dotProduct(lookDirection); | ||
217 | return F32_LOWER_EQUAL_0 ( d ); | ||
218 | } | ||
219 | |||
220 | //! Get the distance to a point. | ||
221 | /** Note that this only works if the normal is normalized. */ | ||
222 | T getDistanceTo(const vector3d<T>& point) const | ||
223 | { | ||
224 | return point.dotProduct(Normal) + D; | ||
225 | } | ||
226 | |||
227 | //! Normal vector of the plane. | ||
228 | vector3d<T> Normal; | ||
229 | |||
230 | //! Distance from origin. | ||
231 | T D; | ||
232 | }; | ||
233 | |||
234 | |||
235 | //! Typedef for a f32 3d plane. | ||
236 | typedef plane3d<f32> plane3df; | ||
237 | |||
238 | //! Typedef for an integer 3d plane. | ||
239 | typedef plane3d<s32> plane3di; | ||
240 | |||
241 | } // end namespace core | ||
242 | } // end namespace irr | ||
243 | |||
244 | #endif | ||
245 | |||