鼠标下的对象?

时间:2010-09-08 17:19:19

标签: c++ algorithm opengl

我的小游戏引擎基本上有一个3D数组Cubes [x] [y] [z](它实际上是一个大的一维数组,但我做了一些重载)。我知道玩家站在X Y Z中的哪个立方体。玩家将能够射击立方体来摧毁它,这就是为什么我需要弄清楚如何找到鼠标所在的立方体。我在拾取时发现了一些OpenGL文档,但这种方法很慢。由于我的立方体是有组织的,我知道播放器在哪个立方体,相机的角度在X和Y(相机不在Z上旋转),并且鼠标总是在screenwidth / 2,screenheight / 2我肯定这比gl采摘技术更快。

以下是相机的设置方法:

void CCubeGame::SetCameraMatrix()
{

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glRotatef(Camera.rotx,1,0,0);
    glRotatef(Camera.roty,0,1,0);
    glRotatef(Camera.rotz,0,0,1);

    glTranslatef(-Camera.x , -Camera.y,-Camera.z );
}

void CCubeGame::MouseMove(int x, int y)
{
    if(!isTrapped)
        return;

    int diffx = x-lastMouse.x; 
    int diffy = y-lastMouse.y; 

    lastMouse.x = x; 
    lastMouse.y = y;
    Camera.rotx += (float) diffy * 0.2; 
    Camera.roty += (float) diffx * 0.2; 
    if(Camera.rotx > 90)
    {
        Camera.rotx = 90;
    }

    if(Camera.rotx < -90)
    {
        Camera.rotx = -90;
    }

    if(isTrapped)
    if (fabs(ScreenDimensions.x/2 - x) > 1 || fabs(ScreenDimensions.y/2 - y) > 1) {
        resetPointer();
    }

}

Vertex3f CCubeGame::MoveCamera( int direction, float amount )
{
    float xrotrad, yrotrad;
    Vertex3f result(0,0,0);

    switch(direction)
    {
    case CAM_FORWARD:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        xrotrad = (Camera.rotx / 180 * 3.141592654f);

        result.x = float(sin(yrotrad)) * amount;
        result.z = -(float(cos(yrotrad)) * amount);
        result.y = 0;
        //Camera.y -= float(sin(xrotrad)) * amount;
        break;
    case CAM_BACKWARD:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        xrotrad = (Camera.rotx / 180 * 3.141592654f);
        result.x = -(float(sin(yrotrad)) * amount);
        result.z = float(cos(yrotrad)) * amount;
        result.y = 0;

        //Camera.y += float(sin(xrotrad)) * amount;
        break;
    case CAM_RIGHT:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        result.x = float(cos(yrotrad)) * amount;
        result.z += float(sin(yrotrad)) * amount;
        result.y = 0;
        break;
    case CAM_LEFT:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        result.x = -(float(cos(yrotrad)) * amount);
        result.z = -(float(sin(yrotrad)) * amount);
        result.y = 0;
        break;
    default:
        break;
    }

    Camera.x += result.x;
    Camera.y += result.y;
    Camera.z += result.z;

    return result;

}

由于

1 个答案:

答案 0 :(得分:0)

如果你不能在Z中旋转,那么你只能在与枪相同的Z高度拍摄立方体。这使得事情变得简单得多,因为你可以用Z对你的立方体进行排序,扔掉任何太高或太低的立方体(如果它们可以处于分数高度,这将需要log(N)时间的立方体数量;如果它们是'所有相同的高度都在彼此相同的高度,你只需索引到数组的那一部分。)

现在你需要从枪中穿过网格绘制一条线,并找出它首先击中的立方体。这样做的方法是使用沿着枪线的矢量:

v = (cos(angle), sin(angle))

找到该行与X或Y中的整数相交的每个边界。如果我们在

(x0,y0)

开始并沿方向v行进然后我们将点击(假设cos(角度)> 0)

ceil(x0), ceil(x0+1), ...

有时

(ceil(x0)-x0)/cos(angle), (ceil(x1)-x1)/cos(angle), ...

,同样适用于y0sin(angle)。现在你只需走下时间列表 - 这将带你进入一个新的广场 - 当你第一次遇到一个立方体时,你会点击它。

如果立方体阵列不是巨大的,那么在一个不错的处理器上整个过程应该只需要几微秒(在嵌入式处理器上可能只有几百个)。