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

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