简单的碰撞检测?

时间:2012-06-28 19:50:25

标签: c opengl collision-detection

编辑:原来我只有一些值-switched - 。


我正在使用OpenGL并在我的Windows计算机上使用C编码,我正在尝试进行真正的,非常基本的碰撞检测。 现在,我正在试着看看Ox,Oz是否在两个方框内:

int collision(int box[2][4]) {
    int col;
    int i;
    for (i=0;i<2;i++){
    col = 0;
    printf("x1:%.0f y1:%.0f x2:%.0f y2:%.0f \n",colbox[i][0],colbox[i][1],colbox[i][2],colbox[i][3]);
    printf("Ox:%.1f Oy:%.1f Oz:%.1f \n" , Ox,here,Oz);
    if ((colbox[i][0] < Ox) && (Ox < colbox[i][2])&& (colbox[i][1] < Oz) && (colbox[i][3] > Oz)) 
        return 1;
    else
        return 0;
    }

}   

我也尝试过各种变体,比如没有任何东西传递给函数,把循环放在函数外面等等。问题似乎是等式检查?

在我想要做的最低级别是看一个点(相机)是否在一个边界内(这是一组保存在2D数组中的4个点),如果它在-any-列出的边界,返回1.如果该点不在任何边界内,则返回0。

当这确实有效时,它只对一个区域执行,IE如果我移动到第一个列出的有界区域,它会正确返回,但第二个区域不能正常返回。

完整代码,如果它真的有用:

//  Values
double Ox=0, Oz=0;
float Oy=1.0;
double asp=1;       //  Aspect ratio
double dim=20;      //  Size of world
double fov=55;      //  Field of View
double ph,th = 0;
// angle of rotation for the camera direction
float angle = 0.0;
// actual vector representing the camera's direction
float lx=0.0,lz=-1.0;
// the key states. These variables will be zero
//when no key is being presses
float deltaAngle = 0.0;
float deltaMove = 0;
double here;
int collide;

// {x1,y1,x2,y2}
double colbox[2][4] = {
    {3,3,6,6},  
    {-1,-14,-3,-16}
};

//front-1 back-2 left-3 right-4
int collision(double box[2][4]) {
    int i;
    for (i=0;i<2;i++){
    col = 0;
    printf("x1:%.0f y1:%.0f x2:%.0f y2:%.0f \n",colbox[i][0],colbox[i][1],colbox[i][2],colbox[i][3]);
    printf("Ox:%.1f Oy:%.1f Oz:%.1f \n" , Ox,here,Oz);
    if ((colbox[i][0] < Ox) && (Ox < colbox[i][2])&& (colbox[i][1] < Oz) && (colbox[i][3] > Oz)) 
        return 1;
    else
        return 0;
    }

}               

//test
static void ball(double x,double y,double z,double r)
{
   //  Save transformation
   glPushMatrix();
   //  Offset, scale and rotate
   glTranslated(x,y,z);
   glScaled(r,r,r);
   //  White ball
   glColor3f(1,1,1);
   glutSolidSphere(1.0,16,16);
   //  Undo transofrmations
   glPopMatrix();
}
static void square(double r) {
    glPushMatrix();
    glScaled(r,r,r);
    glColor3f(1,0,0);
    glBegin(GL_QUADS);
    glVertex3f(-1,0,-1);
    glVertex3f(1,0,-1);
    glVertex3f(1,0,1);
    glVertex3f(-1,0,1);
    glEnd();
    glPopMatrix();
}

//test
void computePos(float deltaMove) {
    Ox += deltaMove * lx * 0.1f;
    Oz += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle) {
    angle += deltaAngle;
    lx = sin(angle);
    lz = -cos(angle);
}


