Over-Shoulder Camera

Hey guys, I’m currently having an issue while trying to create a 3rd-person over-the-shoulder camera.

Basically I am using a chase cam to follow the character. The over-the-should chase cam works fine while facing 2 direction (West, North) but the camera switches sides for the other directions (East, South). To explain what is happening a bit better the following pictures show the character turning from North to East, Notice the camera changes shoulders:



http://i46.tinypic.com/2ufepz9.jpg



http://i47.tinypic.com/rhijqr.jpg



http://i47.tinypic.com/11hs8w8.jpg



The code for the chasecam is as follows:



[java] void init_camera() {

viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1));

flyCam.setEnabled(false);

chase_cam = new ChaseCamera(cam, player_model, inputManager);

chase_cam.setDragToRotate(false);

chase_cam.setInvertVerticalAxis(true);

chase_cam.setLookAtOffset(new Vector3f(-2f, 5f, -2f));

}[/java]

Maybe try use cam.getLeft().mult(distance to the left)

Is this lookAtOffset value in world coords @nehon? That would be kind of silly :slight_smile:

@normen said:
Is this lookAtOffset value in world coords @nehon? That would be kind of silly :)

lookAt is in world space, so basically you add an offset to a world space position, the result is in world space. I don't get what's silly here.

I'll have to look into the code, i did it a long time ago, and there was numerous patches since then.
@embattled a test case would really help here
@nehon said:
lookAt is in world space, so basically you add an offset to a world space position, the result is in world space. I don't get what's silly here.

The offset should be relative to the cam rotation, this way the cam would always be over the left shoulder.
@normen said:
The offset should be relative to the cam rotation, this way the cam would always be over the left shoulder.

That's wouldn't be a lookAtOffset then.
This wasn't the requirement i've been given when I did this. The idea was to offset where the camera was looking at because it was looking the model's origin by default (don't remember who asked but it was a forum request).

The OP's issue here IMO is that he's using the chase cam as a first person view.
The chase cam looks at the model it's attached to.
According to the screens, the user wants to look at "away from the player" but still wants the player's model in the view.
The chase cam does not do that.
@nehon said:
That's wouldn't be a lookAtOffset then.
This wasn't the requirement i've been given when I did this. The idea was to offset where the camera was looking at because it was looking the model's origin by default (don't remember who asked but it was a forum request).

Okay, but if the reason is in model space I don't get why the solution isn't as well.. His model turns so cam and model rotation should be the same?
LookAt happens every frame, so its orientation/offset can also be updated each frame.
@normen said:
His model turns so cam and model rotation should be the same?

This is not handled in the chase cam, it has to be handled by user code.

The rotation of the chase cam is independent from the target's rotation.

To make it work with the chase cam, maybe the OP shoudl attach a node to the player node. Offset it to the "upper left shoulder" position, and set the chaseCam to look at this node with no offset.
Then make the cam rotate along the model (or the other way around, like what you did in TestWalkingChar, make the model's rotation aligned with the camera direction).
I guess, this would make the desired effect.
@nehon said:
This is not handled in the chase cam, it has to be handled by user code.

The rotation of the chase cam is independent from the target's rotation.

To make it work with the chase cam, maybe the OP shoudl attach a node to the player node. Offset it to the "upper left shoulder" position, and set the chaseCam to look at this node with no offset.
Then make the cam rotate along the model (or the other way around, like what you did in TestWalkingChar, make the model's rotation aligned with the camera direction).
I guess, this would make the desired effect.

Yes okay, the other way round: Whats the actual use case of this method?

you mean like it’s done right now?



The use case is when you look at the character, usually the origin of the model is at its feet.

Usually you want to look at his head. so you set an offset of (0,heightOftheModel, 0).

@nehon said:
you mean like it's done right now?

The use case is when you look at the character, usually the origin of the model is at its feet.
Usually you want to look at his head. so you set an offset of (0,heightOftheModel, 0).

But if its head is tilted cause he's spiderman and walks on the wall that doesn't count?

mhhh, I didn’t consider spiderman…

nope the cam will look straight up the model’s origin.

If you look at it from far enough this is no real problem.



The chase cam does not fit every single need anyway…

I’d argue that the function wouldn’t be compromised if it was changed like I say for its current use, plus it would additionally cover the use case described here.

Thank you everyone for the time and assistance. I will take into account what you all have said and try to find the best solution! I will post my progress here.



Thank you once again :slight_smile:



EDIT: I have been following advice to try to get the camera to stay over the left shoulder. To do this, I have created a node, whose position updates constantly. The idea is to have a node positions just above the left shoulder, and make the chase cam aim at that. However, I can’t seem to find a way to position a node above the shoulder. The position of the shoulder is constantly changing and I’m trying to think of a method which will return the position of the shoulder. So far the closest I can get is this:

[java]cameraNode.setLocalTranslation(player.getPhysicsLocation().add(cam.getLeft().mult(50)));[/java]



However that just has the same result as shown in the original post. All help is appreciated.

Thank you.

Add the “shoulder” node as a sub-node of the model, it will then automatically move/rotate etc as the model moves. (See the scene graph tutorials for more info). If the model is a geometry you will need to wrap that in a node, add the shoulder node and the geometry to that one and then move/rotate the containing node rather than the geometry.

1 Like

What you could try is doing something like this:



[java]

if(player.getLocalRotation().toAngles(null)[1] * FastMath.RAD_TO_DEG >= 180) {

chase_cam.setLookAtOffset(new Vector3f(-2f, 5f, -2f));

}

else {

chase_cam.setLookAtOffset(new Vector3f(2f, 5f, -2f));

}

[/java]



You probably should play a little with the parameter of the if-statement and maybe even try switching the y or z coördinate of the setLookAtOffset() method. If this is the best way to fix your problem? Probably not… That’s one of the reasons why I wonder why you can’t attach a camera to a node. That way it’s possible to handle movement on a node which is, for instance, called player. And that way the camera and other objects in this same node are always relative to eachother, or rather… relative to the parentNode.



In case this is coming, you probably want to ignore the camera in case physics are added to the node…

Instead of offsetting the camera what about offsetting your character? I did this with a model I was working on recently since I didn’t like where it was centred. Set your chase cam to follow a node that has a child spatial of your model and then offset the spatial model.



I can’t paste the code I use right now since I’m not near my PC with the code in question. So right now this is food for thought.