dRay_Sphere.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Ripped from Magic Software
  2. #include "Include\dRay.h"
  3. #include "dxRay.h"
  4. int dCollideSR(dxGeom* RayGeom, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){
  5. const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom);
  6. dReal Radius = dGeomSphereGetRadius(SphereGeom);
  7. dVector3 Origin, Direction;
  8. dGeomRayGet(RayGeom, Origin, Direction);
  9. dReal Length = dGeomRayGetLength(RayGeom);
  10. dVector3 Diff;
  11. Diff[0] = Origin[0] - Position[0];
  12. Diff[1] = Origin[1] - Position[1];
  13. Diff[2] = Origin[2] - Position[2];
  14. Diff[3] = Origin[3] - Position[3];
  15. Direction[0] *= Length;
  16. Direction[1] *= Length;
  17. Direction[2] *= Length;
  18. Direction[3] *= Length;
  19. dReal A = Length * Length;
  20. dReal B = dDOT(Diff, Direction);
  21. dReal C = dDOT(Diff, Diff) - (Radius * Radius);
  22. dReal Discr = B * B - A * C;
  23. if (Discr < REAL(0.0)){
  24. return 0;
  25. }
  26. else if (Discr > REAL(0.0)){
  27. dReal T[2];
  28. dReal Root = dSqrt(Discr);
  29. dReal InvA = REAL(1.0) / A;
  30. T[0] = (-B - Root) * InvA;
  31. T[1] = (-B + Root) * InvA;
  32. if (T[0] >= REAL(0.0)){
  33. dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride);
  34. Contact0->pos[0] = Origin[0] + T[0] * Direction[0];
  35. Contact0->pos[1] = Origin[1] + T[0] * Direction[1];
  36. Contact0->pos[2] = Origin[2] + T[0] * Direction[2];
  37. Contact0->pos[3] = Origin[3] + T[0] * Direction[3];
  38. //Contact0->normal = 0;
  39. Contact0->depth = 0.0f;
  40. Contact0->g1 = RayGeom;
  41. Contact0->g2 = SphereGeom;
  42. dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride);
  43. Contact1->pos[0] = Origin[0] + T[1] * Direction[0];
  44. Contact1->pos[1] = Origin[1] + T[1] * Direction[1];
  45. Contact1->pos[2] = Origin[2] + T[1] * Direction[2];
  46. Contact1->pos[3] = Origin[3] + T[1] * Direction[3];
  47. //Contact1->normal = 0;
  48. Contact1->depth = 0.0f;
  49. Contact1->g1 = RayGeom;
  50. Contact1->g2 = SphereGeom;
  51. return 2;
  52. }
  53. else if (T[1] >= REAL(0.0)){
  54. dContactGeom* Contact = CONTACT(Flags, Contacts, 1, Stride);
  55. Contact->pos[0] = Origin[0] + T[1] * Direction[0];
  56. Contact->pos[1] = Origin[1] + T[1] * Direction[1];
  57. Contact->pos[2] = Origin[2] + T[1] * Direction[2];
  58. Contact->pos[3] = Origin[3] + T[1] * Direction[3];
  59. //Contact->normal = 0;
  60. Contact->depth = 0.0f;
  61. Contact->g1 = RayGeom;
  62. Contact->g2 = SphereGeom;
  63. return 1;
  64. }
  65. else return 0;
  66. }
  67. else{
  68. dReal T;
  69. T = -B / A;
  70. if (T >= REAL(0.0)){
  71. dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride);
  72. Contact->pos[0] = Origin[0] + T * Direction[0];
  73. Contact->pos[1] = Origin[1] + T * Direction[1];
  74. Contact->pos[2] = Origin[2] + T * Direction[2];
  75. Contact->pos[3] = Origin[3] + T * Direction[3];
  76. //Contact->normal = 0;
  77. Contact->depth = 0.0f;
  78. Contact->g1 = RayGeom;
  79. Contact->g2 = SphereGeom;
  80. return 1;
  81. }
  82. else return 0;
  83. }
  84. }