~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to include/plane3d.h

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
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
template <class T>
 
28
class plane3d
 
29
{
 
30
        public:
 
31
 
 
32
                // Constructors
 
33
 
 
34
                plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }
 
35
                
 
36
                plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }
 
37
                
 
38
                plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }
 
39
                
 
40
                plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
 
41
                { setPlane(point1, point2, point3); }
 
42
                
 
43
                plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { }
 
44
 
 
45
                // operators
 
46
 
 
47
                inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);}
 
48
 
 
49
                inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);}
 
50
 
 
51
                // functions
 
52
 
 
53
                void setPlane(const vector3d<T>& point, const vector3d<T>& nvector)
 
54
                {
 
55
                        Normal = nvector;
 
56
                        recalculateD(point);
 
57
                }
 
58
 
 
59
                void setPlane(const vector3d<T>& nvect, T d)
 
60
                {
 
61
                        Normal = nvect;
 
62
                        D = d;
 
63
                }
 
64
 
 
65
                void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
 
66
                {
 
67
                        // creates the plane from 3 memberpoints
 
68
                        Normal = (point2 - point1).crossProduct(point3 - point1);
 
69
                        Normal.normalize();
 
70
 
 
71
                        recalculateD(point1);
 
72
                }
 
73
 
 
74
 
 
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.
 
80
                */
 
81
                bool getIntersectionWithLine(const vector3d<T>& linePoint,
 
82
                                const vector3d<T>& lineVect,
 
83
                                vector3d<T>& outIntersection) const
 
84
                {
 
85
                        T t2 = Normal.dotProduct(lineVect);
 
86
 
 
87
                        if (t2 == 0)
 
88
                                return false;
 
89
 
 
90
                        T t =- (Normal.dotProduct(linePoint) + D) / t2;
 
91
                        outIntersection = linePoint + (lineVect * t);
 
92
                        return true;
 
93
                }
 
94
 
 
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.
 
101
                */
 
102
                f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1,
 
103
                        const vector3d<T>& linePoint2) const
 
104
                {
 
105
                        vector3d<T> vect = linePoint2 - linePoint1;
 
106
                        T t2 = (f32)Normal.dotProduct(vect);
 
107
                        return (f32)-((Normal.dotProduct(linePoint1) + D) / t2);
 
108
                }
 
109
 
 
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.
 
115
                */
 
116
                bool getIntersectionWithLimitedLine(
 
117
                                const vector3d<T>& linePoint1,
 
118
                                const vector3d<T>& linePoint2,
 
119
                                vector3d<T>& outIntersection) const
 
120
                {
 
121
                        return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
 
122
                                        outIntersection.isBetweenPoints(linePoint1, linePoint2));
 
123
                }
 
124
 
 
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
 
131
                {
 
132
                        const T d = Normal.dotProduct(point) + D;
 
133
 
 
134
                        if (d < -ROUNDING_ERROR_f32)
 
135
                                return ISREL3D_BACK;
 
136
 
 
137
                        if (d > ROUNDING_ERROR_f32)
 
138
                                return ISREL3D_FRONT;
 
139
 
 
140
                        return ISREL3D_PLANAR;
 
141
                }
 
142
 
 
143
                //! Recalculates the distance from origin by applying a new member point to the plane.
 
144
                void recalculateD(const vector3d<T>& MPoint)
 
145
                {
 
146
                        D = - MPoint.dotProduct(Normal);
 
147
                }
 
148
 
 
149
                //! Gets a member point of the plane.
 
150
                vector3d<T> getMemberPoint() const
 
151
                {
 
152
                        return Normal * -D;
 
153
                }
 
154
 
 
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
 
158
                {
 
159
                        vector3d<T> cross = other.Normal.crossProduct(Normal);
 
160
                        return cross.getLength() > core::ROUNDING_ERROR_f32;
 
161
                }
 
162
 
 
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
 
171
                {
 
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;
 
176
 
 
177
                        if (fabs(det) < ROUNDING_ERROR_f64 )
 
178
                                return false;
 
179
 
 
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;
 
183
 
 
184
                        outLineVect = Normal.crossProduct(other.Normal);
 
185
                        outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1;
 
186
                        return true;
 
187
                }
 
188
 
 
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
 
192
                {
 
193
                        vector3d<T> linePoint, lineVect;
 
194
                        if (getIntersectionWithPlane(o1, linePoint, lineVect))
 
195
                                return o2.getIntersectionWithLine(linePoint, lineVect, outPoint);
 
196
 
 
197
                        return false;
 
198
                }
 
199
 
 
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
 
203
                the given direction.
 
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
 
210
                {
 
211
                        const f32 d = Normal.dotProduct(lookDirection);
 
212
                        return F32_LOWER_EQUAL_0 ( d );
 
213
                }
 
214
 
 
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
 
218
                {
 
219
                        return point.dotProduct(Normal) + D;
 
220
                }
 
221
 
 
222
                //! Normal vector of the plane.
 
223
                vector3d<T> Normal;
 
224
 
 
225
                //! Distance from origin.
 
226
                T D;
 
227
};
 
228
 
 
229
 
 
230
//! Typedef for a f32 3d plane.
 
231
typedef plane3d<f32> plane3df;
 
232
 
 
233
//! Typedef for an integer 3d plane.
 
234
typedef plane3d<s32> plane3di;
 
235
 
 
236
} // end namespace core
 
237
} // end namespace irr
 
238
 
 
239
#endif
 
240