1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#ifndef __IRR_PLANE_3D_H_INCLUDED__
6
#define __IRR_PLANE_3D_H_INCLUDED__
16
//! Enumeration for intersection relations of 3d objects
17
enum EIntersectionRelation3D
26
//! Template plane class with some intersection testing methods.
34
plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }
36
plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }
38
plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }
40
plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
41
{ setPlane(point1, point2, point3); }
43
plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { }
47
inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);}
49
inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);}
53
void setPlane(const vector3d<T>& point, const vector3d<T>& nvector)
59
void setPlane(const vector3d<T>& nvect, T d)
65
void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
67
// creates the plane from 3 memberpoints
68
Normal = (point2 - point1).crossProduct(point3 - point1);
75
//! Get an intersection with a 3d line.
76
/** \param lineVect Vector of the line to intersect with.
77
\param linePoint Point of the line to intersect with.
78
\param outIntersection Place to store the intersection point, if there is one.
79
\return True if there was an intersection, false if there was not.
81
bool getIntersectionWithLine(const vector3d<T>& linePoint,
82
const vector3d<T>& lineVect,
83
vector3d<T>& outIntersection) const
85
T t2 = Normal.dotProduct(lineVect);
90
T t =- (Normal.dotProduct(linePoint) + D) / t2;
91
outIntersection = linePoint + (lineVect * t);
95
//! Get percentage of line between two points where an intersection with this plane happens.
96
/** Only useful if known that there is an intersection.
97
\param linePoint1 Point1 of the line to intersect with.
98
\param linePoint2 Point2 of the line to intersect with.
99
\return Where on a line between two points an intersection with this plane happened.
100
For example, 0.5 is returned if the intersection happened exactly in the middle of the two points.
102
f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1,
103
const vector3d<T>& linePoint2) const
105
vector3d<T> vect = linePoint2 - linePoint1;
106
T t2 = (f32)Normal.dotProduct(vect);
107
return (f32)-((Normal.dotProduct(linePoint1) + D) / t2);
110
//! Get an intersection with a 3d line, limited between two 3d points.
111
/** \param linePoint1 Point 1 of the line.
112
\param linePoint2 Point 2 of the line.
113
\param outIntersection Place to store the intersection point, if there is one.
114
\return True if there was an intersection, false if there was not.
116
bool getIntersectionWithLimitedLine(
117
const vector3d<T>& linePoint1,
118
const vector3d<T>& linePoint2,
119
vector3d<T>& outIntersection) const
121
return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
122
outIntersection.isBetweenPoints(linePoint1, linePoint2));
125
//! Classifies the relation of a point to this plane.
126
/** \param point Point to classify its relation.
127
\return ISREL3D_FRONT if the point is in front of the plane,
128
ISREL3D_BACK if the point is behind of the plane, and
129
ISREL3D_PLANAR if the point is within the plane. */
130
EIntersectionRelation3D classifyPointRelation(const vector3d<T>& point) const
132
const T d = Normal.dotProduct(point) + D;
134
if (d < -ROUNDING_ERROR_f32)
137
if (d > ROUNDING_ERROR_f32)
138
return ISREL3D_FRONT;
140
return ISREL3D_PLANAR;
143
//! Recalculates the distance from origin by applying a new member point to the plane.
144
void recalculateD(const vector3d<T>& MPoint)
146
D = - MPoint.dotProduct(Normal);
149
//! Gets a member point of the plane.
150
vector3d<T> getMemberPoint() const
155
//! Tests if there is an intersection with the other plane
156
/** \return True if there is a intersection. */
157
bool existsIntersection(const plane3d<T>& other) const
159
vector3d<T> cross = other.Normal.crossProduct(Normal);
160
return cross.getLength() > core::ROUNDING_ERROR_f32;
163
//! Intersects this plane with another.
164
/** \param other Other plane to intersect with.
165
\param outLinePoint Base point of intersection line.
166
\param outLineVect Vector of intersection.
167
\return True if there is a intersection, false if not. */
168
bool getIntersectionWithPlane(const plane3d<T>& other,
169
vector3d<T>& outLinePoint,
170
vector3d<T>& outLineVect) const
172
const T fn00 = Normal.getLength();
173
const T fn01 = Normal.dotProduct(other.Normal);
174
const T fn11 = other.Normal.getLength();
175
const f64 det = fn00*fn11 - fn01*fn01;
177
if (fabs(det) < ROUNDING_ERROR_f64 )
180
const f64 invdet = 1.0 / det;
181
const f64 fc0 = (fn11*-D + fn01*other.D) * invdet;
182
const f64 fc1 = (fn00*-other.D + fn01*D) * invdet;
184
outLineVect = Normal.crossProduct(other.Normal);
185
outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1;
189
//! Get the intersection point with two other planes if there is one.
190
bool getIntersectionWithPlanes(const plane3d<T>& o1,
191
const plane3d<T>& o2, vector3d<T>& outPoint) const
193
vector3d<T> linePoint, lineVect;
194
if (getIntersectionWithPlane(o1, linePoint, lineVect))
195
return o2.getIntersectionWithLine(linePoint, lineVect, outPoint);
200
//! Test if the triangle would be front or backfacing from any point.
201
/** Thus, this method assumes a camera position from
202
which the triangle is definitely visible when looking into
204
Note that this only works if the normal is Normalized.
205
Do not use this method with points as it will give wrong results!
206
\param lookDirection: Look direction.
207
\return True if the plane is front facing and
208
false if it is backfacing. */
209
bool isFrontFacing(const vector3d<T>& lookDirection) const
211
const f32 d = Normal.dotProduct(lookDirection);
212
return F32_LOWER_EQUAL_0 ( d );
215
//! Get the distance to a point.
216
/** Note that this only works if the normal is normalized. */
217
T getDistanceTo(const vector3d<T>& point) const
219
return point.dotProduct(Normal) + D;
222
//! Normal vector of the plane.
225
//! Distance from origin.
230
//! Typedef for a f32 3d plane.
231
typedef plane3d<f32> plane3df;
233
//! Typedef for an integer 3d plane.
234
typedef plane3d<s32> plane3di;
236
} // end namespace core
237
} // end namespace irr