@@ -817,6 +817,284 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
817817 rlEnd ();
818818}
819819
820+ // Draw a capsule with the center of its sphere caps at startPos and endPos
821+ void DrawCapsule (Vector3 startPos , Vector3 endPos , float radius , int slices , int rings , Color color )
822+ {
823+ if (slices < 3 ) slices = 3 ;
824+
825+ Vector3 direction = { endPos .x - startPos .x , endPos .y - startPos .y , endPos .z - startPos .z };
826+
827+ // draw a sphere if start and end points are the same
828+ bool sphereCase = (direction .x == 0 ) && (direction .y == 0 ) && (direction .z == 0 );
829+ if (sphereCase ) direction = (Vector3 ){0.0f , 1.0f , 0.0f };
830+
831+ // Construct a basis of the base and the caps:
832+ Vector3 b0 = Vector3Normalize (direction );
833+ Vector3 b1 = Vector3Normalize (Vector3Perpendicular (direction ));
834+ Vector3 b2 = Vector3Normalize (Vector3CrossProduct (b1 , direction ));
835+ Vector3 capCenter = endPos ;
836+
837+ float baseSliceAngle = (2.0f * PI )/slices ;
838+ float baseRingAngle = PI * 0.5 / rings ;
839+
840+ rlBegin (RL_TRIANGLES );
841+ rlColor4ub (color .r , color .g , color .b , color .a );
842+
843+ // render both caps
844+ for (int c = 0 ; c < 2 ; c ++ )
845+ {
846+ for (int i = 0 ; i < rings ; i ++ )
847+ {
848+ for (int j = 0 ; j < slices ; j ++ )
849+ {
850+
851+ // we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
852+
853+ // as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
854+ // as we iterate through the rings they must get smaller by the cos(angle(i))
855+
856+ // compute the four vertices
857+ float ringSin1 = sinf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 0 ));
858+ float ringCos1 = cosf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 0 ));
859+ Vector3 w1 = (Vector3 ){
860+ capCenter .x + (sinf (baseRingAngle * ( i + 0 ))* b0 .x + ringSin1 * b1 .x + ringCos1 * b2 .x ) * radius ,
861+ capCenter .y + (sinf (baseRingAngle * ( i + 0 ))* b0 .y + ringSin1 * b1 .y + ringCos1 * b2 .y ) * radius ,
862+ capCenter .z + (sinf (baseRingAngle * ( i + 0 ))* b0 .z + ringSin1 * b1 .z + ringCos1 * b2 .z ) * radius
863+ };
864+ float ringSin2 = sinf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 0 ));
865+ float ringCos2 = cosf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 0 ));
866+ Vector3 w2 = (Vector3 ){
867+ capCenter .x + (sinf (baseRingAngle * ( i + 0 ))* b0 .x + ringSin2 * b1 .x + ringCos2 * b2 .x ) * radius ,
868+ capCenter .y + (sinf (baseRingAngle * ( i + 0 ))* b0 .y + ringSin2 * b1 .y + ringCos2 * b2 .y ) * radius ,
869+ capCenter .z + (sinf (baseRingAngle * ( i + 0 ))* b0 .z + ringSin2 * b1 .z + ringCos2 * b2 .z ) * radius
870+ };
871+
872+ float ringSin3 = sinf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 1 ));
873+ float ringCos3 = cosf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 1 ));
874+ Vector3 w3 = (Vector3 ){
875+ capCenter .x + (sinf (baseRingAngle * ( i + 1 ))* b0 .x + ringSin3 * b1 .x + ringCos3 * b2 .x ) * radius ,
876+ capCenter .y + (sinf (baseRingAngle * ( i + 1 ))* b0 .y + ringSin3 * b1 .y + ringCos3 * b2 .y ) * radius ,
877+ capCenter .z + (sinf (baseRingAngle * ( i + 1 ))* b0 .z + ringSin3 * b1 .z + ringCos3 * b2 .z ) * radius
878+ };
879+ float ringSin4 = sinf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 1 ));
880+ float ringCos4 = cosf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 1 ));
881+ Vector3 w4 = (Vector3 ){
882+ capCenter .x + (sinf (baseRingAngle * ( i + 1 ))* b0 .x + ringSin4 * b1 .x + ringCos4 * b2 .x ) * radius ,
883+ capCenter .y + (sinf (baseRingAngle * ( i + 1 ))* b0 .y + ringSin4 * b1 .y + ringCos4 * b2 .y ) * radius ,
884+ capCenter .z + (sinf (baseRingAngle * ( i + 1 ))* b0 .z + ringSin4 * b1 .z + ringCos4 * b2 .z ) * radius
885+ };
886+
887+ // make sure cap triangle normals are facing outwards
888+ if (c == 0 )
889+ {
890+ rlVertex3f (w1 .x , w1 .y , w1 .z );
891+ rlVertex3f (w2 .x , w2 .y , w2 .z );
892+ rlVertex3f (w3 .x , w3 .y , w3 .z );
893+
894+ rlVertex3f (w2 .x , w2 .y , w2 .z );
895+ rlVertex3f (w4 .x , w4 .y , w4 .z );
896+ rlVertex3f (w3 .x , w3 .y , w3 .z );
897+ }
898+ else
899+ {
900+ rlVertex3f (w1 .x , w1 .y , w1 .z );
901+ rlVertex3f (w3 .x , w3 .y , w3 .z );
902+ rlVertex3f (w2 .x , w2 .y , w2 .z );
903+
904+ rlVertex3f (w2 .x , w2 .y , w2 .z );
905+ rlVertex3f (w3 .x , w3 .y , w3 .z );
906+ rlVertex3f (w4 .x , w4 .y , w4 .z );
907+ }
908+ }
909+ }
910+ capCenter = startPos ;
911+ b0 = Vector3Scale (b0 , -1.0f );
912+ }
913+ // render middle
914+ if (!sphereCase )
915+ {
916+ for (int j = 0 ; j < slices ; j ++ )
917+ {
918+ // compute the four vertices
919+ float ringSin1 = sinf (baseSliceAngle * (j + 0 ))* radius ;
920+ float ringCos1 = cosf (baseSliceAngle * (j + 0 ))* radius ;
921+ Vector3 w1 = {
922+ startPos .x + ringSin1 * b1 .x + ringCos1 * b2 .x ,
923+ startPos .y + ringSin1 * b1 .y + ringCos1 * b2 .y ,
924+ startPos .z + ringSin1 * b1 .z + ringCos1 * b2 .z
925+ };
926+ float ringSin2 = sinf (baseSliceAngle * (j + 1 ))* radius ;
927+ float ringCos2 = cosf (baseSliceAngle * (j + 1 ))* radius ;
928+ Vector3 w2 = {
929+ startPos .x + ringSin2 * b1 .x + ringCos2 * b2 .x ,
930+ startPos .y + ringSin2 * b1 .y + ringCos2 * b2 .y ,
931+ startPos .z + ringSin2 * b1 .z + ringCos2 * b2 .z
932+ };
933+
934+ float ringSin3 = sinf (baseSliceAngle * (j + 0 ))* radius ;
935+ float ringCos3 = cosf (baseSliceAngle * (j + 0 ))* radius ;
936+ Vector3 w3 = {
937+ endPos .x + ringSin3 * b1 .x + ringCos3 * b2 .x ,
938+ endPos .y + ringSin3 * b1 .y + ringCos3 * b2 .y ,
939+ endPos .z + ringSin3 * b1 .z + ringCos3 * b2 .z
940+ };
941+ float ringSin4 = sinf (baseSliceAngle * (j + 1 ))* radius ;
942+ float ringCos4 = cosf (baseSliceAngle * (j + 1 ))* radius ;
943+ Vector3 w4 = {
944+ endPos .x + ringSin4 * b1 .x + ringCos4 * b2 .x ,
945+ endPos .y + ringSin4 * b1 .y + ringCos4 * b2 .y ,
946+ endPos .z + ringSin4 * b1 .z + ringCos4 * b2 .z
947+ };
948+ // w2 x.-----------x startPos
949+ rlVertex3f (w1 .x , w1 .y , w1 .z ); // | |\'. T0 /
950+ rlVertex3f (w2 .x , w2 .y , w2 .z ); // T1 | \ '. /
951+ rlVertex3f (w3 .x , w3 .y , w3 .z ); // | |T \ '. /
952+ // | 2 \ T 'x w1
953+ rlVertex3f (w2 .x , w2 .y , w2 .z ); // | w4 x.---\-1-|---x endPos
954+ rlVertex3f (w4 .x , w4 .y , w4 .z ); // T2 '. \ |T3/
955+ rlVertex3f (w3 .x , w3 .y , w3 .z ); // | '. \ | /
956+ // '.\|/
957+ // 'x w3
958+ }
959+ }
960+ rlEnd ();
961+ }
962+
963+ // Draw capsule wires with the center of its sphere caps at startPos and endPos
964+ void DrawCapsuleWires (Vector3 startPos , Vector3 endPos , float radius , int slices , int rings , Color color )
965+ {
966+ if (slices < 3 ) slices = 3 ;
967+
968+ Vector3 direction = { endPos .x - startPos .x , endPos .y - startPos .y , endPos .z - startPos .z };
969+
970+ // draw a sphere if start and end points are the same
971+ bool sphereCase = (direction .x == 0 ) && (direction .y == 0 ) && (direction .z == 0 );
972+ if (sphereCase ) direction = (Vector3 ){0.0f , 1.0f , 0.0f };
973+
974+ // Construct a basis of the base and the caps:
975+ Vector3 b0 = Vector3Normalize (direction );
976+ Vector3 b1 = Vector3Normalize (Vector3Perpendicular (direction ));
977+ Vector3 b2 = Vector3Normalize (Vector3CrossProduct (b1 , direction ));
978+ Vector3 capCenter = endPos ;
979+
980+ float baseSliceAngle = (2.0f * PI )/slices ;
981+ float baseRingAngle = PI * 0.5 / rings ;
982+
983+ rlBegin (RL_LINES );
984+ rlColor4ub (color .r , color .g , color .b , color .a );
985+
986+ // render both caps
987+ for (int c = 0 ; c < 2 ; c ++ )
988+ {
989+ for (int i = 0 ; i < rings ; i ++ )
990+ {
991+ for (int j = 0 ; j < slices ; j ++ )
992+ {
993+
994+ // we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
995+
996+ // as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
997+ // as we iterate through the rings they must get smaller by the cos(angle(i))
998+
999+ // compute the four vertices
1000+ float ringSin1 = sinf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 0 ));
1001+ float ringCos1 = cosf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 0 ));
1002+ Vector3 w1 = (Vector3 ){
1003+ capCenter .x + (sinf (baseRingAngle * ( i + 0 ))* b0 .x + ringSin1 * b1 .x + ringCos1 * b2 .x ) * radius ,
1004+ capCenter .y + (sinf (baseRingAngle * ( i + 0 ))* b0 .y + ringSin1 * b1 .y + ringCos1 * b2 .y ) * radius ,
1005+ capCenter .z + (sinf (baseRingAngle * ( i + 0 ))* b0 .z + ringSin1 * b1 .z + ringCos1 * b2 .z ) * radius
1006+ };
1007+ float ringSin2 = sinf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 0 ));
1008+ float ringCos2 = cosf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 0 ));
1009+ Vector3 w2 = (Vector3 ){
1010+ capCenter .x + (sinf (baseRingAngle * ( i + 0 ))* b0 .x + ringSin2 * b1 .x + ringCos2 * b2 .x ) * radius ,
1011+ capCenter .y + (sinf (baseRingAngle * ( i + 0 ))* b0 .y + ringSin2 * b1 .y + ringCos2 * b2 .y ) * radius ,
1012+ capCenter .z + (sinf (baseRingAngle * ( i + 0 ))* b0 .z + ringSin2 * b1 .z + ringCos2 * b2 .z ) * radius
1013+ };
1014+
1015+ float ringSin3 = sinf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 1 ));
1016+ float ringCos3 = cosf (baseSliceAngle * (j + 0 ))* cosf (baseRingAngle * ( i + 1 ));
1017+ Vector3 w3 = (Vector3 ){
1018+ capCenter .x + (sinf (baseRingAngle * ( i + 1 ))* b0 .x + ringSin3 * b1 .x + ringCos3 * b2 .x ) * radius ,
1019+ capCenter .y + (sinf (baseRingAngle * ( i + 1 ))* b0 .y + ringSin3 * b1 .y + ringCos3 * b2 .y ) * radius ,
1020+ capCenter .z + (sinf (baseRingAngle * ( i + 1 ))* b0 .z + ringSin3 * b1 .z + ringCos3 * b2 .z ) * radius
1021+ };
1022+ float ringSin4 = sinf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 1 ));
1023+ float ringCos4 = cosf (baseSliceAngle * (j + 1 ))* cosf (baseRingAngle * ( i + 1 ));
1024+ Vector3 w4 = (Vector3 ){
1025+ capCenter .x + (sinf (baseRingAngle * ( i + 1 ))* b0 .x + ringSin4 * b1 .x + ringCos4 * b2 .x ) * radius ,
1026+ capCenter .y + (sinf (baseRingAngle * ( i + 1 ))* b0 .y + ringSin4 * b1 .y + ringCos4 * b2 .y ) * radius ,
1027+ capCenter .z + (sinf (baseRingAngle * ( i + 1 ))* b0 .z + ringSin4 * b1 .z + ringCos4 * b2 .z ) * radius
1028+ };
1029+
1030+ rlVertex3f (w1 .x , w1 .y , w1 .z );
1031+ rlVertex3f (w2 .x , w2 .y , w2 .z );
1032+
1033+ rlVertex3f (w2 .x , w2 .y , w2 .z );
1034+ rlVertex3f (w3 .x , w3 .y , w3 .z );
1035+
1036+ rlVertex3f (w1 .x , w1 .y , w1 .z );
1037+ rlVertex3f (w3 .x , w3 .y , w3 .z );
1038+
1039+ rlVertex3f (w2 .x , w2 .y , w2 .z );
1040+ rlVertex3f (w4 .x , w4 .y , w4 .z );
1041+
1042+ rlVertex3f (w3 .x , w3 .y , w3 .z );
1043+ rlVertex3f (w4 .x , w4 .y , w4 .z );
1044+ }
1045+ }
1046+ capCenter = startPos ;
1047+ b0 = Vector3Scale (b0 , -1.0f );
1048+ }
1049+ // render middle
1050+ if (!sphereCase )
1051+ {
1052+ for (int j = 0 ; j < slices ; j ++ )
1053+ {
1054+ // compute the four vertices
1055+ float ringSin1 = sinf (baseSliceAngle * (j + 0 ))* radius ;
1056+ float ringCos1 = cosf (baseSliceAngle * (j + 0 ))* radius ;
1057+ Vector3 w1 = {
1058+ startPos .x + ringSin1 * b1 .x + ringCos1 * b2 .x ,
1059+ startPos .y + ringSin1 * b1 .y + ringCos1 * b2 .y ,
1060+ startPos .z + ringSin1 * b1 .z + ringCos1 * b2 .z
1061+ };
1062+ float ringSin2 = sinf (baseSliceAngle * (j + 1 ))* radius ;
1063+ float ringCos2 = cosf (baseSliceAngle * (j + 1 ))* radius ;
1064+ Vector3 w2 = {
1065+ startPos .x + ringSin2 * b1 .x + ringCos2 * b2 .x ,
1066+ startPos .y + ringSin2 * b1 .y + ringCos2 * b2 .y ,
1067+ startPos .z + ringSin2 * b1 .z + ringCos2 * b2 .z
1068+ };
1069+
1070+ float ringSin3 = sinf (baseSliceAngle * (j + 0 ))* radius ;
1071+ float ringCos3 = cosf (baseSliceAngle * (j + 0 ))* radius ;
1072+ Vector3 w3 = {
1073+ endPos .x + ringSin3 * b1 .x + ringCos3 * b2 .x ,
1074+ endPos .y + ringSin3 * b1 .y + ringCos3 * b2 .y ,
1075+ endPos .z + ringSin3 * b1 .z + ringCos3 * b2 .z
1076+ };
1077+ float ringSin4 = sinf (baseSliceAngle * (j + 1 ))* radius ;
1078+ float ringCos4 = cosf (baseSliceAngle * (j + 1 ))* radius ;
1079+ Vector3 w4 = {
1080+ endPos .x + ringSin4 * b1 .x + ringCos4 * b2 .x ,
1081+ endPos .y + ringSin4 * b1 .y + ringCos4 * b2 .y ,
1082+ endPos .z + ringSin4 * b1 .z + ringCos4 * b2 .z
1083+ };
1084+
1085+ rlVertex3f (w1 .x , w1 .y , w1 .z );
1086+ rlVertex3f (w3 .x , w3 .y , w3 .z );
1087+
1088+ rlVertex3f (w2 .x , w2 .y , w2 .z );
1089+ rlVertex3f (w4 .x , w4 .y , w4 .z );
1090+
1091+ rlVertex3f (w2 .x , w2 .y , w2 .z );
1092+ rlVertex3f (w3 .x , w3 .y , w3 .z );
1093+ }
1094+ }
1095+ rlEnd ();
1096+ }
1097+
8201098// Draw a plane
8211099void DrawPlane (Vector3 centerPos , Vector2 size , Color color )
8221100{
0 commit comments