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 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*!
  2. * \file include/ViewVolume.h
  3. * \brief Viewing Volume for culling use
  4. *
  5. * Thanks Mark Morley for the article I used to get several algorithms.
  6. *
  7. * \author Mongoose
  8. */
  9. #include <math.h>
  10. #include "ViewVolume.h"
  11. ViewVolume::ViewVolume() {
  12. mFrustum[0][0] = mFrustum[0][1] = mFrustum[0][2] = mFrustum[0][3] = 0.0f;
  13. mFrustum[1][0] = mFrustum[1][1] = mFrustum[1][2] = mFrustum[1][3] = 0.0f;
  14. mFrustum[2][0] = mFrustum[2][1] = mFrustum[2][2] = mFrustum[2][3] = 0.0f;
  15. mFrustum[3][0] = mFrustum[3][1] = mFrustum[3][2] = mFrustum[3][3] = 0.0f;
  16. mFrustum[4][0] = mFrustum[4][1] = mFrustum[4][2] = mFrustum[4][3] = 0.0f;
  17. mFrustum[5][0] = mFrustum[5][1] = mFrustum[5][2] = mFrustum[5][3] = 0.0f;
  18. }
  19. bool ViewVolume::isBoundingVolumeInFrustum(BoundingVolume bvol) {
  20. return (isBoundingSphereInFrustum(bvol.mSphere) &&
  21. isBoundingBoxInFrustum(bvol.mBox));
  22. }
  23. bool ViewVolume::isBoundingSphereInFrustum(BoundingSphere bvol) {
  24. return (isSphereInFrustum(bvol.mCenter[0],
  25. bvol.mCenter[1],
  26. bvol.mCenter[2],
  27. bvol.mRadius));
  28. }
  29. bool ViewVolume::isBoundingBoxInFrustum(BoundingBox bvol) {
  30. return (isBboxInFrustum(bvol.mMin, bvol.mMax));
  31. }
  32. bool ViewVolume::isPointInFrustum(vec_t x, vec_t y, vec_t z) {
  33. for (unsigned int p = 0; p < 6; ++p) {
  34. if (mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z +
  35. mFrustum[p][3] <= 0) {
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. bool ViewVolume::isSphereInFrustum(vec_t x, vec_t y, vec_t z, vec_t radius) {
  42. vec_t d;
  43. for (unsigned int p = 0; p < 6; ++p) {
  44. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  45. if (d <= -radius)
  46. return false;
  47. }
  48. return true;
  49. }
  50. bool ViewVolume::isBboxInFrustum(vec3_t min, vec3_t max) {
  51. for (unsigned int p = 0; p < 6; ++p) {
  52. if (mFrustum[p][0] * min[0] +
  53. mFrustum[p][1] * min[1] +
  54. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  55. continue;
  56. if (mFrustum[p][0] * max[0] +
  57. mFrustum[p][1] * max[1] +
  58. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  59. continue;
  60. if (mFrustum[p][0] * min[0] +
  61. mFrustum[p][1] * max[1] +
  62. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  63. continue;
  64. if (mFrustum[p][0] * min[0] +
  65. mFrustum[p][1] * min[1] +
  66. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  67. continue;
  68. if (mFrustum[p][0] * min[0] +
  69. mFrustum[p][1] * max[1] +
  70. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  71. continue;
  72. if (mFrustum[p][0] * max[0] +
  73. mFrustum[p][1] * min[1] +
  74. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  75. continue;
  76. if (mFrustum[p][0] * max[0] +
  77. mFrustum[p][1] * max[1] +
  78. mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
  79. continue;
  80. if (mFrustum[p][0] * max[0] +
  81. mFrustum[p][1] * min[1] +
  82. mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
  83. continue;
  84. return false;
  85. }
  86. return true;
  87. }
  88. vec_t ViewVolume::getDistToSphereFromNear(vec_t x, vec_t y, vec_t z, vec_t radius) {
  89. vec_t d = 0.0;
  90. for (unsigned int p = 0; p < 6; ++p) {
  91. d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
  92. if (d <= -radius)
  93. return 0;
  94. }
  95. return d + radius;
  96. }
  97. vec_t ViewVolume::getDistToBboxFromNear(vec3_t min, vec3_t max) {
  98. vec3_t center;
  99. vec_t d, radius;
  100. midpoint(min, max, center);
  101. // 5 should be near plane
  102. d = (mFrustum[5][0] * center[0] +
  103. mFrustum[5][1] * center[1] +
  104. mFrustum[5][2] * center[2] +
  105. mFrustum[5][3]);
  106. radius = distance(max, center);
  107. if (d <= -radius)
  108. return 0;
  109. return d + radius;
  110. }
  111. void ViewVolume::getFrustum(vec_t frustum[6][4]) {
  112. for (unsigned int p = 0; p < 6; ++p) {
  113. for (unsigned int i = 0; i < 4; ++i) {
  114. frustum[p][i] = mFrustum[p][i];
  115. }
  116. }
  117. }
  118. void ViewVolume::getPlane(ViewVolumeSide p, vec4_t plane) {
  119. for (unsigned int i = 0; i < 4; ++i) {
  120. plane[i] = mFrustum[p][i];
  121. }
  122. }
  123. void ViewVolume::updateFrame(matrix_t proj, matrix_t mdl) {
  124. setModel(mdl);
  125. setProjection(proj);
  126. updateClip();
  127. updateFrustum();
  128. }
  129. void ViewVolume::updateFrame() {
  130. updateClip();
  131. updateFrustum();
  132. }
  133. void ViewVolume::setModel(matrix_t mdl) {
  134. mModel.setMatrix(mdl);
  135. }
  136. void ViewVolume::setProjection(matrix_t proj) {
  137. mProjection.setMatrix(proj);
  138. }
  139. void ViewVolume::updateClip() {
  140. mClip = mProjection * mModel;
  141. }
  142. void ViewVolume::updateFrustum() {
  143. matrix_t clip;
  144. vec_t t;
  145. mClip.getMatrix(clip);
  146. /* Extract the numbers for the RIGHT plane */
  147. mFrustum[0][0] = clip[ 3] - clip[ 0];
  148. mFrustum[0][1] = clip[ 7] - clip[ 4];
  149. mFrustum[0][2] = clip[11] - clip[ 8];
  150. mFrustum[0][3] = clip[15] - clip[12];
  151. /* Normalize the result */
  152. t = sqrtf(mFrustum[0][0] * mFrustum[0][0] +
  153. mFrustum[0][1] * mFrustum[0][1] +
  154. mFrustum[0][2] * mFrustum[0][2]);
  155. mFrustum[0][0] /= t;
  156. mFrustum[0][1] /= t;
  157. mFrustum[0][2] /= t;
  158. mFrustum[0][3] /= t;
  159. /* Extract the numbers for the LEFT plane */
  160. mFrustum[1][0] = clip[ 3] + clip[ 0];
  161. mFrustum[1][1] = clip[ 7] + clip[ 4];
  162. mFrustum[1][2] = clip[11] + clip[ 8];
  163. mFrustum[1][3] = clip[15] + clip[12];
  164. /* Normalize the result */
  165. t = sqrtf(mFrustum[1][0] * mFrustum[1][0] +
  166. mFrustum[1][1] * mFrustum[1][1] +
  167. mFrustum[1][2] * mFrustum[1][2]);
  168. mFrustum[1][0] /= t;
  169. mFrustum[1][1] /= t;
  170. mFrustum[1][2] /= t;
  171. mFrustum[1][3] /= t;
  172. /* Extract the BOTTOM plane */
  173. mFrustum[2][0] = clip[ 3] + clip[ 1];
  174. mFrustum[2][1] = clip[ 7] + clip[ 5];
  175. mFrustum[2][2] = clip[11] + clip[ 9];
  176. mFrustum[2][3] = clip[15] + clip[13];
  177. /* Normalize the result */
  178. t = sqrtf(mFrustum[2][0] * mFrustum[2][0] +
  179. mFrustum[2][1] * mFrustum[2][1] +
  180. mFrustum[2][2] * mFrustum[2][2]);
  181. mFrustum[2][0] /= t;
  182. mFrustum[2][1] /= t;
  183. mFrustum[2][2] /= t;
  184. mFrustum[2][3] /= t;
  185. /* Extract the TOP plane */
  186. mFrustum[3][0] = clip[ 3] - clip[ 1];
  187. mFrustum[3][1] = clip[ 7] - clip[ 5];
  188. mFrustum[3][2] = clip[11] - clip[ 9];
  189. mFrustum[3][3] = clip[15] - clip[13];
  190. /* Normalize the result */
  191. t = sqrtf(mFrustum[3][0] * mFrustum[3][0] +
  192. mFrustum[3][1] * mFrustum[3][1] +
  193. mFrustum[3][2] * mFrustum[3][2]);
  194. mFrustum[3][0] /= t;
  195. mFrustum[3][1] /= t;
  196. mFrustum[3][2] /= t;
  197. mFrustum[3][3] /= t;
  198. /* Extract the FAR plane */
  199. mFrustum[4][0] = clip[ 3] - clip[ 2];
  200. mFrustum[4][1] = clip[ 7] - clip[ 6];
  201. mFrustum[4][2] = clip[11] - clip[10];
  202. mFrustum[4][3] = clip[15] - clip[14];
  203. /* Normalize the result */
  204. t = sqrtf(mFrustum[4][0] * mFrustum[4][0] +
  205. mFrustum[4][1] * mFrustum[4][1] +
  206. mFrustum[4][2] * mFrustum[4][2]);
  207. mFrustum[4][0] /= t;
  208. mFrustum[4][1] /= t;
  209. mFrustum[4][2] /= t;
  210. mFrustum[4][3] /= t;
  211. /* Extract the NEAR plane */
  212. mFrustum[5][0] = clip[ 3] + clip[ 2];
  213. mFrustum[5][1] = clip[ 7] + clip[ 6];
  214. mFrustum[5][2] = clip[11] + clip[10];
  215. mFrustum[5][3] = clip[15] + clip[14];
  216. /* Normalize the result */
  217. t = sqrtf(mFrustum[5][0] * mFrustum[5][0] +
  218. mFrustum[5][1] * mFrustum[5][1] +
  219. mFrustum[5][2] * mFrustum[5][2]);
  220. mFrustum[5][0] /= t;
  221. mFrustum[5][1] /= t;
  222. mFrustum[5][2] /= t;
  223. mFrustum[5][3] /= t;
  224. }