Camera libGDX-透视相机和视野

Camera libGDX-透视相机和视野,camera,libgdx,perspective,fieldofview,Camera,Libgdx,Perspective,Fieldofview,我很难理解libGDX中透视相机的视野(或者我的计算是错误的) 我想画一个盒子(例如800px宽,480px高,20px深)。长方体放置在x轴和y轴之间(换句话说:x轴上的宽度和y轴上的高度)。现在我想站在x轴上的盒子后面(相机位置),朝着一个方向看,这样我就能看到屏幕右侧的盒子。 我画了一些草图: 在最后一个草图上,长方体位于视野的右侧 此外,盒子的高度必须与屏幕完全匹配。换句话说:盒子的上边缘必须在我的屏幕顶部,盒子的下边缘必须在我的屏幕底部。 以下是实现此目的的一些代码和计算: pu

我很难理解libGDX中透视相机的视野(或者我的计算是错误的)

我想画一个盒子(例如800px宽,480px高,20px深)。长方体放置在x轴和y轴之间(换句话说:x轴上的宽度和y轴上的高度)。现在我想站在x轴上的盒子后面(相机位置),朝着一个方向看,这样我就能看到屏幕右侧的盒子。 我画了一些草图:

在最后一个草图上,长方体位于视野的右侧

此外,盒子的高度必须与屏幕完全匹配。换句话说:盒子的上边缘必须在我的屏幕顶部,盒子的下边缘必须在我的屏幕底部。 以下是实现此目的的一些代码和计算:

public class Box implements ApplicationListener {

public PerspectiveCamera camera;
public float SCREEN_WIDTH;   
public float SCREEN_HEIGHT; 

@Override
public void create() {
    SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
    SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px

    // Create camera (90°) and set position
    camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
    camera.position.set(SCREEN_WIDTH + SCREEN_HEIGHT/2, SCREEN_HEIGHT/2, 0f);
    camera.lookAt(0f, SCREEN_HEIGHT/2, 0f);
    camera.near = 1;
    camera.far = 2 * SCREEN_WIDTH;
    camera.update();
}

@Override
public void render() {
    Gdx.gl.glClearColor(Color.WHITE.r, Color.WHITE.g, Color.WHITE.b, Color.WHITE.a);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 

    // Build the box - width is screenwidth and height is screenheight - one corner in origin
    ModelBuilder modelBuilder = new ModelBuilder(); 
    modelBuilder.begin();
    MeshPartBuilder mpb = modelBuilder.part("ID", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal,
            new Material(ColorAttribute.createDiffuse(Color.GREEN)));
    // bottom left corner of the box should be in (0,0,0)
    mpb.box(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, -10f, SCREEN_WIDTH, SCREEN_HEIGHT, 20f);
    Model model = modelBuilder.end();
    ModelInstance instance = new ModelInstance(model);

    // Build some light
    Environment environment = new Environment();
    environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
    environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));

    // Draw the box
    ModelBatch modelBatch = new ModelBatch();
    modelBatch.begin(camera);
    modelBatch.render(instance, environment);
    modelBatch.end();
}
}
为了适应屏幕中的框高度,我必须后退screen_height/2,因为x=screen_height/2/tan(45°)=screen_height/2/1=screen_height/2,这就是我在位置设置中将此长度添加到x分量的原因

代码表示草图2,并给出正确的屏幕截图:

为了绘制草图3,我必须将视野向左旋转约45°。但在这方面,我必须退一步,因为视野的侧面比中心线长。我画了两幅手绘草图:

其中h=屏幕高度。首先,我要计算x。x=h/2/sin(45°)=h/sqrt(2)。现在,我必须后退x的长度,朝一个新的方向看(盒子左45°)。为了计算我要查看的点,我计算此草图上的长度y:

y=sin(45°)*h/2=h*sqrt(2)/4。例如,点是(屏幕宽度+(x-y),屏幕高度/2,y)。现在我更改代码中的位置和观察点:

public void create() {
    SCREEN_WIDTH = Gdx.graphics.getWidth(); // 800px
    SCREEN_HEIGHT = Gdx.graphics.getHeight(); // 480px

    // Create camera (90°) and set position
    camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);
    float x = (float) (SCREEN_HEIGHT / Math.sqrt(2));
    float y = (float) (SCREEN_HEIGHT * Math.sqrt(2)/4f);
    camera.position.set(SCREEN_WIDTH + x, SCREEN_HEIGHT/2, 0f);
    camera.lookAt(SCREEN_WIDTH + x - y, SCREEN_HEIGHT/2, y);
    camera.near = 1;
    camera.far = 2 * SCREEN_WIDTH;
    camera.update();
}
我看到这个屏幕:

但盒子不在右边:(

那么现在的问题是:什么是错的?我对视野的思考是错的还是我的计算是错的


致以最诚挚的问候!

您对透视摄影机的理解有点偏差,特别是对第二个(
视口宽度
)和第三个(
视口高度
)参数的理解

PerspectiveCamera
对它们所做的唯一一件事就是获取纵横比并使用它来设置
projectionMatrix
。对于它使用的特定代码,请参见计算纵横比并设置
projectionMatrix

现在,这一切都很好,除了你也做了数学来处理纵横比,做两次会导致相机再次拉伸。解决方法很简单,要么重做数学以不调整纵横比,要么替换

camera = new PerspectiveCamera(90f, SCREEN_WIDTH, SCREEN_HEIGHT);

使libgdx计算的纵横比为
1

我不太擅长正弦和余弦,所以我不能提供第一个选项的解决方案,但你似乎没有任何困难的数学问题

camera = new PerspectiveCamera(90f, 1, 1);