Mam problemy z rozumieniem pola widzenia kamery perspektywicznej w libGDX (a może moje obliczenia są błędne).libGDX - kamera perspektywiczna i pole widzenia
Chcę narysować pudełko (na przykład o szerokości 800 pikseli, wysokości 480 pikseli i głębokości 20 pikseli). Skrzynka jest umieszczona między osią X i Y (innymi słowy: szerokość na osi X i wysokość na osi Y). Teraz chcę stanąć za pudłem na osi X (pozycja kamery) i patrzeć w kierunku w taki sposób, że widzę pudełko po mojej prawej stronie ekranu. Zrobiłem kilka szkiców:
na ostatnim szkicu, okno znajduje się po prawej stronie pola widzenia.
Co więcej, wysokość pudełka musi dokładnie pasować do ekranu. Innymi słowy: górna krawędź pola musi znajdować się na górze ekranu, a dolna krawędź pola musi znajdować się na dole ekranu. Oto kodu oraz obliczenia, które to umożliwiają
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();
}
}
Aby dopasować wysokość skrzynki na ekranie muszę cofnąć SCREEN_HEIGHT/2, ponieważ X = SCREEN_HEIGHT/2/tan (45 °) = SCREEN_HEIGHT/2/1 = SCREEN_HEIGHT/2, dlatego dodałem tę długość do komponentu x w ustawieniu pozycji.
kod stanowi szkic 2 i daj mi, że prawidłowym zrzucie:
W celu osiągnięcia szkic 3, muszę obracać moje pole widzenia o 45 ° w lewo. Ale w związku z tym muszę trochę cofnąć, ponieważ boki pola widzenia są dłuższe niż linia środkowa. I wykonane dwa ręcznie wyciągnąć rysunki:
gdzie h = SCREEN_HEIGHT. Przede wszystkim muszę obliczyć x. x = h/2/sin (45 °) = h/sqrt (2). Teraz muszę cofnąć się o x i spojrzeć w nowym kierunku (45 ° w lewo od pudełka). W celu wyznaczenia punktu, w której będę wyglądzie, obliczać na długość Y na szkicu:
y = sin (45 °) * h/2 = H * sqrt (2)/4. Tak więc punkt jest na przykład (SCREEN_WIDTH + (x-y), SCREEN_HEIGHT/2, y). Teraz mogę zmienić pozycję i punkt patrząc w moim kodu:
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();
}
I mam taki ekran:
Ale pole nie jest na bardzo prawej strony :(
Więc teraz pytanie: co jest nie tak? Czy moje myślenie o polu widzenia jest błędne lub moje obliczenia?
Pozdrawiam!