2
0

BsConvexVolume.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Math/BsConvexVolume.h"
  4. #include "Math/BsAABox.h"
  5. #include "Math/BsSphere.h"
  6. #include "Math/BsPlane.h"
  7. #include "Math/BsMath.h"
  8. namespace bs
  9. {
  10. ConvexVolume::ConvexVolume(const Vector<Plane>& planes)
  11. :mPlanes(planes)
  12. { }
  13. ConvexVolume::ConvexVolume(const Matrix4& projectionMatrix, bool useNearPlane)
  14. {
  15. mPlanes.reserve(6);
  16. const Matrix4& proj = projectionMatrix;
  17. // Left
  18. {
  19. Plane plane;
  20. plane.normal.x = proj[3][0] + proj[0][0];
  21. plane.normal.y = proj[3][1] + proj[0][1];
  22. plane.normal.z = proj[3][2] + proj[0][2];
  23. plane.d = proj[3][3] + proj[0][3];
  24. mPlanes.push_back(plane);
  25. }
  26. // Right
  27. {
  28. Plane plane;
  29. plane.normal.x = proj[3][0] - proj[0][0];
  30. plane.normal.y = proj[3][1] - proj[0][1];
  31. plane.normal.z = proj[3][2] - proj[0][2];
  32. plane.d = proj[3][3] - proj[0][3];
  33. mPlanes.push_back(plane);
  34. }
  35. // Top
  36. {
  37. Plane plane;
  38. plane.normal.x = proj[3][0] - proj[1][0];
  39. plane.normal.y = proj[3][1] - proj[1][1];
  40. plane.normal.z = proj[3][2] - proj[1][2];
  41. plane.d = proj[3][3] - proj[1][3];
  42. mPlanes.push_back(plane);
  43. }
  44. // Bottom
  45. {
  46. Plane plane;
  47. plane.normal.x = proj[3][0] + proj[1][0];
  48. plane.normal.y = proj[3][1] + proj[1][1];
  49. plane.normal.z = proj[3][2] + proj[1][2];
  50. plane.d = proj[3][3] + proj[1][3];
  51. mPlanes.push_back(plane);
  52. }
  53. // Near
  54. if(useNearPlane)
  55. {
  56. Plane plane;
  57. plane.normal.x = proj[3][0] + proj[2][0];
  58. plane.normal.y = proj[3][1] + proj[2][1];
  59. plane.normal.z = proj[3][2] + proj[2][2];
  60. plane.d = proj[3][3] + proj[2][3];
  61. mPlanes.push_back(plane);
  62. }
  63. // Far
  64. {
  65. Plane plane;
  66. plane.normal.x = proj[3][0] - proj[2][0];
  67. plane.normal.y = proj[3][1] - proj[2][1];
  68. plane.normal.z = proj[3][2] - proj[2][2];
  69. plane.d = proj[3][3] - proj[2][3];
  70. mPlanes.push_back(plane);
  71. }
  72. for (UINT32 i = 0; i < (UINT32)mPlanes.size(); i++)
  73. {
  74. float length = mPlanes[i].normal.normalize();
  75. mPlanes[i].d /= -length;
  76. }
  77. }
  78. bool ConvexVolume::intersects(const AABox& box) const
  79. {
  80. Vector3 center = box.getCenter();
  81. Vector3 extents = box.getHalfSize();
  82. Vector3 absExtents(Math::abs(extents.x), Math::abs(extents.y), Math::abs(extents.z));
  83. for (auto& plane : mPlanes)
  84. {
  85. float dist = center.dot(plane.normal) - plane.d;
  86. float effectiveRadius = absExtents.x * Math::abs(plane.normal.x);
  87. effectiveRadius += absExtents.y * Math::abs(plane.normal.y);
  88. effectiveRadius += absExtents.z * Math::abs(plane.normal.z);
  89. if (dist < -effectiveRadius)
  90. return false;
  91. }
  92. return true;
  93. }
  94. bool ConvexVolume::intersects(const Sphere& sphere) const
  95. {
  96. Vector3 center = sphere.getCenter();
  97. float radius = sphere.getRadius();
  98. for (auto& plane : mPlanes)
  99. {
  100. float dist = center.dot(plane.normal) - plane.d;
  101. if (dist < -radius)
  102. return false;
  103. }
  104. return true;
  105. }
  106. bool ConvexVolume::contains(const Vector3& p, float expand) const
  107. {
  108. for(auto& plane : mPlanes)
  109. {
  110. if (plane.getDistance(p) < -expand)
  111. return false;
  112. }
  113. return true;
  114. }
  115. }