如何将相机对准我角色前面单元格的z-index?

时间:2017-03-09 20:39:36

标签: c++ opengl glut

我有这样的3D地形环境:

我试图让角色(相机)在爬山时抬头仰视,并在下降时往下看,就像在现实生活中攀爬一样。

这就是它目前正在做的事情:

现在相机在山上上下移动很好,但是我无法让相机角度正常工作。我可以想到根据地形向上或向下瞄准的唯一方法是获取我的角色当前面临的单元格的z-index,并将其设置为焦点,但我真的不知道该怎么做。

这无疑是一项任务,我们故意不使用对象,所以事情的组织有点奇怪。

以下是我目前正在做的事情:

const int M = 100;  // width
const int N = 100;  // height
double zHeights[M+1][N+1];  // 2D array containing the z-indexes of terrain cells
double gRX = 1.5;  // x position of character
double gRY = 2.5;  // y position of character
double gDirection = 45;  // direction of character
double gRSpeed = 0.05;  // move speed of character


double getZ(double x, double y)  // returns the height of the current cell
{
    double z = .5*sin(x*.25) + .4*sin(y*.15-.43);
    z += sin(x*.45-.7) * cos(y*.315-.31)+.5;
    z += sin(x*.15-.97) * sin(y*.35-8.31);

    double amplitute = 5;
    z *= amplitute;
    return z;
}

void generateTerrain()
{
    glBegin(GL_QUADS);

    for (int i = 0; i <= M; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            zHeights[i][j] = getZ(i,j);
        }
    }
}

void drawTerrain()
{
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            glColor3ub( (i*34525+j*5245)%256, (i*3456345+j*6757)%256, (i*98776+j*6554544)%256);
            glVertex3d(i, j, getZ(i,j));
            glVertex3d(i, j+1, getZ(i,j+1));
            glVertex3d(i+1, j+1, getZ(i+1,j+1));
            glVertex3d(i+1, j, getZ(i+1,j));
        }
    }
}

void display()  // callback to glutDisplayFunc
{
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    double radians = gDirection /180.*3.141592654;  // converts direction to radians
    double z = getZ((int)gRX, (int)gRY);  // casts as int to find z-index in zHeights[][]
    double dx = cos(radians)*gRSpeed;
    double dy = sin(radians)*gRSpeed;
    double at_x = gRX + dx;
    double at_y = gRY + dy;
    double at_z = z;  // source of problem, no idea what to do

    gluLookAt(gRX, gRY, z + 2,  // eye position
              at_x, at_y, at_z + 2,  // point to look at,  also wrong
              0, 0, 1);   // up vector

    drawTerrain();
    glEnd();
}

void init()
{
    generateTerrain();
}

1 个答案:

答案 0 :(得分:0)

首先,我认为没有理由在此处投放int

double z = getZ((int)gRX, (int)gRY);

只需使用double值即可获得流畅的行为。

你的基本方法已经相当不错了。你取当前位置(gRX, gRY),在观察方向(dx, dy)走一点,然后用它作为要点。只有两件小事需要改编:

double dx = cos(radians)*gRSpeed;
double dy = sin(radians)*gRSpeed;

虽然乘以gRSpeed可能是一个好主意,但在我看来,这个因素不应该与角色的运动学相关。相反,这代表了您的视图方向的平滑度。较小的值使方向与地形几何形状非常接近,较大的值使其平滑。

最后,你需要在你的观察点评估高度:

double at_z = getZ(at_x, at_y);