Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

# triangle3d.h

Go to the documentation of this file.

    00001 // Copyright (C) 2002-2009 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_TRIANGLE_3D_H_INCLUDED__
    00006 #define __IRR_TRIANGLE_3D_H_INCLUDED__
    00007
    00008 #include "vector3d.h"
    00009 #include "line3d.h"
    00010 #include "plane3d.h"
    00011 #include "aabbox3d.h"
    00012
    00013 namespace irr
    00014 {
    00015 namespace core
    00016 {
    00017
    00019         template <class T>
    00020         class triangle3d
    00021         {
    00022         public:
    00023
    00025                 triangle3d() {}
    00027                 triangle3d(vector3d<T> v1, vector3d<T> v2, vector3d<T> v3) : pointA(v1), pointB(v2), pointC(v3) {}
    00028
    00030                 bool operator==(const triangle3d<T>& other) const
    00031                 {
    00032                         return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC;
    00033                 }
    00034
    00036                 bool operator!=(const triangle3d<T>& other) const
    00037                 {
    00038                         return !(*this==other);
    00039                 }
    00040
    00042
    00044                 bool isTotalInsideBox(const aabbox3d<T>& box) const
    00045                 {
    00046                         return (box.isPointInside(pointA) &&
    00047                                 box.isPointInside(pointB) &&
    00048                                 box.isPointInside(pointC));
    00049                 }
    00050
    00052
    00054                 bool isTotalOutsideBox(const aabbox3d<T>& box) const
    00055                 {
    00056                         return ((pointA.X > box.MaxEdge.X && pointB.X > box.MaxEdge.X && pointC.X > box.MaxEdge.X) ||
    00057
    00058                                 (pointA.Y > box.MaxEdge.Y && pointB.Y > box.MaxEdge.Y && pointC.Y > box.MaxEdge.Y) ||
    00059                                 (pointA.Z > box.MaxEdge.Z && pointB.Z > box.MaxEdge.Z && pointC.Z > box.MaxEdge.Z) ||
    00060                                 (pointA.X < box.MinEdge.X && pointB.X < box.MinEdge.X && pointC.X < box.MinEdge.X) ||
    00061                                 (pointA.Y < box.MinEdge.Y && pointB.Y < box.MinEdge.Y && pointC.Y < box.MinEdge.Y) ||
    00062                                 (pointA.Z < box.MinEdge.Z && pointB.Z < box.MinEdge.Z && pointC.Z < box.MinEdge.Z));
    00063                 }
    00064
    00066
    00068                 core::vector3d<T> closestPointOnTriangle(const core::vector3d<T>& p) const
    00069                 {
    00070                         const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
    00071                         const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
    00072                         const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
    00073
    00074                         const T d1 = rab.getDistanceFrom(p);
    00075                         const T d2 = rbc.getDistanceFrom(p);
    00076                         const T d3 = rca.getDistanceFrom(p);
    00077
    00078                         if (d1 < d2)
    00079                                 return d1 < d3 ? rab : rca;
    00080
    00081                         return d2 < d3 ? rbc : rca;
    00082                 }
    00083
    00085
    00088                 bool isPointInside(const vector3d<T>& p) const
    00089                 {
    00090                         return (isOnSameSide(p, pointA, pointB, pointC) &&
    00091                                 isOnSameSide(p, pointB, pointA, pointC) &&
    00092                                 isOnSameSide(p, pointC, pointA, pointB));
    00093                 }
    00094
    00096
    00102                 bool isPointInsideFast(const vector3d<T>& p) const
    00103                 {
    00104                         const vector3d<T> f = pointB - pointA;
    00105                         const vector3d<T> g = pointC - pointA;
    00106
    00107                         const f32 a = f.dotProduct(f);
    00108                         const f32 b = f.dotProduct(g);
    00109                         const f32 c = g.dotProduct(g);
    00110
    00111                         const vector3d<T> vp = p - pointA;
    00112                         const f32 d = vp.dotProduct(f);
    00113                         const f32 e = vp.dotProduct(g);
    00114
    00115                         f32 x = (d*c)-(e*b);
    00116                         f32 y = (e*a)-(d*b);
    00117                         const f32 ac_bb = (a*c)-(b*b);
    00118                         f32 z = x+y-ac_bb;
    00119
    00120                         // return sign(z) && !(sign(x)||sign(y))
    00121                         return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0;
    00122                 }
    00123
    00124
    00126
    00129                 bool getIntersectionWithLimitedLine(const line3d<T>& line,
    00130                         vector3d<T>& outIntersection) const
    00131                 {
    00132                         return getIntersectionWithLine(line.start,
    00133                                 line.getVector(), outIntersection) &&
    00134                                 outIntersection.isBetweenPoints(line.start, line.end);
    00135                 }
    00136
    00137
    00139
    00147                 bool getIntersectionWithLine(const vector3d<T>& linePoint,
    00148                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
    00149                 {
    00150                         if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection))
    00151                                 return isPointInside(outIntersection);
    00152
    00153                         return false;
    00154                 }
    00155
    00156
    00158
    00162                 bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint,
    00163                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
    00164                 {
    00165                         const vector3d<T> normal = getNormal().normalize();
    00166                         T t2;
    00167
    00168                         if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) )
    00169                                 return false;
    00170
    00171                         T d = pointA.dotProduct(normal);
    00172                         T t = -(normal.dotProduct(linePoint) - d) / t2;
    00173                         outIntersection = linePoint + (lineVect * t);
    00174                         return true;
    00175                 }
    00176
    00177
    00179
    00180                 vector3d<T> getNormal() const
    00181                 {
    00182                         return (pointB - pointA).crossProduct(pointC - pointA);
    00183                 }
    00184
    00186
    00191                 bool isFrontFacing(const vector3d<T>& lookDirection) const
    00192                 {
    00193                         const vector3d<T> n = getNormal().normalize();
    00194                         const f32 d = (f32)n.dotProduct(lookDirection);
    00195                         return F32_LOWER_EQUAL_0(d);
    00196                 }
    00197
    00199                 plane3d<T> getPlane() const
    00200                 {
    00201                         return plane3d<T>(pointA, pointB, pointC);
    00202                 }
    00203
    00205                 T getArea() const
    00206                 {
    00207                         return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5;
    00208
    00209                 }
    00210
    00212                 void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c)
    00213                 {
    00214                         pointA = a;
    00215                         pointB = b;
    00216                         pointC = c;
    00217                 }
    00218
    00220                 vector3d<T> pointA;
    00221                 vector3d<T> pointB;
    00222                 vector3d<T> pointC;
    00223
    00224         private:
    00225                 bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
    00226                         const vector3d<T>& a, const vector3d<T>& b) const
    00227                 {
    00228                         vector3d<T> bminusa = b - a;
    00229                         vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
    00230                         vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
    00231                         return (cp1.dotProduct(cp2) >= 0.0f);
    00232                 }
    00233         };
    00234
    00235
    00237         typedef triangle3d<f32> triangle3df;
    00238
    00240         typedef triangle3d<s32> triangle3di;
    00241
    00242 } // end namespace core
    00243 } // end namespace irr
    00244
    00245 #endif
    00246

| The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Feb 14 13:06:58 2010 by Doxygen (1.6.2)