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.2KB

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. }