[英]How to move my camera straight to mouse cursor, with any rotation?
我正在使用LWJGL創建Java 3D游戲。 我是游戲的第一人稱視角,玩家可以用鼠標“轉動”相機(它實際上根據相機的旋轉移動所有其他對象)。
我正在嘗試從攝像機的俯仰,偏航和橫滾獲得3d矢量。 當我按W時,它應將相機X增加矢量X乘以速度,它也應與相機Y和Z相同。 這應該使攝像機直接移動到我的鼠標光標正在查看的位置(鼠標光標始終設置在屏幕的中間)。
目前,只要攝像機的橫搖角(Z旋轉)為0,此方法就可以正常工作。當攝像機的橫搖角不為0時,它將攝像機/播放器向錯誤的方向移動。
我想做的就是使相機朝我的光標移動,即使橫搖不等於0。
我的頂點着色器代碼如下(這似乎很相關,因為此處是計算渲染位置):
#version 400 core
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 passTextureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
uniform mat4 projectionMatrix;
uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;
void main(void){
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
passTextureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal,0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz;
}
位置vec3只是對象的世界位置。 下面的代碼計算了transformationMatrix和視圖矩陣:
public static final Matrix4f createTransformationMatrix(Vector3f position, float rx, float ry, float rz, float size){
Matrix4f matrix = new Matrix4f();
matrix.setIdentity();
Matrix4f.translate(position, matrix, matrix);
Matrix4f.rotate((float) toRadians(rz), new Vector3f(0, 0, 1), matrix, matrix);
Matrix4f.rotate((float) toRadians(ry), new Vector3f(0, 1, 0), matrix, matrix);
Matrix4f.rotate((float) toRadians(rx), new Vector3f(1, 0, 0), matrix, matrix);
Matrix4f.scale(new Vector3f(size, size, size), matrix, matrix);
return matrix;
}
public static final Matrix4f createViewMatrix(Camera camera){
Matrix4f view = new Matrix4f();
view.setIdentity();
Matrix4f.rotate(camera.getRadPitch(), new Vector3f(1, 0, 0), view, view);
Matrix4f.rotate(camera.getRadYaw(), new Vector3f(0, 1, 0), view, view);
Matrix4f.rotate(camera.getRadRoll(), new Vector3f(0, 0, 1), view, view);
Vector3f c = camera.getPosition();
Vector3f invert = new Vector3f(-c.x, -c.y, -c.z);
Matrix4f.translate(invert, view, view);
return view;
}
我很想知道為什么在代碼中不能只使用滾動旋轉,但是我對矩陣不是很了解。
我試圖獲得向量,以將照相機的運動與以下代碼相乘:
public static final Vector3f getRotationVector(float pitch, float yaw, float roll){
Matrix4f mat = createTransformationMatrix(Game.getCamera().getPosition(), pitch, yaw, roll, 1);
return new Vector3f(mat.m20, mat.m21, -mat.m22);
}
這是我更新旋轉和位置的相機代碼,稱為每幀:
public void update(){
super.update();
int midX = Display.getWidth() / 2;
int midY = Display.getHeight() / 2;
int mx = Mouse.getDX();
int my = Mouse.getDY();
if(rotationX > 360)
rotationX -= 360;
if(rotationX < 0)
rotationX += 360;
if(rotationY > 360)
rotationY -= 360;
if(rotationY < 0)
rotationY += 360;
if(rotationZ > 360)
rotationZ -= 360;
if(rotationZ < 0)
rotationZ += 360;
if(mouseMoved){
mouseMoved = false;
mx = 0;
my = 0;
}
float speed = 0.02f;
float rotateSpeed = 0.25f;
if(Keyboard.isKeyDown(Keyboard.KEY_A)){
Vector3f left = Maths.getRotationVector(-rotationX, rotationY - 90, rotationZ);
move(left.x * speed, left.y * speed, left.z * speed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_D)){
Vector3f right = Maths.getRotationVector(rotationX, rotationY + 90, rotationZ);
move(right.x * speed, right.y * speed, right.z * speed);
}
if(Keyboard.isKeyDown(Keyboard.KEY_W)){
Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
move(forward.x * speed * 3, forward.y * speed * 3, forward.z * speed * 3);
}
if(Keyboard.isKeyDown(Keyboard.KEY_S)){
Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
move(-forward.x * speed * 3, -forward.y * speed * 3, -forward.z * speed * 3);
}
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))
position.y += speed;
if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
position.y -= speed;
if(mx != 0 && Mouse.isInsideWindow() && wasMouse){
rotationY += rotateSpeed * mx;
Mouse.setCursorPosition(midX, midY);
mouseMoved = true;
}
if(my != 0 && Mouse.isInsideWindow() && wasMouse){
rotationX += rotateSpeed * -my;
Mouse.setCursorPosition(midX, midY);
mouseMoved = true;
}
if(Keyboard.isKeyDown(Keyboard.KEY_LCONTROL))
rotationZ -= rotateSpeed;
if(Keyboard.isKeyDown(Keyboard.KEY_RCONTROL))
rotationZ += rotateSpeed;
if(Keyboard.isKeyDown(Keyboard.KEY_M))
System.out.println("rotationX = " + rotationX + " rotationY = " + rotationY + " rotationZ = " + rotationZ);
if(Keyboard.isKeyDown(Keyboard.KEY_T))
System.out.println(Maths.getRotationVector(getPitch(), getYaw(), getRoll()));
if(Keyboard.isKeyDown(Keyboard.KEY_U)){
motionX = 0;
motionY = 0;
motionZ = 0;
}
if(Keyboard.isKeyDown(Keyboard.KEY_X)){
if(cooldown == 0){
Vector3f forward = Maths.getRotationVector(rotationX, rotationY, rotationZ);
world.spawnEntity(new Entity(new TexturedModel(Game.getLoader().loadModelToVAO("geometric/pyramid"), new ModelTexture(Game.getLoader().loadTexture("test 2"))), new Vector3f(position.x + forward.x * 2, position.y + forward.y * 2, position.z + forward.z * 2), rotationX, rotationY, rotationZ, 1f).addForce(rotationX, rotationY, rotationZ, 1000));
cooldown = 120;
}
}
if(!mouseMoved)
wasMouse = Mouse.isInsideWindow();
if(cooldown > 0)
--cooldown;
}
有誰知道為什么我不能毫無問題地更換相機膠卷,或者如何使它工作?
在對情況進行了許多邏輯思考之后,我自己找到了一種方法。 在計算了X軸和Y軸的向量后,我對其進行了編輯,然后使用Z軸對其進行了編輯。 這可能是一種奇怪的方法,但至少可以起作用。
工作方法是這樣的:
public static final Vector3f getRotationVector(float pitch, float yaw, float roll){
float r = (float) toRadians(roll);
Matrix4f mat = createTransformationMatrix(new Vector3f(), pitch, yaw, 0, 1);
Vector3f vector = new Vector3f(mat.m20, mat.m21, -mat.m22);
return new Vector3f((float)(vector.x * cos(r) + vector.y * sin(r)), (float)(vector.y * cos(r) - vector.x * sin(r)), vector.z);
}
回答我自己的問題可能看起來有點愚蠢,但是我沒想到我在發布此文章時會設法自己解決問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.