Hey there,
I’ve got a problem with not being able to move down or up when the camera is facing right or left. (Forward being y rotation 0 looking along the z- axis)
What I’ve got:
- An environment with a few boxes
- A camera that has position and rotation vectors which are converted into an up, left and forward vector and put into a matrix. (the viewmatrix)
- The move method uses a given direction to translate the camera relative to where it is facing. (I.e. press w = move to forward vector)
Weird stuff: Somehow the Y direction gets inverted when between 90 and 270 rotation. (kinda sorta fixed that, but not very well)
Somehow the Y element of the forward vector decreases when getting closer to 90 & 270 rotation around y axis. (need to fix this)
package varelse;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
//TODO Incorporate getting the time delta, or maybe do that in the inputManager.
public class CameraModelling implements Camera{
private Vector3f cameraPosition;
private Vector3f cameraRotation;
private Vector3f maxRotation;
private Vector3f minRotation;
private float moveSpeed;
private float rotationSpeed;
private Vector3f lVec; // The left vector, x
private Vector3f uVec; // The up vector, y
private Vector3f fVec; // The forward vector, z
private Matrix4f camMatrix;
CameraModelling () {
cameraPosition = new Vector3f(0,0,0);
cameraRotation = new Vector3f(0,0,0);
maxRotation = new Vector3f(269,0,0);
minRotation = new Vector3f(89,0,0);
moveSpeed = 0.01f;
rotationSpeed = 0.2f;
camMatrix = new Matrix4f();
lVec = new Vector3f(1,0,0);
uVec = new Vector3f(0,1,0);
fVec = new Vector3f(0,0,1);
updateCamMatrix();
}
CameraModelling (Vector3f pos, Vector3f rot) {
this.cameraPosition = pos;
this.cameraRotation = rot;
moveSpeed = 0.01f;
rotationSpeed = 0.2f;
camMatrix = new Matrix4f();
lVec = new Vector3f(1,0,0);
uVec = new Vector3f(0,1,0);
fVec = new Vector3f(0,0,1);
updateCamMatrix();
}
private void updateCamMatrix() {
float DEG2RAD = 3.141593f / 180;
float sx, sy, sz, cx, cy, cz, theta;
theta = cameraRotation.x * DEG2RAD;
sx = (float) Math.sin(theta);
cx = (float) Math.cos(theta);
theta = cameraRotation.y * DEG2RAD;
sy = (float) Math.sin(theta);
cy = (float) Math.cos(theta);
theta = cameraRotation.z * DEG2RAD;
sz = (float) Math.sin(theta);
cz = (float) Math.cos(theta);
lVec.x = cy*cz;
lVec.y = sx*sy*cz + cx*sz;
lVec.z = -cx*sy*cz + sx*sz;
uVec.x = -cy*sz; // up.x = -cy*sz;dd
uVec.y = -sx*sy*sz + cx*cz; // up.y = -sx*sy*sz + cx*cz;
uVec.z = cx*sy*sz + sx*cz; // up.z = cx*sy*sz + sx*cz;
fVec.x = sy;
fVec.y = -sx*cy;
fVec.z = cx*cy;
/* Matrix is shaped like this:
m00 m10 m20 m30 1.0 0.0 0.0 0.0 lx ux fx px
m01 m11 m21 m31 0.0 1.0 0.0 0.0 ly uy fy py // No animals were harmed during the testing of matrix order.
m02 m12 m22 m32 0.0 0.0 1.0 0.0 lz uz fz pz // My pride, however, was.
m03 m13 m23 m33 0.0 0.0 0.0 1.0 lw uw fw pw
*/
camMatrix.m00 = lVec.x;
camMatrix.m01 = lVec.y;
camMatrix.m02 = lVec.z;
camMatrix.m10 = uVec.x;
camMatrix.m11 = uVec.y;
camMatrix.m12 = uVec.z;
camMatrix.m20 = fVec.x;
camMatrix.m21 = fVec.y;
camMatrix.m22 = fVec.z;
camMatrix.m30 = 0;
camMatrix.m31 = 0;
camMatrix.m32 = 0;
camMatrix.translate(cameraPosition); // figure out why l, u and f change on translation (lrn2matrix)
/*
camMatrix.m30 = cameraPosition.x;
camMatrix.m31 = cameraPosition.y; // Doing this causes shenanigans like orbiting around the origin.
camMatrix.m32 = cameraPosition.z;
*/
camMatrix.m33 = 1;
}
public void rotate(Vector3f v0) {
this.cameraRotation.x += v0.x;
this.cameraRotation.y += v0.y;
this.cameraRotation.z += v0.z;
if (this.cameraRotation.x > minRotation.x && this.cameraRotation.x < maxRotation.x && v0.x < 0) cameraRotation.x = 269;
if (this.cameraRotation.x > minRotation.x && this.cameraRotation.x < maxRotation.x && v0.x > 0) cameraRotation.x = 89;
updateCamMatrix();
}
public void move(Vector3f dir, float delta) {
// Moves the camera relative to the way it is looking.
System.out.println("y rotation is " + cameraRotation.y + " y forward vector is " + fVec.y);
if (dir.z > 0) {
cameraPosition.x -= (fVec.x * moveSpeed * delta);
if (cameraRotation.y > 90 && cameraRotation.y < 270) { cameraPosition.y += (fVec.y * moveSpeed * delta); }
else { cameraPosition.y -= (fVec.y * moveSpeed * delta); }
cameraPosition.z += (fVec.z * moveSpeed * delta);
} else if (dir.z < 0) {
cameraPosition.x += (fVec.x * moveSpeed * delta);
if (cameraRotation.y > 90 && cameraRotation.y < 270) { cameraPosition.y -= (fVec.y * moveSpeed * delta); } // still not sure why exactly Y goes inverse past 90 rot...
else { cameraPosition.y += (fVec.y * moveSpeed * delta); }
cameraPosition.z -= (fVec.z * moveSpeed * delta);
} else if (dir.x > 0) {
cameraPosition.x += lVec.x * moveSpeed * delta;
//cameraPosition.y += lVec.y * moveSpeed; //Don't want to move in Y space when going sideways
cameraPosition.z -= lVec.z * moveSpeed * delta;
} else if (dir.x < 0) {
cameraPosition.x -= lVec.x * moveSpeed * delta;
//cameraPosition.y -= lVec.y * moveSpeed; //Don't want to move in Y space when going sideways
cameraPosition.z += lVec.z * moveSpeed * delta;
} else if (dir.y > 0) {
cameraPosition.y -= moveSpeed * delta;
} else if (dir.y < 0) {
cameraPosition.y += moveSpeed * delta;
}
updateCamMatrix();
}
public Matrix4f getCameraMatrix() {
Matrix4f matrix = camMatrix;
return matrix;
}
public void setRotation(Vector3f v0) {
this.cameraRotation.x = v0.x;
this.cameraRotation.y = v0.y;
this.cameraRotation.z = v0.z;
updateCamMatrix();
}
public void setPosition(Vector3f v0) {
this.cameraPosition.x = v0.x;
this.cameraPosition.y = v0.y;
this.cameraPosition.z = v0.z;
updateCamMatrix();
}
public Vector3f getRotation() {
Vector3f v0 = new Vector3f();
v0 = cameraRotation;
return v0;
}
public Vector3f getPosition() {
Vector3f v0 = new Vector3f();
v0 = cameraPosition;
return v0;
}
public void setMoveSpeed(float f) {
moveSpeed = f;
}
public void setRotationSpeed(float f) {
rotationSpeed = f;
}
public float getMoveSpeed() {
float f = moveSpeed;
return f;
}
public float getRotationSpeed() {
float f = rotationSpeed;
return f;
}
public void log() {
System.out.println(camMatrix.m00 + " " + camMatrix.m10 + " " + camMatrix.m20 + " " + camMatrix.m30 + " " + uVec.x);
System.out.println(camMatrix.m01 + " " + camMatrix.m11 + " " + camMatrix.m21 + " " + camMatrix.m31);
System.out.println(camMatrix.m02 + " " + camMatrix.m12 + " " + camMatrix.m22 + " " + camMatrix.m32);
System.out.println(camMatrix.m03 + " " + camMatrix.m13 + " " + camMatrix.m23 + " " + camMatrix.m33);
}
}
Since getting even this to work was a real headbreaker I now feel kinda overwhelmed trying to figure out more. Anyways, any help & pointing in the right direction is appreciated!
(Any other feedback on my code is also very welcome :P)