首页 > 解决方案 > LWJGL 3 相机问题

问题描述

当我在我的项目中创建第三人称相机时,我遇到的问题就开始了。我已经毫无问题地使用了 LWJGL 2,因此我采用了与 LWJGL 3 相同的路径,并针对版本之间的变化进行了调整。我遇到的问题是:

  1. 当围绕我的对象旋转时,旋转是倾斜的并且速度非常快。我必须将鼠标拖离屏幕才能以相反的方式旋转。
  2. 旋转时,我的模型不在相机的视野内(但是模型仍然是它旋转的中心点)。
  3. 当我放大或缩小时,它会不断放大。马不停蹄。(很确定我可以用一些 tweeks 自己解决这个问题)。

我认为其中一些问题是由于版本的差异造成的。例如,在 LWJGL 2 中,我将使用 Mouse.getDWheel(); ,但是对于 LWJGL 3,我使用 GLFW 的 scrollCallback 来检索 Y 滚动值。我注意到它在向上滚动时返回 1.0-5.0(它可能会更高,但 5 是我见过的最高值),而负值会下降。

以下是我的相机类:

package entities;

import org.joml.Vector3f;
import org.lwjgl.glfw.GLFW;

import input.Input;

public class Camera {

private float distanceFromPlayer = 50;
private float angleAroundPlayer = 0;

private Vector3f position = new Vector3f(0,0,0);
private float pitch = 20;
private float yaw;
private float roll;

private Player player;

public Camera(Player player) {

    this.player = player;

}

public void move(Input input) {
    calculateZoom(input);
    calculatePitch(input);
    calculateAngleAroundPlayer(input);
    float horizontalDistance = calculateHorizontalDistance();
    float verticalDistance = calculateVerticalDistance();
    calculateCameraPosition(horizontalDistance, verticalDistance);
}

public Vector3f getPosition() {
    return position;
}

public float getPitch() {
    return pitch;
}

public float getYaw() {
    return yaw;
}

public float getRoll() {
    return roll;
}

private void calculateCameraPosition(float horizDistance, float verticDistance) {
    float theta = player.getRotY() + angleAroundPlayer;
    float offsetX = (float) (horizDistance * Math.sin(Math.toRadians(theta)));
    float offsetZ = (float) (horizDistance * Math.cos(Math.toRadians(theta)));
    position.x = player.getPosition().x - offsetX;
    position.z = player.getPosition().z - offsetZ;
    position.y = player.getPosition().y + verticDistance;
    this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
}

private float calculateHorizontalDistance() {
    return (float) (distanceFromPlayer * Math.cos(Math.toRadians(pitch)));
}

private float calculateVerticalDistance() {
    return (float) (distanceFromPlayer * Math.sin(Math.toRadians(pitch)));
}

private void calculateZoom(Input input) {
    float zoomLevel = input.getMouseWheelVelocity() * 0.1f;
    distanceFromPlayer -= zoomLevel;

}

private void calculatePitch(Input input) {
    if(input.isMouseDown(GLFW.GLFW_MOUSE_BUTTON_1)) {
        //possible issue
        float pitchChange = (float) (input.getMouseY() * 0.01f);
        pitch -= pitchChange;
    }
}

private void calculateAngleAroundPlayer(Input input) {
    if(input.isMouseDown(GLFW.GLFW_MOUSE_BUTTON_2)) {
        float angleChange = (float) (input.getMouseX() * 0.01f);
        angleAroundPlayer -= angleChange;
    }
}
}

这是我的输入类,我在其中获得鼠标滚轮速度:

package input;

import java.nio.DoubleBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;

import renderEngine.Window;

public class Input {


private long window;
private boolean[] keys = new boolean[GLFW.GLFW_KEY_LAST];
private boolean[] mouseButtons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
private float mouseWheelVelocity = 0;


public Input(Window win) {
    super();
    this.window = win.getID();
}

public void init() {

    GLFW.glfwSetScrollCallback(window, (long win, double dx, double dy) -> {
        System.out.println(dy);
        setMouseWheelVelocity((float) dy);


    });
}


public boolean isKeyDown(int keyCode) {

    return GLFW.glfwGetKey(window, keyCode) == 1;

}

public boolean isMouseDown(int mouseButton) {

    return GLFW.glfwGetMouseButton(window, mouseButton) == 1;

}

public boolean isKeyPressed(int keyCode) {

    return isKeyDown(keyCode) && !keys[keyCode];
}

public boolean isKeyReleased(int keyCode) {

    return !isKeyDown(keyCode) && keys[keyCode];

}

public boolean isMousePressed(int mouseButton) {

    return isMouseDown(mouseButton) && !mouseButtons[mouseButton];

}

public boolean isMouseReleased(int mouseButton) {

    return !isMouseDown(mouseButton) && mouseButtons[mouseButton];

}

public double getMouseX() {
    DoubleBuffer buffer = BufferUtils.createDoubleBuffer(1);
    GLFW.glfwGetCursorPos(window, buffer, null);
    return buffer.get(0);
}

public double getMouseY() {
    DoubleBuffer buffer = BufferUtils.createDoubleBuffer(1);
    GLFW.glfwGetCursorPos(window, null, buffer);
    return buffer.get(0);

}

public float getMouseWheelVelocity() {
    return mouseWheelVelocity;
}

public void setMouseWheelVelocity(float mouseWheelVelocity) {
    this.mouseWheelVelocity = mouseWheelVelocity;
}

public void updateInput() {
    for (int i = 0; i < GLFW.GLFW_KEY_LAST; i++) {
        keys[i] = isKeyDown(i);
    }
    for (int i = 0; i < GLFW.GLFW_MOUSE_BUTTON_LAST; i++) {
        mouseButtons[i] = isMouseDown(i);
    }
}

public void currentKeyBind() {
    if(isKeyPressed(GLFW.GLFW_KEY_Q)) {
        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
    }
    if(isKeyReleased(GLFW.GLFW_KEY_Q)) {
        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
    }
}

}

只是一些关于可能出错的输入,以及我应该前往修复它的方向会很棒。我查看了 glfw 和 LWJGL 的教程和文档来寻找答案,如果不完全重建我的大部分项目,我似乎找不到一个。

标签: javalwjglglfw

解决方案


推荐阅读