2010-09-08 2 views
0

В моем маленьком игровом движке в основном есть кубики 3D-массива [x] [y] [z] (на самом деле это большой 1D-массив, но я сделал некоторую перегрузку). Я знаю, какой куб в X Y Z заставляет игрока стоять. Игрок сможет снимать куб, чтобы уничтожить его, поэтому мне нужно выяснить, как найти куб, на который находится мышь. Я нашел документацию OpenGL по сборке, но этот метод был медленным. Поскольку мои кубы организованы, и я знаю, в каком кубе находится плеер, а угол камеры в X и Y (камера не вращается на Z), и что мышь всегда находится на экране/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), ... 

и аналогичным образом для y0 и sin(angle). Теперь вы просто сходите по списку раз, что приведет вас к новой площади - и в первый раз, когда вы столкнетесь с кубом, вы ударите его.

Если массив кубов не является гигантским, все это должно занимать всего несколько микросекунд на приличном процессоре (может быть, несколько сотен встроенных процессоров).

+0

Фактически относительно высоты Z игрок может смотреть вверх и вниз, а пистолет находится в центре лица игрока, который является центром экрана, также, мои кубы уже отсортированы по Z? как в кубе (5,5,5) находится рядом с кубом (5,5,6). – jmasterx

Смежные вопросы