dRay_Box.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Ripped from Magic Software
  2. #include "Include\dRay.h"
  3. #include "dxRay.h"
  4. bool Clip(dReal Denom, dReal Numer, dReal& T0, dReal& T1){
  5. // Return value is 'true' if line segment intersects the current test
  6. // plane. Otherwise 'false' is returned in which case the line segment
  7. // is entirely clipped.
  8. if (Denom > REAL(0.0)){
  9. if (Numer > Denom * T1){
  10. return false;
  11. }
  12. if (Numer > Denom * T0){
  13. T0 = Numer / Denom;
  14. }
  15. return true;
  16. }
  17. else if (Denom < REAL(0.0)){
  18. if (Numer > Denom * T0){
  19. return false;
  20. }
  21. if (Numer > Denom * T1){
  22. T1 = Numer / Denom;
  23. }
  24. return true;
  25. }
  26. else return Numer <= REAL(0.0);
  27. }
  28. bool FindIntersection(const dVector3 Origin, const dVector3 Direction, const dVector3 Extents, dReal& T0, dReal& T1){
  29. dReal SaveT0 = T0;
  30. dReal SaveT1 = T1;
  31. bool NotEntirelyClipped =
  32. Clip(+Direction[0], -Origin[0] - Extents[0], T0, T1) &&
  33. Clip(-Direction[0], +Origin[0] - Extents[0], T0, T1) &&
  34. Clip(+Direction[1], -Origin[1] - Extents[1], T0, T1) &&
  35. Clip(-Direction[1], +Origin[1] - Extents[1], T0, T1) &&
  36. Clip(+Direction[2], -Origin[2] - Extents[2], T0, T1) &&
  37. Clip(-Direction[2], +Origin[2] - Extents[2], T0, T1);
  38. return NotEntirelyClipped && (T0 != SaveT0 || T1 != SaveT1);
  39. }
  40. int dCollideBR(dxGeom* RayGeom, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){
  41. const dVector3& Position = *(const dVector3*)dGeomGetPosition(BoxGeom);
  42. const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(BoxGeom);
  43. dVector3 Extents;
  44. dGeomBoxGetLengths(BoxGeom, Extents);
  45. Extents[0] /= 2;
  46. Extents[1] /= 2;
  47. Extents[2] /= 2;
  48. Extents[3] /= 2;
  49. dVector3 Origin, Direction;
  50. dGeomRayGet(RayGeom, Origin, Direction);
  51. dReal Length = dGeomRayGetLength(RayGeom);
  52. dVector3 Diff;
  53. Diff[0] = Origin[0] - Position[0];
  54. Diff[1] = Origin[1] - Position[1];
  55. Diff[2] = Origin[2] - Position[2];
  56. Diff[3] = Origin[3] - Position[3];
  57. Direction[0] *= Length;
  58. Direction[1] *= Length;
  59. Direction[2] *= Length;
  60. Direction[3] *= Length;
  61. dVector3 Rot[3];
  62. Decompose(Rotation, Rot);
  63. dVector3 TransOrigin;
  64. TransOrigin[0] = dDOT(Diff, Rot[0]);
  65. TransOrigin[1] = dDOT(Diff, Rot[1]);
  66. TransOrigin[2] = dDOT(Diff, Rot[2]);
  67. TransOrigin[3] = REAL(0.0);
  68. dVector3 TransDirection;
  69. TransDirection[0] = dDOT(Direction, Rot[0]);
  70. TransDirection[1] = dDOT(Direction, Rot[1]);
  71. TransDirection[2] = dDOT(Direction, Rot[2]);
  72. TransDirection[3] = REAL(0.0);
  73. dReal T[2];
  74. T[0] = 0.0f;
  75. T[1] = dInfinity;
  76. bool Intersect = FindIntersection(TransOrigin, TransDirection, Extents, T[0], T[1]);
  77. if (Intersect){
  78. if (T[0] > REAL(0.0)){
  79. dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride);
  80. Contact0->pos[0] = Origin[0] + T[0] * Direction[0];
  81. Contact0->pos[1] = Origin[1] + T[0] * Direction[1];
  82. Contact0->pos[2] = Origin[2] + T[0] * Direction[2];
  83. Contact0->pos[3] = Origin[3] + T[0] * Direction[3];
  84. //Contact0->normal = 0;
  85. Contact0->depth = 0.0f;
  86. Contact0->g1 = RayGeom;
  87. Contact0->g2 = BoxGeom;
  88. dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride);
  89. Contact1->pos[0] = Origin[0] + T[1] * Direction[0];
  90. Contact1->pos[1] = Origin[1] + T[1] * Direction[1];
  91. Contact1->pos[2] = Origin[2] + T[1] * Direction[2];
  92. Contact1->pos[3] = Origin[3] + T[1] * Direction[3];
  93. //Contact1->normal = 0;
  94. Contact1->depth = 0.0f;
  95. Contact1->g1 = RayGeom;
  96. Contact1->g2 = BoxGeom;
  97. return 2;
  98. }
  99. else{
  100. dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride);
  101. Contact->pos[0] = Origin[0] + T[1] * Direction[0];
  102. Contact->pos[1] = Origin[1] + T[1] * Direction[1];
  103. Contact->pos[2] = Origin[2] + T[1] * Direction[2];
  104. Contact->pos[3] = Origin[3] + T[1] * Direction[3];
  105. //Contact->normal = 0;
  106. Contact->depth = 0.0f;
  107. Contact->g1 = RayGeom;
  108. Contact->g2 = BoxGeom;
  109. return 1;
  110. }
  111. }
  112. else return 0;
  113. }