6

libGDX のパースペクティブ カメラの視野を理解するのに問題があります (または計算が間違っている可能性があります)。

ボックスを描画したい (たとえば、幅 800 ピクセル、高さ 480 ピクセル、深さ 20 ピクセル)。ボックスは x 軸と y 軸の間に配置されます (つまり、x 軸の幅と y 軸の高さ)。ここで、x 軸 (カメラの位置) のボックスの後ろに立って、画面の右端にボックスが見えるように方向を見たいと思います。私はいくつかのスケッチを作りました:

箱を描く

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 を表し、正しいスクリーンショットが表示されます。

スケッチ 2 のスクリーンショット

スケッチ 3 を完成させるには、視野を左に約 45° 回転させる必要があります。しかし、これに関連して、視野の辺が中心線よりも長いため、少し後退する必要があります。手描きのスケッチを 2 つ作成しました。

視野の回転

ここで、h = SCREEN_HEIGHT です。まず、x を計算する必要があります。x = h/2 / sin(45°) = h/sqrt(2)。ここで、x の長さだけ戻り、新しい方向 (ボックスから左 45°) を見る必要があります。見るポイントを計算するために、このスケッチで長さ y を計算します。

計算y

y = sin(45°) * h/2 = h * sqrt(2)/4. したがって、ポイントはたとえば (SCREEN_WIDTH + (xy), SCREEN_HEIGHT/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();
}

そして、私はこの画面を取得します:

スケッチ 3 を表すスクリーンショット

しかし、ボックスは右側にありません:(

では、問題は次のとおりです。何が間違っているのでしょうか。私の視野の考え方や私の計算は間違っていますか?

よろしくお願いします!

4

1 に答える 1