ccFrustum.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: CloudCompare project #
  15. //# #
  16. //##########################################################################
  17. #ifndef CC_FRUSTUM_HEADER
  18. #define CC_FRUSTUM_HEADER
  19. //CCCoreLib
  20. #include <RayAndBox.h>
  21. //Local
  22. #include "ccGLMatrix.h"
  23. class Plane
  24. {
  25. public:
  26. Plane()
  27. : normal(0, 0, 1)
  28. , constCoef(0)
  29. {}
  30. virtual ~Plane() = default;
  31. void setCoefficients(float a, float b, float c, float d)
  32. {
  33. // set the normal vector
  34. normal = CCVector3f(a, b, c);
  35. //compute the length of the vector
  36. float l = normal.norm();
  37. if (l != 0)
  38. {
  39. // normalize the vector
  40. normal /= l;
  41. // and divide constCoef as well
  42. constCoef = d / l;
  43. }
  44. else
  45. {
  46. constCoef = d;
  47. }
  48. }
  49. float distance(const CCVector3f& p) const
  50. {
  51. return normal.dot(p) + constCoef;
  52. }
  53. public: //members
  54. CCVector3f normal;
  55. float constCoef;
  56. };
  57. class AABox : public CCCoreLib::AABB<float>
  58. {
  59. public:
  60. AABox(const CCVector3f& A, const CCVector3f& B) : CCCoreLib::AABB<float>(A, B)
  61. {
  62. }
  63. CCVector3f getVertexP(const CCVector3f& normal) const
  64. {
  65. return {
  66. corners[normal.x > 0 ? 1 : 0].x,
  67. corners[normal.y > 0 ? 1 : 0].y,
  68. corners[normal.z > 0 ? 1 : 0].z
  69. };
  70. }
  71. CCVector3f getVertexN(const CCVector3f& normal) const
  72. {
  73. return {
  74. corners[normal.x < 0 ? 1 : 0].x,
  75. corners[normal.y < 0 ? 1 : 0].y,
  76. corners[normal.z < 0 ? 1 : 0].z
  77. };
  78. }
  79. };
  80. class AACube
  81. {
  82. public:
  83. AACube()
  84. : O(0, 0, 0)
  85. , d(0)
  86. {}
  87. AACube(const CCVector3f& origin, float size)
  88. : O(origin)
  89. , d(size)
  90. {
  91. }
  92. virtual ~AACube() = default;
  93. CCVector3f getVertexP(const CCVector3f& normal) const
  94. {
  95. return {
  96. normal.x > 0 ? O.x + d : O.x,
  97. normal.y > 0 ? O.y + d : O.y,
  98. normal.z > 0 ? O.z + d : O.z
  99. };
  100. }
  101. CCVector3f getVertexN(const CCVector3f& normal) const
  102. {
  103. return {
  104. normal.x < 0 ? O.x + d : O.x,
  105. normal.y < 0 ? O.y + d : O.y,
  106. normal.z < 0 ? O.z + d : O.z
  107. };
  108. }
  109. public: //members
  110. CCVector3f O;
  111. float d;
  112. };
  113. class Frustum
  114. {
  115. public:
  116. Frustum() = default;
  117. Frustum(const ccGLMatrixd& modelViewMat, const ccGLMatrixd& projMat)
  118. {
  119. ccGLMatrixd MP = projMat * modelViewMat;
  120. initfromMPMatrix(MP);
  121. }
  122. virtual ~Frustum() = default;
  123. enum Intersection
  124. {
  125. OUTSIDE = 0,
  126. INTERSECT = 1,
  127. INSIDE = 2,
  128. };
  129. public: //Intersection tests
  130. Intersection pointInFrustum(const CCVector3f& p) const
  131. {
  132. for (const auto &plane : pl)
  133. {
  134. if (plane.distance(p) < 0)
  135. {
  136. return OUTSIDE;
  137. }
  138. }
  139. return INSIDE;
  140. }
  141. Intersection sphereInFrustum(const CCVector3f &c, float r) const
  142. {
  143. Intersection result = INSIDE;
  144. for (const auto &plane : pl)
  145. {
  146. float distance = plane.distance(c);
  147. if (distance < -r)
  148. return OUTSIDE;
  149. else if (distance < r)
  150. result = INTERSECT;
  151. }
  152. return result;
  153. }
  154. Intersection boxInFrustum(const AABox& box) const
  155. {
  156. Intersection result = INSIDE;
  157. for (const auto &plane : pl)
  158. {
  159. if (plane.distance(box.getVertexP(plane.normal)) < 0)
  160. return OUTSIDE;
  161. else if (plane.distance(box.getVertexN(plane.normal)) < 0)
  162. result = INTERSECT;
  163. }
  164. return result;
  165. }
  166. Intersection boxInFrustum(const AACube& cube) const
  167. {
  168. Intersection result = INSIDE;
  169. for (const auto &plane : pl)
  170. {
  171. if (plane.distance(cube.getVertexP(plane.normal)) < 0)
  172. return OUTSIDE;
  173. else if (plane.distance(cube.getVertexN(plane.normal)) < 0)
  174. result = INTERSECT;
  175. }
  176. return result;
  177. }
  178. protected: //protected methods
  179. enum PLANE
  180. {
  181. TOP = 0,
  182. BOTTOM = 1,
  183. LEFT = 2,
  184. RIGHT = 3,
  185. NEARP = 4,
  186. FARP = 5
  187. };
  188. template <typename T> void initfromMPMatrix(const ccGLMatrixTpl<T>& MP)
  189. {
  190. const T* m = MP.data();
  191. pl[NEARP].setCoefficients
  192. (
  193. m[3] + m[2],
  194. m[7] + m[6],
  195. m[11] + m[10],
  196. m[15] + m[14]
  197. );
  198. pl[FARP].setCoefficients
  199. (
  200. m[3] - m[2],
  201. m[7] - m[6],
  202. m[11] - m[10],
  203. m[15] - m[14]
  204. );
  205. pl[BOTTOM].setCoefficients
  206. (
  207. m[3] + m[1],
  208. m[7] + m[5],
  209. m[11] + m[9],
  210. m[15] + m[13]
  211. );
  212. pl[TOP].setCoefficients
  213. (
  214. m[3] - m[1],
  215. m[7] - m[5],
  216. m[11] - m[9],
  217. m[15] - m[13]
  218. );
  219. pl[LEFT].setCoefficients
  220. (
  221. m[3] + m[0],
  222. m[7] + m[4],
  223. m[11] + m[8],
  224. m[15] + m[12]
  225. );
  226. pl[RIGHT].setCoefficients
  227. (
  228. m[3] - m[0],
  229. m[7] - m[4],
  230. m[11] - m[8],
  231. m[15] - m[12]
  232. );
  233. }
  234. protected: //members
  235. Plane pl[6];
  236. };
  237. #endif // CC_FRUSTUM_HEADER