Open Source Tomb Raider Engine
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.

ViewVolume.cpp 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : hel
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : ViewVolume
  9. * License : No use w/o permission (C) 2002 Mongoose
  10. * Comments: This is the viewing volume for culling use
  11. *
  12. * Thanks Mark Morley for the article I used
  13. * to get several algorithms.
  14. *
  15. * This file was generated using Mongoose's C++
  16. * template generator script. <stu7440@westga.edu>
  17. *
  18. *-- History -------------------------------------------------
  19. *
  20. * 2002.12.15:
  21. * Mongoose - Created
  22. =================================================================*/
  23. #include <math.h>
  24. #include <ViewVolume.h>
  25. ////////////////////////////////////////////////////////////
  26. // Constructors
  27. ////////////////////////////////////////////////////////////
  28. ViewVolume::ViewVolume()
  29. {
  30. mFrustum[0][0] = mFrustum[0][1] = mFrustum[0][2] = mFrustum[0][3] = 0.0f;
  31. mFrustum[1][0] = mFrustum[1][1] = mFrustum[1][2] = mFrustum[1][3] = 0.0f;
  32. mFrustum[2][0] = mFrustum[2][1] = mFrustum[2][2] = mFrustum[2][3] = 0.0f;
  33. mFrustum[3][0] = mFrustum[3][1] = mFrustum[3][2] = mFrustum[3][3] = 0.0f;
  34. mFrustum[4][0] = mFrustum[4][1] = mFrustum[4][2] = mFrustum[4][3] = 0.0f;
  35. mFrustum[5][0] = mFrustum[5][1] = mFrustum[5][2] = mFrustum[5][3] = 0.0f;
  36. }
  37. ViewVolume::~ViewVolume()
  38. {
  39. }
  40. ////////////////////////////////////////////////////////////
  41. // Public Accessors
  42. ////////////////////////////////////////////////////////////
  43. bool ViewVolume::isBoundingVolumeInFrustum(BoundingVolume bvol)
  44. {
  45. return (isBoundingSphereInFrustum(bvol.mSphere) &&
  46. isBoundingBoxInFrustum(bvol.mBox));
  47. }
  48. bool ViewVolume::isBoundingSphereInFrustum(BoundingSphere bvol)
  49. {
  50. return (isSphereInFrustum(bvol.mCenter[0],
  51. bvol.mCenter[1],
  52. bvol.mCenter[2],
  53. bvol.mRadius));
  54. }
  55. bool ViewVolume::isBoundingBoxInFrustum(BoundingBox bvol)
  56. {
  57. return (isBboxInFrustum(bvol.mMin, bvol.mMax));
  58. }
  59. bool ViewVolume::isPointInFrustum(vec_t x, vec_t y, vec_t z)
  60. {
  61. unsigned int p;
  62. for (p = 0; p < 6; ++p)
  63. {
  64. if (mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z +
  65. mFrustum[p][3] <= 0)
  66. {
  67. return false;
  68. }
  69. }
  70. return true;
  71. }
  72. bool ViewVolume::isSphereInFrustum(vec_t x, vec_t y, vec_t z, vec_t radius)
  73. {
  74. unsigned int p;
  75. vec_t d;
  76. for (p = 0; p < 6; ++p)
  77. {
  78. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  79. if (d <= -radius)
  80. return false;
  81. }
  82. return true;
  83. }
  84. bool ViewVolume::isBboxInFrustum(vec3_t min, vec3_t max)
  85. {
  86. unsigned int p;
  87. for (p = 0; p < 6; ++p)
  88. {
  89. if (mFrustum[p][0] * min[0] +
  90. mFrustum[p][1] * min[1] +
  91. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  92. continue;
  93. if (mFrustum[p][0] * max[0] +
  94. mFrustum[p][1] * max[1] +
  95. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  96. continue;
  97. if (mFrustum[p][0] * min[0] +
  98. mFrustum[p][1] * max[1] +
  99. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  100. continue;
  101. if (mFrustum[p][0] * min[0] +
  102. mFrustum[p][1] * min[1] +
  103. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  104. continue;
  105. if (mFrustum[p][0] * min[0] +
  106. mFrustum[p][1] * max[1] +
  107. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  108. continue;
  109. if (mFrustum[p][0] * max[0] +
  110. mFrustum[p][1] * min[1] +
  111. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  112. continue;
  113. if (mFrustum[p][0] * max[0] +
  114. mFrustum[p][1] * max[1] +
  115. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  116. continue;
  117. if (mFrustum[p][0] * max[0] +
  118. mFrustum[p][1] * min[1] +
  119. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  120. continue;
  121. return false;
  122. }
  123. return true;
  124. }
  125. vec_t ViewVolume::getDistToSphereFromNear(vec_t x, vec_t y, vec_t z,
  126. vec_t radius)
  127. {
  128. unsigned int p;
  129. vec_t d = 0.0;
  130. for (p = 0; p < 6; ++p)
  131. {
  132. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  133. if (d <= -radius)
  134. return 0;
  135. }
  136. return d + radius;
  137. }
  138. vec_t ViewVolume::getDistToBboxFromNear(vec3_t min, vec3_t max)
  139. {
  140. vec3_t center;
  141. vec_t d, radius;
  142. helMidpoint3v(min, max, center);
  143. // 5 should be near plane
  144. d = (mFrustum[5][0] * center[0] +
  145. mFrustum[5][1] * center[1] +
  146. mFrustum[5][2] * center[2] +
  147. mFrustum[5][3]);
  148. radius = helDist3v(max, center);
  149. if (d <= -radius)
  150. return 0;
  151. return d + radius;
  152. }
  153. void ViewVolume::getFrustum(vec_t frustum[6][4])
  154. {
  155. unsigned int plane;
  156. for (plane = 0; plane < 6; ++plane)
  157. {
  158. frustum[plane][0] = mFrustum[plane][0];
  159. frustum[plane][1] = mFrustum[plane][1];
  160. frustum[plane][2] = mFrustum[plane][2];
  161. frustum[plane][3] = mFrustum[plane][3];
  162. }
  163. }
  164. void ViewVolume::getPlane(ViewVolumeSide p, vec4_t plane)
  165. {
  166. plane[0] = mFrustum[p][0];
  167. plane[1] = mFrustum[p][1];
  168. plane[2] = mFrustum[p][2];
  169. plane[3] = mFrustum[p][3];
  170. }
  171. ////////////////////////////////////////////////////////////
  172. // Public Mutators
  173. ////////////////////////////////////////////////////////////
  174. void ViewVolume::updateFrame(matrix_t proj, matrix_t mdl)
  175. {
  176. setModel(mdl);
  177. setProjection(proj);
  178. updateClip();
  179. updateFrustum();
  180. }
  181. void ViewVolume::updateFrame()
  182. {
  183. updateClip();
  184. updateFrustum();
  185. }
  186. void ViewVolume::setModel(matrix_t mdl)
  187. {
  188. mModel.setMatrix(mdl);
  189. }
  190. void ViewVolume::setProjection(matrix_t proj)
  191. {
  192. /*void setProjection(viewAngle, aspectRatio, near, far)
  193. ****************************
  194. *float far = 4000.0f;
  195. *float near = 4.0f;
  196. *float viewAngle = 45.0f;
  197. *float aspectRatio = 800.0f/600.0f;
  198. ****************************
  199. *float top = near * tan(PI/180 * viewAngle/2)
  200. *float bottom = -top
  201. *float right = top * aspectRatio
  202. *float left = - right
  203. */
  204. mProjection.setMatrix(proj);
  205. }
  206. ////////////////////////////////////////////////////////////
  207. // Private Accessors
  208. ////////////////////////////////////////////////////////////
  209. ////////////////////////////////////////////////////////////
  210. // Private Mutators
  211. ////////////////////////////////////////////////////////////
  212. void ViewVolume::updateClip()
  213. {
  214. //mClip = mModel * mProjection;
  215. mClip = mProjection * mModel;
  216. }
  217. void ViewVolume::updateFrustum()
  218. {
  219. matrix_t clip;
  220. vec_t t;
  221. mClip.getMatrix(clip);
  222. /* Extract the numbers for the RIGHT plane */
  223. mFrustum[0][0] = clip[ 3] - clip[ 0];
  224. mFrustum[0][1] = clip[ 7] - clip[ 4];
  225. mFrustum[0][2] = clip[11] - clip[ 8];
  226. mFrustum[0][3] = clip[15] - clip[12];
  227. /* Normalize the result */
  228. t = sqrtf(mFrustum[0][0] * mFrustum[0][0] +
  229. mFrustum[0][1] * mFrustum[0][1] +
  230. mFrustum[0][2] * mFrustum[0][2]);
  231. mFrustum[0][0] /= t;
  232. mFrustum[0][1] /= t;
  233. mFrustum[0][2] /= t;
  234. mFrustum[0][3] /= t;
  235. /* Extract the numbers for the LEFT plane */
  236. mFrustum[1][0] = clip[ 3] + clip[ 0];
  237. mFrustum[1][1] = clip[ 7] + clip[ 4];
  238. mFrustum[1][2] = clip[11] + clip[ 8];
  239. mFrustum[1][3] = clip[15] + clip[12];
  240. /* Normalize the result */
  241. t = sqrtf(mFrustum[1][0] * mFrustum[1][0] +
  242. mFrustum[1][1] * mFrustum[1][1] +
  243. mFrustum[1][2] * mFrustum[1][2]);
  244. mFrustum[1][0] /= t;
  245. mFrustum[1][1] /= t;
  246. mFrustum[1][2] /= t;
  247. mFrustum[1][3] /= t;
  248. /* Extract the BOTTOM plane */
  249. mFrustum[2][0] = clip[ 3] + clip[ 1];
  250. mFrustum[2][1] = clip[ 7] + clip[ 5];
  251. mFrustum[2][2] = clip[11] + clip[ 9];
  252. mFrustum[2][3] = clip[15] + clip[13];
  253. /* Normalize the result */
  254. t = sqrtf(mFrustum[2][0] * mFrustum[2][0] +
  255. mFrustum[2][1] * mFrustum[2][1] +
  256. mFrustum[2][2] * mFrustum[2][2]);
  257. mFrustum[2][0] /= t;
  258. mFrustum[2][1] /= t;
  259. mFrustum[2][2] /= t;
  260. mFrustum[2][3] /= t;
  261. /* Extract the TOP plane */
  262. mFrustum[3][0] = clip[ 3] - clip[ 1];
  263. mFrustum[3][1] = clip[ 7] - clip[ 5];
  264. mFrustum[3][2] = clip[11] - clip[ 9];
  265. mFrustum[3][3] = clip[15] - clip[13];
  266. /* Normalize the result */
  267. t = sqrtf(mFrustum[3][0] * mFrustum[3][0] +
  268. mFrustum[3][1] * mFrustum[3][1] +
  269. mFrustum[3][2] * mFrustum[3][2]);
  270. mFrustum[3][0] /= t;
  271. mFrustum[3][1] /= t;
  272. mFrustum[3][2] /= t;
  273. mFrustum[3][3] /= t;
  274. /* Extract the FAR plane */
  275. mFrustum[4][0] = clip[ 3] - clip[ 2];
  276. mFrustum[4][1] = clip[ 7] - clip[ 6];
  277. mFrustum[4][2] = clip[11] - clip[10];
  278. mFrustum[4][3] = clip[15] - clip[14];
  279. /* Normalize the result */
  280. t = sqrtf(mFrustum[4][0] * mFrustum[4][0] +
  281. mFrustum[4][1] * mFrustum[4][1] +
  282. mFrustum[4][2] * mFrustum[4][2]);
  283. mFrustum[4][0] /= t;
  284. mFrustum[4][1] /= t;
  285. mFrustum[4][2] /= t;
  286. mFrustum[4][3] /= t;
  287. /* Extract the NEAR plane */
  288. mFrustum[5][0] = clip[ 3] + clip[ 2];
  289. mFrustum[5][1] = clip[ 7] + clip[ 6];
  290. mFrustum[5][2] = clip[11] + clip[10];
  291. mFrustum[5][3] = clip[15] + clip[14];
  292. /* Normalize the result */
  293. t = sqrtf(mFrustum[5][0] * mFrustum[5][0] +
  294. mFrustum[5][1] * mFrustum[5][1] +
  295. mFrustum[5][2] * mFrustum[5][2]);
  296. mFrustum[5][0] /= t;
  297. mFrustum[5][1] /= t;
  298. mFrustum[5][2] /= t;
  299. mFrustum[5][3] /= t;
  300. }