plane.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*************************************************************************/
  2. /* plane.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "plane.h"
  30. #include "math_funcs.h"
  31. #define _PLANE_EQ_DOT_EPSILON 0.999
  32. #define _PLANE_EQ_D_EPSILON 0.0001
  33. void Plane::set_normal(const Vector3& p_normal) {
  34. normal=p_normal;
  35. }
  36. void Plane::normalize() {
  37. real_t l = normal.length();
  38. if (l==0) {
  39. *this=Plane(0,0,0,0);
  40. return;
  41. }
  42. normal/=l;
  43. d/=l;
  44. }
  45. Plane Plane::normalized() const {
  46. Plane p = *this;
  47. p.normalize();
  48. return p;
  49. }
  50. Vector3 Plane::get_any_point() const {
  51. return get_normal()*d;
  52. }
  53. Vector3 Plane::get_any_perpendicular_normal() const {
  54. static const Vector3 p1 = Vector3(1,0,0);
  55. static const Vector3 p2 = Vector3(0,1,0);
  56. Vector3 p;
  57. if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
  58. p=p2; // use p2
  59. else
  60. p=p1; // use p1
  61. p-=normal * normal.dot(p);
  62. p.normalize();
  63. return p;
  64. }
  65. /* intersections */
  66. bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result) const {
  67. const Plane &p_plane0=*this;
  68. Vector3 normal0=p_plane0.normal;
  69. Vector3 normal1=p_plane1.normal;
  70. Vector3 normal2=p_plane2.normal;
  71. real_t denom=vec3_cross(normal0,normal1).dot(normal2);
  72. if (ABS(denom)<=CMP_EPSILON)
  73. return false;
  74. if (r_result) {
  75. *r_result = ( (vec3_cross(normal1, normal2) * p_plane0.d) +
  76. (vec3_cross(normal2, normal0) * p_plane1.d) +
  77. (vec3_cross(normal0, normal1) * p_plane2.d) )/denom;
  78. }
  79. return true;
  80. }
  81. bool Plane::intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3* p_intersection) const {
  82. Vector3 segment=p_dir;
  83. real_t den=normal.dot( segment );
  84. //printf("den is %i\n",den);
  85. if (Math::abs(den)<=CMP_EPSILON) {
  86. return false;
  87. }
  88. real_t dist=(normal.dot( p_from ) - d) / den;
  89. //printf("dist is %i\n",dist);
  90. if (dist>CMP_EPSILON) { //this is a ray, before the emiting pos (p_from) doesnt exist
  91. return false;
  92. }
  93. dist=-dist;
  94. *p_intersection = p_from + segment * dist;
  95. return true;
  96. }
  97. bool Plane::intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const {
  98. Vector3 segment= p_begin - p_end;
  99. real_t den=normal.dot( segment );
  100. //printf("den is %i\n",den);
  101. if (Math::abs(den)<=CMP_EPSILON) {
  102. return false;
  103. }
  104. real_t dist=(normal.dot( p_begin ) - d) / den;
  105. //printf("dist is %i\n",dist);
  106. if (dist<-CMP_EPSILON || dist > (1.0 +CMP_EPSILON)) {
  107. return false;
  108. }
  109. dist=-dist;
  110. *p_intersection = p_begin + segment * dist;
  111. return true;
  112. }
  113. /* misc */
  114. bool Plane::is_almost_like(const Plane& p_plane) const {
  115. return (normal.dot( p_plane.normal ) > _PLANE_EQ_DOT_EPSILON && Math::absd(d-p_plane.d) < _PLANE_EQ_D_EPSILON);
  116. }
  117. Plane::operator String() const {
  118. return normal.operator String() + ", " + rtos(d);
  119. }