Chase Camera turning?

I have a node which represents my player, which I am trying to get to turn with the X axis of the mouse, control with the WASD keys and look up and down with the Y axis of the mouse (think third person shooter style), and I tried this with the default ChaseCamera, but I could not get it to work, so instead I tried to write my own. This is what I have for the turning:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; //target.setLocalRotation(target.getLocalRotation().mult(value * rotationSpeed)); float f = value * rotationSpeed; float fn = -value * rotationSpeed; System.out.println(value + "f:" + f + "fn:" + fn); Vector3f v = new Vector3f(cam.getDirection().add(new Vector3f( f,0,fn))); Quaternion a = new Quaternion(); a.lookAt(v, cam.getUp()); System.out.println(a); target.rotate(a); }

and that is just used in place of the rotateCamera on the X axis in the default chaseCamera. It doesn't even seem to get any sort of reaction, and the camera is locked to the y Axis (even though the debug printlns return various values like -9, 0, 9 random quaternions etc). Additionally, the camera rotates strangely when I'm using it in the default mode, kind of like it's on a hinged string (it see saws instead of flat turning, if that makes sense).

This is the code for the camera initialisation:
Code:
cam = Main.appref.getCamera(); ccam = new PlayerCamera(cam, playerNode, Main.appref.getInputManager()); ccam.setDragToRotate(false); ccam.setSmoothMotion(true); ccam.setUpVector(Main.appref.getCamera().getUp()); ccam.setMaxDistance(85); ccam.setMinDistance(100); ccam.setTrailingEnabled(true); ccam.setTrailingSensitivity(1.25f); ccam.setLookAtOffset(new Vector3f(0,15,0)); ccam.setDefaultVerticalRotation(0.15f); ccam.setDefaultHorizontalRotation(-1.5f); playerNode.addControl(player); playerNode.addControl(ccam);

I'm not sure what to do here :(. Any help would be appreciated.

You know that the up and direction vectors for the lookAt method have to be perpendicular right? From what I see this doesn’t happen anymore if the cam direction isn’t parallel to the x axis anymore in your code. To get direction and up vectors just multiply UNIT_Z and UNIT_Y vectors with your quaternion.

1 Like

I hate math :v, I don’t think I understand what you mean… I tried doing:

Code:
a.lookAt(v.mult(Vector3f.UNIT_Z), cam.getUp().mult(Vector3f.UNIT_Y));
and
Code:
a.mult(Vector3f.UNIT_Z); a.mult(Vector3f.UNIT_Y);
and neither of those got a response, same locked position. Sorry if i'm being really silly here, I'm horrible with rotation and 3d space.

btw you also should use target.setLocalRotation()

I wrote up some code to do trackball rotation here: http://hub.jmonkeyengine.org/groups/graphics/forum/topic/trackball-samples Maybe that helps you a bit to get the grips on them rotations :slight_smile:

1 Like

I tried what you mention in that thread, with the code below:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; //target.setLocalRotation(target.getLocalRotation().mult(value * rotationSpeed)); float f = value * rotationSpeed; float fn = -value * rotationSpeed; System.out.println(value + "f:" + f + "fn:" + fn); Vector3f v = new Vector3f(cam.getDirection().add(new Vector3f( f,0,fn))); Quaternion a; if(value > 0) { a = new Quaternion().fromAngleAxis(FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } else { a = new Quaternion().fromAngleAxis(-FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } a.multLocal(v); a.multLocal(cam.getUp()); //target.setLocalRotation(a); target.lookAt(v, cam.getUp()); }

as you can see I tried setLocalRotation and LookAt, but neither worked. I've checked all throughout my code and nothing else anywhere is redirecting/repointing the model, so I'm unsure what's going on. (probably just me being daft and not know how to write code :v).

what are you trying to do with that cam.getdirection().add()? are you aware that the cam direction is a unit vector? if you want to rotate that to another direction you should do the same as described in the math for dummies tutorial and what I do in that code to rotate the vectors (multiplying by a quaternion that defines the relative rotation for this frame).

1 Like

I’m trying to set the new vector v to it, though I should be doing clone shouldn’t I? (just tried adding .clone in before the add and that didn’t do anything either :expressionless: ).

If you don’t use addLocal it will create a new vector anyway. So the whole “new Vector()” thing isn’t needed. As said, it seems you want to rotate it so do that instead of adding something :slight_smile:

1 Like

Aargh! I cannot get it to work! I’ve tried what you’ve got in the examples, I’ve tried setLocalRotation and rotate and all that, and here is what i’m stuck with currently:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; //target.setLocalRotation(target.getLocalRotation().mult(value * rotationSpeed)); float f = value * rotationSpeed; float fn = -value * rotationSpeed; System.out.println(value + "f:" + f + "fn:" + fn); Vector3f v = cam.getDirection().clone().add(new Vector3f( f,0,fn)); Quaternion a; if(value > 0) { a = new Quaternion().fromAngleAxis(FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } else { a = new Quaternion().fromAngleAxis(-FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } a.lookAt(v, cam.getUp()); //target.setLocalRotation(a); target.setLocalRotation(a); }

There is a slight wiggle in the movement, but I think that's from me moving up as I try furiously to turn.

I assume i'm working off the "A rotation around this up axis towards this direction
new Quaternion q" part of the Math sheet, that's what seemed to fit for it, but I can't get it to work. I think i'm just damned daft when it comes to math :'(.

