Question

I'm very new to 3D programming and I'm attempting to implement a camera that will follow my model using LibGDX. I'm having issues with the camera implementation and I would greatly appreciate some advice. As I said, I'm new to this (especially the maths) and the code below will almost certainly not be that great:

To rotate my object and camera at the same time I use the following code with inst being the model instance:

// right
inst.transform.rotate(new Vector3(0,1,0), -1);
Common.cam.rotate(Vector3.Y, -1f);
// left
inst.transform.rotate(new Vector3(0,1,0), 1);
Common.cam.rotate(Vector3.Y, 1f);

To move my object I use:

// forward
Common.inst.transform.mul(new Matrix4(new Vector3(0,0,((float)-0.2)),
                new Quaternion(0,0,0,0), new Vector3(1,1,1)));
// back
Common.inst.transform.mul(new Matrix4(new Vector3(0,0,((float)0.2)),
                new Quaternion(0,0,0,0), new Vector3(1,1,1)));

My camera is currently setup as follows:

Vector3 pos = inst.transform.getTranslation(new Vector3(0,0,0));
pos.z += 5;
cam.position.set(pos);

This code is working fine, but the problem is that the camera is staying in a fixed position when really it should be adjusting itself to be directly behind the new direction the model is facing. I've probably not articulated this clearly so I've represented this visually:

1 ^ Model (black) and camera (red) with no rotation

2 ^ What is currently happening upon rotation

3 ^ What needs to happen

I'd imagine this wouldn't be too difficult to implement if my maths was stronger, but I'm at a complete loss as how to implement this behavior. If someone could point me in the right direction that would be great.

Many thanks!

Was it helpful?

Solution

The problem is that you're translating the camera in world space, not the local space after it's rotated. A camera's position and rotation are stored in two Vector3's, not a Matrix.

You need to rotate your camera's translation vector before applying it.

By the way, you're going to run into GC stuttering issues if you instantiate a lot of Objects like that every frame. Also, there's already a translate method for the Matrix4 class, so you don't need to be manually multiplying it by another matrix to translate the object.

I would revise as follows:

//rotate player
float playerRotation = left ? 1 : -1; //TODO (should involve delta time...)
inst.transform.rotate(Vector3.Y, playerRotation);

//translate player
float playerZtranslation = forward ? 0.2f : -0.2f; //TODO (should involve delta time...)
inst.translate(0, 0, playerZtranslation );

//move camera to position of player.
inst.transform.getTranslation(camera.position);

//rotate camera to face same direction as player
inst.transform.getRotation(mTempRotation); //mTempRotation is a member Quaternion variable to avoid unnecessary instantiations every frame.
camera.direction.set(0,0,-1).rotate(mTempRotation);//reset and rotate to match current player angle

//rotate translation vector to match angle of player
mTempTranslation.set(0,0,5).rotate(mTempRotation); //mTempTranslation is a member Vector3 variable to avoid unnecessary instantiations every frame.

//and apply it.
cam.position.add(mTempTranslation);

Edit (see comments): Maybe try this:

//rotate and transform player variables
mPlayerYAngle += left ? 1 : -1; //TODO (should involve delta time...)
mPlayerPosition.add(0, 0, forward ? 0.2f : -0.2f); //TODO (should involve delta time...)

//apply changes by resetting transform to identity and applying variables
inst.transform.idt().translate(mPlayerPosition).rotate(Vector3.Y, mPlayerYAngle );

//move camera to position of player.
camera.position.set(mPlayerPosition);

//rotate camera to face same direction as player
camera.direction.set(0,0,-1).rotate(mPlayerYAngle ,0,1,0);//reset and rotate to match current player angle

//rotate translation vector to match angle of player
mTempTranslation.set(0,0,5).rotate(mPlayerYAngle ,0,1,0);

//and apply it.
cam.position.add(mTempTranslation);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top