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-2010 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 
00090                 bool isPointInside(const vector3d<T>& p) const
00091                 {
00092                         return (isOnSameSide(p, pointA, pointB, pointC) &&
00093                                 isOnSameSide(p, pointB, pointA, pointC) &&
00094                                 isOnSameSide(p, pointC, pointA, pointB));
00095                 }
00096 
00098 
00105                 bool isPointInsideFast(const vector3d<T>& p) const
00106                 {
00107                         const vector3d<T> a = pointC - pointA;
00108                         const vector3d<T> b = pointB - pointA;
00109                         const vector3d<T> c = p - pointA;
00110                         
00111                         const f64 dotAA = a.dotProduct( a);
00112                         const f64 dotAB = a.dotProduct( b);
00113                         const f64 dotAC = a.dotProduct( c);
00114                         const f64 dotBB = b.dotProduct( b);
00115                         const f64 dotBC = b.dotProduct( c);
00116                          
00117                         // get coordinates in barycentric coordinate system
00118                         const f64 invDenom =  1/(dotAA * dotBB - dotAB * dotAB); 
00119                         const f64 u = (dotBB * dotAC - dotAB * dotBC) * invDenom;
00120                         const f64 v = (dotAA * dotBC - dotAB * dotAC ) * invDenom;
00121                  
00122                         // We count border-points as inside to keep downward compatibility.
00123                         // That's why we use >= and <= instead of > and < as more commonly seen on the web.
00124                         return (u >= 0) && (v >= 0) && (u + v <= 1);
00125 
00126                 }
00127 
00128 
00130 
00133                 bool getIntersectionWithLimitedLine(const line3d<T>& line,
00134                         vector3d<T>& outIntersection) const
00135                 {
00136                         return getIntersectionWithLine(line.start,
00137                                 line.getVector(), outIntersection) &&
00138                                 outIntersection.isBetweenPoints(line.start, line.end);
00139                 }
00140 
00141 
00143 
00151                 bool getIntersectionWithLine(const vector3d<T>& linePoint,
00152                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
00153                 {
00154                         if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection))
00155                                 return isPointInside(outIntersection);
00156 
00157                         return false;
00158                 }
00159 
00160 
00162 
00166                 bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint,
00167                         const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
00168                 {
00169                         const vector3d<T> normal = getNormal().normalize();
00170                         T t2;
00171 
00172                         if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) )
00173                                 return false;
00174 
00175                         T d = pointA.dotProduct(normal);
00176                         T t = -(normal.dotProduct(linePoint) - d) / t2;
00177                         outIntersection = linePoint + (lineVect * t);
00178                         return true;
00179                 }
00180 
00181 
00183 
00184                 vector3d<T> getNormal() const
00185                 {
00186                         return (pointB - pointA).crossProduct(pointC - pointA);
00187                 }
00188 
00190 
00195                 bool isFrontFacing(const vector3d<T>& lookDirection) const
00196                 {
00197                         const vector3d<T> n = getNormal().normalize();
00198                         const f32 d = (f32)n.dotProduct(lookDirection);
00199                         return F32_LOWER_EQUAL_0(d);
00200                 }
00201 
00203                 plane3d<T> getPlane() const
00204                 {
00205                         return plane3d<T>(pointA, pointB, pointC);
00206                 }
00207 
00209                 T getArea() const
00210                 {
00211                         return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5f;
00212 
00213                 }
00214 
00216                 void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c)
00217                 {
00218                         pointA = a;
00219                         pointB = b;
00220                         pointC = c;
00221                 }
00222 
00224                 vector3d<T> pointA;
00225                 vector3d<T> pointB;
00226                 vector3d<T> pointC;
00227 
00228         private:
00229                 bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
00230                         const vector3d<T>& a, const vector3d<T>& b) const
00231                 {
00232                         vector3d<T> bminusa = b - a;
00233                         vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
00234                         vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
00235                         return (cp1.dotProduct(cp2) >= 0.0f);
00236                 }
00237         };
00238 
00239 
00241         typedef triangle3d<f32> triangle3df;
00242 
00244         typedef triangle3d<s32> triangle3di;
00245 
00246 } // end namespace core
00247 } // end namespace irr
00248 
00249 #endif
00250 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Fri May 25 2012 04:23:20 by Doxygen (1.7.6.1)