Capsule.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /******************************************************************************
  2. Use 'Capsule' to handle capsule shapes.
  3. /******************************************************************************/
  4. struct Capsule // Capsule Shape
  5. {
  6. Flt r , // radius
  7. h ; // total height
  8. Vec pos, // center position
  9. up ; // up direction
  10. // set
  11. Capsule& set (Flt r, Flt h , C Vec &pos=VecZero, C Vec &up=Vec(0,1,0)) {T.r=r; T.h=h; T.pos=pos; T.up=up; return T;}
  12. Capsule& set (Flt r, C Vec &from, C Vec &to); // 'from' and 'to' are the bottom and top points of capsule
  13. Capsule& setEdge(Flt r, C Vec &from, C Vec &to); // 'from' and 'to' are the bottom and top points of capsule inner edge
  14. // get
  15. Flt area ()C {return PI2*r* h ;} // get surface area
  16. Flt volume()C {return PI *r*r*(h-r*(2.0f/3));} // get volume
  17. Vec pointD()C {return pos-up*(h*0.5f-r); } // get lower ball center point
  18. Vec pointU()C {return pos+up*(h*0.5f-r); } // get upper ball center point
  19. Ball ballD()C {return Ball(r, pointD()); } // get lower ball
  20. Ball ballU()C {return Ball(r, pointU()); } // get upper ball
  21. Edge edge ()C {return Edge(pointD(), pointU());} // get edge between lower and upper ball center points
  22. Vec nearest(C Vec &normal)C; // get nearest point on capsule towards normal
  23. Bool isBall()C {return h<=r*2+EPS;} // if this capsule is actually a ball (total height is smaller than 2*radius)
  24. Str asText()C {return S+"Radius: "+r+", Height: "+h+", Pos: "+pos+", Up: "+up;} // get text description
  25. // transform
  26. Capsule& operator+=(C Vec &v) {pos+=v; return T;}
  27. Capsule& operator-=(C Vec &v) {pos-=v; return T;}
  28. Capsule& operator*=( Flt f);
  29. Capsule& operator/=( Flt f);
  30. Capsule& operator*=(C Vec &v);
  31. Capsule& operator/=(C Vec &v);
  32. Capsule& operator*=(C Matrix3 &m);
  33. Capsule& operator/=(C Matrix3 &m);
  34. Capsule& operator*=(C Matrix &m);
  35. Capsule& operator/=(C Matrix &m);
  36. friend Capsule operator+ (C Capsule &capsule, C Vec &v) {return Capsule(capsule)+=v;}
  37. friend Capsule operator- (C Capsule &capsule, C Vec &v) {return Capsule(capsule)-=v;}
  38. friend Capsule operator* (C Capsule &capsule, Flt f) {return Capsule(capsule)*=f;}
  39. friend Capsule operator/ (C Capsule &capsule, Flt f) {return Capsule(capsule)/=f;}
  40. friend Capsule operator* (C Capsule &capsule, C Vec &v) {return Capsule(capsule)*=v;}
  41. friend Capsule operator/ (C Capsule &capsule, C Vec &v) {return Capsule(capsule)/=v;}
  42. friend Capsule operator* (C Capsule &capsule, C Matrix3 &m) {return Capsule(capsule)*=m;}
  43. friend Capsule operator/ (C Capsule &capsule, C Matrix3 &m) {return Capsule(capsule)/=m;}
  44. friend Capsule operator* (C Capsule &capsule, C Matrix &m) {return Capsule(capsule)*=m;}
  45. friend Capsule operator/ (C Capsule &capsule, C Matrix &m) {return Capsule(capsule)/=m;}
  46. // operations
  47. Capsule& extend(Flt e) {r+=e; h+=e+e; return T;} // extend
  48. // draw
  49. void draw(C Color &color=WHITE, Bool fill=false, Int resolution=-1)C; // this relies on active object matrix which can be set using 'SetMatrix' function
  50. Capsule() {}
  51. Capsule(Flt r, Flt h , C Vec &pos=VecZero, C Vec &up=Vec(0,1,0)) {set(r, h, pos , up);}
  52. Capsule(Flt r, C Vec &from, C Vec &to ) {set(r, from, to);}
  53. };
  54. /******************************************************************************/
  55. struct CapsuleM // Capsule Shape (mixed precision)
  56. {
  57. Flt r , // radius
  58. h ; // total height
  59. VecD pos; // center position
  60. Vec up ; // up direction
  61. // set
  62. CapsuleM& set(Flt r, Flt h, C VecD &pos=0, C Vec &up=Vec(0,1,0)) {T.r=r; T.h=h; T.pos=pos; T.up=up; return T;}
  63. // get
  64. Flt area ()C {return PI2*r* h ;} // get surface area
  65. Flt volume()C {return PI *r*r*(h-r*(2.0f/3));} // get volume
  66. VecD pointD()C {return pos-up*(h*0.5f-r); } // get lower ball center point
  67. VecD pointU()C {return pos+up*(h*0.5f-r); } // get upper ball center point
  68. BallM ballD()C {return BallM(r, pointD()); } // get lower ball
  69. BallM ballU()C {return BallM(r, pointU()); } // get upper ball
  70. EdgeD edge ()C {return EdgeD(pointD(), pointU());} // get edge between lower and upper ball center points
  71. VecD nearest(C Vec &normal)C; // get nearest point on capsule towards normal
  72. Bool isBall()C {return h<=r*2+EPS;} // if this capsule is actually a ball (total height is smaller than 2*radius)
  73. Str asText()C {return S+"Radius: "+r+", Height: "+h+", Pos: "+pos+", Up: "+up;} // get text description
  74. // transform
  75. CapsuleM& operator+=(C VecD &v) {pos+=v; return T;}
  76. CapsuleM& operator-=(C VecD &v) {pos-=v; return T;}
  77. CapsuleM& operator*=( Flt f);
  78. CapsuleM& operator/=( Flt f);
  79. CapsuleM& operator*=(C Vec &v);
  80. CapsuleM& operator/=(C Vec &v);
  81. friend CapsuleM operator+ (C CapsuleM &capsule, C VecD &v) {return CapsuleM(capsule)+=v;}
  82. friend CapsuleM operator- (C CapsuleM &capsule, C VecD &v) {return CapsuleM(capsule)-=v;}
  83. friend CapsuleM operator* (C CapsuleM &capsule, Flt f) {return CapsuleM(capsule)*=f;}
  84. friend CapsuleM operator/ (C CapsuleM &capsule, Flt f) {return CapsuleM(capsule)/=f;}
  85. friend CapsuleM operator* (C CapsuleM &capsule, C Vec &v) {return CapsuleM(capsule)*=v;}
  86. friend CapsuleM operator/ (C CapsuleM &capsule, C Vec &v) {return CapsuleM(capsule)/=v;}
  87. CapsuleM() {}
  88. CapsuleM(Flt r, Flt h, C VecD &pos=0, C Vec &up=Vec(0,1,0)) {set(r, h, pos , up);}
  89. };
  90. /******************************************************************************/
  91. // distance
  92. Flt Dist (C Vec &point , C Capsule &capsule ); // distance between point and a capsule
  93. Flt Dist (C Edge &edge , C Capsule &capsule ); // distance between edge and a capsule
  94. Flt Dist (C Tri &tri , C Capsule &capsule ); // distance between triangle and a capsule
  95. Flt Dist (C Box &box , C Capsule &capsule ); // distance between box and a capsule
  96. Flt Dist (C OBox &obox , C Capsule &capsule ); // distance between box and a capsule
  97. Flt Dist (C Ball &ball , C Capsule &capsule ); // distance between ball and a capsule
  98. Flt Dist (C Capsule &a , C Capsule &b ); // distance between capsule and a capsule
  99. Flt DistCapsulePlane(C Capsule &capsule, C Vec &plane, C Vec &normal); // distance between capsule and a plane
  100. Dbl DistCapsulePlane(C Capsule &capsule, C VecD &plane, C Vec &normal); // distance between capsule and a plane
  101. Dbl DistCapsulePlane(C CapsuleM &capsule, C VecD &plane, C Vec &normal); // distance between capsule and a plane
  102. inline Flt Dist (C Capsule &capsule, C Plane &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
  103. inline Dbl Dist (C Capsule &capsule, C PlaneM &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
  104. inline Dbl Dist (C CapsuleM &capsule, C PlaneM &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
  105. // cuts
  106. Bool Cuts(C Vec &point, C Capsule &capsule); // if point cuts a capsule
  107. Bool Cuts(C VecD &point, C Capsule &capsule); // if point cuts a capsule
  108. Bool Cuts(C VecD &point, C CapsuleM &capsule); // if point cuts a capsule
  109. Bool Cuts(C Edge &edge , C Capsule &capsule); // if edge cuts a capsule
  110. Bool Cuts(C Tri &tri , C Capsule &capsule); // if triangle cuts a capsule
  111. Bool Cuts(C Box &box , C Capsule &capsule); // if box cuts a capsule
  112. Bool Cuts(C OBox &obox , C Capsule &capsule); // if box cuts a capsule
  113. Bool Cuts(C Ball &ball , C Capsule &capsule); // if ball cuts a capsule
  114. Bool Cuts(C Capsule &a , C Capsule &b ); // if capsule cuts a capsule
  115. // sweep
  116. Bool SweepPointCapsule(C Vec &point, C Vec &move, C Capsule &capsule, Flt *hit_frac=null, Vec *hit_normal=null); // if moving point cuts through a static capsule
  117. Bool SweepBallCapsule (C Ball &ball , C Vec &move, C Capsule &capsule, Flt *hit_frac=null, Vec *hit_normal=null); // if moving ball cuts through a static capsule
  118. Bool SweepCapsuleEdge (C Capsule &capsule, C Vec &move, C Edge &edge , Flt *hit_frac=null, Vec *hit_normal=null ); // if moving capsule cuts through a static edge
  119. Bool SweepCapsulePlane(C Capsule &capsule, C Vec &move, C Plane &plane, Flt *hit_frac=null, Vec *hit_normal=null, Vec *hit_pos=null); // if moving capsule cuts through a static plane
  120. Bool SweepCapsuleTri (C Capsule &capsule, C Vec &move, C Tri &tri , Flt *hit_frac=null, Vec *hit_normal=null ); // if moving capsule cuts through a static triangle
  121. /******************************************************************************/