java - LWJGL 3 相机问题
问题描述
当我在我的项目中创建第三人称相机时,我遇到的问题就开始了。我已经毫无问题地使用了 LWJGL 2,因此我采用了与 LWJGL 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 的教程和文档来寻找答案,如果不完全重建我的大部分项目,我似乎找不到一个。
解决方案
推荐阅读
- c# - 将自定义 AWS Lambda 运行时与 asp.net 核心一起使用
- go - 嵌入式结构还是嵌套结构?
- javascript - 如何在 Nock Get 请求中发送二进制缓冲区?
- c - C 赋值和参数传递会导致隐式转换,还是应该显式转换?
- laravel - Vue 在 axios 发布成功或失败后更改值和文本
- google-sheets - 如何根据给定月份创建双周工资表
- javascript - 将函数作为参数传递“试图理解链接”
- python - 使用 GCSFilesStore 在 Scrapy Cloud 上获取蜘蛛以将文件存储在 Google Cloud Storage 上并获取 ImportError
- go - golang + redis 并发调度器性能问题
- php - 可以从 docker 容器外部连接到数据库,但不能从内部(在 laravel 中)