2010-09-08 59 views
0

我的小游戏引擎基本上有一个3D数组Cubes [x] [y] [z](其实它是一个很大的一维数组,但我做了一些重载)。我知道玩家站在X Y Z的哪个立方体。玩家将能够拍摄立方体来摧毁它,这就是为什么我需要弄清楚如何找到鼠标所在的立方体。我发现了一些关于采摘的OpenGL文档,但是这种方法很慢。由于我的立方体是有组织的,并且我知道玩家在哪个立方体上,并且相机在X和Y上的角度(相机不在Z上旋转),并且鼠标总是处于screenwidth/2,screenheight/2我确定theres比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; 

} 

感谢

回答

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)。现在你只是走在时间列表 - 这将带你进入一个新的广场 - 第一次遇到一个立方体,你打它。

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

+0

实际上,关于Z高度,玩家可以上下看,枪在玩家脸部的中心位置,屏幕的中心也是,我的立方体已经Z排序了吗?如立方体(5,5,5)旁边的立方体(5,5,6)。 – jmasterx 2010-09-08 17:37:12