| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /******************************************************************************
- Use 'Capsule' to handle capsule shapes.
- /******************************************************************************/
- struct Capsule // Capsule Shape
- {
- Flt r , // radius
- h ; // total height
- Vec pos, // center position
- up ; // up direction
- // set
- 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;}
- Capsule& set (Flt r, C Vec &from, C Vec &to); // 'from' and 'to' are the bottom and top points of capsule
- Capsule& setEdge(Flt r, C Vec &from, C Vec &to); // 'from' and 'to' are the bottom and top points of capsule inner edge
- // get
- Flt area ()C {return PI2*r* h ;} // get surface area
- Flt volume()C {return PI *r*r*(h-r*(2.0f/3));} // get volume
- Vec pointD()C {return pos-up*(h*0.5f-r); } // get lower ball center point
- Vec pointU()C {return pos+up*(h*0.5f-r); } // get upper ball center point
- Ball ballD()C {return Ball(r, pointD()); } // get lower ball
- Ball ballU()C {return Ball(r, pointU()); } // get upper ball
- Edge edge ()C {return Edge(pointD(), pointU());} // get edge between lower and upper ball center points
- Vec nearest(C Vec &normal)C; // get nearest point on capsule towards normal
- Bool isBall()C {return h<=r*2+EPS;} // if this capsule is actually a ball (total height is smaller than 2*radius)
- Str asText()C {return S+"Radius: "+r+", Height: "+h+", Pos: "+pos+", Up: "+up;} // get text description
- // transform
- Capsule& operator+=(C Vec &v) {pos+=v; return T;}
- Capsule& operator-=(C Vec &v) {pos-=v; return T;}
- Capsule& operator*=( Flt f);
- Capsule& operator/=( Flt f);
- Capsule& operator*=(C Vec &v);
- Capsule& operator/=(C Vec &v);
- Capsule& operator*=(C Matrix3 &m);
- Capsule& operator/=(C Matrix3 &m);
- Capsule& operator*=(C Matrix &m);
- Capsule& operator/=(C Matrix &m);
- friend Capsule operator+ (C Capsule &capsule, C Vec &v) {return Capsule(capsule)+=v;}
- friend Capsule operator- (C Capsule &capsule, C Vec &v) {return Capsule(capsule)-=v;}
- friend Capsule operator* (C Capsule &capsule, Flt f) {return Capsule(capsule)*=f;}
- friend Capsule operator/ (C Capsule &capsule, Flt f) {return Capsule(capsule)/=f;}
- friend Capsule operator* (C Capsule &capsule, C Vec &v) {return Capsule(capsule)*=v;}
- friend Capsule operator/ (C Capsule &capsule, C Vec &v) {return Capsule(capsule)/=v;}
- friend Capsule operator* (C Capsule &capsule, C Matrix3 &m) {return Capsule(capsule)*=m;}
- friend Capsule operator/ (C Capsule &capsule, C Matrix3 &m) {return Capsule(capsule)/=m;}
- friend Capsule operator* (C Capsule &capsule, C Matrix &m) {return Capsule(capsule)*=m;}
- friend Capsule operator/ (C Capsule &capsule, C Matrix &m) {return Capsule(capsule)/=m;}
- // operations
- Capsule& extend(Flt e) {r+=e; h+=e+e; return T;} // extend
- // draw
- 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
- Capsule() {}
- Capsule(Flt r, Flt h , C Vec &pos=VecZero, C Vec &up=Vec(0,1,0)) {set(r, h, pos , up);}
- Capsule(Flt r, C Vec &from, C Vec &to ) {set(r, from, to);}
- };
- /******************************************************************************/
- struct CapsuleM // Capsule Shape (mixed precision)
- {
- Flt r , // radius
- h ; // total height
- VecD pos; // center position
- Vec up ; // up direction
- // set
- 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;}
- // get
- Flt area ()C {return PI2*r* h ;} // get surface area
- Flt volume()C {return PI *r*r*(h-r*(2.0f/3));} // get volume
- VecD pointD()C {return pos-up*(h*0.5f-r); } // get lower ball center point
- VecD pointU()C {return pos+up*(h*0.5f-r); } // get upper ball center point
- BallM ballD()C {return BallM(r, pointD()); } // get lower ball
- BallM ballU()C {return BallM(r, pointU()); } // get upper ball
- EdgeD edge ()C {return EdgeD(pointD(), pointU());} // get edge between lower and upper ball center points
- VecD nearest(C Vec &normal)C; // get nearest point on capsule towards normal
- Bool isBall()C {return h<=r*2+EPS;} // if this capsule is actually a ball (total height is smaller than 2*radius)
- Str asText()C {return S+"Radius: "+r+", Height: "+h+", Pos: "+pos+", Up: "+up;} // get text description
- // transform
- CapsuleM& operator+=(C VecD &v) {pos+=v; return T;}
- CapsuleM& operator-=(C VecD &v) {pos-=v; return T;}
- CapsuleM& operator*=( Flt f);
- CapsuleM& operator/=( Flt f);
- CapsuleM& operator*=(C Vec &v);
- CapsuleM& operator/=(C Vec &v);
- friend CapsuleM operator+ (C CapsuleM &capsule, C VecD &v) {return CapsuleM(capsule)+=v;}
- friend CapsuleM operator- (C CapsuleM &capsule, C VecD &v) {return CapsuleM(capsule)-=v;}
- friend CapsuleM operator* (C CapsuleM &capsule, Flt f) {return CapsuleM(capsule)*=f;}
- friend CapsuleM operator/ (C CapsuleM &capsule, Flt f) {return CapsuleM(capsule)/=f;}
- friend CapsuleM operator* (C CapsuleM &capsule, C Vec &v) {return CapsuleM(capsule)*=v;}
- friend CapsuleM operator/ (C CapsuleM &capsule, C Vec &v) {return CapsuleM(capsule)/=v;}
- CapsuleM() {}
- CapsuleM(Flt r, Flt h, C VecD &pos=0, C Vec &up=Vec(0,1,0)) {set(r, h, pos , up);}
- };
- /******************************************************************************/
- // distance
- Flt Dist (C Vec &point , C Capsule &capsule ); // distance between point and a capsule
- Flt Dist (C Edge &edge , C Capsule &capsule ); // distance between edge and a capsule
- Flt Dist (C Tri &tri , C Capsule &capsule ); // distance between triangle and a capsule
- Flt Dist (C Box &box , C Capsule &capsule ); // distance between box and a capsule
- Flt Dist (C OBox &obox , C Capsule &capsule ); // distance between box and a capsule
- Flt Dist (C Ball &ball , C Capsule &capsule ); // distance between ball and a capsule
- Flt Dist (C Capsule &a , C Capsule &b ); // distance between capsule and a capsule
- Flt DistCapsulePlane(C Capsule &capsule, C Vec &plane, C Vec &normal); // distance between capsule and a plane
- Dbl DistCapsulePlane(C Capsule &capsule, C VecD &plane, C Vec &normal); // distance between capsule and a plane
- Dbl DistCapsulePlane(C CapsuleM &capsule, C VecD &plane, C Vec &normal); // distance between capsule and a plane
- inline Flt Dist (C Capsule &capsule, C Plane &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
- inline Dbl Dist (C Capsule &capsule, C PlaneM &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
- inline Dbl Dist (C CapsuleM &capsule, C PlaneM &plane ) {return DistCapsulePlane(capsule, plane.pos, plane.normal);} // distance between capsule and a plane
- // cuts
- Bool Cuts(C Vec &point, C Capsule &capsule); // if point cuts a capsule
- Bool Cuts(C VecD &point, C Capsule &capsule); // if point cuts a capsule
- Bool Cuts(C VecD &point, C CapsuleM &capsule); // if point cuts a capsule
- Bool Cuts(C Edge &edge , C Capsule &capsule); // if edge cuts a capsule
- Bool Cuts(C Tri &tri , C Capsule &capsule); // if triangle cuts a capsule
- Bool Cuts(C Box &box , C Capsule &capsule); // if box cuts a capsule
- Bool Cuts(C OBox &obox , C Capsule &capsule); // if box cuts a capsule
- Bool Cuts(C Ball &ball , C Capsule &capsule); // if ball cuts a capsule
- Bool Cuts(C Capsule &a , C Capsule &b ); // if capsule cuts a capsule
- // sweep
- 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
- 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
- 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
- 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
- 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
- /******************************************************************************/
|