Search code examples
c++openglglslcollision-detectionheightmap

OpenGL - Camera movement have a latch when I move from a cell to another


Hello everyone I'm developing a OpenGL game using c++ and GLFW + GLEW libraries. I've generated a terrain from a Heightmap and now I'm trying to move on it calculating the height of the camera (y co-ordinate) every step I take. My map is divided in triangles, this is an example image of it with GL_LINE and then GL_FILL polygon mode enter image description here

I've calculated the height by calculating two vectors that pass from a triangle vertex to another and then I made the cross product to calculate the normal vector of it; I obtained my y coordinate from it and it's working but I noticed that while moving my height does not get a smooth variation while passing from a triangle to another one and I don't know why, because while moving on the same triangle the y scales well.

I'll now show you my code with many explanations as possible and then I'll show you an example of a run.

float Terrain::getCollisionHeight(float x, float z) {
    //lato is the side of my triangle and it seems to work when is 1.0f but not with other values, now I put it at 5.0f
    //x_pos and z_pos gives the triangle coordinates in the heightmap ( I THINK THE ERROR MIGHT BE IN THE FOLLOWING 2 LINES)
    float x_pos = (int)(x / lato);
    float z_pos = (int)(z / lato);

    cout << "x: " << (int)x << " - z: " << (int)z << endl;

    cout << "x pos: " << x_pos << " - z pos: " << z_pos << endl;
    cout << "I'm in triangle: " << x_pos << ", " << z_pos << endl;

    //i calculate _x and _z  to understand if I am in an upper triangle or lower triangle (my draw function draws two triangles at the time as a square)
    float _x = x - x_pos;
    float _z = z - z_pos;

    //then I calculate the coordinates of the two vectors: p(x,y,z) v1 is p1-p0 and v2 is p2-p1
    //I always get the height value from a height function that returns the corresponding value of the heightmap given x,z
    float x0, x1, x2, y0, y1, y2, z0, z1, z2;
    x0 = x_pos*lato;
    z0 = z_pos*lato;
    y0 = hm->getHeight(x_pos, z_pos);

    x2 = x0 + lato;
    z2 = z0 + lato;
    y2 = hm->getHeight(x_pos + 1, z_pos + 1);

    if (_x >= _z) {
        cout << "upper triangle" << endl;
        x1 = x0 + lato;
        z1 = z0;
        y1 = hm->getHeight(x_pos + 1, z_pos);
    } else {
        cout << "lower triangle" << endl;
        x1 = x0;
        z1 = z0 + lato;
        y1 = hm->getHeight(x_pos, z_pos + 1);
    }

    //i make the cross product and then I return the calculated y (height) value
    vec3 v = cross(vec3(x1 - x0, y1 - y0, z1 - z0), vec3(x2 - x1, y2 - y1, z2 - z1));
    float y =(-v[0] * x - v[2] * z + v[0] * x0 + v[1] * y0 + v[2] * z0) / v[1];
    cout << "p0: " << x0 << " " << y0 << " " << z0 << endl;
    cout << "p1: " << x1 << " " << y1 << " " << z1 << endl;
    cout << "p2: " << x2 << " " << y2 << " " << z2 << endl;

    cout << "PP:" << x << " " << y<< " " << z << endl;
    return y;

}

Now I'll show how heavily my position changes when changing triangle:

This a same triangle movement and y gets the right value enter image description here

And this is the latch I get while passing from a triangle to another enter image description here

This latch is highly percepted while playing. What can I do to fix it? Thanks a lot

This is a video of the problem, horizon artifacts are present because of fraps https://www.youtube.com/watch?v=CiRKVK89Fkk&feature=youtu.be


Solution

  • I found at least one mistake.

    This:

     float _x = x - x_pos;
     float _z = z - z_pos;
    

    Should be this:

    float _x = (x / lato) - x_pos;
    float _z = (z / lato) - z_pos;
    

    Thats why it works at lato = 1.