2013-01-22 45 views
0

我ming在一個android opengl 1.1 2d遊戲與車輛和相機的頂視圖相對於車輛的速度縮放。當速度增加時,相機會縮小以提供最佳的道路可見度。android opengl檢查一個點與相機變焦的可見性

我沒有小心找到確切的方法來檢測精靈是否可見或不關於他的位置和當前的相機縮放。

重要的精度,我所有的遊戲對象都在同一個z座標上。我使用3d僅用於相機效果。 (這就是爲什麼我不需要截複雜的計算)

這裏是我GLSurfaceView.Renderer類的樣本

public static float fov_degrees = 45f; 
public static float fov_radians = fov_degrees/180 * (float) Math.PI; 
public static float aspect; //1.15572 on my device 
public static float camZ; //927 on my device 



@Override 
public void onSurfaceChanged(GL10 gl, int x, int y) { 

    aspect = (float) x/(float) y; 
    camZ = y/2/(float) Math.tan(fov_radians/2); 

    Camera.MINIDECAL = y/4; // minimum cam zoom out (192 on my device) 

    if (x == 0) { // Prevent A Divide By Zero By 
     x = 1; // Making Height Equal One 
    } 
    gl.glViewport(0, 0, x, y); // Reset The Current Viewport 
    gl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix 
    gl.glLoadIdentity(); // Reset The Projection Matrix 

    // Calculate The Aspect Ratio Of The Window 
    GLU.gluPerspective(gl, fov_degrees, aspect , camZ/10, camZ * 10); 

    GLU.gluLookAt(gl, 0, 0, camZ, 0, 0, 0, 0, 1, 0); // move camera back 


    gl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix 

    gl.glLoadIdentity(); // Reset The Modelview Matrix 

當我畫我用這種翻譯方法的任何相機相對對象:

gl.glTranslatef(position.x - camera.centerPosition.x , position.y -camera.centerPosition.y , - camera.zDecal); 

Eveything顯示正常,問題來自我的物理線程,當他檢查對象是否可見時:

public static boolean isElementVisible(Element element) { 

    xDelta = (float) ((camera.zDecal + GameRenderer.camZ) * GameRenderer.aspect * Math.atan(GameRenderer.fov_radians)); 
    yDelta = (float) ((camera.zDecal + GameRenderer.camZ)* Math.atan(GameRenderer.fov_radians)); 

    //(xDelta and yDelta are in reallity updated only ones a frame or when camera zoom change) 

    Camera camera = ObjectRegistry.INSTANCE.camera; 

    float xMin = camera.centerPosition.x - xDelta/2; 
    float xMax = camera.centerPosition.x + xDelta/2; 

    float yMin = camera.centerPosition.y - yDelta/2; 
    float yMax = camera.centerPosition.y + yDelta/2; 

    //xMin and yMin are supposed to be the lower bounds x and y of the visible plan 
    // same for yMax and xMax 

    // then i just check that my sprite is visible on this rectangle. 


    Vector2 phD = element.getDimToTestIfVisibleOnScreen(); 
    int sizeXd2 = (int) phD.x/2; 
    int sizeYd2 = (int) phD.y/2; 


    return (element.position.x + sizeXd2 > xMin) 
      && (element.position.x - sizeXd2 < xMax) 
      && (element.position.y - sizeYd2 < yMax) 
      && (element.position.y + sizeYd2 > yMin); 


} 

不幸的是,物體過早消失,看起來很晚,所以我manuelly增加了一些縮小在相機上的測試目的。

我做了一些手動測試,發現在計算xDelta和yDelta的時候,通過在攝像機z索引中添加大約260,效果很好。 所以該行現在是:

xDelta = (float) ((camera.zDecal + GameRenderer.camZ + 260) * GameRenderer.aspect * Math.atan(GameRenderer.fov_radians)); 
yDelta = (float) ((camera.zDecal + GameRenderer.camZ + 260)* Math.atan(GameRenderer.fov_radians)); 

因爲它是一個黑客,一個神奇的數字可能不是每次我想明白了什麼,我錯過的設備上運行。我猜想有一些來自fov或配給寬度/高度的「260」幻數,它可以作爲像素完美檢測的公式參數。

任何猜測?

+0

如果使用Math.tan(會發生什麼GameRenderer.fov_radians)而不是atan? – Patashu

回答

0

我的猜測是你應該使用Math.tan(GameRenderer.fov_radians)而不是Math.atan(GameRenderer.fov_radians)

推理:

如果您使用的攝像頭,支持90度視場,然後xDeltayDelta應該是無限大的,對不對?由於相機將不得不查看整個無限的平面。

tan(pi/2)是無窮大(負無窮大)。 ATAN(PI/2)僅僅是1.00388 ...

譚(π/ 4)爲1時,相較於ATAN的0.66577(π/ 4)...

+0

它的工作原理!非常感謝Patashu你剛剛贏得了我未來遊戲的免費副本;) – jocelyn