You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

880 lines
28 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
  5. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file bbox_3d_ray.cpp
  26. * @brief 3D bounding box ray intersection tests.
  27. */
  28. #include "bbox_3d.h"
  29. #include "../ray.h"
  30. #include <wx/debug.h>
  31. // This BBOX Ray intersection test have the following credits:
  32. // "This source code accompanies the Journal of Graphics Tools paper:
  33. //
  34. // "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
  35. // by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
  36. // Computer Graphics Lab, TU Braunschweig, Germany and
  37. // University of Koblenz-Landau, Germany
  38. //
  39. // This source code is public domain, but please mention us if you use it."
  40. bool BBOX_3D::Intersect( const RAY& aRay, float* t ) const
  41. {
  42. switch( aRay.m_Classification )
  43. {
  44. case RAY_CLASSIFICATION::MMM:
  45. {
  46. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  47. || ( aRay.m_Origin.z < m_min.z )
  48. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  49. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 )
  50. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  51. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 )
  52. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  53. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  54. return false;
  55. // compute the intersection distance
  56. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  57. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  58. if( t1 > *t )
  59. *t = t1;
  60. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  61. if( t2 > *t )
  62. *t = t2;
  63. return true;
  64. }
  65. case RAY_CLASSIFICATION::MMP:
  66. {
  67. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  68. || ( aRay.m_Origin.z > m_max.z )
  69. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  70. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 )
  71. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  72. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 )
  73. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  74. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  75. return false;
  76. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  77. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  78. if( t1 > *t )
  79. *t = t1;
  80. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  81. if( t2 > *t )
  82. *t = t2;
  83. return true;
  84. }
  85. case RAY_CLASSIFICATION::MPM:
  86. {
  87. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  88. || ( aRay.m_Origin.z < m_min.z )
  89. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  90. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 )
  91. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  92. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 )
  93. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  94. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  95. return false;
  96. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  97. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  98. if( t1 > *t )
  99. *t = t1;
  100. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  101. if( t2 > *t )
  102. *t = t2;
  103. return true;
  104. }
  105. case RAY_CLASSIFICATION::MPP:
  106. {
  107. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  108. || ( aRay.m_Origin.z > m_max.z )
  109. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  110. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 )
  111. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  112. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 )
  113. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  114. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  115. return false;
  116. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  117. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  118. if( t1 > *t )
  119. *t = t1;
  120. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  121. if( t2 > *t )
  122. *t = t2;
  123. return true;
  124. }
  125. case RAY_CLASSIFICATION::PMM:
  126. {
  127. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  128. || ( aRay.m_Origin.z < m_min.z )
  129. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  130. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 )
  131. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  132. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 )
  133. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  134. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  135. return false;
  136. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  137. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  138. if( t1 > *t )
  139. *t = t1;
  140. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  141. if( t2 > *t )
  142. *t = t2;
  143. return true;
  144. }
  145. case RAY_CLASSIFICATION::PMP:
  146. {
  147. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  148. || ( aRay.m_Origin.z > m_max.z )
  149. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  150. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 )
  151. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  152. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 )
  153. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  154. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  155. return false;
  156. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  157. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  158. if( t1 > *t )
  159. *t = t1;
  160. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  161. if( t2 > *t )
  162. *t = t2;
  163. return true;
  164. }
  165. case RAY_CLASSIFICATION::PPM:
  166. {
  167. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  168. || ( aRay.m_Origin.z < m_min.z )
  169. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  170. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 )
  171. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  172. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 )
  173. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  174. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  175. return false;
  176. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  177. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  178. if( t1 > *t )
  179. *t = t1;
  180. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  181. if( t2 > *t )
  182. *t = t2;
  183. return true;
  184. }
  185. case RAY_CLASSIFICATION::PPP:
  186. {
  187. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  188. || ( aRay.m_Origin.z > m_max.z )
  189. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  190. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 )
  191. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  192. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 )
  193. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  194. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  195. return false;
  196. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  197. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  198. if( t1 > *t )
  199. *t = t1;
  200. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  201. if( t2 > *t )
  202. *t = t2;
  203. return true;
  204. }
  205. case RAY_CLASSIFICATION::OMM:
  206. {
  207. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  208. || ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.z < m_min.z )
  209. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  210. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 ) )
  211. return false;
  212. *t = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  213. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  214. if( t2 > *t )
  215. *t = t2;
  216. return true;
  217. }
  218. case RAY_CLASSIFICATION::OMP:
  219. {
  220. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  221. || ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.z > m_max.z )
  222. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  223. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 ) )
  224. return false;
  225. *t = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  226. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  227. if( t2 > *t )
  228. *t = t2;
  229. return true;
  230. }
  231. case RAY_CLASSIFICATION::OPM:
  232. {
  233. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  234. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  235. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  236. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 ) )
  237. return false;
  238. *t = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  239. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  240. if( t2 > *t )
  241. *t = t2;
  242. return true;
  243. }
  244. case RAY_CLASSIFICATION::OPP:
  245. {
  246. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  247. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z > m_max.z )
  248. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  249. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 ) )
  250. return false;
  251. *t = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  252. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  253. if( t2 > *t )
  254. *t = t2;
  255. return true;
  256. }
  257. case RAY_CLASSIFICATION::MOM:
  258. {
  259. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  260. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.z < m_min.z )
  261. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  262. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  263. return false;
  264. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  265. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  266. if( t2 > *t )
  267. *t = t2;
  268. return true;
  269. }
  270. case RAY_CLASSIFICATION::MOP:
  271. {
  272. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  273. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.z > m_max.z )
  274. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  275. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  276. return false;
  277. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  278. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  279. if( t2 > *t )
  280. *t = t2;
  281. return true;
  282. }
  283. case RAY_CLASSIFICATION::POM:
  284. {
  285. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  286. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  287. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  288. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  289. return false;
  290. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  291. float t2 = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  292. if( t2 > *t )
  293. *t = t2;
  294. return true;
  295. }
  296. case RAY_CLASSIFICATION::POP:
  297. {
  298. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  299. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z > m_max.z )
  300. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  301. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  302. return false;
  303. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  304. float t2 = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  305. if( t2 > *t )
  306. *t = t2;
  307. return true;
  308. }
  309. case RAY_CLASSIFICATION::MMO:
  310. {
  311. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  312. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  313. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  314. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 ) )
  315. return false;
  316. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  317. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  318. if( t1 > *t )
  319. *t = t1;
  320. return true;
  321. }
  322. case RAY_CLASSIFICATION::MPO:
  323. {
  324. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  325. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  326. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  327. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 ) )
  328. return false;
  329. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  330. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  331. if( t1 > *t )
  332. *t = t1;
  333. return true;
  334. }
  335. case RAY_CLASSIFICATION::PMO:
  336. {
  337. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  338. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  339. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  340. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 ) )
  341. return false;
  342. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  343. float t1 = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  344. if( t1 > *t )
  345. *t = t1;
  346. return true;
  347. }
  348. case RAY_CLASSIFICATION::PPO:
  349. {
  350. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  351. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  352. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  353. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 ) )
  354. return false;
  355. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  356. float t1 = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  357. if( t1 > *t )
  358. *t = t1;
  359. return true;
  360. }
  361. case RAY_CLASSIFICATION::MOO:
  362. {
  363. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  364. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  365. || ( aRay.m_Origin.z > m_max.z ) )
  366. return false;
  367. *t = ( m_max.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  368. return true;
  369. }
  370. case RAY_CLASSIFICATION::POO:
  371. {
  372. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  373. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  374. || ( aRay.m_Origin.z > m_max.z ) )
  375. return false;
  376. *t = ( m_min.x - aRay.m_Origin.x ) * aRay.m_InvDir.x;
  377. return true;
  378. }
  379. case RAY_CLASSIFICATION::OMO:
  380. {
  381. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.x < m_min.x )
  382. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  383. || ( aRay.m_Origin.z > m_max.z ) )
  384. return false;
  385. *t = ( m_max.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  386. return true;
  387. }
  388. case RAY_CLASSIFICATION::OPO:
  389. {
  390. if( ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.x < m_min.x )
  391. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  392. || ( aRay.m_Origin.z > m_max.z ) )
  393. return false;
  394. *t = ( m_min.y - aRay.m_Origin.y ) * aRay.m_InvDir.y;
  395. return true;
  396. }
  397. case RAY_CLASSIFICATION::OOM:
  398. {
  399. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.x < m_min.x )
  400. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  401. || ( aRay.m_Origin.y > m_max.y ) )
  402. return false;
  403. *t = ( m_max.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  404. return true;
  405. }
  406. case RAY_CLASSIFICATION::OOP:
  407. {
  408. if( ( aRay.m_Origin.z > m_max.z ) || ( aRay.m_Origin.x < m_min.x )
  409. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  410. || ( aRay.m_Origin.y > m_max.y ) )
  411. return false;
  412. *t = ( m_min.z - aRay.m_Origin.z ) * aRay.m_InvDir.z;
  413. return true;
  414. }
  415. }
  416. return false;
  417. }
  418. bool BBOX_3D::Intersect( const RAY& aRay ) const
  419. {
  420. switch( aRay.m_Classification )
  421. {
  422. case RAY_CLASSIFICATION::MMM:
  423. {
  424. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  425. || ( aRay.m_Origin.z < m_min.z )
  426. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  427. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 )
  428. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  429. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 )
  430. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  431. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  432. return false;
  433. return true;
  434. }
  435. case RAY_CLASSIFICATION::MMP:
  436. {
  437. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  438. || ( aRay.m_Origin.z > m_max.z )
  439. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  440. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 )
  441. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  442. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 )
  443. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  444. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  445. return false;
  446. return true;
  447. }
  448. case RAY_CLASSIFICATION::MPM:
  449. {
  450. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  451. || ( aRay.m_Origin.z < m_min.z )
  452. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  453. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 )
  454. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  455. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 )
  456. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  457. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  458. return false;
  459. return true;
  460. }
  461. case RAY_CLASSIFICATION::MPP:
  462. {
  463. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  464. || ( aRay.m_Origin.z > m_max.z )
  465. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  466. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 )
  467. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  468. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 )
  469. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  470. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  471. return false;
  472. return true;
  473. }
  474. case RAY_CLASSIFICATION::PMM:
  475. {
  476. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  477. || ( aRay.m_Origin.z < m_min.z )
  478. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  479. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 )
  480. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  481. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 )
  482. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  483. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  484. return false;
  485. return true;
  486. }
  487. case RAY_CLASSIFICATION::PMP:
  488. {
  489. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  490. || ( aRay.m_Origin.z > m_max.z )
  491. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  492. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 )
  493. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  494. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 )
  495. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  496. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  497. return false;
  498. return true;
  499. }
  500. case RAY_CLASSIFICATION::PPM:
  501. {
  502. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  503. || ( aRay.m_Origin.z < m_min.z )
  504. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  505. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 )
  506. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  507. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 )
  508. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  509. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  510. return false;
  511. return true;
  512. }
  513. case RAY_CLASSIFICATION::PPP:
  514. {
  515. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  516. || ( aRay.m_Origin.z > m_max.z )
  517. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  518. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 )
  519. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  520. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 )
  521. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  522. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  523. return false;
  524. return true;
  525. }
  526. case RAY_CLASSIFICATION::OMM:
  527. {
  528. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  529. || ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.z < m_min.z )
  530. || ( aRay.jbyk * m_min.z - m_max.y + aRay.c_zy > 0 )
  531. || ( aRay.kbyj * m_min.y - m_max.z + aRay.c_yz > 0 ) )
  532. return false;
  533. return true;
  534. }
  535. case RAY_CLASSIFICATION::OMP:
  536. {
  537. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  538. || ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.z > m_max.z )
  539. || ( aRay.jbyk * m_max.z - m_max.y + aRay.c_zy > 0 )
  540. || ( aRay.kbyj * m_min.y - m_min.z + aRay.c_yz < 0 ) )
  541. return false;
  542. return true;
  543. }
  544. case RAY_CLASSIFICATION::OPM:
  545. {
  546. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  547. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  548. || ( aRay.jbyk * m_min.z - m_min.y + aRay.c_zy < 0 )
  549. || ( aRay.kbyj * m_max.y - m_max.z + aRay.c_yz > 0 ) )
  550. return false;
  551. return true;
  552. }
  553. case RAY_CLASSIFICATION::OPP:
  554. {
  555. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.x > m_max.x )
  556. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z > m_max.z )
  557. || ( aRay.jbyk * m_max.z - m_min.y + aRay.c_zy < 0 )
  558. || ( aRay.kbyj * m_max.y - m_min.z + aRay.c_yz < 0 ) )
  559. return false;
  560. return true;
  561. }
  562. case RAY_CLASSIFICATION::MOM:
  563. {
  564. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  565. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.z < m_min.z )
  566. || ( aRay.kbyi * m_min.x - m_max.z + aRay.c_xz > 0 )
  567. || ( aRay.ibyk * m_min.z - m_max.x + aRay.c_zx > 0 ) )
  568. return false;
  569. return true;
  570. }
  571. case RAY_CLASSIFICATION::MOP:
  572. {
  573. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  574. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.z > m_max.z )
  575. || ( aRay.kbyi * m_min.x - m_min.z + aRay.c_xz < 0 )
  576. || ( aRay.ibyk * m_max.z - m_max.x + aRay.c_zx > 0 ) )
  577. return false;
  578. return true;
  579. }
  580. case RAY_CLASSIFICATION::POM:
  581. {
  582. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  583. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  584. || ( aRay.kbyi * m_max.x - m_max.z + aRay.c_xz > 0 )
  585. || ( aRay.ibyk * m_min.z - m_min.x + aRay.c_zx < 0 ) )
  586. return false;
  587. return true;
  588. }
  589. case RAY_CLASSIFICATION::POP:
  590. {
  591. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.y > m_max.y )
  592. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z > m_max.z )
  593. || ( aRay.kbyi * m_max.x - m_min.z + aRay.c_xz < 0 )
  594. || ( aRay.ibyk * m_max.z - m_min.x + aRay.c_zx < 0 ) )
  595. return false;
  596. return true;
  597. }
  598. case RAY_CLASSIFICATION::MMO:
  599. {
  600. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  601. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  602. || ( aRay.jbyi * m_min.x - m_max.y + aRay.c_xy > 0 )
  603. || ( aRay.ibyj * m_min.y - m_max.x + aRay.c_yx > 0 ) )
  604. return false;
  605. return true;
  606. }
  607. case RAY_CLASSIFICATION::MPO:
  608. {
  609. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  610. || ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y > m_max.y )
  611. || ( aRay.jbyi * m_min.x - m_min.y + aRay.c_xy < 0 )
  612. || ( aRay.ibyj * m_max.y - m_max.x + aRay.c_yx > 0 ) )
  613. return false;
  614. return true;
  615. }
  616. case RAY_CLASSIFICATION::PMO:
  617. {
  618. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  619. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  620. || ( aRay.jbyi * m_max.x - m_max.y + aRay.c_xy > 0 )
  621. || ( aRay.ibyj * m_min.y - m_min.x + aRay.c_yx < 0 ) )
  622. return false;
  623. return true;
  624. }
  625. case RAY_CLASSIFICATION::PPO:
  626. {
  627. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.z > m_max.z )
  628. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y > m_max.y )
  629. || ( aRay.jbyi * m_max.x - m_min.y + aRay.c_xy < 0 )
  630. || ( aRay.ibyj * m_max.y - m_min.x + aRay.c_yx < 0 ) )
  631. return false;
  632. return true;
  633. }
  634. case RAY_CLASSIFICATION::MOO:
  635. {
  636. if( ( aRay.m_Origin.x < m_min.x ) || ( aRay.m_Origin.y < m_min.y )
  637. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  638. || ( aRay.m_Origin.z > m_max.z ) )
  639. return false;
  640. return true;
  641. }
  642. case RAY_CLASSIFICATION::POO:
  643. {
  644. if( ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  645. || ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.z < m_min.z )
  646. || ( aRay.m_Origin.z > m_max.z ) )
  647. return false;
  648. return true;
  649. }
  650. case RAY_CLASSIFICATION::OMO:
  651. {
  652. if( ( aRay.m_Origin.y < m_min.y ) || ( aRay.m_Origin.x < m_min.x )
  653. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  654. || ( aRay.m_Origin.z > m_max.z ) )
  655. return false;
  656. return true;
  657. }
  658. case RAY_CLASSIFICATION::OPO:
  659. {
  660. if( ( aRay.m_Origin.y > m_max.y ) || ( aRay.m_Origin.x < m_min.x )
  661. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.z < m_min.z )
  662. || ( aRay.m_Origin.z > m_max.z ) )
  663. return false;
  664. return true;
  665. }
  666. case RAY_CLASSIFICATION::OOM:
  667. {
  668. if( ( aRay.m_Origin.z < m_min.z ) || ( aRay.m_Origin.x < m_min.x )
  669. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  670. || ( aRay.m_Origin.y > m_max.y ) )
  671. return false;
  672. return true;
  673. }
  674. case RAY_CLASSIFICATION::OOP:
  675. {
  676. if( ( aRay.m_Origin.z > m_max.z ) || ( aRay.m_Origin.x < m_min.x )
  677. || ( aRay.m_Origin.x > m_max.x ) || ( aRay.m_Origin.y < m_min.y )
  678. || ( aRay.m_Origin.y > m_max.y ) )
  679. return false;
  680. return true;
  681. }
  682. }
  683. return false;
  684. }