【发布时间】:2016-09-28 00:38:07
【问题描述】:
我正在使用 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 只是对象的世界位置。转换矩阵和视图矩阵在以下代码中计算:
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;
}
有人知道为什么我不能毫无问题地更换相机胶卷,或者我怎样才能做到这一点?
【问题讨论】:
-
你能分享一下你做旋转和移动的代码吗?
标签: java