Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials
triangle3d.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2010 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_TRIANGLE_3D_H_INCLUDED__
6 #define __IRR_TRIANGLE_3D_H_INCLUDED__
7 
8 #include "vector3d.h"
9 #include "line3d.h"
10 #include "plane3d.h"
11 #include "aabbox3d.h"
12 
13 namespace irr
14 {
15 namespace core
16 {
17 
19  template <class T>
20  class triangle3d
21  {
22  public:
23 
28 
30  bool operator==(const triangle3d<T>& other) const
31  {
32  return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC;
33  }
34 
36  bool operator!=(const triangle3d<T>& other) const
37  {
38  return !(*this==other);
39  }
40 
42 
44  bool isTotalInsideBox(const aabbox3d<T>& box) const
45  {
46  return (box.isPointInside(pointA) &&
47  box.isPointInside(pointB) &&
48  box.isPointInside(pointC));
49  }
50 
52 
54  bool isTotalOutsideBox(const aabbox3d<T>& box) const
55  {
56  return ((pointA.X > box.MaxEdge.X && pointB.X > box.MaxEdge.X && pointC.X > box.MaxEdge.X) ||
57 
58  (pointA.Y > box.MaxEdge.Y && pointB.Y > box.MaxEdge.Y && pointC.Y > box.MaxEdge.Y) ||
59  (pointA.Z > box.MaxEdge.Z && pointB.Z > box.MaxEdge.Z && pointC.Z > box.MaxEdge.Z) ||
60  (pointA.X < box.MinEdge.X && pointB.X < box.MinEdge.X && pointC.X < box.MinEdge.X) ||
61  (pointA.Y < box.MinEdge.Y && pointB.Y < box.MinEdge.Y && pointC.Y < box.MinEdge.Y) ||
62  (pointA.Z < box.MinEdge.Z && pointB.Z < box.MinEdge.Z && pointC.Z < box.MinEdge.Z));
63  }
64 
66 
69  {
70  const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
71  const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
72  const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
73 
74  const T d1 = rab.getDistanceFrom(p);
75  const T d2 = rbc.getDistanceFrom(p);
76  const T d3 = rca.getDistanceFrom(p);
77 
78  if (d1 < d2)
79  return d1 < d3 ? rab : rca;
80 
81  return d2 < d3 ? rbc : rca;
82  }
83 
85 
90  bool isPointInside(const vector3d<T>& p) const
91  {
92  return (isOnSameSide(p, pointA, pointB, pointC) &&
93  isOnSameSide(p, pointB, pointA, pointC) &&
94  isOnSameSide(p, pointC, pointA, pointB));
95  }
96 
98 
105  bool isPointInsideFast(const vector3d<T>& p) const
106  {
107  const vector3d<T> a = pointC - pointA;
108  const vector3d<T> b = pointB - pointA;
109  const vector3d<T> c = p - pointA;
110 
111  const f64 dotAA = a.dotProduct( a);
112  const f64 dotAB = a.dotProduct( b);
113  const f64 dotAC = a.dotProduct( c);
114  const f64 dotBB = b.dotProduct( b);
115  const f64 dotBC = b.dotProduct( c);
116 
117  // get coordinates in barycentric coordinate system
118  const f64 invDenom = 1/(dotAA * dotBB - dotAB * dotAB);
119  const f64 u = (dotBB * dotAC - dotAB * dotBC) * invDenom;
120  const f64 v = (dotAA * dotBC - dotAB * dotAC ) * invDenom;
121 
122  // We count border-points as inside to keep downward compatibility.
123  // That's why we use >= and <= instead of > and < as more commonly seen on the web.
124  return (u >= 0) && (v >= 0) && (u + v <= 1);
125 
126  }
127 
128 
130 
134  vector3d<T>& outIntersection) const
135  {
136  return getIntersectionWithLine(line.start,
137  line.getVector(), outIntersection) &&
138  outIntersection.isBetweenPoints(line.start, line.end);
139  }
140 
141 
143 
151  bool getIntersectionWithLine(const vector3d<T>& linePoint,
152  const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
153  {
154  if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection))
155  return isPointInside(outIntersection);
156 
157  return false;
158  }
159 
160 
162 
167  const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
168  {
169  const vector3d<T> normal = getNormal().normalize();
170  T t2;
171 
172  if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) )
173  return false;
174 
175  T d = pointA.dotProduct(normal);
176  T t = -(normal.dotProduct(linePoint) - d) / t2;
177  outIntersection = linePoint + (lineVect * t);
178  return true;
179  }
180 
181 
183 
185  {
186  return (pointB - pointA).crossProduct(pointC - pointA);
187  }
188 
190 
195  bool isFrontFacing(const vector3d<T>& lookDirection) const
196  {
197  const vector3d<T> n = getNormal().normalize();
198  const f32 d = (f32)n.dotProduct(lookDirection);
199  return F32_LOWER_EQUAL_0(d);
200  }
201 
204  {
205  return plane3d<T>(pointA, pointB, pointC);
206  }
207 
209  T getArea() const
210  {
211  return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5f;
212 
213  }
214 
216  void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c)
217  {
218  pointA = a;
219  pointB = b;
220  pointC = c;
221  }
222 
227 
228  private:
229  bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
230  const vector3d<T>& a, const vector3d<T>& b) const
231  {
232  vector3d<T> bminusa = b - a;
233  vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
234  vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
235  return (cp1.dotProduct(cp2) >= 0.0f);
236  }
237  };
238 
239 
242 
245 
246 } // end namespace core
247 } // end namespace irr
248 
249 #endif
250 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Fri Mar 21 2014 04:40:17 by Doxygen (1.8.1.2)