// display
void display() {
    here = 2.0f*Oy;
    if (deltaMove)
        computePos(deltaMove);
    if (deltaAngle)
        computeDir(deltaAngle);
                const double len=2.0;
    //  Erase the window and the depth buffer
    glClearColor(0.3,0.5,1.0,1);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    //  Enable Z-buffering in OpenGL
    glEnable(GL_DEPTH_TEST);
    //  Set perspective
    glLoadIdentity();
    gluLookAt(Ox,2,Oz, Ox+lx, here, Oz+lz, 0,1,0);

    ball(5,5,5,2); ball(-2,0,-15,1);
    square(15);
    glColor3f(1,1,1);
      glBegin(GL_LINES);
      glVertex3d(0.0,0.0,0.0);
      glVertex3d(len,0.0,0.0);
      glVertex3d(0.0,0.0,0.0);
      glVertex3d(0.0,len,0.0);
      glVertex3d(0.0,0.0,0.0);
      glVertex3d(0.0,0.0,len);
      glEnd();
      //  Label axes
      glRasterPos3d(len,0.0,0.0);
      Print("X");
      glRasterPos3d(0.0,len,0.0);
      Print("Y");
      glRasterPos3d(0.0,0.0,len);
      Print("Z");
    //  Render the scene and make it visible
    glColor3f(0,0,0);
    glWindowPos2i(5,5);
    Print("Ox:%.1f Oy:%.1f Oz:%.1f  lx:%.1f lz:%.1f Collide:%d", Ox,here,Oz,lx,lz,collide);
    ErrCheck("display");
    glFlush();
    glutSwapBuffers();
}


void key(unsigned char ch,int x,int y) {
    //  Exit on ESC
    if (ch == 27)
        exit(0);
    // WASD controls
    else if (ch == 'a' || ch == 'A')
        deltaAngle = -0.05;
    else if (ch == 'd' || ch == 'D')
        deltaAngle = 0.05;
    else if (ch == 'w' || ch == 'W') {
            collide=collision(colbox);
            deltaMove = 1; }

    else if (ch == 's' || ch == 'S') {
            collide=collision(colbox);
            deltaMove = -1; }

    else if ((ch == 'e' || ch == 'E') && here < 4)
        Oy += 0.01;
    else if ((ch == 'c' || ch == 'C') && here > .5)
        Oy -= 0.01;

    Project(fov,asp,dim);
    glutPostRedisplay();
}

void reshape(int width,int height) {
    //  Ratio of the width to the height of the window
    asp = (height>0) ? (double)width/height : 1;
    //  Set the viewport to the entire window
    glViewport(0,0, width,height);
    //  Set projection
    Project(fov,asp,dim);
}

void releaseKey(unsigned char ch, int x, int y) {
    if (ch == 'a' || ch == 'A')
        deltaAngle = 0;
    else if (ch == 'd' || ch == 'D')
        deltaAngle = 0;
    else if (ch == 'w' || ch == 'W')
        deltaMove = 0;
    else if (ch == 's' || ch == 'S')
        deltaMove = 0;
    Project(fov,asp,dim);
    glutPostRedisplay();
}


int main(int argc,char* argv[]) {
   //  Initialize GLUT
   glutInit(&argc,argv);
   //  Request double buffered, true color window with Z buffering at 600x600
   glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
   glutInitWindowSize(800,500);
   glutCreateWindow("Haunted House");
   //  Set callbacks
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
//   glutSpecialFunc(special);
   glutKeyboardFunc(key);

    glutKeyboardUpFunc(releaseKey);
   //  Pass control to GLUT so it can interact with the user
   ErrCheck("init");
   glutMainLoop();
   return 0;
}

1 个答案:

答案 0 :(得分:2)

我想当你有i = 1的第二行

if ((colbox[i+1][0] < Ox) && (Ox < colbox[i+1][2])&& (colbox[i+1][1] < Oz) && (colbox[i+1][3] > Oz))

走出大小为2的数组。(因为这个的最大索引是1。)

所以,鉴于它正在读取不在数组内部的内存(我认为通常没问题),你会发现这种情况可能会失败很多,甚至大部分时间都可能因为它正在使用基本上随机数据。所以它返回0。