Saga3D API Documentation  1.0-RC4
plane3d.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2012 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_PLANE_3D_H_INCLUDED__
6 #define __IRR_PLANE_3D_H_INCLUDED__
7 
8 #include "irrMath.h"
9 #include <glm/vec3.hpp>
10 #include <glm/gtc/matrix_inverse.hpp>
11 
12 namespace saga
13 {
14 namespace core
15 {
16 
19 {
25 };
26 
28 
33 template <class T>
34 class plane3d
35 {
36  public:
37 
38  // Constructors
39 
40  plane3d(): Normal(0,1,0) { recalculateD(glm::vec3(0,0,0)); }
41 
42  plane3d(const glm::vec3& MPoint, const glm::vec3& Normal) : Normal(Normal) { recalculateD(MPoint); }
43 
44  plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(glm::vec3(px, py, pz)); }
45 
46  plane3d(const glm::vec3& point1, const glm::vec3& point2, const glm::vec3& point3)
47  { setPlane(point1, point2, point3); }
48 
49  plane3d(const glm::vec3 & normal, const T d) : Normal(normal), D(d) { }
50 
51  // operators
52 
53  inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);}
54 
55  inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);}
56 
57  // functions
58 
59  void setPlane(const glm::vec3& point, const glm::vec3& nvector)
60  {
61  Normal = nvector;
62  recalculateD(point);
63  }
64 
65  void setPlane(const glm::vec3& nvect, T d)
66  {
67  Normal = nvect;
68  D = d;
69  }
70 
71  void setPlane(const glm::vec3& point1, const glm::vec3& point2, const glm::vec3& point3)
72  {
73  // creates the plane from 3 memberpoints
74  Normal = glm::cross(point2 - point1, point3 - point1);
75  Normal = glm::normalize(Normal);
76 
77  recalculateD(point1);
78  }
79 
80 
81  void transform(const glm::mat4& mat)
82  {
83  // Transform the plane member point, i.e. rotate, translate and scale it.
84  glm::vec4 member = mat * glm::vec4(getMemberPoint(), 1);
85 
86  // Transform the normal by the transposed inverse of the matrix
87  auto transposedInverse = glm::inverseTranspose(mat);
88  auto normal = transposedInverse * glm::vec4(Normal, 1) ;
89 
90  setPlane(member, normal);
91  }
92 
94 
99  bool getIntersectionWithLine(const glm::vec3& linePoint,
100  const glm::vec3& lineVect,
101  glm::vec3& outIntersection) const
102  {
103  T t2 = glm::dot(Normal, lineVect);
104 
105  if (t2 == 0)
106  return false;
107 
108  T t =- (glm::dot(Normal, linePoint) + D) / t2;
109  outIntersection = linePoint + (lineVect * t);
110  return true;
111  }
112 
114 
120  float getKnownIntersectionWithLine(const glm::vec3& linePoint1,
121  const glm::vec3& linePoint2) const
122  {
123  glm::vec3 vect = linePoint2 - linePoint1;
124  T t2 = (float) glm::dot(Normal, vect);
125  return (float)-((glm::dot(Normal, linePoint1) + D) / t2);
126  }
127 
129 
135  const glm::vec3& linePoint1,
136  const glm::vec3& linePoint2,
137  glm::vec3& outIntersection) const
138  {
139  return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
140  isBetweenPoints(outIntersection, linePoint1, linePoint2));
141  }
142 
144 
148  EIntersectionRelation3D classifyPointRelation(const glm::vec3& point) const
149  {
150  const T d = glm::dot(Normal, point) + D;
151 
152  if (d < -ROUNDING_ERROR_float)
153  return ISREL3D_BACK;
154 
155  if (d > ROUNDING_ERROR_float)
156  return ISREL3D_FRONT;
157 
158  return ISREL3D_PLANAR;
159  }
160 
162  void recalculateD(const glm::vec3& MPoint)
163  {
164  D = - glm::dot(MPoint, Normal);
165  }
166 
168  glm::vec3 getMemberPoint() const
169  {
170  return Normal * -D;
171  }
172 
174 
175  bool existsIntersection(const plane3d<T>& other) const
176  {
177  glm::vec3 cross = glm::cross(other.Normal, Normal);
178  return glm::length(cross) > core::ROUNDING_ERROR_float;
179  }
180 
182 
187  glm::vec3& outLinePoint,
188  glm::vec3& outLineVect) const
189  {
190  const T fn00 = glm::length(Normal);
191  const T fn01 = glm::dot(Normal, other.Normal);
192  const T fn11 = glm::length(other.Normal);
193  const double det = fn00*fn11 - fn01*fn01;
194 
195  if (fabs(det) < ROUNDING_ERROR_double)
196  return false;
197 
198  const double invdet = 1.0 / det;
199  const double fc0 = (fn11*-D + fn01*other.D) * invdet;
200  const double fc1 = (fn00*-other.D + fn01*D) * invdet;
201 
202  outLineVect = glm::cross(Normal, other.Normal);
203  outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1;
204  return true;
205  }
206 
209  const plane3d<T>& o2, glm::vec3& outPoint) const
210  {
211  glm::vec3 linePoint, lineVect;
212  if (getIntersectionWithPlane(o1, linePoint, lineVect))
213  return o2.getIntersectionWithLine(linePoint, lineVect, outPoint);
214 
215  return false;
216  }
217 
219 
227  bool isFrontFacing(const glm::vec3& lookDirection) const
228  {
229  const float d = glm::dot(Normal, lookDirection);
230  return F32_LOWER_EQUAL_0 (d);
231  }
232 
234 
235  T getDistanceTo(const glm::vec3& point) const
236  {
237  return glm::dot(point, Normal) + D;
238  }
239 
241  glm::vec3 Normal;
242 
244  T D;
245 };
246 
247 
250 
253 
254 } // namespace core
255 } // namespace saga
256 
257 #endif
258 
saga::core::plane3d::plane3d
plane3d(T px, T py, T pz, T nx, T ny, T nz)
Definition: plane3d.h:44
saga::core::plane3d
Template plane class with some intersection testing methods.
Definition: plane3d.h:34
saga::core::plane3d::transform
void transform(const glm::mat4 &mat)
Definition: plane3d.h:81
saga::core::plane3d::plane3d
plane3d(const glm::vec3 &MPoint, const glm::vec3 &Normal)
Definition: plane3d.h:42
saga::core::ISREL3D_FRONT
@ ISREL3D_FRONT
Definition: plane3d.h:20
saga::core::plane3d::setPlane
void setPlane(const glm::vec3 &nvect, T d)
Definition: plane3d.h:65
saga::core::plane3d::isFrontFacing
bool isFrontFacing(const glm::vec3 &lookDirection) const
Test if the triangle would be front or backfacing from any point.
Definition: plane3d.h:227
saga::core::plane3d::getKnownIntersectionWithLine
float getKnownIntersectionWithLine(const glm::vec3 &linePoint1, const glm::vec3 &linePoint2) const
Get percentage of line between two points where an intersection with this plane happens.
Definition: plane3d.h:120
saga::core::plane3d::getIntersectionWithLine
bool getIntersectionWithLine(const glm::vec3 &linePoint, const glm::vec3 &lineVect, glm::vec3 &outIntersection) const
Get an intersection with a 3d line.
Definition: plane3d.h:99
saga::core::EIntersectionRelation3D
EIntersectionRelation3D
Enumeration for intersection relations of 3d objects.
Definition: plane3d.h:18
saga::core::plane3d::getMemberPoint
glm::vec3 getMemberPoint() const
Gets a member point of the plane.
Definition: plane3d.h:168
saga::core::plane3d::plane3d
plane3d()
Definition: plane3d.h:40
saga::core::plane3d::D
T D
Distance from origin.
Definition: plane3d.h:244
saga::core::equals
bool equals(const T a, const T b, const T tolerance=roundingError< T >())
returns if a equals b, taking possible rounding errors into account
Definition: irrMath.h:285
saga::core::plane3d::recalculateD
void recalculateD(const glm::vec3 &MPoint)
Recalculates the distance from origin by applying a new member point to the plane.
Definition: plane3d.h:162
saga::core::plane3d::classifyPointRelation
EIntersectionRelation3D classifyPointRelation(const glm::vec3 &point) const
Classifies the relation of a point to this plane.
Definition: plane3d.h:148
saga::core::plane3di
plane3d< std::int32_t > plane3di
Typedef for an integer 3d plane.
Definition: plane3d.h:252
saga::core::isBetweenPoints
bool isBetweenPoints(const glm::vec3 &point, const glm::vec3 &begin, const glm::vec3 &end)
Definition: irrMath.h:65
saga::core::ROUNDING_ERROR_float
const float ROUNDING_ERROR_float
Definition: irrMath.h:29
saga::core::plane3d::getDistanceTo
T getDistanceTo(const glm::vec3 &point) const
Get the distance to a point.
Definition: plane3d.h:235
saga::core::ISREL3D_SPANNING
@ ISREL3D_SPANNING
Definition: plane3d.h:23
saga::core::plane3d::setPlane
void setPlane(const glm::vec3 &point, const glm::vec3 &nvector)
Definition: plane3d.h:59
saga::core::plane3d::getIntersectionWithPlane
bool getIntersectionWithPlane(const plane3d< T > &other, glm::vec3 &outLinePoint, glm::vec3 &outLineVect) const
Intersects this plane with another.
Definition: plane3d.h:186
saga::core::ROUNDING_ERROR_double
const double ROUNDING_ERROR_double
Definition: irrMath.h:30
saga::core::plane3d::operator!=
bool operator!=(const plane3d< T > &other) const
Definition: plane3d.h:55
saga::core::plane3d::setPlane
void setPlane(const glm::vec3 &point1, const glm::vec3 &point2, const glm::vec3 &point3)
Definition: plane3d.h:71
saga::core::ISREL3D_PLANAR
@ ISREL3D_PLANAR
Definition: plane3d.h:22
F32_LOWER_EQUAL_0
#define F32_LOWER_EQUAL_0(n)
Definition: irrMath.h:462
saga::core::plane3d::getIntersectionWithLimitedLine
bool getIntersectionWithLimitedLine(const glm::vec3 &linePoint1, const glm::vec3 &linePoint2, glm::vec3 &outIntersection) const
Get an intersection with a 3d line, limited between two 3d points.
Definition: plane3d.h:134
irrMath.h
saga::core::plane3df
plane3d< float > plane3df
Typedef for a float 3d plane.
Definition: plane3d.h:249
saga::core::plane3d::operator==
bool operator==(const plane3d< T > &other) const
Definition: plane3d.h:53
saga::core::plane3d::existsIntersection
bool existsIntersection(const plane3d< T > &other) const
Tests if there is an intersection with the other plane.
Definition: plane3d.h:175
saga::core::plane3d::getIntersectionWithPlanes
bool getIntersectionWithPlanes(const plane3d< T > &o1, const plane3d< T > &o2, glm::vec3 &outPoint) const
Get the intersection point with two other planes if there is one.
Definition: plane3d.h:208
saga::core::plane3d::plane3d
plane3d(const glm::vec3 &point1, const glm::vec3 &point2, const glm::vec3 &point3)
Definition: plane3d.h:46
saga::core::plane3d::plane3d
plane3d(const glm::vec3 &normal, const T d)
Definition: plane3d.h:49
saga::core::ISREL3D_BACK
@ ISREL3D_BACK
Definition: plane3d.h:21
saga::core::plane3d::Normal
glm::vec3 Normal
Normal vector of the plane.
Definition: plane3d.h:241
saga
Definition: aabbox3d.h:11
saga::core::ISREL3D_CLIPPED
@ ISREL3D_CLIPPED
Definition: plane3d.h:24