[java]Vector3f v = cam.getDirection().clone().add(new Vector3f(

f,0,fn));[/java]

why do you do this?? you want to rotate the vector and not extend it. Read the math for dummies again (and again if necessary)

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies



You want to do something like this probably (it goes a bit back and forth between quaternions and vectors to show you how):

[java]

//get the current direction and up vectors

Vector3f dir = cam.getDirection().clone();

Vector3f up = cam.getDirection().clone();

//create a quaternion that defines a rotation around the Y axis

Quaternion quat = new Quaternion().fromAngleAxis(-FastMath.QUARTER_PI * tpf, Vector3f.UNIT_Y);

//rotate the vectors

quat.multLocal(dir);

quat.multLocal(up);

//make a new quaternion and create the rotation from the new dir and up vectors

Quaternion result = new Quaternion();

result.lookAt(dir,up);

//set to camera

cam.setRotation(result);

[/java]

1 Like

Whaaaat. Okay, I changed it to this:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; Vector3f dir = cam.getDirection(); Vector3f up = cam.getUp(); Quaternion a; if(value > 0) { a = new Quaternion().fromAngleAxis(FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } else { a = new Quaternion().fromAngleAxis(-FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } a.multLocal(dir); a.multLocal(up); Quaternion b = new Quaternion(); b.lookAt(dir, up); target.setLocalRotation(b); }

and it's still not working. It's still adamant in refusing to turn, on the upside, I've learned more how Quaternions work now. But apart from that, I can't find anything in my code that would stop that turn, nothing else is setting the angles of the player (target) spatial..

I’ve looked further into this, and I’m still unable to get it to work, but upon further testing, I’m unable to get the player to rotate in any way, anywhere (in the player update loop, main loop, other keys etc.), I’ve checked and double checked, nothing is setting the rotation, no setting viewdirection etc.



What could be preventing this from moving? The player is a CharacterControl attached to a spatial, and the camera is a modified ChaseCam.



I can’t find anything that’s causing it to do this, I’m so damn confused.



These are the only two files that majorly reference the player:

PlayerCamera.java

ObjectPlayer.java



I have no idea what’s going on.

Lol. If you have physics controls attached they move the spatial.

1 Like

I should have been paying attention to the other parts of my code, but even when I do something like:

Code:
target.getControl(CharacterControl.class).setViewDirection(dir);

The model only rotates up and down (the camera won't rotate left and right), and if I add the previous code from the old rotate camera, it goes back to it's pivot style rotate instead of left and right.

How can I achieve a camera turning left and right in a flat motion, instead of rotating like it's around a ball?

(Meanwhile i'm going to go sit in a corner for not realising that physics part, thanks so much normen.)

Okay, so i’ve tried this:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; isTurning = true; Vector3f dir = cam.getDirection(); Vector3f up = cam.getUp(); Quaternion a; if(value > 0) { a = new Quaternion().fromAngleAxis(FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } else { a = new Quaternion().fromAngleAxis(-FastMath.QUARTER_PI * value * rotationSpeed, Vector3f.UNIT_Y); } a.multLocal(dir); a.multLocal(up); Vector3f flat = new Vector3f(dir.x,0,dir.z); cam.lookAt(flat, up); target.getControl(CharacterControl.class).setViewDirection(flat); }

plus I changed the end of the update camera part to this:

[code]
if(!isTurning)
{
cam.lookAt(targetLocation, initialUpVec);
}


and included a added isTurning = false alongside the rotating = false in the update camera part, and this gets a sort of reaction; It makes the model spasmodically flip around and if I try to move and rotate at the same time, the character starts to move in the opposite of the direction I drag (no turning involved :().

Bah, what have I created! I don't get what's going on.

Start from scratch, the premise is much different with the character as it works using viewDirection and walkDirection vectors already and not with quaternions.

How do I get it to work though? From what i’ve tested, viewDirection changes the direction of the model and walkDirection adds to where it walks, but even with both of these, how would I go about putting it into the ChaseCamera?



From what I probed around, (as you could see in my previous post) the thing that was locking it in position was the final cam.lookAt of the update loop of the ChaseCamera, is using a boolean there the best way of switching between the rotations or is there better?

Okay, so I redid the rotation as this:

Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; isTurning = true; Vector3f dir = cam.getDirection(); Vector3f up = cam.getUp(); Vector3f flat = new Vector3f(dir.x,0,dir.z); target.getControl(CharacterControl.class).setViewDirection(flat); cam.lookAt(flat, up); }

And it still has pretty much the same effect, though if I remove the "cam.lookAt" it stops the random spasmodic movement. I'm so confused.

Edit:

Also tried this:
Code:
private void rotateTarget(float value) { if (!canRotate || !enabled) { return; } rotating = true; isTurning = true; Vector3f dir = cam.getDirection(); horizRotate = new Vector3f(dir.x,0,dir.z); }

along with this in the update:
Code:
if(!isTurning) { cam.lookAt(targetLocation, initialUpVec); } else { target.getControl(CharacterControl.class).setViewDirection(horizRotate); cam.lookAt(targetLocation, initialUpVec); isTurning = false; }
It does get to the else block, as i've tried putting debugging text there and it reaches it, but it still has the same effect of absolutely nothing, or stretchy movement on the cursor.

What am I doing wrong here?

Did you check the MonkeyZone sources? E.g. this file:

http://code.google.com/p/monkeyzone/source/browse/trunk/src/com/jme3/monkeyzone/controls/ManualCharacterControl.java