| Irrlicht 3D Engine |

plane3d.h
Go to the documentation of this file.

    00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt
    00002 // This file is part of the "Irrlicht Engine".
    00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
    00004
    00005 #ifndef __IRR_PLANE_3D_H_INCLUDED__
    00006 #define __IRR_PLANE_3D_H_INCLUDED__
    00007
    00008 #include "irrMath.h"
    00009 #include "vector3d.h"
    00010
    00011 namespace irr
    00012 {
    00013 namespace core
    00014 {
    00015
    00017 enum EIntersectionRelation3D
    00018 {
    00019     ISREL3D_FRONT = 0,
    00020     ISREL3D_BACK,
    00021     ISREL3D_PLANAR,
    00022     ISREL3D_SPANNING,
    00023     ISREL3D_CLIPPED
    00024 };
    00025
    00027
    00032 template <class T>
    00033 class plane3d
    00034 {
    00035     public:
    00036
    00037         // Constructors
    00038
    00039         plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }
    00040
    00041         plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }
    00042
    00043         plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }
    00044
    00045         plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
    00046         { setPlane(point1, point2, point3); }
    00047
    00048         plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { }
    00049
    00050         // operators
    00051
    00052         inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);}
    00053
    00054         inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);}
    00055
    00056         // functions
    00057
    00058         void setPlane(const vector3d<T>& point, const vector3d<T>& nvector)
    00059         {
    00060             Normal = nvector;
    00061             recalculateD(point);
    00062         }
    00063
    00064         void setPlane(const vector3d<T>& nvect, T d)
    00065         {
    00066             Normal = nvect;
    00067             D = d;
    00068         }
    00069
    00070         void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
    00071         {
    00072             // creates the plane from 3 memberpoints
    00073             Normal = (point2 - point1).crossProduct(point3 - point1);
    00074             Normal.normalize();
    00075
    00076             recalculateD(point1);
    00077         }
    00078
    00079
    00081
    00086         bool getIntersectionWithLine(const vector3d<T>& linePoint,
    00087                 const vector3d<T>& lineVect,
    00088                 vector3d<T>& outIntersection) const
    00089         {
    00090             T t2 = Normal.dotProduct(lineVect);
    00091
    00092             if (t2 == 0)
    00093                 return false;
    00094
    00095             T t =- (Normal.dotProduct(linePoint) + D) / t2;
    00096             outIntersection = linePoint + (lineVect * t);
    00097             return true;
    00098         }
    00099
    00101
    00107         f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1,
    00108             const vector3d<T>& linePoint2) const
    00109         {
    00110             vector3d<T> vect = linePoint2 - linePoint1;
    00111             T t2 = (f32)Normal.dotProduct(vect);
    00112             return (f32)-((Normal.dotProduct(linePoint1) + D) / t2);
    00113         }
    00114
    00116
    00121         bool getIntersectionWithLimitedLine(
    00122                 const vector3d<T>& linePoint1,
    00123                 const vector3d<T>& linePoint2,
    00124                 vector3d<T>& outIntersection) const
    00125         {
    00126             return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
    00127                     outIntersection.isBetweenPoints(linePoint1, linePoint2));
    00128         }
    00129
    00131
    00135         EIntersectionRelation3D classifyPointRelation(const vector3d<T>& point) const
    00136         {
    00137             const T d = Normal.dotProduct(point) + D;
    00138
    00139             if (d < -ROUNDING_ERROR_f32)
    00140                 return ISREL3D_BACK;
    00141
    00142             if (d > ROUNDING_ERROR_f32)
    00143                 return ISREL3D_FRONT;
    00144
    00145             return ISREL3D_PLANAR;
    00146         }
    00147
    00149         void recalculateD(const vector3d<T>& MPoint)
    00150         {
    00151             D = - MPoint.dotProduct(Normal);
    00152         }
    00153
    00155         vector3d<T> getMemberPoint() const
    00156         {
    00157             return Normal * -D;
    00158         }
    00159
    00161
    00162         bool existsIntersection(const plane3d<T>& other) const
    00163         {
    00164             vector3d<T> cross = other.Normal.crossProduct(Normal);
    00165             return cross.getLength() > core::ROUNDING_ERROR_f32;
    00166         }
    00167
    00169
    00173         bool getIntersectionWithPlane(const plane3d<T>& other,
    00174                 vector3d<T>& outLinePoint,
    00175                 vector3d<T>& outLineVect) const
    00176         {
    00177             const T fn00 = Normal.getLength();
    00178             const T fn01 = Normal.dotProduct(other.Normal);
    00179             const T fn11 = other.Normal.getLength();
    00180             const f64 det = fn00*fn11 - fn01*fn01;
    00181
    00182             if (fabs(det) < ROUNDING_ERROR_f64 )
    00183                 return false;
    00184
    00185             const f64 invdet = 1.0 / det;
    00186             const f64 fc0 = (fn11*-D + fn01*other.D) * invdet;
    00187             const f64 fc1 = (fn00*-other.D + fn01*D) * invdet;
    00188
    00189             outLineVect = Normal.crossProduct(other.Normal);
    00190             outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1;
    00191             return true;
    00192         }
    00193
    00195         bool getIntersectionWithPlanes(const plane3d<T>& o1,
    00196                 const plane3d<T>& o2, vector3d<T>& outPoint) const
    00197         {
    00198             vector3d<T> linePoint, lineVect;
    00199             if (getIntersectionWithPlane(o1, linePoint, lineVect))
    00200                 return o2.getIntersectionWithLine(linePoint, lineVect, outPoint);
    00201
    00202             return false;
    00203         }
    00204
    00206
    00214         bool isFrontFacing(const vector3d<T>& lookDirection) const
    00215         {
    00216             const f32 d = Normal.dotProduct(lookDirection);
    00217             return F32_LOWER_EQUAL_0 ( d );
    00218         }
    00219
    00221
    00222         T getDistanceTo(const vector3d<T>& point) const
    00223         {
    00224             return point.dotProduct(Normal) + D;
    00225         }
    00226
    00228         vector3d<T> Normal;
    00229
    00231         T D;
    00232 };
    00233
    00234
    00236 typedef plane3d<f32> plane3df;
    00237
    00239 typedef plane3d<s32> plane3di;
    00240
    00241 } // end namespace core
    00242 } // end namespace irr
    00243
    00244 #endif
    00245