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                 core::vector3d<T> closestPointOnTriangle(const core::vector3d<T>& p) const
00055                 {
00056                         const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
00057                         const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
00058                         const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
00059 
00060                         const T d1 = rab.getDistanceFrom(p);
00061                         const T d2 = rbc.getDistanceFrom(p);
00062                         const T d3 = rca.getDistanceFrom(p);
00063 
00064                         if (d1 < d2)
00065                                 return d1 < d3 ? rab : rca;
00066 
00067                         return d2 < d3 ? rbc : rca;
00068                 }
00069 
00071 
00074                 bool isPointInside(const vector3d<T>& p) const
00075                 {
00076                         return (isOnSameSide(p, pointA, pointB, pointC) &&
00077                                 isOnSameSide(p, pointB, pointA, pointC) &&
00078                                 isOnSameSide(p, pointC, pointA, pointB));
00079                 }
00080 
00082 
00088                 bool isPointInsideFast(const vector3d<T>& p) const
00089                 {
00090                         const vector3d<T> f = pointB - pointA;
00091                         const vector3d<T> g = pointC - pointA;
00092 
00093                         const f32 a = f.dotProduct(f);
00094                         const f32 b = f.dotProduct(g);
00095                         const f32 c = g.dotProduct(g);
00096 
00097                         const vector3d<T> vp = p - pointA;
00098                         const f32 d = vp.dotProduct(f);
00099                         const f32 e = vp.dotProduct(g);
00100 
00101                         f32 x = (d*c)-(e*b);
00102                         f32 y = (e*a)-(d*b);
00103                         const f32 ac_bb = (a*c)-(b*b);
00104                         f32 z = x+y-ac_bb;
00105 
00106                         // return sign(z) && !(sign(x)||sign(y))
00107                         return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0;
00108                 }
00109 
00110 
00112 
00115                 bool getIntersectionWithLimitedLine(const line3d<T>& line,
00116                         vector3d<T>& outIntersection) const
00117                 {
00118                         return getIntersectionWithLine(line.start,
00119                                 line.getVector(), outIntersection) &&
00120                                 outIntersection.isBetweenPoints(line.start, line.end);
00121                 }
00122 
00123 
00125 
00133                 bool getIntersectionWithLine(const vector3d<T>& linePoint,
00134                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
00135                 {
00136                         if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection))
00137                                 return isPointInside(outIntersection);
00138 
00139                         return false;
00140                 }
00141 
00142 
00144 
00148                 bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint,
00149                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
00150                 {
00151                         const vector3d<T> normal = getNormal().normalize();
00152                         T t2;
00153 
00154                         if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) )
00155                                 return false;
00156 
00157                         T d = pointA.dotProduct(normal);
00158                         T t = -(normal.dotProduct(linePoint) - d) / t2;
00159                         outIntersection = linePoint + (lineVect * t);
00160                         return true;
00161                 }
00162 
00163 
00165 
00166                 vector3d<T> getNormal() const
00167                 {
00168                         return (pointB - pointA).crossProduct(pointC - pointA);
00169                 }
00170 
00172 
00177                 bool isFrontFacing(const vector3d<T>& lookDirection) const
00178                 {
00179                         const vector3d<T> n = getNormal().normalize();
00180                         const f32 d = (f32)n.dotProduct(lookDirection);
00181                         return F32_LOWER_EQUAL_0(d);
00182                 }
00183 
00185                 plane3d<T> getPlane() const
00186                 {
00187                         return plane3d<T>(pointA, pointB, pointC);
00188                 }
00189 
00191                 T getArea() const
00192                 {
00193                         return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5;
00194 
00195                 }
00196 
00198                 void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c)
00199                 {
00200                         pointA = a;
00201                         pointB = b;
00202                         pointC = c;
00203                 }
00204 
00206                 vector3d<T> pointA;
00207                 vector3d<T> pointB;
00208                 vector3d<T> pointC;
00209 
00210         private:
00211                 bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
00212                         const vector3d<T>& a, const vector3d<T>& b) const
00213                 {
00214                         vector3d<T> bminusa = b - a;
00215                         vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
00216                         vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
00217                         return (cp1.dotProduct(cp2) >= 0.0f);
00218                 }
00219         };
00220 
00221 
00223         typedef triangle3d<f32> triangle3df;
00224 
00226         typedef triangle3d<s32> triangle3di;
00227 
00228 } // end namespace core
00229 } // end namespace irr
00230 
00231 #endif
00232 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2009 by Nikolaus Gebhardt. Generated on Sun Jan 10 09:24:05 2010 by Doxygen (1.5.6)