thecplusplusguy

OpenGL (SDL,C++) - 3d collision detection - functions.cpp

Oct 14th, 2011
3,021
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.48 KB | None | 0 0
  1. /*3d Collision detection (sphere-sphere, plane-sphere), I only upload the functions.cpp, the functions.h and third.cpp, the rest of the files are not changed. The third.cpp already contain the material of the next tutorial, because I recordedit after this one.
  2. http://www.youtube.com/user/thecplusplusguy
  3. */
  4. #include "functions.h"
  5.  
  6. float camX=0.0,camY=0.0,camZ=5.0;
  7. float camYaw=0.0;
  8. float camPitch=0.0;
  9. enum {SKY_LEFT=0,SKY_BACK,SKY_RIGHT,SKY_FRONT,SKY_TOP,SKY_BOTTOM};
  10. unsigned int skybox[6];
  11. #ifndef M_PI
  12. #define M_PI 3.1415926535
  13. #endif
  14.  
  15.  
  16. void initskybox()
  17. {
  18.     skybox[SKY_LEFT]=loadTexture("left.bmp");
  19.     skybox[SKY_BACK]=loadTexture("back.bmp");
  20.     skybox[SKY_RIGHT]=loadTexture("right.bmp");
  21.     skybox[SKY_FRONT]=loadTexture("front.bmp");
  22.     skybox[SKY_TOP]=loadTexture("top.bmp");
  23.     skybox[SKY_BOTTOM]=loadTexture("bottom.bmp");
  24. }
  25.  
  26. void killskybox()
  27. {
  28.     glDeleteTextures(6,&skybox[0]);
  29. }
  30.  
  31. void lockCamera()
  32. {
  33.     if(camPitch>90)
  34.         camPitch=90;
  35.     if(camPitch<-90)
  36.         camPitch=-90;
  37.     if(camYaw<0.0)
  38.         camYaw+=360.0;
  39.     if(camYaw>360.0)
  40.         camYaw-=360;
  41. }
  42.  
  43. void moveCamera(float dist,float dir)
  44. {
  45.     float rad=(camYaw+dir)*M_PI/180.0;
  46.     camX-=sin(rad)*dist;
  47.     camZ-=cos(rad)*dist;
  48. }
  49.  
  50. void moveCameraUp(float dist,float dir)
  51. {
  52.     float rad=(camPitch+dir)*M_PI/180.0;
  53.     camY+=sin(rad)*dist;   
  54. }
  55.  
  56. void Control(float movevel,float mousevel,bool mi)
  57. {
  58.     if(mi)
  59.     {
  60.         int MidX=320;
  61.         int MidY=240;
  62.         SDL_ShowCursor(SDL_DISABLE);
  63.         int tmpx,tmpy;
  64.         SDL_GetMouseState(&tmpx,&tmpy);
  65.         camYaw+=mousevel*(MidX-tmpx);
  66.         camPitch+=mousevel*(MidY-tmpy);
  67.         lockCamera();
  68.         SDL_WarpMouse(MidX,MidY);
  69.         Uint8* state=SDL_GetKeyState(NULL);
  70.         if(state[SDLK_w])
  71.         {
  72.             if(camPitch!=90 && camPitch!=-90)
  73.                 moveCamera(movevel,0.0);
  74.             moveCameraUp(movevel,0.0);
  75.         }else if(state[SDLK_s])
  76.         {
  77.             if(camPitch!=90 && camPitch!=-90)
  78.                 moveCamera(movevel,180.0);
  79.             moveCameraUp(movevel,180.0);
  80.         }      
  81.         if(state[SDLK_a])
  82.             moveCamera(movevel,90.0);
  83.         else if(state[SDLK_d])
  84.             moveCamera(movevel,270);   
  85.     }
  86.     glRotatef(-camPitch,1.0,0.0,0.0);
  87.     glRotatef(-camYaw,0.0,1.0,0.0);
  88. }
  89.  
  90. void UpdateCamera()
  91. {
  92.     glTranslatef(-camX,-camY,-camZ);
  93. }
  94.  
  95. void drawCube(float size)
  96. {
  97.     float difamb[]={1.0,0.5,0.3,1.0};
  98.     glBegin(GL_QUADS);
  99.         //front face
  100.         glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,difamb);
  101.         glNormal3f(0.0,0.0,1.0);
  102.         glVertex3f(size/2,size/2,size/2);
  103.         glVertex3f(-size/2,size/2,size/2);
  104.         glVertex3f(-size/2,-size/2,size/2);
  105.         glVertex3f(size/2,-size/2,size/2);
  106.  
  107.         //left face
  108.         glNormal3f(-1.0,0.0,0.0);
  109.         glVertex3f(-size/2,size/2,size/2);
  110.         glVertex3f(-size/2,size/2,-size/2);
  111.         glVertex3f(-size/2,-size/2,-size/2);
  112.         glVertex3f(-size/2,-size/2,size/2);
  113.  
  114.         //back face
  115.         glNormal3f(0.0,0.0,-1.0);
  116.         glVertex3f(size/2,size/2,-size/2);
  117.         glVertex3f(-size/2,size/2,-size/2);
  118.         glVertex3f(-size/2,-size/2,-size/2);
  119.         glVertex3f(size/2,-size/2,-size/2);
  120.  
  121.         //right face
  122.         glNormal3f(1.0,0.0,0.0);
  123.         glVertex3f(size/2,size/2,-size/2);
  124.         glVertex3f(size/2,size/2,size/2);
  125.         glVertex3f(size/2,-size/2,size/2);
  126.         glVertex3f(size/2,-size/2,-size/2);
  127.  
  128.         //top face
  129.         glNormal3f(0.0,1.0,0.0);
  130.         glVertex3f(size/2,size/2,size/2);
  131.         glVertex3f(-size/2,size/2,size/2);
  132.         glVertex3f(-size/2,size/2,-size/2);
  133.         glVertex3f(size/2,size/2,-size/2);
  134.  
  135.         //bottom face
  136.         glNormal3f(0.0,-1.0,0.0);
  137.         glVertex3f(size/2,-size/2,size/2);
  138.         glVertex3f(-size/2,-size/2,size/2);
  139.         glVertex3f(-size/2,-size/2,-size/2);
  140.         glVertex3f(size/2,-size/2,-size/2);
  141.     glEnd();
  142. }
  143.  
  144. void drawSkybox(float size)
  145. {
  146.     glDisable(GL_LIGHTING);
  147.     glDisable(GL_DEPTH_TEST);
  148.     glEnable(GL_TEXTURE_2D);
  149.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_BACK]);
  150.     glBegin(GL_QUADS);
  151.         //back face
  152.         glTexCoord2f(0,0);
  153.         glVertex3f(size/2,size/2,size/2);
  154.         glTexCoord2f(1,0);
  155.         glVertex3f(-size/2,size/2,size/2);
  156.         glTexCoord2f(1,1);
  157.         glVertex3f(-size/2,-size/2,size/2);
  158.         glTexCoord2f(0,1);
  159.         glVertex3f(size/2,-size/2,size/2);
  160.     glEnd();
  161.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_LEFT]);
  162.     glBegin(GL_QUADS); 
  163.         //left face
  164.         glTexCoord2f(0,0);
  165.         glVertex3f(-size/2,size/2,size/2);
  166.         glTexCoord2f(1,0);
  167.         glVertex3f(-size/2,size/2,-size/2);
  168.         glTexCoord2f(1,1);
  169.         glVertex3f(-size/2,-size/2,-size/2);
  170.         glTexCoord2f(0,1);
  171.         glVertex3f(-size/2,-size/2,size/2);
  172.     glEnd();
  173.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_FRONT]);
  174.     glBegin(GL_QUADS); 
  175.         //front face
  176.         glTexCoord2f(1,0);
  177.         glVertex3f(size/2,size/2,-size/2);
  178.         glTexCoord2f(0,0);
  179.         glVertex3f(-size/2,size/2,-size/2);
  180.         glTexCoord2f(0,1);
  181.         glVertex3f(-size/2,-size/2,-size/2);
  182.         glTexCoord2f(1,1);
  183.         glVertex3f(size/2,-size/2,-size/2);
  184.     glEnd();
  185.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_RIGHT]);
  186.     glBegin(GL_QUADS); 
  187.         //right face
  188.         glTexCoord2f(0,0);
  189.         glVertex3f(size/2,size/2,-size/2);
  190.         glTexCoord2f(1,0);
  191.         glVertex3f(size/2,size/2,size/2);
  192.         glTexCoord2f(1,1);
  193.         glVertex3f(size/2,-size/2,size/2);
  194.         glTexCoord2f(0,1);
  195.         glVertex3f(size/2,-size/2,-size/2);
  196.     glEnd();
  197.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_TOP]);      
  198.     glBegin(GL_QUADS);          //top face
  199.         glTexCoord2f(1,0);
  200.         glVertex3f(size/2,size/2,size/2);
  201.         glTexCoord2f(0,0);
  202.         glVertex3f(-size/2,size/2,size/2);
  203.         glTexCoord2f(0,1);
  204.         glVertex3f(-size/2,size/2,-size/2);
  205.         glTexCoord2f(1,1);
  206.         glVertex3f(size/2,size/2,-size/2);
  207.     glEnd();
  208.     glBindTexture(GL_TEXTURE_2D,skybox[SKY_BOTTOM]);       
  209.     glBegin(GL_QUADS); 
  210.         //bottom face
  211.         glTexCoord2f(1,1);
  212.         glVertex3f(size/2,-size/2,size/2);
  213.         glTexCoord2f(0,1);
  214.         glVertex3f(-size/2,-size/2,size/2);
  215.         glTexCoord2f(0,0);
  216.         glVertex3f(-size/2,-size/2,-size/2);
  217.         glTexCoord2f(1,0);
  218.         glVertex3f(size/2,-size/2,-size/2);
  219.     glEnd();
  220.     glEnable(GL_LIGHTING);
  221.     glEnable(GL_DEPTH_TEST);
  222.     glDisable(GL_TEXTURE_2D);
  223. }
  224.  
  225. bool raysphere(float xc,float yc, float zc,float xd,float yd, float zd,float xs,float ys, float zs,float r,float* dist,coordinate* point)
  226. {
  227.     float b=2*(xd*(xs-xc)+yd*(ys-yc)+zd*(zs-zc));
  228.     float c=xs*xs-2*xs*xc+xc*xc+ys*ys-2*ys*yc+yc*yc+zs*zs-2*zs*zc+zc*zc-r*r;
  229.     float disc=(b*b-4*c);
  230.     if(disc<0)
  231.         return false;
  232.     if(dist!=NULL)
  233.     {
  234.         //-b+disc/2
  235.         (*dist)=(-b+disc)/2;
  236.         if(point!=NULL)
  237.         {
  238.             //xs+t*xd
  239.             point->x=xs+(*dist)*xd;
  240.             point->y=ys+(*dist)*yd;
  241.             point->z=zs+(*dist)*zd;
  242.         }
  243.     }
  244.     return true;
  245.         //(x+y)^2=x^2+2xy+y^2
  246. }
  247.  
  248. bool rayplane(float nx,float ny,float nz,float xs,float ys,float zs,float xd,float yd,float zd,coordinate p1,coordinate p2,coordinate p3,coordinate p4,float* dist,coordinate* point)
  249. {
  250.     float a=xd*nx+yd*ny+zd*nz;
  251.     if(a==0)
  252.         return false;
  253.     float t=((p1.x*nx+p1.y*ny+p1.z*nz-nx*xs-ny*ys-nz*zs)/a);
  254.     if(t<0)
  255.         return false;
  256.     float x=xs+t*xd;
  257.     float y=ys+t*yd;
  258.     float z=zs+t*zd;
  259.     coordinate cp(x,y,z);
  260.     if(abs(trianglearea(p1,p3,p4)-trianglearea(p1,p4,cp)-trianglearea(p1,p3,cp)-trianglearea(p3,p4,cp))<0.000001 || abs(trianglearea(p1,p2,p3)-trianglearea(p1,p2,cp)-trianglearea(p2,p3,cp)-trianglearea(p1,p3,cp))<0.000001)
  261.     {
  262.         if(dist!=NULL)
  263.         {
  264.             (*dist)=t;
  265.             if(point!=NULL)
  266.             {
  267.                 point->x=x;
  268.                 point->y=y;
  269.                 point->z=z;
  270.             }
  271.         }
  272.         return true;
  273.     }
  274.     return false;
  275. }
  276.  
  277.  
  278. float trianglearea(coordinate p1,coordinate p2,coordinate p3)
  279. {
  280.         //area of the triangle with the heron fomula
  281.         float a=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*(p2.z-p1.z));
  282.         float b=sqrt((p3.x-p2.x)*(p3.x-p2.x)+(p3.y-p2.y)*(p3.y-p2.y)+(p3.z-p2.z)*(p3.z-p2.z));
  283.         float c=sqrt((p1.x-p3.x)*(p1.x-p3.x)+(p1.y-p3.y)*(p1.y-p3.y)+(p1.z-p3.z)*(p1.z-p3.z));
  284.         float s=(a+b+c)/2.;
  285.         return (sqrt(s*((s-a)*(s-b)*(s-c))));
  286.  
  287. }
  288.  
  289.  
  290. unsigned int loadTexture(const char* filename)
  291. {
  292.     unsigned int num;
  293.     glGenTextures(1,&num);
  294.     SDL_Surface* img=SDL_LoadBMP(filename);
  295.     glBindTexture(GL_TEXTURE_2D,num);
  296.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  297.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  298. //  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
  299. //  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
  300.     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,img->w,img->h,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,img->pixels);
  301.     SDL_FreeSurface(img);
  302.     return num;
  303. }
  304.  
  305. bool spheresphere(coordinate& c1,float r1,coordinate c2,float r2)
  306. {
  307.     float dist=pointdistance(c1,c2);
  308.     if(dist<=(r1+r2)*(r1+r2))
  309.     {
  310.         float a=sqrt(dist)-(r1+r2);
  311.         coordinate vec(c2.x-c1.x,c2.y-c1.y,c2.z-c1.z);  //c2-c1
  312.         float len=sqrt((vec.x*vec.x+vec.y*vec.y+vec.z*vec.z));
  313.         vec.x/=len;
  314.         vec.y/=len;
  315.         vec.z/=len;
  316.         c1.x=c1.x+vec.x*a;
  317.         c1.y=c1.y+vec.y*a;
  318.         c1.z=c1.z+vec.z*a;
  319.         return 1;
  320.     }
  321.     return 0;
  322. }
  323.  
  324. float pointdistance(coordinate c1,coordinate c2)
  325. {
  326.     coordinate vec(c2.x-c1.x,c2.y-c1.y,c2.z-c1.z);
  327.     return (vec.x*vec.x+vec.y*vec.y+vec.z*vec.z);
  328. }
  329.  
  330. void moveTo(coordinate c)
  331. {
  332.     camX=c.x;
  333.     camY=c.y;
  334.     camZ=c.z;
  335. }
  336. coordinate camPos()
  337. {
  338.     return (coordinate(camX,camY,camZ));
  339. }
  340.  
  341. bool sphereplane(coordinate& sp, coordinate vn,coordinate p1,coordinate p2,coordinate p3, coordinate p4,float r)
  342. {
  343.     //float nx,float ny,float nz,float xs,float ys,float zs,float xd,float yd,float zd,coordinate p1,coordinate p2,coordinate p3,coordinate p4,float* dist,coordinate* point)
  344.     float dist1=0,dist2=0;
  345.     if(rayplane(-vn.x,-vn.y,-vn.z,sp.x,sp.y,sp.z,vn.x,vn.y,vn.z,p1,p2,p3,p4,&dist1) || rayplane(vn.x,vn.y,vn.z,sp.x,sp.y,sp.z,-vn.x,-vn.y,-vn.z,p1,p2,p3,p4,&dist2))
  346.     {
  347.         if(dist1>r || dist2>r)
  348.             return false;
  349.         if(dist1>0)
  350.         {
  351.             sp.x=sp.x-vn.x*(r-dist1);
  352.             sp.y=sp.y-vn.y*(r-dist1);
  353.             sp.z=sp.z-vn.z*(r-dist1);
  354.         }else{
  355.             sp.x=sp.x+vn.x*(r-dist2);
  356.             sp.y=sp.y+vn.y*(r-dist2);
  357.             sp.z=sp.z+vn.z*(r-dist2);      
  358.         }
  359.         return 1;
  360.     }
  361.     return 0;
  362. }
  363.  
Advertisement
Add Comment
Please, Sign In to add comment