2

Edit: Turns out I just had some values -switched-.


I'm working with OpenGL and coding with C on my Windows computer, and I'm trying to get a really, really basic collision detection going on. Right now, I'm trying this to see if a point Ox,Oz is inside of two boxes:

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;
    }

}   

I've also tried variations, like having nothing pass through to the function, putting the loop outside the function, etc. The problem seems to be with equality check?

At the very lowest level of what I'm trying to do is to see if a point (the camera) is within a boundary (which is a set of 4 points kept in a 2D array), and if it is in -any- of the boundaries listed, return 1. If the point is NOT in any of the boundaries, return 0.

When this does work, it only does it for one area, IE if I move over to the first listed bounded area, it returns properly, but the second area doesn't return properly.

Full Code if it's really helpful:

//  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;
}
4

1 回答 1

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。

于 2012-06-28T20:20:59.050 回答