Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

ViewVolume.cpp 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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. }
  31. ViewVolume::~ViewVolume()
  32. {
  33. }
  34. ////////////////////////////////////////////////////////////
  35. // Public Accessors
  36. ////////////////////////////////////////////////////////////
  37. bool ViewVolume::isBoundingVolumeInFrustum(BoundingVolume bvol)
  38. {
  39. return (isBoundingSphereInFrustum(bvol.mSphere) &&
  40. isBoundingBoxInFrustum(bvol.mBox));
  41. }
  42. bool ViewVolume::isBoundingSphereInFrustum(BoundingSphere bvol)
  43. {
  44. return (isSphereInFrustum(bvol.mCenter[0],
  45. bvol.mCenter[1],
  46. bvol.mCenter[2],
  47. bvol.mRadius));
  48. }
  49. bool ViewVolume::isBoundingBoxInFrustum(BoundingBox bvol)
  50. {
  51. return (isBboxInFrustum(bvol.mMin, bvol.mMax));
  52. }
  53. bool ViewVolume::isPointInFrustum(vec_t x, vec_t y, vec_t z)
  54. {
  55. unsigned int p;
  56. for (p = 0; p < 6; ++p)
  57. {
  58. if (mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z +
  59. mFrustum[p][3] <= 0)
  60. {
  61. return false;
  62. }
  63. }
  64. return true;
  65. }
  66. bool ViewVolume::isSphereInFrustum(vec_t x, vec_t y, vec_t z, vec_t radius)
  67. {
  68. unsigned int p;
  69. vec_t d;
  70. for (p = 0; p < 6; ++p)
  71. {
  72. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  73. if (d <= -radius)
  74. return false;
  75. }
  76. return true;
  77. }
  78. bool ViewVolume::isBboxInFrustum(vec3_t min, vec3_t max)
  79. {
  80. unsigned int p;
  81. for (p = 0; p < 6; ++p)
  82. {
  83. if (mFrustum[p][0] * min[0] +
  84. mFrustum[p][1] * min[1] +
  85. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  86. continue;
  87. if (mFrustum[p][0] * max[0] +
  88. mFrustum[p][1] * max[1] +
  89. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  90. continue;
  91. if (mFrustum[p][0] * min[0] +
  92. mFrustum[p][1] * max[1] +
  93. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  94. continue;
  95. if (mFrustum[p][0] * min[0] +
  96. mFrustum[p][1] * min[1] +
  97. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  98. continue;
  99. if (mFrustum[p][0] * min[0] +
  100. mFrustum[p][1] * max[1] +
  101. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  102. continue;
  103. if (mFrustum[p][0] * max[0] +
  104. mFrustum[p][1] * min[1] +
  105. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  106. continue;
  107. if (mFrustum[p][0] * max[0] +
  108. mFrustum[p][1] * max[1] +
  109. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  110. continue;
  111. if (mFrustum[p][0] * max[0] +
  112. mFrustum[p][1] * min[1] +
  113. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  114. continue;
  115. return false;
  116. }
  117. return true;
  118. }
  119. vec_t ViewVolume::getDistToSphereFromNear(vec_t x, vec_t y, vec_t z,
  120. vec_t radius)
  121. {
  122. unsigned int p;
  123. vec_t d;
  124. for (p = 0; p < 6; ++p)
  125. {
  126. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  127. if (d <= -radius)
  128. return 0;
  129. }
  130. return d + radius;
  131. }
  132. vec_t ViewVolume::getDistToBboxFromNear(vec3_t min, vec3_t max)
  133. {
  134. vec3_t center;
  135. vec_t d, radius;
  136. helMidpoint3v(min, max, center);
  137. // 5 should be near plane
  138. d = (mFrustum[5][0] * center[0] +
  139. mFrustum[5][1] * center[1] +
  140. mFrustum[5][2] * center[2] +
  141. mFrustum[5][3]);
  142. radius = helDist3v(max, center);
  143. if (d <= -radius)
  144. return 0;
  145. return d + radius;
  146. }
  147. void ViewVolume::getFrustum(vec_t frustum[6][4])
  148. {
  149. unsigned int plane;
  150. for (plane = 0; plane < 6; ++plane)
  151. {
  152. frustum[plane][0] = mFrustum[plane][0];
  153. frustum[plane][1] = mFrustum[plane][1];
  154. frustum[plane][2] = mFrustum[plane][2];
  155. frustum[plane][3] = mFrustum[plane][3];
  156. }
  157. }
  158. void ViewVolume::getPlane(ViewVolumeSide p, vec4_t plane)
  159. {
  160. plane[0] = mFrustum[p][0];
  161. plane[1] = mFrustum[p][1];
  162. plane[2] = mFrustum[p][2];
  163. plane[3] = mFrustum[p][3];
  164. }
  165. ////////////////////////////////////////////////////////////
  166. // Public Mutators
  167. ////////////////////////////////////////////////////////////
  168. void ViewVolume::updateFrame(matrix_t proj, matrix_t mdl)
  169. {
  170. setModel(mdl);
  171. setProjection(proj);
  172. updateClip();
  173. updateFrustum();
  174. }
  175. void ViewVolume::updateFrame()
  176. {
  177. updateClip();
  178. updateFrustum();
  179. }
  180. void ViewVolume::setModel(matrix_t mdl)
  181. {
  182. mModel.setMatrix(mdl);
  183. }
  184. void ViewVolume::setProjection(matrix_t proj)
  185. {
  186. /*void setProjection(viewAngle, aspectRatio, near, far)
  187. ****************************
  188. *float far = 4000.0f;
  189. *float near = 4.0f;
  190. *float viewAngle = 45.0f;
  191. *float aspectRatio = 800.0f/600.0f;
  192. ****************************
  193. *float top = near * tan(PI/180 * viewAngle/2)
  194. *float bottom = -top
  195. *float right = top * aspectRatio
  196. *float left = - right
  197. */
  198. mProjection.setMatrix(proj);
  199. }
  200. ////////////////////////////////////////////////////////////
  201. // Private Accessors
  202. ////////////////////////////////////////////////////////////
  203. ////////////////////////////////////////////////////////////
  204. // Private Mutators
  205. ////////////////////////////////////////////////////////////
  206. void ViewVolume::updateClip()
  207. {
  208. //mClip = mModel * mProjection;
  209. mClip = mProjection * mModel;
  210. }
  211. void ViewVolume::updateFrustum()
  212. {
  213. matrix_t clip;
  214. vec_t t;
  215. mClip.getMatrix(clip);
  216. /* Extract the numbers for the RIGHT plane */
  217. mFrustum[0][0] = clip[ 3] - clip[ 0];
  218. mFrustum[0][1] = clip[ 7] - clip[ 4];
  219. mFrustum[0][2] = clip[11] - clip[ 8];
  220. mFrustum[0][3] = clip[15] - clip[12];
  221. /* Normalize the result */
  222. t = sqrt(mFrustum[0][0] * mFrustum[0][0] +
  223. mFrustum[0][1] * mFrustum[0][1] +
  224. mFrustum[0][2] * mFrustum[0][2]);
  225. mFrustum[0][0] /= t;
  226. mFrustum[0][1] /= t;
  227. mFrustum[0][2] /= t;
  228. mFrustum[0][3] /= t;
  229. /* Extract the numbers for the LEFT plane */
  230. mFrustum[1][0] = clip[ 3] + clip[ 0];
  231. mFrustum[1][1] = clip[ 7] + clip[ 4];
  232. mFrustum[1][2] = clip[11] + clip[ 8];
  233. mFrustum[1][3] = clip[15] + clip[12];
  234. /* Normalize the result */
  235. t = sqrt(mFrustum[1][0] * mFrustum[1][0] +
  236. mFrustum[1][1] * mFrustum[1][1] +
  237. mFrustum[1][2] * mFrustum[1][2]);
  238. mFrustum[1][0] /= t;
  239. mFrustum[1][1] /= t;
  240. mFrustum[1][2] /= t;
  241. mFrustum[1][3] /= t;
  242. /* Extract the BOTTOM plane */
  243. mFrustum[2][0] = clip[ 3] + clip[ 1];
  244. mFrustum[2][1] = clip[ 7] + clip[ 5];
  245. mFrustum[2][2] = clip[11] + clip[ 9];
  246. mFrustum[2][3] = clip[15] + clip[13];
  247. /* Normalize the result */
  248. t = sqrt(mFrustum[2][0] * mFrustum[2][0] +
  249. mFrustum[2][1] * mFrustum[2][1] +
  250. mFrustum[2][2] * mFrustum[2][2]);
  251. mFrustum[2][0] /= t;
  252. mFrustum[2][1] /= t;
  253. mFrustum[2][2] /= t;
  254. mFrustum[2][3] /= t;
  255. /* Extract the TOP plane */
  256. mFrustum[3][0] = clip[ 3] - clip[ 1];
  257. mFrustum[3][1] = clip[ 7] - clip[ 5];
  258. mFrustum[3][2] = clip[11] - clip[ 9];
  259. mFrustum[3][3] = clip[15] - clip[13];
  260. /* Normalize the result */
  261. t = sqrt(mFrustum[3][0] * mFrustum[3][0] +
  262. mFrustum[3][1] * mFrustum[3][1] +
  263. mFrustum[3][2] * mFrustum[3][2]);
  264. mFrustum[3][0] /= t;
  265. mFrustum[3][1] /= t;
  266. mFrustum[3][2] /= t;
  267. mFrustum[3][3] /= t;
  268. /* Extract the FAR plane */
  269. mFrustum[4][0] = clip[ 3] - clip[ 2];
  270. mFrustum[4][1] = clip[ 7] - clip[ 6];
  271. mFrustum[4][2] = clip[11] - clip[10];
  272. mFrustum[4][3] = clip[15] - clip[14];
  273. /* Normalize the result */
  274. t = sqrt(mFrustum[4][0] * mFrustum[4][0] +
  275. mFrustum[4][1] * mFrustum[4][1] +
  276. mFrustum[4][2] * mFrustum[4][2]);
  277. mFrustum[4][0] /= t;
  278. mFrustum[4][1] /= t;
  279. mFrustum[4][2] /= t;
  280. mFrustum[4][3] /= t;
  281. /* Extract the NEAR plane */
  282. mFrustum[5][0] = clip[ 3] + clip[ 2];
  283. mFrustum[5][1] = clip[ 7] + clip[ 6];
  284. mFrustum[5][2] = clip[11] + clip[10];
  285. mFrustum[5][3] = clip[15] + clip[14];
  286. /* Normalize the result */
  287. t = sqrt(mFrustum[5][0] * mFrustum[5][0] +
  288. mFrustum[5][1] * mFrustum[5][1] +
  289. mFrustum[5][2] * mFrustum[5][2]);
  290. mFrustum[5][0] /= t;
  291. mFrustum[5][1] /= t;
  292. mFrustum[5][2] /= t;
  293. mFrustum[5][3] /= t;
  294. }
  295. ////////////////////////////////////////////////////////////
  296. // Unit Test code
  297. ////////////////////////////////////////////////////////////
  298. #ifdef UNIT_TEST_VIEWVOLUME
  299. int runViewVolumeUnitTest(int argc, char *argv[])
  300. {
  301. return 0;
  302. }
  303. int main(int argc, char *argv[])
  304. {
  305. ViewVolume test;
  306. printf("[ViewVolume class test]\n");
  307. return runViewVolumeUnitTest(argc, argv);
  308. }
  309. #endif