Open Source Tomb Raider Engine
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

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 = 0.0;
  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