mPlane.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MPLANE_H_
  23. #define _MPLANE_H_
  24. #ifndef _MMATHFN_H_
  25. #include "math/mMathFn.h"
  26. #endif
  27. #ifndef _MPOINT_H_
  28. #include "math/mPoint.h"
  29. #endif
  30. //---------------------------------------------------------------------------
  31. class PlaneF: public Point3F
  32. {
  33. public:
  34. F32 d;
  35. PlaneF();
  36. PlaneF( const Point3F& p, const Point3F& n );
  37. PlaneF( F32 _x, F32 _y, F32 _z, F32 _d);
  38. PlaneF( const Point3F& j, const Point3F& k, const Point3F& l );
  39. // Comparison operators
  40. bool operator==(const PlaneF&a) const
  41. {
  42. return (a.x == x && a.y == y && a.z == z && a.d == d);
  43. }
  44. bool operator!=(const PlaneF&a) const
  45. {
  46. return (a.x != x || a.y != y || a.z != z || a.d == d);
  47. }
  48. // Methods
  49. void set(const F32 _x, const F32 _y, const F32 _z);
  50. void set( const Point3F& p, const Point3F& n);
  51. void set( const Point3F& k, const Point3F& j, const Point3F& l );
  52. void setPoint(const Point3F &p); // assumes the x,y,z fields are already set
  53. // creates an un-normalized plane
  54. void setXY(F32 zz);
  55. void setYZ(F32 xx);
  56. void setXZ(F32 yy);
  57. void setXY(const Point3F& P, F32 dir);
  58. void setYZ(const Point3F& P, F32 dir);
  59. void setXZ(const Point3F& P, F32 dir);
  60. void shiftX(F32 xx);
  61. void shiftY(F32 yy);
  62. void shiftZ(F32 zz);
  63. void invert();
  64. void neg();
  65. Point3F project(Point3F pt); // project's the point onto the plane.
  66. F32 distToPlane( const Point3F& cp ) const;
  67. enum Side
  68. {
  69. Front = 1,
  70. On = 0,
  71. Back = -1
  72. };
  73. Side whichSide(const Point3F& cp) const;
  74. F32 intersect(const Point3F &start, const Point3F &end) const;
  75. bool isHorizontal() const;
  76. bool isVertical() const;
  77. Side whichSideBox(const Point3F& center,
  78. const Point3F& axisx,
  79. const Point3F& axisy,
  80. const Point3F& axisz,
  81. const Point3F& offset) const;
  82. };
  83. #define PARALLEL_PLANE 1e20f
  84. #define PlaneSwitchCode(s, e) (s * 3 + e)
  85. //---------------------------------------------------------------------------
  86. inline PlaneF::PlaneF()
  87. {
  88. }
  89. inline PlaneF::
  90. PlaneF( F32 _x, F32 _y, F32 _z, F32 _d )
  91. {
  92. x = _x; y = _y; z = _z; d = _d;
  93. }
  94. inline PlaneF::PlaneF( const Point3F& p, const Point3F& n )
  95. {
  96. set(p,n);
  97. }
  98. inline PlaneF::PlaneF( const Point3F& j, const Point3F& k, const Point3F& l )
  99. {
  100. set(j,k,l);
  101. }
  102. inline void PlaneF::setXY( F32 zz )
  103. {
  104. x = y = 0; z = 1; d = -zz;
  105. }
  106. inline void PlaneF::setYZ( F32 xx )
  107. {
  108. x = 1; z = y = 0; d = -xx;
  109. }
  110. inline void PlaneF::setXZ( F32 yy )
  111. {
  112. x = z = 0; y = 1; d = -yy;
  113. }
  114. inline void PlaneF::setXY(const Point3F& point, F32 dir) // Normal = (0, 0, -1|1)
  115. {
  116. x = y = 0;
  117. d = -((z = dir) * point.z);
  118. }
  119. inline void PlaneF::setYZ(const Point3F& point, F32 dir) // Normal = (-1|1, 0, 0)
  120. {
  121. z = y = 0;
  122. d = -((x = dir) * point.x);
  123. }
  124. inline void PlaneF::setXZ(const Point3F& point, F32 dir) // Normal = (0, -1|1, 0)
  125. {
  126. x = z = 0;
  127. d = -((y = dir) * point.y);
  128. }
  129. inline void PlaneF::shiftX( F32 xx )
  130. {
  131. d -= xx * x;
  132. }
  133. inline void PlaneF::shiftY( F32 yy )
  134. {
  135. d -= yy * y;
  136. }
  137. inline void PlaneF::shiftZ( F32 zz )
  138. {
  139. d -= zz * z;
  140. }
  141. inline bool PlaneF::isHorizontal() const
  142. {
  143. return (x == 0 && y == 0) ? true : false;
  144. }
  145. inline bool PlaneF::isVertical() const
  146. {
  147. return ((x != 0 || y != 0) && z == 0) ? true : false;
  148. }
  149. inline Point3F PlaneF::project(Point3F pt)
  150. {
  151. F32 dist = distToPlane(pt);
  152. return Point3F(pt.x - x * dist, pt.y - y * dist, pt.z - z * dist);
  153. }
  154. inline F32 PlaneF::distToPlane( const Point3F& cp ) const
  155. {
  156. // return mDot(*this,cp) + d;
  157. return (x * cp.x + y * cp.y + z * cp.z) + d;
  158. }
  159. inline PlaneF::Side PlaneF::whichSide(const Point3F& cp) const
  160. {
  161. F32 dist = distToPlane(cp);
  162. if (dist >= 0.005f) // if (mFabs(dist) < 0.005f)
  163. return Front; // return On;
  164. else if (dist <= -0.005f) // else if (dist > 0.0f)
  165. return Back; // return Front;
  166. else // else
  167. return On; // return Back;
  168. }
  169. inline void PlaneF::set(const F32 _x, const F32 _y, const F32 _z)
  170. {
  171. Point3F::set(_x,_y,_z);
  172. }
  173. //---------------------------------------------------------------------------
  174. /// Calculate the coefficients of the plane passing through
  175. /// a point with the given normal.
  176. inline void PlaneF::setPoint(const Point3F &p)
  177. {
  178. d = -(p.x * x + p.y * y + p.z * z);
  179. }
  180. inline void PlaneF::set( const Point3F& p, const Point3F& n )
  181. {
  182. x = n.x; y = n.y; z = n.z;
  183. normalize();
  184. // Calculate the last plane coefficient.
  185. d = -(p.x * x + p.y * y + p.z * z);
  186. }
  187. //---------------------------------------------------------------------------
  188. /// Calculate the coefficients of the plane passing through
  189. /// three points. Basically it calculates the normal to the three
  190. /// points then calculates a plane through the middle point with that
  191. /// normal.
  192. inline void PlaneF::set( const Point3F& k, const Point3F& j, const Point3F& l )
  193. {
  194. // Point3F kj,lj,pv;
  195. // kj = k;
  196. // kj -= j;
  197. // lj = l;
  198. // lj -= j;
  199. // mCross( kj, lj, &pv );
  200. // set(j,pv);
  201. // Above ends up making function calls up the %*#...
  202. // This is called often enough to be a little more direct
  203. // about it (sqrt should become intrinsic in the future)...
  204. F32 ax = k.x-j.x;
  205. F32 ay = k.y-j.y;
  206. F32 az = k.z-j.z;
  207. F32 bx = l.x-j.x;
  208. F32 by = l.y-j.y;
  209. F32 bz = l.z-j.z;
  210. x = ay*bz - az*by;
  211. y = az*bx - ax*bz;
  212. z = ax*by - ay*bx;
  213. F32 squared = x*x + y*y + z*z;
  214. AssertFatal(squared != 0.0, "Error, no plane possible!");
  215. // In non-debug mode
  216. if (squared != 0) {
  217. F32 invSqrt = 1.0f / mSqrt(x*x + y*y + z*z);
  218. x *= invSqrt;
  219. y *= invSqrt;
  220. z *= invSqrt;
  221. d = -(j.x * x + j.y * y + j.z * z);
  222. } else {
  223. x = 0;
  224. y = 0;
  225. z = 1;
  226. d = -(j.x * x + j.y * y + j.z * z);
  227. }
  228. }
  229. inline void PlaneF::invert()
  230. {
  231. x = -x;
  232. y = -y;
  233. z = -z;
  234. d = -d;
  235. }
  236. inline void PlaneF::neg()
  237. {
  238. invert();
  239. }
  240. inline F32 PlaneF::intersect(const Point3F &p1, const Point3F &p2) const
  241. {
  242. F32 den = mDot(p2 - p1, *this);
  243. if(den == 0)
  244. return PARALLEL_PLANE;
  245. return -distToPlane(p1) / den;
  246. }
  247. inline PlaneF::Side PlaneF::whichSideBox(const Point3F& center,
  248. const Point3F& axisx,
  249. const Point3F& axisy,
  250. const Point3F& axisz,
  251. const Point3F& /*offset*/) const
  252. {
  253. F32 baseDist = distToPlane(center);
  254. F32 compDist = mFabs(mDot(axisx, *this)) +
  255. mFabs(mDot(axisy, *this)) +
  256. mFabs(mDot(axisz, *this));
  257. if (baseDist >= compDist)
  258. return Front;
  259. else if (baseDist <= -compDist)
  260. return Back;
  261. else
  262. return On;
  263. }
  264. #endif